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:
authorBastien Montagne <montagne29@wanadoo.fr>2018-06-09 16:36:37 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2018-06-09 16:36:37 +0300
commit2b83d81f68e18f60955c72cd61b3cdc62670c69a (patch)
tree971e8e8391a852733a8d2bf4e617633bec84912c
parentd3fe0338752de05916bb3e3e15bb3c5ef4d18dc5 (diff)
parent70f8eaf1b769c402ec61d86f25237d6b64186861 (diff)
Merge branch 'blender2.8' into ui_layout_gridflow
-rw-r--r--CMakeLists.txt24
-rw-r--r--build_files/build_environment/cmake/openal.cmake1
-rw-r--r--build_files/build_environment/cmake/options.cmake25
-rw-r--r--build_files/build_environment/patches/openal.diff13
-rw-r--r--build_files/build_environment/patches/osl.diff4
-rw-r--r--build_files/build_environment/windows/build_deps.cmd18
-rw-r--r--build_files/cmake/platform/platform_win32.cmake3
-rw-r--r--build_files/windows/configure_msbuild.cmd7
-rw-r--r--build_files/windows/configure_ninja.cmd6
-rw-r--r--build_files/windows/detect_msvc2017.cmd7
-rw-r--r--build_files/windows/parse_arguments.cmd4
-rw-r--r--build_files/windows/reset_variables.cmd4
-rw-r--r--build_files/windows/show_help.cmd12
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEG.cpp2
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp124
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.h5
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp216
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h13
-rw-r--r--intern/cycles/blender/addon/ui.py562
-rw-r--r--intern/cycles/blender/blender_object.cpp16
-rw-r--r--intern/gawain/gawain/gwn_common.h2
-rw-r--r--intern/gawain/src/gwn_batch.c2
-rw-r--r--intern/gawain/src/gwn_immediate.c2
-rw-r--r--intern/ghost/CMakeLists.txt4
-rw-r--r--intern/ghost/GHOST_C-api.h12
-rw-r--r--intern/ghost/GHOST_IEvent.h10
-rw-r--r--intern/ghost/GHOST_ISystem.h2
-rw-r--r--intern/ghost/GHOST_ISystemPaths.h4
-rw-r--r--intern/ghost/GHOST_ITimerTask.h6
-rw-r--r--intern/ghost/GHOST_IWindow.h2
-rw-r--r--intern/ghost/GHOST_Path-api.h4
-rw-r--r--intern/ghost/GHOST_Types.h20
-rw-r--r--intern/ghost/intern/GHOST_Buttons.h2
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp48
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.h2
-rw-r--r--intern/ghost/intern/GHOST_Debug.h4
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.cpp4
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.h8
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.h8
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.cpp14
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.h6
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.cpp2
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.h8
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.cpp36
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.h22
-rw-r--r--intern/ghost/intern/GHOST_Event.h4
-rw-r--r--intern/ghost/intern/GHOST_EventDragnDrop.h16
-rw-r--r--intern/ghost/intern/GHOST_EventKey.h4
-rw-r--r--intern/ghost/intern/GHOST_EventManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_EventManager.h2
-rw-r--r--intern/ghost/intern/GHOST_EventNDOF.h2
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.cpp12
-rw-r--r--intern/ghost/intern/GHOST_ISystemPaths.cpp2
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h2
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.h2
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerUnix.cpp2
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerUnix.h4
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerWin32.cpp4
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerWin32.h2
-rw-r--r--intern/ghost/intern/GHOST_Rect.cpp2
-rw-r--r--intern/ghost/intern/GHOST_System.cpp6
-rw-r--r--intern/ghost/intern/GHOST_System.h16
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h30
-rw-r--r--intern/ghost/intern/GHOST_SystemPaths.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsCocoa.h4
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsUnix.cpp4
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsUnix.h6
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp146
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h18
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp189
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h27
-rw-r--r--intern/ghost/intern/GHOST_TaskbarWin32.h2
-rw-r--r--intern/ghost/intern/GHOST_TaskbarX11.cpp2
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.cpp6
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.h4
-rw-r--r--intern/ghost/intern/GHOST_TimerTask.h10
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp10
-rw-r--r--intern/ghost/intern/GHOST_Window.h42
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h34
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.cpp10
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.h18
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp10
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h20
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp62
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h26
-rw-r--r--intern/ghost/test/CMakeLists.txt4
-rw-r--r--intern/ghost/test/gears/GHOST_C-Test.c68
-rw-r--r--intern/ghost/test/gears/GHOST_Test.cpp4
-rw-r--r--intern/ghost/test/multitest/Basic.h8
-rw-r--r--intern/ghost/test/multitest/EventToBuf.c4
-rw-r--r--intern/ghost/test/multitest/MultiTest.c168
-rw-r--r--intern/ghost/test/multitest/ScrollBar.c8
-rw-r--r--intern/ghost/test/multitest/ScrollBar.h2
-rw-r--r--intern/ghost/test/multitest/Util.c10
-rw-r--r--intern/ghost/test/multitest/WindowData.c2
-rw-r--r--intern/ghost/test/multitest/WindowData.h4
-rw-r--r--release/datafiles/studiolights/matcap/license.txt3
-rw-r--r--release/datafiles/studiolights/matcap/mc01.jpgbin0 -> 20830 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc02.jpgbin0 -> 23428 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc03.jpgbin0 -> 17550 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc04.jpgbin0 -> 29197 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc05.jpgbin0 -> 25454 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc06.jpgbin0 -> 19864 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc07.jpgbin0 -> 59262 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc08.jpgbin0 -> 24133 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc09.jpgbin0 -> 31101 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc10.jpgbin0 -> 28973 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc11.jpgbin0 -> 21395 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc12.jpgbin0 -> 23797 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc13.jpgbin0 -> 45661 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc14.jpgbin0 -> 44762 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc15.jpgbin0 -> 27456 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc16.jpgbin0 -> 33401 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc17.jpgbin0 -> 49292 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc18.jpgbin0 -> 40254 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc19.jpgbin0 -> 46330 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc20.jpgbin0 -> 52893 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc21.jpgbin0 -> 28717 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc22.jpgbin0 -> 33801 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc23.jpgbin0 -> 26688 bytes
-rw-r--r--release/datafiles/studiolights/matcap/mc24.jpgbin0 -> 14149 bytes
m---------release/scripts/addons0
m---------release/scripts/addons_contrib0
-rw-r--r--release/scripts/startup/bl_operators/image.py2
-rw-r--r--release/scripts/startup/bl_operators/mask.py2
-rw-r--r--release/scripts/startup/bl_operators/screen_play_rendered_anim.py2
-rw-r--r--release/scripts/startup/bl_operators/sequencer.py2
-rw-r--r--release/scripts/startup/bl_operators/wm.py126
-rw-r--r--release/scripts/startup/bl_ui/__init__.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_animviz.py31
-rw-r--r--release/scripts/startup/bl_ui/properties_constraint.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py52
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lamp.py59
-rw-r--r--release/scripts/startup/bl_ui/properties_freestyle.py19
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_mask_common.py32
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py3
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py1254
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_cloth.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py40
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py64
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_view_layer.py2
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py9
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py78
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py72
-rw-r--r--release/scripts/startup/bl_ui/space_image.py41
-rw-r--r--release/scripts/startup/bl_ui/space_node.py41
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py14
-rw-r--r--release/scripts/startup/bl_ui/space_properties.py3
-rw-r--r--release/scripts/startup/bl_ui/space_statusbar.py1
-rw-r--r--release/scripts/startup/bl_ui/space_time.py4
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_common.py23
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py3
-rw-r--r--release/scripts/startup/bl_ui/space_topbar.py7
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py87
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py401
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py35
-rw-r--r--source/blender/alembic/ABC_alembic.h15
-rw-r--r--source/blender/alembic/intern/abc_camera.cc6
-rw-r--r--source/blender/alembic/intern/abc_camera.h4
-rw-r--r--source/blender/alembic/intern/abc_curves.cc53
-rw-r--r--source/blender/alembic/intern/abc_curves.h21
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc101
-rw-r--r--source/blender/alembic/intern/abc_exporter.h18
-rw-r--r--source/blender/alembic/intern/abc_hair.cc60
-rw-r--r--source/blender/alembic/intern/abc_hair.h9
-rw-r--r--source/blender/alembic/intern/abc_mball.cc9
-rw-r--r--source/blender/alembic/intern/abc_mball.h2
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc362
-rw-r--r--source/blender/alembic/intern/abc_mesh.h42
-rw-r--r--source/blender/alembic/intern/abc_nurbs.cc20
-rw-r--r--source/blender/alembic/intern/abc_nurbs.h4
-rw-r--r--source/blender/alembic/intern/abc_object.cc16
-rw-r--r--source/blender/alembic/intern/abc_object.h16
-rw-r--r--source/blender/alembic/intern/abc_points.cc56
-rw-r--r--source/blender/alembic/intern/abc_points.h12
-rw-r--r--source/blender/alembic/intern/abc_transform.cc17
-rw-r--r--source/blender/alembic/intern/abc_transform.h3
-rw-r--r--source/blender/alembic/intern/abc_util.cc10
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc38
-rw-r--r--source/blender/blenfont/intern/blf.c2
-rw-r--r--source/blender/blenfont/intern/blf_dir.c16
-rw-r--r--source/blender/blenfont/intern/blf_font.c2
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c4
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h2
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h12
-rw-r--r--source/blender/blenkernel/BKE_anim.h34
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_collection.h1
-rw-r--r--source/blender/blenkernel/BKE_library.h3
-rw-r--r--source/blender/blenkernel/BKE_mball.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h19
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h85
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h3
-rw-r--r--source/blender/blenkernel/BKE_object.h4
-rw-r--r--source/blender/blenkernel/BKE_paint.h6
-rw-r--r--source/blender/blenkernel/BKE_particle.h4
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/BKE_screen.h109
-rw-r--r--source/blender/blenkernel/BKE_studiolight.h30
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c27
-rw-r--r--source/blender/blenkernel/intern/blender_undo.c12
-rw-r--r--source/blender/blenkernel/intern/blendfile.c44
-rw-r--r--source/blender/blenkernel/intern/bpath.c2
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c1
-rw-r--r--source/blender/blenkernel/intern/cachefile.c23
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c5
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/collection.c41
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c1
-rw-r--r--source/blender/blenkernel/intern/displist.c94
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c2
-rw-r--r--source/blender/blenkernel/intern/font.c6
-rw-r--r--source/blender/blenkernel/intern/image.c9
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/layer.c10
-rw-r--r--source/blender/blenkernel/intern/library.c22
-rw-r--r--source/blender/blenkernel/intern/material.c4
-rw-r--r--source/blender/blenkernel/intern/mball.c5
-rw-r--r--source/blender/blenkernel/intern/mesh.c63
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c5
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c14
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.c22
-rw-r--r--source/blender/blenkernel/intern/modifier.c12
-rw-r--r--source/blender/blenkernel/intern/movieclip.c18
-rw-r--r--source/blender/blenkernel/intern/multires.c1
-rw-r--r--source/blender/blenkernel/intern/node.c34
-rw-r--r--source/blender/blenkernel/intern/object.c83
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c75
-rw-r--r--source/blender/blenkernel/intern/object_update.c1
-rw-r--r--source/blender/blenkernel/intern/packedFile.c14
-rw-r--r--source/blender/blenkernel/intern/paint.c134
-rw-r--r--source/blender/blenkernel/intern/particle.c47
-rw-r--r--source/blender/blenkernel/intern/particle_system.c36
-rw-r--r--source/blender/blenkernel/intern/pbvh.c7
-rw-r--r--source/blender/blenkernel/intern/pointcache.c2
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c3
-rw-r--r--source/blender/blenkernel/intern/scene.c6
-rw-r--r--source/blender/blenkernel/intern/screen.c82
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c13
-rw-r--r--source/blender/blenkernel/intern/sequencer.c21
-rw-r--r--source/blender/blenkernel/intern/sound.c4
-rw-r--r--source/blender/blenkernel/intern/studiolight.c82
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c5
-rw-r--r--source/blender/blenkernel/intern/text.c6
-rw-r--r--source/blender/blenkernel/intern/undo_system.c2
-rw-r--r--source/blender/blenkernel/intern/world.c9
-rw-r--r--source/blender/blenkernel/intern/writeavi.c2
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c2
-rw-r--r--source/blender/blenlib/BLI_math_base.h18
-rw-r--r--source/blender/blenloader/intern/readfile.c33
-rw-r--r--source/blender/blenloader/intern/readfile.h16
-rw-r--r--source/blender/blenloader/intern/undofile.c2
-rw-r--r--source/blender/blenloader/intern/versioning_250.c254
-rw-r--r--source/blender/blenloader/intern/versioning_260.c390
-rw-r--r--source/blender/blenloader/intern/versioning_270.c270
-rw-r--r--source/blender/blenloader/intern/versioning_280.c221
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c427
-rw-r--r--source/blender/blenloader/intern/writefile.c15
-rw-r--r--source/blender/bmesh/bmesh_class.h8
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c58
-rw-r--r--source/blender/bmesh/intern/bmesh_delete.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c44
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators_inline.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c16
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c20
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c1
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c36
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c48
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c8
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c14
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c32
-rw-r--r--source/blender/bmesh/operators/bmo_create.c2
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c12
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c20
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c20
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c18
-rw-r--r--source/blender/bmesh/operators/bmo_mirror.c12
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c34
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c8
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c78
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c12
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c24
-rw-r--r--source/blender/collada/AnimationExporter.cpp54
-rw-r--r--source/blender/collada/AnimationExporter.h22
-rw-r--r--source/blender/collada/AnimationImporter.cpp121
-rw-r--r--source/blender/collada/AnimationImporter.h28
-rw-r--r--source/blender/collada/ArmatureExporter.cpp21
-rw-r--r--source/blender/collada/ArmatureExporter.h4
-rw-r--r--source/blender/collada/ArmatureImporter.cpp57
-rw-r--r--source/blender/collada/ArmatureImporter.h10
-rw-r--r--source/blender/collada/CameraExporter.cpp4
-rw-r--r--source/blender/collada/ControllerExporter.cpp22
-rw-r--r--source/blender/collada/DocumentExporter.cpp21
-rw-r--r--source/blender/collada/DocumentExporter.h2
-rw-r--r--source/blender/collada/DocumentImporter.cpp92
-rw-r--r--source/blender/collada/DocumentImporter.h6
-rw-r--r--source/blender/collada/EffectExporter.cpp22
-rw-r--r--source/blender/collada/EffectExporter.h10
-rw-r--r--source/blender/collada/ErrorHandler.cpp2
-rw-r--r--source/blender/collada/ExtraHandler.cpp4
-rw-r--r--source/blender/collada/ExtraHandler.h18
-rw-r--r--source/blender/collada/ExtraTags.cpp2
-rw-r--r--source/blender/collada/ExtraTags.h16
-rw-r--r--source/blender/collada/GeometryExporter.cpp92
-rw-r--r--source/blender/collada/GeometryExporter.h8
-rw-r--r--source/blender/collada/ImageExporter.cpp10
-rw-r--r--source/blender/collada/ImageExporter.h2
-rw-r--r--source/blender/collada/InstanceWriter.cpp8
-rw-r--r--source/blender/collada/LightExporter.cpp16
-rw-r--r--source/blender/collada/MaterialExporter.h2
-rw-r--r--source/blender/collada/MeshImporter.cpp82
-rw-r--r--source/blender/collada/MeshImporter.h10
-rw-r--r--source/blender/collada/SceneExporter.cpp28
-rw-r--r--source/blender/collada/SceneExporter.h8
-rw-r--r--source/blender/collada/SkinInfo.cpp8
-rw-r--r--source/blender/collada/SkinInfo.h4
-rw-r--r--source/blender/collada/TransformReader.cpp6
-rw-r--r--source/blender/collada/TransformReader.h2
-rw-r--r--source/blender/collada/TransformWriter.cpp2
-rw-r--r--source/blender/collada/collada.cpp5
-rw-r--r--source/blender/collada/collada.h4
-rw-r--r--source/blender/collada/collada_internal.h8
-rw-r--r--source/blender/collada/collada_utils.cpp24
-rw-r--r--source/blender/collada/collada_utils.h8
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp10
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cpp7
-rw-r--r--source/blender/datatoc/datatoc_icon.c2
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h13
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cycle.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc230
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h24
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc31
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc12
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc421
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h23
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc44
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc12
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc14
-rw-r--r--source/blender/depsgraph/intern/depsgraph_type_defines.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_types.h15
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc50
-rw-r--r--source/blender/draw/CMakeLists.txt3
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c2
-rw-r--r--source/blender/draw/engines/clay/clay_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c45
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c144
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c39
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c32
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl14
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl28
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl34
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl13
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_vert.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl71
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl79
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl21
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl3
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl63
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl38
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl50
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl58
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl33
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl3
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl6
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c72
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c274
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c147
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c67
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h47
-rw-r--r--source/blender/draw/engines/workbench/workbench_studiolight.c33
-rw-r--r--source/blender/draw/intern/DRW_render.h4
-rw-r--r--source/blender/draw/intern/draw_armature.c29
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c98
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c4
-rw-r--r--source/blender/draw/intern/draw_common.h6
-rw-r--r--source/blender/draw/intern/draw_hair.c24
-rw-r--r--source/blender/draw/intern/draw_instance_data.h2
-rw-r--r--source/blender/draw/intern/draw_manager.c38
-rw-r--r--source/blender/draw/intern/draw_manager.h5
-rw-r--r--source/blender/draw/intern/draw_manager_data.c47
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c19
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c36
-rw-r--r--source/blender/draw/modes/object_mode.c6
-rw-r--r--source/blender/draw/modes/overlay_mode.c48
-rw-r--r--source/blender/draw/modes/particle_mode.c6
-rw-r--r--source/blender/draw/modes/pose_mode.c24
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl2
-rw-r--r--source/blender/draw/modes/shaders/common_hair_lib.glsl8
-rw-r--r--source/blender/draw/modes/shaders/common_hair_refine_vert.glsl46
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl27
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl78
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl87
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c1140
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c896
-rw-r--r--source/blender/editors/animation/anim_deps.c106
-rw-r--r--source/blender/editors/animation/anim_draw.c44
-rw-r--r--source/blender/editors/animation/anim_filter.c896
-rw-r--r--source/blender/editors/animation/anim_intern.h6
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c58
-rw-r--r--source/blender/editors/animation/anim_markers.c214
-rw-r--r--source/blender/editors/animation/anim_ops.c110
-rw-r--r--source/blender/editors/animation/drivers.c322
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c242
-rw-r--r--source/blender/editors/animation/keyframes_draw.c266
-rw-r--r--source/blender/editors/animation/keyframes_edit.c322
-rw-r--r--source/blender/editors/animation/keyframes_general.c220
-rw-r--r--source/blender/editors/animation/keyframing.c652
-rw-r--r--source/blender/editors/animation/keyingsets.c299
-rw-r--r--source/blender/editors/armature/armature_add.c176
-rw-r--r--source/blender/editors/armature/armature_edit.c265
-rw-r--r--source/blender/editors/armature/armature_intern.h10
-rw-r--r--source/blender/editors/armature/armature_naming.c84
-rw-r--r--source/blender/editors/armature/armature_ops.c100
-rw-r--r--source/blender/editors/armature/armature_relations.c248
-rw-r--r--source/blender/editors/armature/armature_select.c60
-rw-r--r--source/blender/editors/armature/armature_skinning.c63
-rw-r--r--source/blender/editors/armature/armature_utils.c94
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c2644
-rw-r--r--source/blender/editors/armature/meshlaplacian.c51
-rw-r--r--source/blender/editors/armature/pose_edit.c269
-rw-r--r--source/blender/editors/armature/pose_group.c96
-rw-r--r--source/blender/editors/armature/pose_lib.c479
-rw-r--r--source/blender/editors/armature/pose_select.c188
-rw-r--r--source/blender/editors/armature/pose_slide.c432
-rw-r--r--source/blender/editors/armature/pose_transform.c195
-rw-r--r--source/blender/editors/armature/pose_utils.c78
-rw-r--r--source/blender/editors/curve/curve_ops.c18
-rw-r--r--source/blender/editors/curve/editcurve.c228
-rw-r--r--source/blender/editors/curve/editcurve_paint.c4
-rw-r--r--source/blender/editors/curve/editfont.c132
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c26
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c152
-rw-r--r--source/blender/editors/gpencil/gpencil_brush.c446
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c328
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c164
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c577
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c280
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c162
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c493
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c324
-rw-r--r--source/blender/editors/gpencil/gpencil_undo.c52
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c151
-rw-r--r--source/blender/editors/include/ED_anim_api.h96
-rw-r--r--source/blender/editors/include/ED_armature.h17
-rw-r--r--source/blender/editors/include/ED_curve.h11
-rw-r--r--source/blender/editors/include/ED_gpencil.h2
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h14
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h8
-rw-r--r--source/blender/editors/include/ED_keyframing.h36
-rw-r--r--source/blender/editors/include/ED_markers.h2
-rw-r--r--source/blender/editors/include/ED_node.h2
-rw-r--r--source/blender/editors/include/ED_object.h4
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/include/ED_screen_types.h2
-rw-r--r--source/blender/editors/include/ED_space_api.h4
-rw-r--r--source/blender/editors/include/ED_transform_snap_object_context.h4
-rw-r--r--source/blender/editors/include/ED_view3d.h6
-rw-r--r--source/blender/editors/include/UI_icons.h28
-rw-r--r--source/blender/editors/include/UI_interface.h26
-rw-r--r--source/blender/editors/include/UI_resources.h47
-rw-r--r--source/blender/editors/include/UI_view2d.h6
-rw-r--r--source/blender/editors/interface/interface.c14
-rw-r--r--source/blender/editors/interface/interface_anim.c4
-rw-r--r--source/blender/editors/interface/interface_eyedropper_depth.c1
-rw-r--r--source/blender/editors/interface/interface_handlers.c36
-rw-r--r--source/blender/editors/interface/interface_icons.c2
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c78
-rw-r--r--source/blender/editors/interface/interface_ops.c2
-rw-r--r--source/blender/editors/interface/interface_panel.c296
-rw-r--r--source/blender/editors/interface/interface_region_menu_pie.c12
-rw-r--r--source/blender/editors/interface/interface_region_popover.c8
-rw-r--r--source/blender/editors/interface/interface_templates.c4
-rw-r--r--source/blender/editors/interface/interface_widgets.c21
-rw-r--r--source/blender/editors/interface/resources.c17
-rw-r--r--source/blender/editors/io/io_alembic.c8
-rw-r--r--source/blender/editors/io/io_cache.c2
-rw-r--r--source/blender/editors/io/io_collada.c21
-rw-r--r--source/blender/editors/io/io_ops.c2
-rw-r--r--source/blender/editors/mask/mask_editaction.c10
-rw-r--r--source/blender/editors/mesh/editface.c28
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c12
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c1
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c32
-rw-r--r--source/blender/editors/mesh/editmesh_select.c6
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c5
-rw-r--r--source/blender/editors/mesh/mesh_data.c32
-rw-r--r--source/blender/editors/mesh/mesh_navmesh.c8
-rw-r--r--source/blender/editors/mesh/mesh_ops.c54
-rw-r--r--source/blender/editors/mesh/meshtools.c101
-rw-r--r--source/blender/editors/metaball/mball_edit.c34
-rw-r--r--source/blender/editors/metaball/mball_ops.c12
-rw-r--r--source/blender/editors/object/object_add.c15
-rw-r--r--source/blender/editors/object/object_bake_api.c5
-rw-r--r--source/blender/editors/object/object_constraint.c419
-rw-r--r--source/blender/editors/object/object_data_transfer.c1
-rw-r--r--source/blender/editors/object/object_edit.c189
-rw-r--r--source/blender/editors/object/object_group.c46
-rw-r--r--source/blender/editors/object/object_hook.c187
-rw-r--r--source/blender/editors/object/object_modes.c2
-rw-r--r--source/blender/editors/object/object_modifier.c275
-rw-r--r--source/blender/editors/object/object_ops.c50
-rw-r--r--source/blender/editors/object/object_relations.c2
-rw-r--r--source/blender/editors/object/object_select.c106
-rw-r--r--source/blender/editors/object/object_shapekey.c16
-rw-r--r--source/blender/editors/object/object_transform.c98
-rw-r--r--source/blender/editors/object/object_vgroup.c73
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c24
-rw-r--r--source/blender/editors/physics/particle_boids.c42
-rw-r--r--source/blender/editors/physics/particle_edit.c234
-rw-r--r--source/blender/editors/physics/particle_edit_undo.c2
-rw-r--r--source/blender/editors/physics/particle_object.c187
-rw-r--r--source/blender/editors/physics/physics_fluid.c264
-rw-r--r--source/blender/editors/physics/physics_ops.c8
-rw-r--r--source/blender/editors/physics/physics_pointcache.c24
-rw-r--r--source/blender/editors/physics/rigidbody_world.c4
-rw-r--r--source/blender/editors/render/render_internal.c30
-rw-r--r--source/blender/editors/render/render_opengl.c18
-rw-r--r--source/blender/editors/render/render_ops.c2
-rw-r--r--source/blender/editors/render/render_preview.c126
-rw-r--r--source/blender/editors/render/render_shading.c72
-rw-r--r--source/blender/editors/render/render_update.c14
-rw-r--r--source/blender/editors/render/render_view.c12
-rw-r--r--source/blender/editors/screen/area.c281
-rw-r--r--source/blender/editors/screen/glutil.c16
-rw-r--r--source/blender/editors/screen/screen_context.c42
-rw-r--r--source/blender/editors/screen/screen_edit.c165
-rw-r--r--source/blender/editors/screen/screen_intern.h2
-rw-r--r--source/blender/editors/screen/screen_ops.c724
-rw-r--r--source/blender/editors/screen/screendump.c84
-rw-r--r--source/blender/editors/screen/workspace_edit.c8
-rw-r--r--source/blender/editors/screen/workspace_layout_edit.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c24
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c46
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c95
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c22
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c24
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c24
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c21
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_ops.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c1
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c96
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c35
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c2
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_action/action_buttons.c12
-rw-r--r--source/blender/editors/space_action/action_data.c208
-rw-r--r--source/blender/editors/space_action/action_draw.c86
-rw-r--r--source/blender/editors/space_action/action_edit.c518
-rw-r--r--source/blender/editors/space_action/action_intern.h8
-rw-r--r--source/blender/editors/space_action/action_ops.c78
-rw-r--r--source/blender/editors/space_action/action_select.c464
-rw-r--r--source/blender/editors/space_action/space_action.c169
-rw-r--r--source/blender/editors/space_api/spacetypes.c34
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c19
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c15
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c14
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c77
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c4
-rw-r--r--source/blender/editors/space_clip/clip_editor.c2
-rw-r--r--source/blender/editors/space_clip/clip_ops.c4
-rw-r--r--source/blender/editors/space_clip/space_clip.c4
-rw-r--r--source/blender/editors/space_clip/tracking_ops_intern.h2
-rw-r--r--source/blender/editors/space_console/console_draw.c12
-rw-r--r--source/blender/editors/space_console/console_ops.c98
-rw-r--r--source/blender/editors/space_console/space_console.c76
-rw-r--r--source/blender/editors/space_file/file_draw.c30
-rw-r--r--source/blender/editors/space_file/file_intern.h6
-rw-r--r--source/blender/editors/space_file/file_ops.c208
-rw-r--r--source/blender/editors/space_file/filelist.c41
-rw-r--r--source/blender/editors/space_file/filesel.c42
-rw-r--r--source/blender/editors/space_file/fsmenu.c26
-rw-r--r--source/blender/editors/space_file/fsmenu.h2
-rw-r--r--source/blender/editors/space_file/space_file.c44
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c320
-rw-r--r--source/blender/editors/space_graph/graph_draw.c228
-rw-r--r--source/blender/editors/space_graph/graph_edit.c870
-rw-r--r--source/blender/editors/space_graph/graph_intern.h6
-rw-r--r--source/blender/editors/space_graph/graph_ops.c209
-rw-r--r--source/blender/editors/space_graph/graph_select.c498
-rw-r--r--source/blender/editors/space_graph/graph_utils.c64
-rw-r--r--source/blender/editors/space_graph/space_graph.c192
-rw-r--r--source/blender/editors/space_image/image_buttons.c72
-rw-r--r--source/blender/editors/space_image/image_draw.c16
-rw-r--r--source/blender/editors/space_image/image_edit.c4
-rw-r--r--source/blender/editors/space_image/image_ops.c208
-rw-r--r--source/blender/editors/space_image/space_image.c97
-rw-r--r--source/blender/editors/space_info/info_draw.c4
-rw-r--r--source/blender/editors/space_info/info_ops.c108
-rw-r--r--source/blender/editors/space_info/info_stats.c18
-rw-r--r--source/blender/editors/space_info/space_info.c50
-rw-r--r--source/blender/editors/space_info/textview.c12
-rw-r--r--source/blender/editors/space_info/textview.h2
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c126
-rw-r--r--source/blender/editors/space_nla/nla_channels.c206
-rw-r--r--source/blender/editors/space_nla/nla_draw.c134
-rw-r--r--source/blender/editors/space_nla/nla_edit.c900
-rw-r--r--source/blender/editors/space_nla/nla_ops.c130
-rw-r--r--source/blender/editors/space_nla/nla_select.c196
-rw-r--r--source/blender/editors/space_nla/space_nla.c132
-rw-r--r--source/blender/editors/space_node/drawnode.c320
-rw-r--r--source/blender/editors/space_node/node_add.c96
-rw-r--r--source/blender/editors/space_node/node_buttons.c36
-rw-r--r--source/blender/editors/space_node/node_draw.c248
-rw-r--r--source/blender/editors/space_node/node_edit.c363
-rw-r--r--source/blender/editors/space_node/node_group.c305
-rw-r--r--source/blender/editors/space_node/node_intern.h5
-rw-r--r--source/blender/editors/space_node/node_ops.c70
-rw-r--r--source/blender/editors/space_node/node_relationships.c122
-rw-r--r--source/blender/editors/space_node/node_select.c182
-rw-r--r--source/blender/editors/space_node/node_templates.c67
-rw-r--r--source/blender/editors/space_node/node_toolbar.c6
-rw-r--r--source/blender/editors/space_node/node_view.c21
-rw-r--r--source/blender/editors/space_node/space_node.c70
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c154
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c314
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h2
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c26
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c74
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c216
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c212
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c44
-rw-r--r--source/blender/editors/space_script/space_script.c52
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c100
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c104
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c330
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_preview.c24
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c26
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c136
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c4
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c46
-rw-r--r--source/blender/editors/space_text/space_text.c82
-rw-r--r--source/blender/editors/space_text/text_draw.c52
-rw-r--r--source/blender/editors/space_text/text_format.c2
-rw-r--r--source/blender/editors/space_text/text_format_lua.c4
-rw-r--r--source/blender/editors/space_text/text_format_osl.c2
-rw-r--r--source/blender/editors/space_text/text_header.c22
-rw-r--r--source/blender/editors/space_text/text_ops.c188
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c8
-rw-r--r--source/blender/editors/space_view3d/drawobject.c3
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c113
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c49
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h4
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_armature.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_camera.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_empty.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_forcefield.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_lamp.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_navigate.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_ruler.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c55
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c153
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c70
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c34
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c68
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c4
-rw-r--r--source/blender/editors/transform/transform.c12
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_conversions.c185
-rw-r--r--source/blender/editors/transform/transform_generics.c6
-rw-r--r--source/blender/editors/transform/transform_manipulator_3d.c51
-rw-r--r--source/blender/editors/transform/transform_orientations.c12
-rw-r--r--source/blender/editors/transform/transform_snap.c8
-rw-r--r--source/blender/editors/transform/transform_snap_object.c9
-rw-r--r--source/blender/editors/undo/ed_undo.c5
-rw-r--r--source/blender/editors/util/ed_util.c6
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c12
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c38
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c120
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c168
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.h2
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c58
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp2
-rw-r--r--source/blender/gpu/GPU_material.h19
-rw-r--r--source/blender/gpu/GPU_texture.h7
-rw-r--r--source/blender/gpu/GPU_uniformbuffer.h2
-rw-r--r--source/blender/gpu/intern/gpu_basic_shader.c4
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c4
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c217
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h16
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c4
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c4
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c6
-rw-r--r--source/blender/gpu/intern/gpu_material.c180
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c2
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c2
-rw-r--r--source/blender/gpu/intern/gpu_shader.c4
-rw-r--r--source/blender/gpu/intern/gpu_texture.c64
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.c79
-rw-r--r--source/blender/gpu/shaders/gpu_shader_basic_vert.glsl4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl20
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl4
-rw-r--r--source/blender/ikplugin/CMakeLists.txt2
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c2
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp2
-rw-r--r--source/blender/makesdna/DNA_ID.h9
-rw-r--r--source/blender/makesdna/DNA_action_types.h8
-rw-r--r--source/blender/makesdna/DNA_object_types.h25
-rw-r--r--source/blender/makesdna/DNA_screen_types.h5
-rw-r--r--source/blender/makesdna/DNA_space_types.h133
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h21
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/RNA_define.h2
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/RNA_types.h32
-rw-r--r--source/blender/makesrna/intern/makesrna.c24
-rw-r--r--source/blender/makesrna/intern/rna_ID.c12
-rw-r--r--source/blender/makesrna/intern/rna_access.c193
-rw-r--r--source/blender/makesrna/intern/rna_action.c126
-rw-r--r--source/blender/makesrna/intern/rna_action_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_animation.c197
-rw-r--r--source/blender/makesrna/intern/rna_animation_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_animviz.c86
-rw-r--r--source/blender/makesrna/intern/rna_armature.c156
-rw-r--r--source/blender/makesrna/intern/rna_boid.c20
-rw-r--r--source/blender/makesrna/intern/rna_brush.c44
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c54
-rw-r--r--source/blender/makesrna/intern/rna_color.c52
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c166
-rw-r--r--source/blender/makesrna/intern/rna_curve.c124
-rw-r--r--source/blender/makesrna/intern/rna_define.c108
-rw-r--r--source/blender/makesrna/intern/rna_depsgraph.c23
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c60
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c398
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c30
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c150
-rw-r--r--source/blender/makesrna/intern/rna_group.c9
-rw-r--r--source/blender/makesrna/intern/rna_image.c44
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_key.c62
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c20
-rw-r--r--source/blender/makesrna/intern/rna_lattice.c10
-rw-r--r--source/blender/makesrna/intern/rna_layer.c34
-rw-r--r--source/blender/makesrna/intern/rna_main.c4
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_material.c20
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c2
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c4
-rw-r--r--source/blender/makesrna/intern/rna_mesh_utils.h2
-rw-r--r--source/blender/makesrna/intern/rna_meta.c40
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c174
-rw-r--r--source/blender/makesrna/intern/rna_movieclip.c4
-rw-r--r--source/blender/makesrna/intern/rna_nla.c162
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c1078
-rw-r--r--source/blender/makesrna/intern/rna_object.c165
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c206
-rw-r--r--source/blender/makesrna/intern/rna_particle.c87
-rw-r--r--source/blender/makesrna/intern/rna_pose.c146
-rw-r--r--source/blender/makesrna/intern/rna_render.c8
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c94
-rw-r--r--source/blender/makesrna/intern/rna_rna.c51
-rw-r--r--source/blender/makesrna/intern/rna_scene.c356
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c12
-rw-r--r--source/blender/makesrna/intern/rna_screen.c8
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c70
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c100
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c8
-rw-r--r--source/blender/makesrna/intern/rna_space.c283
-rw-r--r--source/blender/makesrna/intern/rna_test.c2
-rw-r--r--source/blender/makesrna/intern/rna_text.c18
-rw-r--r--source/blender/makesrna/intern/rna_texture.c88
-rw-r--r--source/blender/makesrna/intern/rna_ui.c93
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c72
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c545
-rw-r--r--source/blender/makesrna/intern/rna_vfont.c2
-rw-r--r--source/blender/makesrna/intern/rna_wm.c42
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c28
-rw-r--r--source/blender/makesrna/intern/rna_world.c6
-rwxr-xr-xsource/blender/makesrna/rna_cleanup/rna_cleaner.py34
-rwxr-xr-xsource/blender/makesrna/rna_cleanup/rna_cleaner_merge.py20
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c1
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.c6
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c2
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c2
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c55
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c6
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c12
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c1
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c2
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c36
-rw-r--r--source/blender/nodes/composite/node_composite_util.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bokehblur.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bokehimage.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_boxmask.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_brightness.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorSpill.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorbalance.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_common.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_dilate.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_ellipsemask.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_gamma.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_huecorrect.c6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c20
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_inpaint.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_math.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_moviedistortion.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_normalize.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_outputFile.c34
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_splitViewer.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_stabilize2d.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_valToRgb.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_viewer.c2
-rw-r--r--source/blender/nodes/intern/node_common.c100
-rw-r--r--source/blender/nodes/intern/node_exec.c62
-rw-r--r--source/blender/nodes/intern/node_exec.h6
-rw-r--r--source/blender/nodes/intern/node_socket.c84
-rw-r--r--source/blender/nodes/intern/node_util.c38
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c52
-rw-r--r--source/blender/nodes/shader/node_shader_util.c20
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_brightness.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bump.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_common.c42
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_fresnel.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_gamma.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geom.c163
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_hueSatVal.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_invert.c8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_material.c374
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mixRgb.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal.c10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output.c97
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_world.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_squeeze.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_brick.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c166
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectMath.c24
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectTransform.c8
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c56
-rw-r--r--source/blender/nodes/texture/node_texture_util.c16
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_at.c6
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_bricks.c26
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_checker.c8
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_common.c28
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_compose.c6
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_coord.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_curves.c14
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_decompose.c6
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_distance.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_hueSatVal.c16
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_image.c16
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_invert.c10
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_mixRgb.c10
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_output.c26
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_proc.c38
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_rotate.c20
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_scale.c10
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_texture.c14
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_translate.c12
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_valToNor.c10
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_valToRgb.c10
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_viewer.c6
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp334
-rw-r--r--source/blender/physics/intern/ConstrainedConjugateGradient.h34
-rw-r--r--source/blender/physics/intern/eigen_utils.h42
-rw-r--r--source/blender/physics/intern/hair_volume.cpp264
-rw-r--r--source/blender/physics/intern/implicit.h2
-rw-r--r--source/blender/physics/intern/implicit_blender.c436
-rw-r--r--source/blender/physics/intern/implicit_eigen.cpp326
-rw-r--r--source/blender/python/bmesh/CMakeLists.txt2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c2
-rw-r--r--source/blender/python/generic/CMakeLists.txt4
-rw-r--r--source/blender/python/generic/bgl.c8
-rw-r--r--source/blender/python/generic/bgl.h2
-rw-r--r--source/blender/python/generic/blf_py_api.c2
-rw-r--r--source/blender/python/generic/bpy_internal_import.c18
-rw-r--r--source/blender/python/generic/bpy_internal_import.h4
-rw-r--r--source/blender/python/generic/imbuf_py_api.c447
-rw-r--r--source/blender/python/generic/imbuf_py_api.h30
-rw-r--r--source/blender/python/generic/py_capi_utils.c18
-rw-r--r--source/blender/python/intern/bpy.c2
-rw-r--r--source/blender/python/intern/bpy_app.c8
-rw-r--r--source/blender/python/intern/bpy_capi_utils.c6
-rw-r--r--source/blender/python/intern/bpy_driver.c4
-rw-r--r--source/blender/python/intern/bpy_interface.c22
-rw-r--r--source/blender/python/intern/bpy_library_load.c2
-rw-r--r--source/blender/python/intern/bpy_library_write.c2
-rw-r--r--source/blender/python/intern/bpy_operator.c26
-rw-r--r--source/blender/python/intern/bpy_props.c32
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c45
-rw-r--r--source/blender/python/intern/bpy_rna_array.c6
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c2
-rw-r--r--source/blender/python/intern/gpu_offscreen.c2
-rw-r--r--source/blender/python/mathutils/CMakeLists.txt2
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.h2
-rw-r--r--source/blender/python/mathutils/mathutils_interpolate.c16
-rw-r--r--source/blender/python/mathutils/mathutils_noise.c2
-rw-r--r--source/blender/render/CMakeLists.txt2
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h20
-rw-r--r--source/blender/render/intern/include/envmap.h54
-rw-r--r--source/blender/render/intern/include/initrender.h2
-rw-r--r--source/blender/render/intern/include/pixelblending.h65
-rw-r--r--source/blender/render/intern/include/pixelshading.h62
-rw-r--r--source/blender/render/intern/include/pointdensity.h51
-rw-r--r--source/blender/render/intern/include/raycounter.h74
-rw-r--r--source/blender/render/intern/include/rayintersection.h136
-rw-r--r--source/blender/render/intern/include/render_types.h34
-rw-r--r--source/blender/render/intern/include/rendercore.h105
-rw-r--r--source/blender/render/intern/include/shading.h105
-rw-r--r--source/blender/render/intern/include/strand.h99
-rw-r--r--source/blender/render/intern/include/sunsky.h81
-rw-r--r--source/blender/render/intern/include/texture_ocean.h35
-rw-r--r--source/blender/render/intern/include/voxeldata.h47
-rw-r--r--source/blender/render/intern/include/zbuf.h2
-rw-r--r--source/blender/render/intern/raytrace/bvh.h407
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp534
-rw-r--r--source/blender/render/intern/raytrace/rayobject_hint.h72
-rw-r--r--source/blender/render/intern/raytrace/rayobject_instance.cpp211
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp1101
-rw-r--r--source/blender/render/intern/raytrace/rayobject_qbvh.cpp160
-rw-r--r--source/blender/render/intern/raytrace/rayobject_raycounter.cpp91
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp531
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.h125
-rw-r--r--source/blender/render/intern/raytrace/rayobject_svbvh.cpp192
-rw-r--r--source/blender/render/intern/raytrace/rayobject_vbvh.cpp206
-rw-r--r--source/blender/render/intern/raytrace/reorganize.h513
-rw-r--r--source/blender/render/intern/raytrace/svbvh.h317
-rw-r--r--source/blender/render/intern/raytrace/vbvh.h238
-rw-r--r--source/blender/render/intern/source/bake.c1342
-rw-r--r--source/blender/render/intern/source/convertblender.c6014
-rw-r--r--source/blender/render/intern/source/envmap.c822
-rw-r--r--source/blender/render/intern/source/external_engine.c20
-rw-r--r--source/blender/render/intern/source/imagetexture.c132
-rw-r--r--source/blender/render/intern/source/initrender.c46
-rw-r--r--source/blender/render/intern/source/occlusion.c1533
-rw-r--r--source/blender/render/intern/source/pipeline.c188
-rw-r--r--source/blender/render/intern/source/pixelblending.c400
-rw-r--r--source/blender/render/intern/source/pixelshading.c650
-rw-r--r--source/blender/render/intern/source/pointdensity.c44
-rw-r--r--source/blender/render/intern/source/rayshade.c2503
-rw-r--r--source/blender/render/intern/source/render_result.c85
-rw-r--r--source/blender/render/intern/source/render_texture.c192
-rw-r--r--source/blender/render/intern/source/rendercore.c2030
-rw-r--r--source/blender/render/intern/source/renderdatabase.c1603
-rw-r--r--source/blender/render/intern/source/shadbuf.c2647
-rw-r--r--source/blender/render/intern/source/shadeinput.c1490
-rw-r--r--source/blender/render/intern/source/shadeoutput.c2182
-rw-r--r--source/blender/render/intern/source/sss.c1074
-rw-r--r--source/blender/render/intern/source/strand.c1069
-rw-r--r--source/blender/render/intern/source/sunsky.c506
-rw-r--r--source/blender/render/intern/source/volume_precache.c855
-rw-r--r--source/blender/render/intern/source/volumetric.c836
-rw-r--r--source/blender/render/intern/source/voxeldata.c571
-rw-r--r--source/blender/render/intern/source/zbuf.c52
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/WM_keymap.h6
-rw-r--r--source/blender/windowmanager/WM_types.h38
-rw-r--r--source/blender/windowmanager/intern/wm.c31
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c58
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c66
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c10
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c438
-rw-r--r--source/blender/windowmanager/intern/wm_files.c131
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c12
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c20
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c46
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c108
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c72
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c168
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c34
-rw-r--r--source/blender/windowmanager/intern/wm_window.c256
-rw-r--r--source/blender/windowmanager/wm.h4
-rw-r--r--source/blender/windowmanager/wm_cursors.h36
-rw-r--r--source/blender/windowmanager/wm_event_types.h2
m---------source/tools0
-rw-r--r--tests/gtests/alembic/abc_export_test.cc10
-rw-r--r--tests/gtests/blenlib/BLI_heap_test.cc2
-rw-r--r--tests/python/bl_pyapi_mathutils.py2
-rw-r--r--tests/python/collada/animation/test_animation_simple.py236
-rw-r--r--tests/python/collada/mesh/test_mesh_simple.py6
-rwxr-xr-xtests/python/ffmpeg_tests.py2
-rwxr-xr-xtests/python/modules/test_utils.py2
-rw-r--r--tests/python/rna_array.py16
-rw-r--r--tests/python/view_layer/CMakeLists.txt4
1026 files changed, 67962 insertions, 25949 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 43820159456..69d0abe1e25 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -817,18 +817,20 @@ set(PLATFORM_LINKLIBS "")
set(PLATFORM_LINKFLAGS "")
set(PLATFORM_LINKFLAGS_DEBUG "")
-if(WITH_COMPILER_ASAN)
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COMPILER_ASAN_CFLAGS}")
- set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${COMPILER_ASAN_CFLAGS}")
-
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMPILER_ASAN_CXXFLAGS}")
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMPILER_ASAN_CXXFLAGS}")
- if(MSVC)
- set(COMPILER_ASAN_LINKER_FLAGS "/FUNCTIONPADMIN:6")
+if (NOT CMAKE_BUILD_TYPE MATCHES "Release")
+ if(WITH_COMPILER_ASAN)
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COMPILER_ASAN_CFLAGS}")
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${COMPILER_ASAN_CFLAGS}")
+
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMPILER_ASAN_CXXFLAGS}")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMPILER_ASAN_CXXFLAGS}")
+ if(MSVC)
+ set(COMPILER_ASAN_LINKER_FLAGS "/FUNCTIONPADMIN:6")
+ endif()
+ set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS};${COMPILER_ASAN_LIBRARY}")
+ set(PLATFORM_LINKFLAGS "${COMPILER_ASAN_LIBRARY} ${COMPILER_ASAN_LINKER_FLAGS}")
+ set(PLATFORM_LINKFLAGS_DEBUG "${COMPILER_ASAN_LIBRARY} ${COMPILER_ASAN_LINKER_FLAGS}")
endif()
- set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS};${COMPILER_ASAN_LIBRARY}")
- set(PLATFORM_LINKFLAGS "${COMPILER_ASAN_LIBRARY} ${COMPILER_ASAN_LINKER_FLAGS}")
- set(PLATFORM_LINKFLAGS_DEBUG "${COMPILER_ASAN_LIBRARY} ${COMPILER_ASAN_LINKER_FLAGS}")
endif()
#-----------------------------------------------------------------------------
diff --git a/build_files/build_environment/cmake/openal.cmake b/build_files/build_environment/cmake/openal.cmake
index 3331361bfbc..2af530069a5 100644
--- a/build_files/build_environment/cmake/openal.cmake
+++ b/build_files/build_environment/cmake/openal.cmake
@@ -39,5 +39,6 @@ if(BUILD_MODE STREQUAL Release)
PREFIX ${BUILD_DIR}/openal
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openal ${DEFAULT_CMAKE_FLAGS} ${OPENAL_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/openal
+ PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openal/src/external_openal < ${PATCH_DIR}/openal.diff
)
endif()
diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake
index 2dcf653db43..2a89bd726c1 100644
--- a/build_files/build_environment/cmake/options.cmake
+++ b/build_files/build_environment/cmake/options.cmake
@@ -56,24 +56,27 @@ if(WIN32)
# For OIIO and OSL
set(COMMON_DEFINES /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS)
- # TODO FIXME highly MSVC specific
+ if(MSVC_VERSION GREATER 1909)
+ set(COMMON_MSVC_FLAGS "/Wv:18") #some deps with warnings as error aren't quite ready for dealing with the new 2017 warnings.
+ endif()
+
if(WITH_OPTIMIZED_DEBUG)
- set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MTd /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MTd ${COMMON_MSVC_FLAGS} /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
else()
- set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MTd /Zi /Ob0 /Od /RTC1 /D_DEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MTd ${COMMON_MSVC_FLAGS} /Zi /Ob0 /Od /RTC1 /D_DEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
endif()
- set(BLENDER_CMAKE_C_FLAGS_MINSIZEREL "/MT /O1 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
- set(BLENDER_CMAKE_C_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
- set(BLENDER_CMAKE_C_FLAGS_RELWITHDEBINFO "/MT /Zi /O2 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_C_FLAGS_MINSIZEREL "/MT ${COMMON_MSVC_FLAGS} /O1 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_C_FLAGS_RELEASE "/MT ${COMMON_MSVC_FLAGS} /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_C_FLAGS_RELWITHDEBINFO "/MT ${COMMON_MSVC_FLAGS} /Zi /O2 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
if(WITH_OPTIMIZED_DEBUG)
- set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/MTd /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/MTd ${COMMON_MSVC_FLAGS} /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
else()
- set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /D PLATFORM_WINDOWS /MTd /Zi /Ob0 /Od /RTC1 /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /D PLATFORM_WINDOWS /MTd ${COMMON_MSVC_FLAGS} /Zi /Ob0 /Od /RTC1 /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
endif()
- set(BLENDER_CMAKE_CXX_FLAGS_MINSIZEREL "/MT /O1 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
- set(BLENDER_CMAKE_CXX_FLAGS_RELEASE "/MT /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
- set(BLENDER_CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MT /Zi /O2 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_CXX_FLAGS_MINSIZEREL "/MT /${COMMON_MSVC_FLAGS} /O1 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_CXX_FLAGS_RELEASE "/MT ${COMMON_MSVC_FLAGS} /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MT ${COMMON_MSVC_FLAGS} /Zi /O2 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
set(PLATFORM_FLAGS)
set(PLATFORM_CXX_FLAGS)
diff --git a/build_files/build_environment/patches/openal.diff b/build_files/build_environment/patches/openal.diff
new file mode 100644
index 00000000000..2c9862b95a0
--- /dev/null
+++ b/build_files/build_environment/patches/openal.diff
@@ -0,0 +1,13 @@
+diff -Naur external_openal_original/CMakeLists.txt external_openal/CMakeLists.txt
+--- external_openal_original/CMakeLists.txt 2016-01-24 20:12:39 -0700
++++ external_openal/CMakeLists.txt 2018-06-02 12:16:52 -0600
+@@ -885,7 +885,8 @@
+ OPTION(ALSOFT_REQUIRE_MMDEVAPI "Require MMDevApi backend" OFF)
+ IF(HAVE_WINDOWS_H)
+ # Check MMSystem backend
+- CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H -D_WIN32_WINNT=0x0502)
++ set(CMAKE_REQUIRED_FLAGS "-D_WIN32_WINNT=0x0502")
++ CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H)
+ IF(HAVE_MMSYSTEM_H)
+ CHECK_SHARED_FUNCTION_EXISTS(waveOutOpen "windows.h;mmsystem.h" winmm "" HAVE_LIBWINMM)
+ IF(HAVE_LIBWINMM)
diff --git a/build_files/build_environment/patches/osl.diff b/build_files/build_environment/patches/osl.diff
index 960a2506374..ccf34d99699 100644
--- a/build_files/build_environment/patches/osl.diff
+++ b/build_files/build_environment/patches/osl.diff
@@ -10,8 +10,8 @@ diff -Naur osl/src/external_osl/src/cmake/flexbison.cmake osl_bak/src/external_o
MAIN_DEPENDENCY ${flexsrc}
DEPENDS ${${compiler_headers}}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
---- a/src/include/OSL/oslconfig.h 2016-10-31 16:48:19 -0600
-+++ b/src/include/OSL/oslconfig.h 2018-05-27 11:18:08 -0600
+--- osl/src/external_osl/src/include/OSL/oslconfig.h 2016-10-31 16:48:19 -0600
++++ osl/src/external_osl/src/include/OSL/oslconfig.h 2018-05-27 11:18:08 -0600
@@ -44,12 +44,18 @@
// same if another packages is compiling against OSL and using these headers
// (OSL may be C++11 but the client package may be older, or vice versa --
diff --git a/build_files/build_environment/windows/build_deps.cmd b/build_files/build_environment/windows/build_deps.cmd
index 96280014df2..500e689cdc8 100644
--- a/build_files/build_environment/windows/build_deps.cmd
+++ b/build_files/build_environment/windows/build_deps.cmd
@@ -14,10 +14,18 @@ if NOT "%1" == "" (
set BuildDir=VS14
goto par2
)
+ if "%1" == "2017" (
+ echo "Building for VS2017"
+ set VSVER=15.0
+ set VSVER_SHORT=15
+ set BuildDir=VS15
+ goto par2
+ )
+
)
:usage
-Echo Usage build_deps 2013/2015 x64/x86
+Echo Usage build_deps 2013/2015/2017 x64/x86
goto exit
:par2
if NOT "%2" == "" (
@@ -31,6 +39,10 @@ if NOT "%2" == "" (
if "%1" == "2015" (
set CMAKE_BUILDER=Visual Studio 14 2015
)
+ if "%1" == "2017" (
+ set CMAKE_BUILDER=Visual Studio 15 2017
+ )
+
goto start
)
if "%2" == "x64" (
@@ -43,6 +55,10 @@ if NOT "%2" == "" (
if "%1" == "2015" (
set CMAKE_BUILDER=Visual Studio 14 2015 Win64
)
+ if "%1" == "2017" (
+ set CMAKE_BUILDER=Visual Studio 15 2017 Win64
+ )
+
goto start
)
)
diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake
index f55178b89e2..0ee0845be33 100644
--- a/build_files/cmake/platform/platform_win32.cmake
+++ b/build_files/cmake/platform/platform_win32.cmake
@@ -31,7 +31,8 @@ endif()
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(MSVC_CLANG On)
- set(MSVC_REDIST_DIR $ENV{VCToolsRedistDir})
+ set(VC_TOOLS_DIR $ENV{VCToolsRedistDir} CACHE STRING "Location of the msvc redistributables")
+ set(MSVC_REDIST_DIR ${VC_TOOLS_DIR})
if (DEFINED MSVC_REDIST_DIR)
file(TO_CMAKE_PATH ${MSVC_REDIST_DIR} MSVC_REDIST_DIR)
else()
diff --git a/build_files/windows/configure_msbuild.cmd b/build_files/windows/configure_msbuild.cmd
index eee21f568be..f8c2a87de8e 100644
--- a/build_files/windows/configure_msbuild.cmd
+++ b/build_files/windows/configure_msbuild.cmd
@@ -1,5 +1,3 @@
-set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%WINDOWS_ARCH%" %TESTS_CMAKE_ARGS%
-
if "%BUILD_ARCH%"=="x64" (
set MSBUILD_PLATFORM=x64
) else if "%BUILD_ARCH%"=="x86" (
@@ -11,9 +9,9 @@ if "%BUILD_ARCH%"=="x64" (
)
if "%WITH_CLANG%"=="1" (
- set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -T"LLVM-vs2017"
+ set CLANG_CMAKE_ARGS=-T"LLVM-vs2017"
if "%WITH_ASAN%"=="1" (
- set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DWITH_COMPILER_ASAN=On
+ set ASAN_CMAKE_ARGS=-DWITH_COMPILER_ASAN=On
)
) else (
if "%WITH_ASAN%"=="1" (
@@ -21,6 +19,7 @@ if "%WITH_CLANG%"=="1" (
exit /b 1
)
)
+set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%WINDOWS_ARCH%" %TESTS_CMAKE_ARGS% %CLANG_CMAKE_ARGS% %ASAN_CMAKE_ARGS%
if NOT EXIST %BUILD_DIR%\nul (
mkdir %BUILD_DIR%
diff --git a/build_files/windows/configure_ninja.cmd b/build_files/windows/configure_ninja.cmd
index d3b002e9a24..224d761adf6 100644
--- a/build_files/windows/configure_ninja.cmd
+++ b/build_files/windows/configure_ninja.cmd
@@ -1,3 +1,9 @@
+ninja --version 1>NUL 2>&1
+if %ERRORLEVEL% NEQ 0 (
+ echo "Ninja not detected in the path"
+ exit /b 1
+ )
+
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Ninja" %TESTS_CMAKE_ARGS% -DCMAKE_BUILD_TYPE=%BUILD_TYPE%
if "%WITH_CLANG%" == "1" (
diff --git a/build_files/windows/detect_msvc2017.cmd b/build_files/windows/detect_msvc2017.cmd
index 90fad8744b5..060e9f88617 100644
--- a/build_files/windows/detect_msvc2017.cmd
+++ b/build_files/windows/detect_msvc2017.cmd
@@ -12,7 +12,12 @@ if not exist "%vs_where%" (
goto FAIL
)
)
-for /f "usebackq tokens=1* delims=: " %%i in (`"%vs_where%" -products * -latest %VSWHERE_ARGS% -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64`) do (
+
+if NOT "%verbose%" == "" (
+ echo "%vs_where%" -latest %VSWHERE_ARGS% -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64`
+ )
+
+for /f "usebackq tokens=1* delims=: " %%i in (`"%vs_where%" -latest %VSWHERE_ARGS% -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64`) do (
if /i "%%i"=="installationPath" set VS_InstallDir=%%j
)
diff --git a/build_files/windows/parse_arguments.cmd b/build_files/windows/parse_arguments.cmd
index 2cc0acfd243..8a6d743978d 100644
--- a/build_files/windows/parse_arguments.cmd
+++ b/build_files/windows/parse_arguments.cmd
@@ -53,6 +53,10 @@ if NOT "%1" == "" (
) else if "%1" == "2017pre" (
set BUILD_VS_YEAR=2017
set VSWHERE_ARGS=-prerelease
+ set BUILD_VS_YEAR=2017
+ ) else if "%1" == "2017b" (
+ set BUILD_VS_YEAR=2017
+ set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools
) else if "%1" == "2015" (
set BUILD_VS_YEAR=2015
) else if "%1" == "2013" (
diff --git a/build_files/windows/reset_variables.cmd b/build_files/windows/reset_variables.cmd
index f933729b91c..a522ed7407f 100644
--- a/build_files/windows/reset_variables.cmd
+++ b/build_files/windows/reset_variables.cmd
@@ -22,4 +22,6 @@ set BUILD_SHOW_HASHES=
set SHOW_HELP=
set BUILD_WITH_NINJA=
set WITH_CLANG=
-set WITH_ASAN= \ No newline at end of file
+set WITH_ASAN=
+set CLANG_CMAKE_ARGS=
+set ASAN_CMAKE_ARGS=
diff --git a/build_files/windows/show_help.cmd b/build_files/windows/show_help.cmd
index 0524e8a84fc..2b297120f4b 100644
--- a/build_files/windows/show_help.cmd
+++ b/build_files/windows/show_help.cmd
@@ -23,7 +23,13 @@ echo - buildir [newdir] ^(override default build folder^)
echo - x86 ^(override host auto-detect and build 32 bit code^)
echo - x64 ^(override host auto-detect and build 64 bit code^)
echo - 2013 ^(build with visual studio 2013^)
-echo - 2015 ^(build with visual studio 2015^) [EXPERIMENTAL]
-echo - 2017 ^(build with visual studio 2017^) [EXPERIMENTAL]
-echo - 2017pre ^(build with visual studio 2017 pre-release^) [EXPERIMENTAL]
+echo.
+echo Experimental options
+echo - 2015 ^(build with visual studio 2015^)
+echo - 2017 ^(build with visual studio 2017^)
+echo - 2017pre ^(build with visual studio 2017 pre-release^)
+echo - 2017b ^(build with visual studio 2017 Build Tools^)
+echo - clang ^(enable building with clang^)
+echo - asan ^(enable asan when building with clang^)
+echo - ninja ^(enable building with ninja instead of msbuild^)
echo.
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
index 7f9b762f816..3ffe963b2b9 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
@@ -23,7 +23,9 @@ AUD_NAMESPACE_BEGIN
FFMPEG::FFMPEG()
{
+#if LIBAVCODEC_VERSION_MAJOR < 58
av_register_all();
+#endif
}
void FFMPEG::registerPlugin()
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
index 6b79cc5abfd..2da84ce0d4c 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
@@ -22,37 +22,37 @@
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avio.h>
+#include <libavutil/avutil.h>
}
AUD_NAMESPACE_BEGIN
+#if LIBAVCODEC_VERSION_MAJOR < 58
+#define FFMPEG_OLD_CODE
+#endif
+
int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
{
- AVFrame* frame = nullptr;
+ int buf_size = buffer.getSize();
+ int buf_pos = 0;
+
+#ifdef FFMPEG_OLD_CODE
int got_frame;
int read_length;
uint8_t* orig_data = packet.data;
int orig_size = packet.size;
- int buf_size = buffer.getSize();
- int buf_pos = 0;
-
while(packet.size > 0)
{
got_frame = 0;
- if(!frame)
- frame = av_frame_alloc();
- else
- av_frame_unref(frame);
-
- read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
+ read_length = avcodec_decode_audio4(m_codecCtx, m_frame, &got_frame, &packet);
if(read_length < 0)
break;
if(got_frame)
{
- int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);
+ int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1);
if(buf_size - buf_pos < data_size)
{
@@ -62,18 +62,18 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
if(m_tointerleave)
{
- int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
+ int single_size = data_size / m_codecCtx->channels / m_frame->nb_samples;
for(int channel = 0; channel < m_codecCtx->channels; channel++)
{
- for(int i = 0; i < frame->nb_samples; i++)
+ for(int i = 0; i < m_frame->nb_samples; i++)
{
std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
- frame->data[channel] + i * single_size, single_size);
+ m_frame->data[channel] + i * single_size, single_size);
}
}
}
else
- std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[0], data_size);
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, m_frame->data[0], data_size);
buf_pos += data_size;
}
@@ -83,7 +83,42 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
packet.data = orig_data;
packet.size = orig_size;
- av_free(frame);
+#else
+ avcodec_send_packet(m_codecCtx, &packet);
+
+ while(true)
+ {
+ auto ret = avcodec_receive_frame(m_codecCtx, m_frame);
+
+ if(ret != 0)
+ break;
+
+ int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1);
+
+ if(buf_size - buf_pos < data_size)
+ {
+ buffer.resize(buf_size + data_size, true);
+ buf_size += data_size;
+ }
+
+ if(m_tointerleave)
+ {
+ int single_size = data_size / m_codecCtx->channels / m_frame->nb_samples;
+ for(int channel = 0; channel < m_codecCtx->channels; channel++)
+ {
+ for(int i = 0; i < m_frame->nb_samples; i++)
+ {
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
+ m_frame->data[channel] + i * single_size, single_size);
+ }
+ }
+ }
+ else
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, m_frame->data[0], data_size);
+
+ buf_pos += data_size;
+ }
+#endif
return buf_pos;
}
@@ -101,7 +136,11 @@ void FFMPEGReader::init()
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
{
+#ifdef FFMPEG_OLD_CODE
if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+#else
+ if((m_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
+#endif
&& (m_stream < 0))
{
m_stream=i;
@@ -112,12 +151,34 @@ void FFMPEGReader::init()
if(m_stream == -1)
AUD_THROW(FileException, "File couldn't be read, no audio stream found by ffmpeg.");
- m_codecCtx = m_formatCtx->streams[m_stream]->codec;
-
// get a decoder and open it
- AVCodec* aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+#ifndef FFMPEG_OLD_CODE
+ AVCodec* aCodec = avcodec_find_decoder(m_formatCtx->streams[m_stream]->codecpar->codec_id);
+
if(!aCodec)
AUD_THROW(FileException, "File couldn't be read, no decoder found with ffmpeg.");
+#endif
+
+ m_frame = av_frame_alloc();
+
+ if(!m_frame)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg frame couldn't be allocated.");
+
+#ifdef FFMPEG_OLD_CODE
+ m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+
+ AVCodec* aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+#else
+ m_codecCtx = avcodec_alloc_context3(aCodec);
+#endif
+
+ if(!m_codecCtx)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg context couldn't be allocated.");
+
+#ifndef FFMPEG_OLD_CODE
+ if(avcodec_parameters_to_context(m_codecCtx, m_formatCtx->streams[m_stream]->codecpar) < 0)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg decoder parameters couldn't be copied to decoder context.");
+#endif
if(avcodec_open2(m_codecCtx, aCodec, nullptr) < 0)
AUD_THROW(FileException, "File couldn't be read, ffmpeg codec couldn't be opened.");
@@ -157,6 +218,8 @@ void FFMPEGReader::init()
FFMPEGReader::FFMPEGReader(std::string filename) :
m_pkgbuf(),
m_formatCtx(nullptr),
+ m_codecCtx(nullptr),
+ m_frame(nullptr),
m_aviocontext(nullptr),
m_membuf(nullptr)
{
@@ -177,12 +240,14 @@ FFMPEGReader::FFMPEGReader(std::string filename) :
FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
m_pkgbuf(),
+ m_codecCtx(nullptr),
+ m_frame(nullptr),
m_membuffer(buffer),
m_membufferpos(0)
{
- m_membuf = reinterpret_cast<data_t*>(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE));
+ m_membuf = reinterpret_cast<data_t*>(av_malloc(AV_INPUT_BUFFER_MIN_SIZE + AV_INPUT_BUFFER_PADDING_SIZE));
- m_aviocontext = avio_alloc_context(m_membuf, FF_MIN_BUFFER_SIZE, 0, this, read_packet, nullptr, seek_packet);
+ m_aviocontext = avio_alloc_context(m_membuf, AV_INPUT_BUFFER_MIN_SIZE, 0, this, read_packet, nullptr, seek_packet);
if(!m_aviocontext)
{
@@ -212,7 +277,14 @@ FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
FFMPEGReader::~FFMPEGReader()
{
+ if(m_frame)
+ av_frame_free(&m_frame);
+#ifdef FFMPEG_OLD_CODE
avcodec_close(m_codecCtx);
+#else
+ if(m_codecCtx)
+ avcodec_free_context(&m_codecCtx);
+#endif
avformat_close_input(&m_formatCtx);
}
@@ -312,7 +384,7 @@ void FFMPEGReader::seek(int position)
}
}
}
- av_free_packet(&packet);
+ av_packet_unref(&packet);
}
}
else
@@ -343,7 +415,7 @@ Specs FFMPEGReader::getSpecs() const
void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
{
// read packages and decode them
- AVPacket packet;
+ AVPacket packet = {};
int data_size = 0;
int pkgbuf_pos;
int left = length;
@@ -359,7 +431,7 @@ void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
data_size = std::min(pkgbuf_pos, left * sample_size);
m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size/sample_size;
+ left -= data_size / sample_size;
}
// for each frame read as long as there isn't enough data already
@@ -375,9 +447,9 @@ void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
data_size = std::min(pkgbuf_pos, left * sample_size);
m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size/sample_size;
+ left -= data_size / sample_size;
}
- av_free_packet(&packet);
+ av_packet_unref(&packet);
}
// read more data than necessary?
if(pkgbuf_pos > data_size)
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
index e2ae959912d..a69ac7709c8 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
@@ -80,6 +80,11 @@ private:
AVCodecContext* m_codecCtx;
/**
+ * The AVFrame structure for using ffmpeg.
+ */
+ AVFrame* m_frame;
+
+ /**
* The AVIOContext to read the data from.
*/
AVIOContext* m_aviocontext;
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
index f79f0f7fc6b..09b70897c31 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
@@ -27,6 +27,10 @@ extern "C" {
AUD_NAMESPACE_BEGIN
+#if LIBAVCODEC_VERSION_MAJOR < 58
+#define FFMPEG_OLD_CODE
+#endif
+
void FFMPEGWriter::encode()
{
sample_t* data = m_input_buffer.getBuffer();
@@ -58,82 +62,106 @@ void FFMPEGWriter::encode()
if(m_input_size)
m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_samples * m_specs.channels);
- AVPacket packet;
-
- packet.data = nullptr;
- packet.size = 0;
+#ifdef FFMPEG_OLD_CODE
+ m_packet->data = nullptr;
+ m_packet->size = 0;
- av_init_packet(&packet);
+ av_init_packet(m_packet);
- AVFrame* frame = av_frame_alloc();
- av_frame_unref(frame);
+ av_frame_unref(m_frame);
int got_packet;
+#endif
- frame->nb_samples = m_input_samples;
- frame->format = m_codecCtx->sample_fmt;
- frame->channel_layout = m_codecCtx->channel_layout;
+ m_frame->nb_samples = m_input_samples;
+ m_frame->format = m_codecCtx->sample_fmt;
+ m_frame->channel_layout = m_codecCtx->channel_layout;
- if(avcodec_fill_audio_frame(frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
+ if(avcodec_fill_audio_frame(m_frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
AUD_THROW(FileException, "File couldn't be written, filling the audio frame failed with ffmpeg.");
AVRational sample_time = { 1, static_cast<int>(m_specs.rate) };
- frame->pts = av_rescale_q(m_position - m_input_samples, m_codecCtx->time_base, sample_time);
+ m_frame->pts = av_rescale_q(m_position - m_input_samples, m_codecCtx->time_base, sample_time);
- if(avcodec_encode_audio2(m_codecCtx, &packet, frame, &got_packet))
+#ifdef FFMPEG_OLD_CODE
+ if(avcodec_encode_audio2(m_codecCtx, m_packet, m_frame, &got_packet))
{
- av_frame_free(&frame);
AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
}
if(got_packet)
{
- packet.flags |= AV_PKT_FLAG_KEY;
- packet.stream_index = m_stream->index;
- if(av_write_frame(m_formatCtx, &packet) < 0)
+ m_packet->flags |= AV_PKT_FLAG_KEY;
+ m_packet->stream_index = m_stream->index;
+ if(av_write_frame(m_formatCtx, m_packet) < 0)
{
- av_free_packet(&packet);
- av_frame_free(&frame);
+ av_free_packet(m_packet);
AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
}
- av_free_packet(&packet);
+ av_free_packet(m_packet);
}
+#else
+ if(avcodec_send_frame(m_codecCtx, m_frame) < 0)
+ AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
+
+ while(avcodec_receive_packet(m_codecCtx, m_packet) == 0)
+ {
+ m_packet->stream_index = m_stream->index;
- av_frame_free(&frame);
+ if(av_write_frame(m_formatCtx, m_packet) < 0)
+ AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
+ }
+#endif
}
void FFMPEGWriter::close()
{
+#ifdef FFMPEG_OLD_CODE
int got_packet = true;
while(got_packet)
{
- AVPacket packet;
+ m_packet->data = nullptr;
+ m_packet->size = 0;
- packet.data = nullptr;
- packet.size = 0;
+ av_init_packet(m_packet);
- av_init_packet(&packet);
-
- if(avcodec_encode_audio2(m_codecCtx, &packet, nullptr, &got_packet))
+ if(avcodec_encode_audio2(m_codecCtx, m_packet, nullptr, &got_packet))
AUD_THROW(FileException, "File end couldn't be written, audio encoding failed with ffmpeg.");
if(got_packet)
{
- packet.flags |= AV_PKT_FLAG_KEY;
- packet.stream_index = m_stream->index;
- if(av_write_frame(m_formatCtx, &packet))
+ m_packet->flags |= AV_PKT_FLAG_KEY;
+ m_packet->stream_index = m_stream->index;
+ if(av_write_frame(m_formatCtx, m_packet))
{
- av_free_packet(&packet);
+ av_free_packet(m_packet);
AUD_THROW(FileException, "Final frames couldn't be writen to the file with ffmpeg.");
}
- av_free_packet(&packet);
+ av_free_packet(m_packet);
}
}
+#else
+ if(avcodec_send_frame(m_codecCtx, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
+
+ while(avcodec_receive_packet(m_codecCtx, m_packet) == 0)
+ {
+ m_packet->stream_index = m_stream->index;
+
+ if(av_write_frame(m_formatCtx, m_packet) < 0)
+ AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
+ }
+#endif
}
FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate) :
m_position(0),
m_specs(specs),
+ m_formatCtx(nullptr),
+ m_codecCtx(nullptr),
+ m_stream(nullptr),
+ m_packet(nullptr),
+ m_frame(nullptr),
m_input_samples(0),
m_deinterleave(false)
{
@@ -142,75 +170,105 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
if(avformat_alloc_output_context2(&m_formatCtx, nullptr, formats[format], filename.c_str()) < 0)
AUD_THROW(FileException, "File couldn't be written, format couldn't be found with ffmpeg.");
- m_outputFmt = m_formatCtx->oformat;
+ AVOutputFormat* outputFmt = m_formatCtx->oformat;
- if(!m_outputFmt) {
+ if(!outputFmt) {
avformat_free_context(m_formatCtx);
AUD_THROW(FileException, "File couldn't be written, output format couldn't be found with ffmpeg.");
}
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ outputFmt->audio_codec = AV_CODEC_ID_NONE;
switch(codec)
{
case CODEC_AAC:
- m_outputFmt->audio_codec = AV_CODEC_ID_AAC;
+ outputFmt->audio_codec = AV_CODEC_ID_AAC;
break;
case CODEC_AC3:
- m_outputFmt->audio_codec = AV_CODEC_ID_AC3;
+ outputFmt->audio_codec = AV_CODEC_ID_AC3;
break;
case CODEC_FLAC:
- m_outputFmt->audio_codec = AV_CODEC_ID_FLAC;
+ outputFmt->audio_codec = AV_CODEC_ID_FLAC;
break;
case CODEC_MP2:
- m_outputFmt->audio_codec = AV_CODEC_ID_MP2;
+ outputFmt->audio_codec = AV_CODEC_ID_MP2;
break;
case CODEC_MP3:
- m_outputFmt->audio_codec = AV_CODEC_ID_MP3;
+ outputFmt->audio_codec = AV_CODEC_ID_MP3;
break;
case CODEC_OPUS:
- m_outputFmt->audio_codec = AV_CODEC_ID_OPUS;
+ outputFmt->audio_codec = AV_CODEC_ID_OPUS;
break;
case CODEC_PCM:
switch(specs.format)
{
case FORMAT_U8:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
break;
case FORMAT_S16:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
break;
case FORMAT_S24:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
break;
case FORMAT_S32:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
break;
case FORMAT_FLOAT32:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
break;
case FORMAT_FLOAT64:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
+ outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
break;
default:
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ outputFmt->audio_codec = AV_CODEC_ID_NONE;
break;
}
break;
case CODEC_VORBIS:
- m_outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
+ outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
break;
default:
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ break;
+ }
+
+ uint64_t channel_layout = 0;
+
+ switch(m_specs.channels)
+ {
+ case CHANNELS_MONO:
+ channel_layout = AV_CH_LAYOUT_MONO;
+ break;
+ case CHANNELS_STEREO:
+ channel_layout = AV_CH_LAYOUT_STEREO;
+ break;
+ case CHANNELS_STEREO_LFE:
+ channel_layout = AV_CH_LAYOUT_2POINT1;
+ break;
+ case CHANNELS_SURROUND4:
+ channel_layout = AV_CH_LAYOUT_QUAD;
+ break;
+ case CHANNELS_SURROUND5:
+ channel_layout = AV_CH_LAYOUT_5POINT0_BACK;
+ break;
+ case CHANNELS_SURROUND51:
+ channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
+ break;
+ case CHANNELS_SURROUND61:
+ channel_layout = AV_CH_LAYOUT_6POINT1_BACK;
+ break;
+ case CHANNELS_SURROUND71:
+ channel_layout = AV_CH_LAYOUT_7POINT1;
break;
}
try
{
- if(m_outputFmt->audio_codec == AV_CODEC_ID_NONE)
+ if(outputFmt->audio_codec == AV_CODEC_ID_NONE)
AUD_THROW(FileException, "File couldn't be written, audio codec not found with ffmpeg.");
- AVCodec* codec = avcodec_find_encoder(m_outputFmt->audio_codec);
+ AVCodec* codec = avcodec_find_encoder(outputFmt->audio_codec);
if(!codec)
AUD_THROW(FileException, "File couldn't be written, audio encoder couldn't be found with ffmpeg.");
@@ -220,7 +278,14 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
m_stream->id = m_formatCtx->nb_streams - 1;
+#ifdef FFMPEG_OLD_CODE
m_codecCtx = m_stream->codec;
+#else
+ m_codecCtx = avcodec_alloc_context3(codec);
+#endif
+
+ if(!m_codecCtx)
+ AUD_THROW(FileException, "File couldn't be written, context creation failed with ffmpeg.");
switch(m_specs.format)
{
@@ -247,7 +312,7 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
}
if(m_formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
- m_codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ m_codecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
bool format_supported = false;
@@ -328,9 +393,13 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
m_specs.rate = m_codecCtx->sample_rate;
- m_codecCtx->codec_id = m_outputFmt->audio_codec;
+#ifdef FFMPEG_OLD_CODE
+ m_codecCtx->codec_id = outputFmt->audio_codec;
+#endif
+
m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
m_codecCtx->bit_rate = bitrate;
+ m_codecCtx->channel_layout = channel_layout;
m_codecCtx->channels = m_specs.channels;
m_stream->time_base.num = m_codecCtx->time_base.num = 1;
m_stream->time_base.den = m_codecCtx->time_base.den = m_codecCtx->sample_rate;
@@ -338,6 +407,11 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
if(avcodec_open2(m_codecCtx, codec, nullptr) < 0)
AUD_THROW(FileException, "File couldn't be written, encoder couldn't be opened with ffmpeg.");
+#ifndef FFMPEG_OLD_CODE
+ if(avcodec_parameters_from_context(m_stream->codecpar, m_codecCtx) < 0)
+ AUD_THROW(FileException, "File couldn't be written, codec parameters couldn't be copied to the context.");
+#endif
+
int samplesize = std::max(int(AUD_SAMPLE_SIZE(m_specs)), AUD_DEVICE_SAMPLE_SIZE(m_specs));
if((m_input_size = m_codecCtx->frame_size))
@@ -346,13 +420,26 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo
if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
AUD_THROW(FileException, "File couldn't be written, file opening failed with ffmpeg.");
- avformat_write_header(m_formatCtx, nullptr);
+ if(avformat_write_header(m_formatCtx, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be written, writing the header failed.");
}
catch(Exception&)
{
+#ifndef FFMPEG_OLD_CODE
+ if(m_codecCtx)
+ avcodec_free_context(&m_codecCtx);
+#endif
avformat_free_context(m_formatCtx);
throw;
}
+
+#ifdef FFMPEG_OLD_CODE
+ m_packet = new AVPacket({});
+#else
+ m_packet = av_packet_alloc();
+#endif
+
+ m_frame = av_frame_alloc();
}
FFMPEGWriter::~FFMPEGWriter()
@@ -365,9 +452,26 @@ FFMPEGWriter::~FFMPEGWriter()
av_write_trailer(m_formatCtx);
+ if(m_frame)
+ av_frame_free(&m_frame);
+
+ if(m_packet)
+ {
+#ifdef FFMPEG_OLD_CODE
+ delete m_packet;
+#else
+ av_packet_free(&m_packet);
+#endif
+ }
+
+#ifdef FFMPEG_OLD_CODE
avcodec_close(m_codecCtx);
+#else
+ if(m_codecCtx)
+ avcodec_free_context(&m_codecCtx);
+#endif
- avio_close(m_formatCtx->pb);
+ avio_closep(&m_formatCtx->pb);
avformat_free_context(m_formatCtx);
}
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
index 690185deb64..c22f479d83c 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
@@ -66,14 +66,19 @@ private:
AVCodecContext* m_codecCtx;
/**
- * The AVOutputFormat structure for using ffmpeg.
+ * The AVStream structure for using ffmpeg.
*/
- AVOutputFormat* m_outputFmt;
+ AVStream* m_stream;
/**
- * The AVStream structure for using ffmpeg.
+ * The AVPacket structure for using ffmpeg.
*/
- AVStream* m_stream;
+ AVPacket* m_packet;
+
+ /**
+ * The AVFrame structure for using ffmpeg.
+ */
+ AVFrame* m_frame;
/**
* The input buffer for the format converted data before encoding.
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 8793ddb83f6..721b395e596 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -162,33 +162,55 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
if cscene.progressive == 'PATH' or use_branched_path(context) is False:
col = layout.column(align=True)
- col.prop(cscene, "samples", text="Render Samples")
- col.prop(cscene, "preview_samples", text="Preview Samples")
+ col.prop(cscene, "samples", text="Render")
+ col.prop(cscene, "preview_samples", text="Viewport")
+ col.separator()
col.prop(cscene, "use_square_samples") # Duplicate below.
else:
+
col = layout.column(align=True)
- col.prop(cscene, "aa_samples", text="Render Samples")
- col.prop(cscene, "preview_aa_samples", text="Preview Samples")
+ col.label(text="AA Samples")
+ col.prop(cscene, "aa_samples", text="Render")
+ col.prop(cscene, "preview_aa_samples", text="Preview")
col = layout.column(align=True)
- col.prop(cscene, "diffuse_samples", text="Diffuse Samples")
- col.prop(cscene, "glossy_samples", text="Glossy Samples")
- col.prop(cscene, "transmission_samples", text="Transmission Samples")
- col.prop(cscene, "ao_samples", text="AO Samples")
+ col.label(text="Samples")
+ col.prop(cscene, "diffuse_samples", text="Diffuse")
+ col.prop(cscene, "glossy_samples", text="Glossy")
+ col.prop(cscene, "transmission_samples", text="Transmission")
+ col.prop(cscene, "ao_samples", text="AO")
sub = col.row(align=True)
sub.active = use_sample_all_lights(context)
- sub.prop(cscene, "mesh_light_samples", text="Mesh Light Samples")
-
- col.prop(cscene, "subsurface_samples", text="Subsurface Samples")
- col.prop(cscene, "volume_samples", text="Volume Samples")
-
+ sub.prop(cscene, "mesh_light_samples", text="Mesh Light")
+ col.prop(cscene, "subsurface_samples", text="Subsurface")
+ col.prop(cscene, "volume_samples", text="Volume")
+ col.separator()
col.prop(cscene, "use_square_samples") # Duplicate above.
col = layout.column(align=True)
col.prop(cscene, "sample_all_lights_direct")
col.prop(cscene, "sample_all_lights_indirect")
+ row = layout.row(align=True)
+ row.prop(cscene, "seed")
+ row.prop(cscene, "use_animated_seed", text="", icon="TIME")
+
+ layout.prop(cscene, "sampling_pattern", text="Pattern")
+
+
+class CYCLES_RENDER_PT_sampling_light(CyclesButtonsPanel, Panel):
+ bl_label = "Light"
+ bl_parent_id = "CYCLES_RENDER_PT_sampling"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ cscene = scene.cycles
+
col = layout.column(align=True)
col.prop(cscene, "light_sampling_threshold", text="Light Threshold")
@@ -196,12 +218,6 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
col.prop(cscene, "sample_clamp_direct")
col.prop(cscene, "sample_clamp_indirect")
- row = layout.row(align=True)
- row.prop(cscene, "seed")
- row.prop(cscene, "use_animated_seed", text="", icon="TIME")
-
- layout.row().prop(cscene, "sampling_pattern", text="Pattern")
-
draw_samples_info(layout, context)
@@ -210,37 +226,78 @@ class CYCLES_RENDER_PT_geometry(CyclesButtonsPanel, Panel):
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
+ pass
+
+
+class CYCLES_RENDER_PT_geometry_subdivision(CyclesButtonsPanel, Panel):
+ bl_label = "Subdivision"
+ bl_parent_id = "CYCLES_RENDER_PT_geometry"
+
+ @classmethod
+ def poll(self, context):
+ return context.scene.cycles.feature_set == 'EXPERIMENTAL'
+
+ def draw(self, context):
layout = self.layout
layout.use_property_split = True
scene = context.scene
cscene = scene.cycles
- ccscene = scene.cycles_curves
- col = layout.column(align=True)
- col.prop(cscene, "volume_step_size", text="Volume Step Size")
- col.prop(cscene, "volume_max_steps", text="Volume Max Steps")
+ col = layout.column()
+ sub = col.column(align=True)
+ sub.prop(cscene, "dicing_rate", text="Dicing Rate Render")
+ sub.prop(cscene, "preview_dicing_rate", text="Preview")
col.separator()
- if cscene.feature_set == 'EXPERIMENTAL':
+ col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale")
+ col.prop(cscene, "max_subdivisions")
- col = layout.column()
- sub = col.column(align=True)
- sub.prop(cscene, "dicing_rate", text="Dicing Rate Render")
- sub.prop(cscene, "preview_dicing_rate", text="Dicing Rate Preview")
+ col.prop(cscene, "dicing_camera")
- col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale")
- col.prop(cscene, "max_subdivisions")
- col.prop(cscene, "dicing_camera")
+class CYCLES_RENDER_PT_geometry_volume(CyclesButtonsPanel, Panel):
+ bl_label = "Volume"
+ bl_parent_id = "CYCLES_RENDER_PT_geometry"
- col.separator()
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ cscene = scene.cycles
+ ccscene = scene.cycles_curves
- layout.prop(ccscene, "use_curves", text="Hair Rendering")
col = layout.column()
- col.active = ccscene.use_curves
+ col.prop(cscene, "volume_step_size", text="Step Size")
+ col.prop(cscene, "volume_max_steps", text="Max Steps")
+
+
+class CYCLES_RENDER_PT_geometry_hair(CyclesButtonsPanel, Panel):
+ bl_label = "Hair"
+ bl_parent_id = "CYCLES_RENDER_PT_geometry"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw_header(self, context):
+ layout = self.layout
+ scene = context.scene
+ cscene = scene.cycles
+ ccscene = scene.cycles_curves
+ layout.prop(ccscene, "use_curves", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ cscene = scene.cycles
+ ccscene = scene.cycles_curves
+
+ layout.active = ccscene.use_curves
+
+ col = layout.column()
col.prop(ccscene, "minimum_width", text="Min Pixels")
col.prop(ccscene, "maximum_width", text="Max Extension")
col.prop(ccscene, "shape", text="Shape")
@@ -270,14 +327,41 @@ class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel):
row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMIN")
row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMOUT").remove_active = True
+
+class CYCLES_RENDER_PT_light_paths_max_bounces(CyclesButtonsPanel, Panel):
+ bl_label = "Max Bounces"
+ bl_parent_id = "CYCLES_RENDER_PT_light_paths"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ cscene = scene.cycles
+
+ col = layout.column(align=True)
+ col.prop(cscene, "max_bounces", text="Total")
+
col = layout.column(align=True)
- col.prop(cscene, "max_bounces", text="Max Bounces")
- col.prop(cscene, "transparent_max_bounces", text="Transparency")
col.prop(cscene, "diffuse_bounces", text="Diffuse")
col.prop(cscene, "glossy_bounces", text="Glossy")
+ col.prop(cscene, "transparent_max_bounces", text="Transparency")
col.prop(cscene, "transmission_bounces", text="Transmission")
col.prop(cscene, "volume_bounces", text="Volume")
+
+class CYCLES_RENDER_PT_light_paths_caustics(CyclesButtonsPanel, Panel):
+ bl_label = "Caustics"
+ bl_parent_id = "CYCLES_RENDER_PT_light_paths"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ cscene = scene.cycles
+
col = layout.column()
col.prop(cscene, "blur_glossy")
col.prop(cscene, "caustics_reflective")
@@ -305,9 +389,29 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
col = layout.column()
col.prop(cscene, "motion_blur_position", text="Position")
col.prop(rd, "motion_blur_shutter")
+ col.separator()
+ col.prop(cscene, "rolling_shutter_type", text="Rolling Shutter")
+ sub = col.column()
+ sub.active = cscene.rolling_shutter_type != 'NONE'
+ sub.prop(cscene, "rolling_shutter_duration")
+
+
+class CYCLES_RENDER_PT_motion_blur_curve(CyclesButtonsPanel, Panel):
+ bl_label = "Shutter Curve"
+ bl_parent_id = "CYCLES_RENDER_PT_motion_blur"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ cscene = scene.cycles
+ rd = scene.render
+ layout.active = rd.use_motion_blur
col = layout.column()
- col.label("Shutter curve:")
+
col.template_curve_mapping(rd, "motion_blur_shutter_curve")
col = layout.column(align=True)
@@ -319,12 +423,6 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
row.operator("render.shutter_curve_preset", icon='LINCURVE', text="").shape = 'LINE'
row.operator("render.shutter_curve_preset", icon='NOCURVE', text="").shape = 'MAX'
- col = layout.column()
- col.prop(cscene, "rolling_shutter_type")
- row = col.row()
- row.active = cscene.rolling_shutter_type != 'NONE'
- row.prop(cscene, "rolling_shutter_duration")
-
class CYCLES_RENDER_PT_film(CyclesButtonsPanel, Panel):
bl_label = "Film"
@@ -339,24 +437,51 @@ class CYCLES_RENDER_PT_film(CyclesButtonsPanel, Panel):
col = layout.column()
col.prop(cscene, "film_exposure")
- layout.separator()
- col = layout.column()
- col.prop(cscene, "pixel_filter_type")
- if cscene.pixel_filter_type != 'BOX':
- col.prop(cscene, "filter_width")
+class CYCLES_RENDER_PT_film_transparency(CyclesButtonsPanel, Panel):
+ bl_label = "Transparency"
+ bl_parent_id = "CYCLES_RENDER_PT_film"
- layout.separator()
+ def draw_header(self, context):
+ layout = self.layout
+ rd = context.scene.render
+
+ scene = context.scene
+ cscene = scene.cycles
+
+ layout.prop(cscene, "film_transparent", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ scene = context.scene
+ cscene = scene.cycles
+
+ layout.active = cscene.film_transparent
col = layout.column()
- col.prop(cscene, "film_transparent")
+ col.prop(cscene, "film_transparent_glass", text="Transparent Glass")
+
sub = col.column()
- sub.prop(cscene, "film_transparent_glass", text="Transparent Glass")
- sub.active = cscene.film_transparent
+ sub.active = cscene.film_transparent and cscene.film_transparent_glass
+ sub.prop(cscene, "film_transparent_roughness", text="Roughness Threshold")
+
+
+class CYCLES_RENDER_PT_film_pixel_filter(CyclesButtonsPanel, Panel):
+ bl_label = "Pixel Filter"
+ bl_parent_id = "CYCLES_RENDER_PT_film"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ scene = context.scene
+ cscene = scene.cycles
col = layout.column()
- col.active = cscene.film_transparent and cscene.film_transparent_glass
- col.prop(cscene, "film_transparent_roughness", text="Roughness Threshold")
+ col.prop(cscene, "pixel_filter_type", text="Type")
+ if cscene.pixel_filter_type != 'BOX':
+ col.prop(cscene, "filter_width", text="Width")
class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel):
@@ -372,13 +497,45 @@ class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel):
cscene = scene.cycles
col = layout.column()
+ col.active = show_device_active(context)
+ col.prop(cscene, "device")
+
+ from . import engine
+ if engine.with_osl() and use_cpu(context):
+ col.prop(cscene, "shading_system")
+
+
+class CYCLES_RENDER_PT_performance_threads(CyclesButtonsPanel, Panel):
+ bl_label = "Threads"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
+
+ col = layout.column()
- col.row(align=True).prop(rd, "threads_mode")
+ col.prop(rd, "threads_mode")
sub = col.column(align=True)
sub.enabled = rd.threads_mode == 'FIXED'
sub.prop(rd, "threads")
- col.separator()
+
+class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
+ bl_label = "Tiles"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
col = layout.column()
@@ -394,28 +551,63 @@ class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel):
sub.active = False
sub.prop(cscene, "use_progressive_refine")
- layout.separator()
- col = layout.column()
+class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Panel):
+ bl_label = "Acceleration Structure"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
+ bl_options = {'DEFAULT_CLOSED'}
- col.prop(rd, "use_save_buffers")
- col.prop(rd, "use_persistent_data", text="Persistent Images")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
- layout.separator()
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
col = layout.column()
col.prop(cscene, "debug_use_spatial_splits")
col.prop(cscene, "debug_use_hair_bvh")
-
sub = col.column()
sub.active = not cscene.debug_use_spatial_splits
sub.prop(cscene, "debug_bvh_time_steps")
- layout.separator()
+
+class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
+ bl_label = "Final Render"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
+
+ col = layout.column()
+
+ col.prop(rd, "use_save_buffers")
+ col.prop(rd, "use_persistent_data", text="Persistent Images")
+
+
+class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
+ bl_label = "Viewport"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
col = layout.column()
- col.prop(rd, "preview_pixel_size", text="Viewport Pixel Size")
+ col.prop(rd, "preview_pixel_size", text="Pixel Size")
col.prop(cscene, "preview_start_resolution", text="Start Pixels")
@@ -747,7 +939,7 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
if CyclesButtonsPanel.poll(context) and ob:
if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA'}:
return True
- if ob.dupli_type == 'GROUP' and ob.dupli_group:
+ if ob.dupli_type == 'COLLECTION' and ob.dupli_group:
return True
# TODO(sergey): More duplicator types here?
return False
@@ -792,7 +984,7 @@ class CYCLES_OBJECT_PT_cycles_settings(CyclesButtonsPanel, Panel):
ob = context.object
return (CyclesButtonsPanel.poll(context) and
ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LAMP'}) or
- (ob.dupli_type == 'GROUP' and ob.dupli_group)))
+ (ob.dupli_type == 'COLLECTION' and ob.dupli_group)))
def draw(self, context):
layout = self.layout
@@ -1039,6 +1231,7 @@ class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
bl_label = "Ambient Occlusion"
bl_context = "world"
+ bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
@@ -1050,15 +1243,16 @@ class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
light = context.world.light_settings
scene = context.scene
- row = layout.row()
- sub = row.row()
+ col = layout.column()
+ sub = col.column()
sub.active = light.use_ambient_occlusion or scene.render.use_simplify
sub.prop(light, "ao_factor", text="Factor")
- row.prop(light, "distance", text="Distance")
+ col.prop(light, "distance", text="Distance")
class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel):
@@ -1123,33 +1317,65 @@ class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
world = context.world
cworld = world.cycles
# cscene = context.scene.cycles
- split = layout.split()
+ col = layout.column()
- col = split.column()
+class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
+ bl_label = "Surface"
+ bl_parent_id = "CYCLES_WORLD_PT_settings"
+ bl_context = "world"
+
+ @classmethod
+ def poll(cls, context):
+ return context.world and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ world = context.world
+ cworld = world.cycles
- col.label(text="Surface:")
+ col = layout.column()
col.prop(cworld, "sample_as_light", text="Multiple Importance")
- sub = col.column(align=True)
+ sub = col.column()
sub.active = cworld.sample_as_light
sub.prop(cworld, "sample_map_resolution")
if use_branched_path(context):
- subsub = sub.row(align=True)
+ subsub = sub.column(align=True)
subsub.active = use_sample_all_lights(context)
subsub.prop(cworld, "samples")
sub.prop(cworld, "max_bounces")
- col = split.column()
- col.label(text="Volume:")
+
+class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
+ bl_label = "Volume"
+ bl_parent_id = "CYCLES_WORLD_PT_settings"
+ bl_context = "world"
+
+ @classmethod
+ def poll(cls, context):
+ return context.world and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ world = context.world
+ cworld = world.cycles
+
+ col = layout.column()
+
sub = col.column()
sub.active = use_cpu(context)
- sub.prop(cworld, "volume_sampling", text="")
- col.prop(cworld, "volume_interpolation", text="")
+ sub.prop(cworld, "volume_sampling", text="Sampling")
+ col.prop(cworld, "volume_interpolation", text="Interpolation")
col.prop(cworld, "homogeneous_volume", text="Homogeneous")
@@ -1227,30 +1453,60 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
mat = context.material
cmat = mat.cycles
- split = layout.split()
- col = split.column()
- col.label(text="Surface:")
+ layout.prop(mat, "pass_index")
+
+
+class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
+ bl_label = "Surface"
+ bl_parent_id = "CYCLES_MATERIAL_PT_settings"
+ bl_context = "material"
+
+ @classmethod
+ def poll(cls, context):
+ return context.material and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ mat = context.material
+ cmat = mat.cycles
+
+ col = layout.column()
col.prop(cmat, "sample_as_light", text="Multiple Importance")
col.prop(cmat, "use_transparent_shadow")
+ col.prop(cmat, "displacement_method", text="Displacement Method")
- col.separator()
- col.label(text="Geometry:")
- col.prop(cmat, "displacement_method", text="")
- col = split.column()
- col.label(text="Volume:")
+class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
+ bl_label = "Volume"
+ bl_parent_id = "CYCLES_MATERIAL_PT_settings"
+ bl_context = "material"
+
+ @classmethod
+ def poll(cls, context):
+ return context.material and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ mat = context.material
+ cmat = mat.cycles
+
+ col = layout.column()
sub = col.column()
sub.active = use_cpu(context)
- sub.prop(cmat, "volume_sampling", text="")
- col.prop(cmat, "volume_interpolation", text="")
+ sub.prop(cmat, "volume_sampling", text="Sampling")
+ col.prop(cmat, "volume_interpolation", text="Interpolation")
col.prop(cmat, "homogeneous_volume", text="Homogeneous")
- col.separator()
- col.prop(mat, "pass_index")
+
class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
@@ -1398,7 +1654,18 @@ class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel):
self.layout.prop(rd, "use_simplify", text="")
def draw(self, context):
+ pass
+
+
+class CYCLES_SCENE_PT_simplify_viewport(CyclesButtonsPanel, Panel):
+ bl_label = "Viewport"
+ bl_context = "scene"
+ bl_parent_id = "CYCLES_SCENE_PT_simplify"
+ COMPAT_ENGINES = {'CYCLES'}
+
+ def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
scene = context.scene
rd = scene.render
@@ -1406,46 +1673,65 @@ class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel):
layout.active = rd.use_simplify
- col = layout.column(align=True)
- col.label(text="Subdivision")
- row = col.row(align=True)
- row.prop(rd, "simplify_subdivision", text="Viewport")
- row.prop(rd, "simplify_subdivision_render", text="Render")
+ col = layout.column()
+ col.prop(rd, "simplify_subdivision", text="Max Subdivision")
+ col.prop(rd, "simplify_child_particles", text="Child Particles")
+ col.prop(cscene, "texture_limit", text="Texture Limit")
+ col.prop(cscene, "ao_bounces", text="AO Bounces")
- col = layout.column(align=True)
- col.label(text="Child Particles")
- row = col.row(align=True)
- row.prop(rd, "simplify_child_particles", text="Viewport")
- row.prop(rd, "simplify_child_particles_render", text="Render")
- col = layout.column(align=True)
- split = col.split()
- sub = split.column()
- sub.label(text="Texture Limit Viewport")
- sub.prop(cscene, "texture_limit", text="")
- sub = split.column()
- sub.label(text="Texture Limit Render")
- sub.prop(cscene, "texture_limit_render", text="")
+class CYCLES_SCENE_PT_simplify_render(CyclesButtonsPanel, Panel):
+ bl_label = "Render"
+ bl_context = "scene"
+ bl_parent_id = "CYCLES_SCENE_PT_simplify"
+ COMPAT_ENGINES = {'CYCLES'}
- split = layout.split()
- col = split.column()
- col.prop(cscene, "use_camera_cull")
- row = col.row()
- row.active = cscene.use_camera_cull
- row.prop(cscene, "camera_cull_margin")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
- col = split.column()
- col.prop(cscene, "use_distance_cull")
- row = col.row()
- row.active = cscene.use_distance_cull
- row.prop(cscene, "distance_cull_margin", text="Distance")
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
- split = layout.split()
- col = split.column()
- col.prop(cscene, "ao_bounces")
+ layout.active = rd.use_simplify
- col = split.column()
- col.prop(cscene, "ao_bounces_render")
+ col = layout.column()
+
+ col.prop(rd, "simplify_subdivision_render", text="Max Subdivision")
+ col.prop(rd, "simplify_child_particles_render", text="Child Particles")
+ col.prop(cscene, "texture_limit_render", text="Texture Limit")
+ col.prop(cscene, "ao_bounces_render", text="AO Bounces")
+
+
+class CYCLES_SCENE_PT_simplify_culling(CyclesButtonsPanel, Panel):
+ bl_label = "Culling"
+ bl_context = "scene"
+ bl_parent_id = "CYCLES_SCENE_PT_simplify"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'CYCLES'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
+
+ layout.active = rd.use_simplify
+
+ col = layout.column()
+ col.prop(cscene, "use_camera_cull")
+ sub = col.column()
+ sub.active = cscene.use_camera_cull
+ sub.prop(cscene, "camera_cull_margin")
+
+ col = layout.column()
+ col.prop(cscene, "use_distance_cull")
+ sub = col.column()
+ sub.active = cscene.use_distance_cull
+ sub.prop(cscene, "distance_cull_margin", text="Distance")
def draw_device(self, context):
@@ -1460,13 +1746,6 @@ def draw_device(self, context):
col = layout.column()
col.prop(cscene, "feature_set")
- col = layout.column()
- col.active = show_device_active(context)
- col.prop(cscene, "device")
-
- if engine.with_osl() and use_cpu(context):
- layout.prop(cscene, "shading_system")
-
def draw_pause(self, context):
layout = self.layout
@@ -1509,11 +1788,25 @@ classes = (
CYCLES_MT_sampling_presets,
CYCLES_MT_integrator_presets,
CYCLES_RENDER_PT_sampling,
+ CYCLES_RENDER_PT_sampling_light,
CYCLES_RENDER_PT_geometry,
+ CYCLES_RENDER_PT_geometry_subdivision,
+ CYCLES_RENDER_PT_geometry_volume,
+ CYCLES_RENDER_PT_geometry_hair,
CYCLES_RENDER_PT_light_paths,
+ CYCLES_RENDER_PT_light_paths_max_bounces,
+ CYCLES_RENDER_PT_light_paths_caustics,
CYCLES_RENDER_PT_motion_blur,
+ CYCLES_RENDER_PT_motion_blur_curve,
CYCLES_RENDER_PT_film,
+ CYCLES_RENDER_PT_film_transparency,
+ CYCLES_RENDER_PT_film_pixel_filter,
CYCLES_RENDER_PT_performance,
+ CYCLES_RENDER_PT_performance_threads,
+ CYCLES_RENDER_PT_performance_tiles,
+ CYCLES_RENDER_PT_performance_acceleration_structure,
+ CYCLES_RENDER_PT_performance_final_render,
+ CYCLES_RENDER_PT_performance_viewport,
CYCLES_RENDER_PT_filter,
CYCLES_RENDER_PT_layer_passes,
CYCLES_RENDER_PT_denoising,
@@ -1534,14 +1827,21 @@ classes = (
CYCLES_WORLD_PT_mist,
CYCLES_WORLD_PT_ray_visibility,
CYCLES_WORLD_PT_settings,
+ CYCLES_WORLD_PT_settings_surface,
+ CYCLES_WORLD_PT_settings_volume,
CYCLES_MATERIAL_PT_preview,
CYCLES_MATERIAL_PT_surface,
CYCLES_MATERIAL_PT_volume,
CYCLES_MATERIAL_PT_displacement,
CYCLES_MATERIAL_PT_settings,
+ CYCLES_MATERIAL_PT_settings_surface,
+ CYCLES_MATERIAL_PT_settings_volume,
CYCLES_RENDER_PT_bake,
CYCLES_RENDER_PT_debug,
CYCLES_SCENE_PT_simplify,
+ CYCLES_SCENE_PT_simplify_viewport,
+ CYCLES_SCENE_PT_simplify_render,
+ CYCLES_SCENE_PT_simplify_culling,
)
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 3c38c7a4584..8ed3eafb488 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -482,7 +482,8 @@ static bool object_render_hide_original(BL::Object::type_enum ob_type,
static bool object_render_hide(BL::Object& b_ob,
bool top_level,
bool parent_hide,
- bool& hide_triangles)
+ bool& hide_triangles,
+ BL::Depsgraph::mode_enum depsgraph_mode)
{
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
@@ -501,11 +502,16 @@ static bool object_render_hide(BL::Object& b_ob,
has_particles = true;
}
+ /* Both mode_PREVIEW and mode_VIEWPORT are treated the same here.*/
+ const bool show_duplicator = depsgraph_mode == BL::Depsgraph::mode_RENDER
+ ? b_ob.show_duplicator_for_render()
+ : b_ob.show_duplicator_for_viewport();
+
if(has_particles) {
- show_emitter = b_ob.show_duplicator_for_render();
+ show_emitter = show_duplicator;
hide_emitter = !show_emitter;
} else if(b_ob.is_duplicator()) {
- if(top_level || b_ob.show_duplicator_for_render()) {
+ if(top_level || show_duplicator) {
hide_as_dupli_parent = true;
}
}
@@ -563,6 +569,8 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
bool cancel = false;
bool use_portal = false;
+ BL::Depsgraph::mode_enum depsgraph_mode = b_depsgraph.mode();
+
BL::Depsgraph::object_instances_iterator b_instance_iter;
for(b_depsgraph.object_instances.begin(b_instance_iter);
b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
@@ -582,7 +590,7 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
/* test if object needs to be hidden */
bool hide_tris;
- if(!object_render_hide(b_ob, true, true, hide_tris)) {
+ if(!object_render_hide(b_ob, true, true, hide_tris, depsgraph_mode)) {
/* object itself */
sync_object(b_depsgraph,
b_instance,
diff --git a/intern/gawain/gawain/gwn_common.h b/intern/gawain/gawain/gwn_common.h
index dc0a52ca096..f1512bf4466 100644
--- a/intern/gawain/gawain/gwn_common.h
+++ b/intern/gawain/gawain/gwn_common.h
@@ -33,4 +33,4 @@
# define GWN_INLINE static __forceinline
#else
# define GWN_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__))
-#endif \ No newline at end of file
+#endif
diff --git a/intern/gawain/src/gwn_batch.c b/intern/gawain/src/gwn_batch.c
index 2e3a4eff0f0..64d5d146578 100644
--- a/intern/gawain/src/gwn_batch.c
+++ b/intern/gawain/src/gwn_batch.c
@@ -179,7 +179,7 @@ int GWN_batch_vertbuf_add_ex(
return v;
}
}
-
+
// we only make it this far if there is no room for another Gwn_VertBuf
#if TRUST_NO_ONE
assert(false);
diff --git a/intern/gawain/src/gwn_immediate.c b/intern/gawain/src/gwn_immediate.c
index 006af0abe01..b0b587d1b8c 100644
--- a/intern/gawain/src/gwn_immediate.c
+++ b/intern/gawain/src/gwn_immediate.c
@@ -47,7 +47,7 @@ typedef struct {
GLuint vbo_id;
GLuint vao_id;
-
+
GLuint bound_program;
const Gwn_ShaderInterface* shader_interface;
Gwn_AttrBinding attrib_binding;
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index e4b74ae24af..d8330d43c16 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -280,7 +280,7 @@ elseif(WIN32)
if(NOT WITH_GL_EGL)
list(APPEND SRC
intern/GHOST_ContextWGL.cpp
-
+
intern/GHOST_ContextWGL.h
)
endif()
@@ -307,7 +307,7 @@ endif()
if(WITH_GL_EGL AND NOT (WITH_HEADLESS OR WITH_GHOST_SDL))
list(APPEND SRC
intern/GHOST_ContextEGL.cpp
-
+
intern/GHOST_ContextEGL.h
)
endif()
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 071474e57dc..a911c4560e4 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -36,7 +36,7 @@
#include "GHOST_Types.h"
#ifdef __cplusplus
-extern "C" {
+extern "C" {
#endif
/**
@@ -103,7 +103,7 @@ extern GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle);
/**
* Installs a timer.
- * Note that, on most operating systems, messages need to be processed in order
+ * Note that, on most operating systems, messages need to be processed in order
* for the timer callbacks to be invoked.
* \param systemhandle The handle to the system
* \param delay The time to wait for the first call to the timerProc (in milliseconds)
@@ -165,7 +165,7 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
/**
* Create a new window.
- * The new window is added to the list of windows managed.
+ * 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 title The name of the window (displayed in the title bar of the window if the OS supports it).
@@ -218,7 +218,7 @@ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandl
* \param windowhandle The handle to the window
* \param userdata The window user data.
*/
-extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle,
+extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle,
GHOST_TUserDataPtr userdata);
/**
@@ -488,7 +488,7 @@ extern GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle);
extern GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle);
/**
- * Returns the window this event was generated on,
+ * Returns the window this event was generated on,
* or NULL if it is a 'system' event.
* \param eventhandle The handle to the event
* \return The generating window.
@@ -566,7 +566,7 @@ extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle,
/**
* Returns the title displayed in the title bar. The title
* should be free'd with free().
- *
+ *
* \param windowhandle The handle to the window
* \return The title, free with free().
*/
diff --git a/intern/ghost/GHOST_IEvent.h b/intern/ghost/GHOST_IEvent.h
index ba5d9ee33b9..83273716950 100644
--- a/intern/ghost/GHOST_IEvent.h
+++ b/intern/ghost/GHOST_IEvent.h
@@ -42,8 +42,8 @@ class GHOST_IWindow;
* Interface class for events received from GHOST.
* You should not need to inherit this class. The system will pass these events
* to the GHOST_IEventConsumer::processEvent() method of event consumers.<br>
- * Use the getType() method to retrieve the type of event and the getData()
- * method to get the event data out. Using the event type you can cast the
+ * Use the getType() method to retrieve the type of event and the getData()
+ * method to get the event data out. Using the event type you can cast the
* event data to the correct event dat structure.
* \see GHOST_IEventConsumer#processEvent
* \see GHOST_TEventType
@@ -73,18 +73,18 @@ public:
virtual GHOST_TUns64 getTime() = 0;
/**
- * Returns the window this event was generated on,
+ * Returns the window this event was generated on,
* or NULL if it is a 'system' event.
* \return The generating window.
*/
virtual GHOST_IWindow *getWindow() = 0;
-
+
/**
* Returns the event data.
* \return The event data.
*/
virtual GHOST_TEventDataPtr getData() = 0;
-
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEvent")
#endif
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 25b7fb26e0e..1a6c0f9a1bf 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -315,7 +315,7 @@ public:
* \return The current status.
*/
virtual bool getFullScreen(void) = 0;
-
+
/**
* Native pixel size support (MacBook 'retina').
*/
diff --git a/intern/ghost/GHOST_ISystemPaths.h b/intern/ghost/GHOST_ISystemPaths.h
index 8f81a226f94..14b1183af2c 100644
--- a/intern/ghost/GHOST_ISystemPaths.h
+++ b/intern/ghost/GHOST_ISystemPaths.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,7 +18,7 @@
* The Original Code is Copyright (C) 2009 Blender Foundation.
* All rights reserved.
*
- *
+ *
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
diff --git a/intern/ghost/GHOST_ITimerTask.h b/intern/ghost/GHOST_ITimerTask.h
index 9bea697cbc8..dd3db5623cc 100644
--- a/intern/ghost/GHOST_ITimerTask.h
+++ b/intern/ghost/GHOST_ITimerTask.h
@@ -39,11 +39,11 @@
/**
* Interface for a timer task.
* Timer tasks are created by the system and can be installed by the system.
- * After installation, the timer callback-procedure or "timerProc" will be called
+ * After installation, the timer callback-procedure or "timerProc" will be called
* periodically. You should not need to inherit this class. It is passed to the
* application in the timer-callback.<br>
* <br>
- * Note that GHOST processes timers in the UI thread. You should ask GHOST
+ * Note that GHOST processes timers in the UI thread. You should ask GHOST
* process messages in order for the timer-callbacks to be called.
* \see GHOST_ISystem#installTimer
* \see GHOST_TimerProcPtr
@@ -77,7 +77,7 @@ public:
* \return The timer user data.
*/
virtual GHOST_TUserDataPtr getUserData() const = 0;
-
+
/**
* Changes the time user data.
* \param userData: The timer user data.
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 4a4d6be5ced..5a3403bcbd3 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -361,7 +361,7 @@ public:
*/
virtual void endIME() = 0;
#endif /* WITH_INPUT_IME */
-
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow")
#endif
diff --git a/intern/ghost/GHOST_Path-api.h b/intern/ghost/GHOST_Path-api.h
index 5af3adaa570..9a4d065d2ad 100644
--- a/intern/ghost/GHOST_Path-api.h
+++ b/intern/ghost/GHOST_Path-api.h
@@ -36,7 +36,7 @@
#include "GHOST_Types.h"
#ifdef __cplusplus
-extern "C" {
+extern "C" {
#endif
GHOST_DECLARE_HANDLE(GHOST_SystemPathsHandle);
@@ -79,7 +79,7 @@ extern const GHOST_TUns8 *GHOST_getBinaryDir(void);
extern void GHOST_addToSystemRecentFiles(const char *filename);
#ifdef __cplusplus
-}
+}
#endif
#endif
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 02b5063e515..b206bb677a7 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -77,7 +77,7 @@ typedef enum {
GHOST_kSuccess
} GHOST_TSuccess;
-/* Xtilt and Ytilt represent how much the pen is tilted away from
+/* Xtilt and Ytilt represent how much the pen is tilted away from
* vertically upright in either the X or Y direction, with X and Y the
* axes of the tablet surface.
* In other words, Xtilt and Ytilt are components of a vector created by projecting
@@ -190,12 +190,12 @@ typedef enum {
GHOST_kEventWindowSize,
GHOST_kEventWindowMove,
GHOST_kEventWindowDPIHintChanged,
-
+
GHOST_kEventDraggingEntered,
GHOST_kEventDraggingUpdated,
GHOST_kEventDraggingExited,
GHOST_kEventDraggingDropDone,
-
+
GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup
GHOST_kEventNativeResolutionChange, // Needed for Cocoa when window moves to other display
@@ -214,9 +214,9 @@ typedef enum {
GHOST_kStandardCursorDefault = 0,
GHOST_kStandardCursorRightArrow,
GHOST_kStandardCursorLeftArrow,
- GHOST_kStandardCursorInfo,
+ GHOST_kStandardCursorInfo,
GHOST_kStandardCursorDestroy,
- GHOST_kStandardCursorHelp,
+ GHOST_kStandardCursorHelp,
GHOST_kStandardCursorCycle,
GHOST_kStandardCursorSpray,
GHOST_kStandardCursorWait,
@@ -233,7 +233,7 @@ typedef enum {
GHOST_kStandardCursorBottomRightCorner,
GHOST_kStandardCursorBottomLeftCorner,
GHOST_kStandardCursorCopy,
- GHOST_kStandardCursorCustom,
+ GHOST_kStandardCursorCustom,
GHOST_kStandardCursorPencil,
GHOST_kStandardCursorNumCursors
@@ -247,7 +247,7 @@ typedef enum {
GHOST_kKeyLinefeed,
GHOST_kKeyClear,
GHOST_kKeyEnter = 0x0D,
-
+
GHOST_kKeyEsc = 0x1B,
GHOST_kKeySpace = ' ',
GHOST_kKeyQuote = 0x27,
@@ -305,7 +305,7 @@ typedef enum {
GHOST_kKeyBackslash = 0x5C,
GHOST_kKeyAccentGrave = '`',
-
+
GHOST_kKeyLeftShift = 0x100,
GHOST_kKeyRightShift,
GHOST_kKeyLeftControl,
@@ -377,7 +377,7 @@ typedef enum {
GHOST_kKeyF22,
GHOST_kKeyF23,
GHOST_kKeyF24,
-
+
// Multimedia keypad buttons
GHOST_kKeyMediaPlay,
GHOST_kKeyMediaStop,
@@ -418,7 +418,7 @@ typedef enum {
GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */
GHOST_kTrackpadEventMagnify
} GHOST_TTrackpadEventSubTypes;
-
+
typedef struct {
/** The event subtype */
diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h
index 0aa93a2fad0..aed9a3cc81f 100644
--- a/intern/ghost/intern/GHOST_Buttons.h
+++ b/intern/ghost/intern/GHOST_Buttons.h
@@ -38,7 +38,7 @@
/**
* This struct stores the state of the mouse buttons.
- * Buttons can be set using button masks.
+ * Buttons can be set using button masks.
* \author Maarten Gribnau
* \date May 15, 2001
*/
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index c89ef49de33..90956cf541a 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -119,7 +119,7 @@ void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
GHOST_TUns32 *height)
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
-
+
system->getMainDisplayDimensions(*width, *height);
}
@@ -182,7 +182,7 @@ GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
-
+
return system->disposeWindow(window);
}
@@ -193,7 +193,7 @@ int GHOST_ValidWindow(GHOST_SystemHandle systemhandle,
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
-
+
return (int) system->validWindow(window);
}
@@ -211,7 +211,7 @@ GHOST_WindowHandle GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle,
bstereoVisual = true;
else
bstereoVisual = false;
-
+
system->beginFullScreen(*setting, &window, bstereoVisual);
return (GHOST_WindowHandle)window;
@@ -240,7 +240,7 @@ int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle)
int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent)
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
-
+
return (int) system->processEvents(waitForEvent ? true : false);
}
@@ -249,7 +249,7 @@ int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent)
void GHOST_DispatchEvents(GHOST_SystemHandle systemhandle)
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
-
+
system->dispatchEvents();
}
@@ -257,7 +257,7 @@ void GHOST_DispatchEvents(GHOST_SystemHandle systemhandle)
GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, GHOST_EventConsumerHandle consumerhandle)
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
-
+
return system->addEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle);
}
@@ -353,7 +353,7 @@ GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TInt32 *y)
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
-
+
return system->getCursorPosition(*x, *y);
}
@@ -364,7 +364,7 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TInt32 y)
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
-
+
return system->setCursorPosition(x, y);
}
@@ -398,7 +398,7 @@ GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
GHOST_TSuccess result;
bool isdown = false;
-
+
result = system->getModifierKeyState(mask, isdown);
*isDown = (int) isdown;
@@ -414,7 +414,7 @@ GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
GHOST_TSuccess result;
bool isdown = false;
-
+
result = system->getButtonState(mask, isdown);
*isDown = (int) isdown;
@@ -441,7 +441,7 @@ void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, GHOST_TInt8 c
GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle)
{
GHOST_IEvent *event = (GHOST_IEvent *) eventhandle;
-
+
return event->getType();
}
@@ -466,7 +466,7 @@ GHOST_WindowHandle GHOST_GetEventWindow(GHOST_EventHandle eventhandle)
GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle)
{
GHOST_IEvent *event = (GHOST_IEvent *) eventhandle;
-
+
return event->getData();
}
@@ -475,7 +475,7 @@ GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle)
GHOST_TimerProcPtr GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle)
{
GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle;
-
+
return timertask->getTimerProc();
}
@@ -485,7 +485,7 @@ void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle,
GHOST_TimerProcPtr timerproc)
{
GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle;
-
+
timertask->setTimerProc(timerproc);
}
@@ -504,13 +504,13 @@ void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle,
GHOST_TUserDataPtr userdata)
{
GHOST_ITimerTask *timertask = (GHOST_ITimerTask *) timertaskhandle;
-
+
timertask->setUserData(userdata);
}
-int GHOST_GetValid(GHOST_WindowHandle windowhandle)
+int GHOST_GetValid(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
@@ -542,7 +542,7 @@ void GHOST_SetTitle(GHOST_WindowHandle windowhandle,
const char *title)
{
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
-
+
window->setTitle(title);
}
@@ -567,7 +567,7 @@ char *GHOST_GetTitle(GHOST_WindowHandle windowhandle)
-GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)
+GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
GHOST_Rect *rectangle = NULL;
@@ -580,7 +580,7 @@ GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)
-GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle)
+GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
GHOST_Rect *rectangle = NULL;
@@ -678,16 +678,16 @@ GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle,
GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, GHOST_TUns8 isUnsavedChanges)
{
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
-
+
return window->setModifiedState(isUnsavedChanges);
-}
+}
GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle,
GHOST_TWindowOrder order)
{
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
-
+
return window->setOrder(order);
}
@@ -725,7 +725,7 @@ GHOST_TUns16 GHOST_GetNumOfAASamples(GHOST_WindowHandle windowhandle)
GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
-
+
return window->activateDrawingContext();
}
diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h
index 6f575db73c6..be9575844c9 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.h
+++ b/intern/ghost/intern/GHOST_ContextWGL.h
@@ -158,7 +158,7 @@ private:
const int m_contextResetNotificationStrategy;
HGLRC m_hGLRC;
-
+
#ifndef NDEBUG
const char *m_dummyVendor;
const char *m_dummyRenderer;
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
index db49627b378..658c9bf5d2c 100644
--- a/intern/ghost/intern/GHOST_Debug.h
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -40,9 +40,9 @@
# endif // DEBUG
#endif // _MSC_VER
-#ifdef WITH_GHOST_DEBUG
+#ifdef WITH_GHOST_DEBUG
# define GHOST_DEBUG // spit ghost events to stdout
-#endif // WITH_GHOST_DEBUG
+#endif // WITH_GHOST_DEBUG
#ifdef GHOST_DEBUG
# include <iostream>
diff --git a/intern/ghost/intern/GHOST_DisplayManager.cpp b/intern/ghost/intern/GHOST_DisplayManager.cpp
index 9f0b32148f6..2f8240e826b 100644
--- a/intern/ghost/intern/GHOST_DisplayManager.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManager.cpp
@@ -179,9 +179,9 @@ GHOST_DisplayManager::findMatch(
best = score;
}
}
-
+
match = m_settings[display][found];
-
+
GHOST_PRINT("GHOST_DisplayManager::findMatch(): settings of match:\n");
GHOST_PRINT(" setting.xPixels=" << match.xPixels << "\n");
GHOST_PRINT(" setting.yPixels=" << match.yPixels << "\n");
diff --git a/intern/ghost/intern/GHOST_DisplayManager.h b/intern/ghost/intern/GHOST_DisplayManager.h
index afdb11543e9..02a742a54db 100644
--- a/intern/ghost/intern/GHOST_DisplayManager.h
+++ b/intern/ghost/intern/GHOST_DisplayManager.h
@@ -50,7 +50,7 @@ public:
* Constructor.
*/
GHOST_DisplayManager(void);
-
+
/**
* Destructor.
*/
@@ -79,7 +79,7 @@ public:
GHOST_TInt32& numSettings) const;
/**
- * Returns the current setting for this display device.
+ * Returns the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param index The setting index to be returned.
* \param setting The setting of the display device with this index.
@@ -90,7 +90,7 @@ public:
GHOST_DisplaySetting& setting) const;
/**
- * Returns the current setting for this display device.
+ * Returns the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param setting The current setting of the display device with this index.
* \return Indication of success.
@@ -128,7 +128,7 @@ protected:
* \return Indication of success.
*/
GHOST_TSuccess initializeSettings(void);
-
+
/** Tells whether the list of display modes has been stored already. */
bool m_settingsInitialized;
/** The list with display settings for the main display. */
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
index f580820d8f6..3ce0b4e2239 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
@@ -69,7 +69,7 @@ public:
GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
/**
- * Returns the current setting for this display device.
+ * Returns the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param index The setting index to be returned.
* \param setting The setting of the display device with this index.
@@ -78,7 +78,7 @@ public:
GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
/**
- * Returns the current setting for this display device.
+ * Returns the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param setting The current setting of the display device with this index.
* \return Indication of success.
@@ -86,14 +86,14 @@ public:
GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
/**
- * Changes the current setting for this display device.
+ * Changes the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param setting The current setting of the display device with this index.
* \return Indication of success.
*/
GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
-protected:
+protected:
//Do not cache values as OS X supports screen hot plug
/** Cached number of displays. */
//CGDisplayCount m_numDisplays;
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
index 7b9a897fe57..f5f6de330a9 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
@@ -62,11 +62,11 @@ static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd)
}
/*
- * When you call EnumDisplaySettings with iModeNum set to zero, the operating system
- * initializes and caches information about the display device. When you call
- * EnumDisplaySettings with iModeNum set to a non-zero value, the function returns
+ * When you call EnumDisplaySettings with iModeNum set to zero, the operating system
+ * initializes and caches information about the display device. When you call
+ * EnumDisplaySettings with iModeNum set to a non-zero value, the function returns
* the information that was cached the last time the function was called with iModeNum
- * set to zero.
+ * set to zero.
*/
GHOST_TSuccess GHOST_DisplayManagerWin32::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
{
@@ -98,9 +98,9 @@ GHOST_TSuccess GHOST_DisplayManagerWin32::getDisplaySetting(GHOST_TUns8 display,
setting.bpp = dm.dmBitsPerPel;
/* When you call the EnumDisplaySettings function, the dmDisplayFrequency member
* may return with the value 0 or 1. These values represent the display hardware's
- * default refresh rate. This default rate is typically set by switches on a display
- * card or computer motherboard, or by a configuration program that does not use
- * Win32 display functions such as ChangeDisplaySettings.
+ * default refresh rate. This default rate is typically set by switches on a display
+ * card or computer motherboard, or by a configuration program that does not use
+ * Win32 display functions such as ChangeDisplaySettings.
*/
/* First, we tried to explicitly set the frequency to 60 if EnumDisplaySettings
* returned 0 or 1 but this doesn't work since later on an exact match will
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.h b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
index ff8849f03c9..f0d6d62083c 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
@@ -69,7 +69,7 @@ public:
GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
/**
- * Returns the current setting for this display device.
+ * Returns the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param index The setting index to be returned.
* \param setting The setting of the display device with this index.
@@ -78,7 +78,7 @@ public:
GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
/**
- * Returns the current setting for this display device.
+ * Returns the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param setting The current setting of the display device with this index.
* \return Indication of success.
@@ -86,7 +86,7 @@ public:
GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
/**
- * Changes the current setting for this display device.
+ * Changes the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param setting The current setting of the display device with this index.
* \return Indication of success.
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
index b3e6f2e53fa..8a629b2bf18 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
@@ -158,7 +158,7 @@ getDisplaySetting(
return GHOST_kSuccess;
}
-
+
GHOST_TSuccess
GHOST_DisplayManagerX11::
getCurrentDisplaySetting(
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.h b/intern/ghost/intern/GHOST_DisplayManagerX11.h
index b54c53c67bd..857a8a5fce8 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.h
@@ -76,7 +76,7 @@ public:
) const;
/**
- * Returns the current setting for this display device.
+ * Returns the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param index The setting index to be returned.
* \param setting The setting of the display device with this index.
@@ -90,7 +90,7 @@ public:
) const;
/**
- * Returns the current setting for this display device.
+ * Returns the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param setting The current setting of the display device with this index.
* \return Indication of success.
@@ -102,7 +102,7 @@ public:
) const;
/**
- * Changes the current setting for this display device.
+ * Changes the current setting for this display device.
* \param display The index of the display to query with 0 <= display < getNumDisplays().
* \param setting The current setting of the display device with this index.
* \return Indication of success.
@@ -119,5 +119,5 @@ private:
};
-#endif //
+#endif //
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
index cbf37bf1b16..79d7a2d48b4 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
@@ -29,7 +29,7 @@
* \ingroup GHOST
*/
-
+
#include "GHOST_Debug.h"
#include "GHOST_DropTargetWin32.h"
#include <shellapi.h>
@@ -59,7 +59,7 @@ GHOST_DropTargetWin32::~GHOST_DropTargetWin32()
}
-/*
+/*
* IUnknown::QueryInterface
*/
HRESULT __stdcall GHOST_DropTargetWin32::QueryInterface(REFIID riid, void **ppvObj)
@@ -81,8 +81,8 @@ HRESULT __stdcall GHOST_DropTargetWin32::QueryInterface(REFIID riid, void **ppvO
}
-/*
- * IUnknown::AddRef
+/*
+ * IUnknown::AddRef
*/
ULONG __stdcall GHOST_DropTargetWin32::AddRef(void)
@@ -90,13 +90,13 @@ ULONG __stdcall GHOST_DropTargetWin32::AddRef(void)
return ::InterlockedIncrement(&m_cRef);
}
-/*
+/*
* IUnknown::Release
*/
ULONG __stdcall GHOST_DropTargetWin32::Release(void)
{
ULONG refs = ::InterlockedDecrement(&m_cRef);
-
+
if (refs == 0) {
delete this;
return 0;
@@ -106,7 +106,7 @@ ULONG __stdcall GHOST_DropTargetWin32::Release(void)
}
}
-/*
+/*
* Implementation of IDropTarget::DragEnter
*/
HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
@@ -114,13 +114,13 @@ HRESULT __stdcall GHOST_DropTargetWin32::DragEnter(IDataObject *pDataObject, DWO
// we accept all drop by default
m_window->setAcceptDragOperation(true);
*pdwEffect = DROPEFFECT_NONE;
-
+
m_draggedObjectType = getGhostType(pDataObject);
m_system->pushDragDropEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, m_window, pt.x, pt.y, NULL);
return S_OK;
}
-/*
+/*
* Implementation of IDropTarget::DragOver
*/
HRESULT __stdcall GHOST_DropTargetWin32::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
@@ -136,7 +136,7 @@ HRESULT __stdcall GHOST_DropTargetWin32::DragOver(DWORD grfKeyState, POINTL pt,
return S_OK;
}
-/*
+/*
* Implementation of IDropTarget::DragLeave
*/
HRESULT __stdcall GHOST_DropTargetWin32::DragLeave(void)
@@ -147,7 +147,7 @@ HRESULT __stdcall GHOST_DropTargetWin32::DragLeave(void)
}
/* Implementation of IDropTarget::Drop
- * This function will not be called if pdwEffect is set to DROPEFFECT_NONE in
+ * This function will not be called if pdwEffect is set to DROPEFFECT_NONE in
* the implementation of IDropTarget::DragOver
*/
HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
@@ -162,15 +162,15 @@ HRESULT __stdcall GHOST_DropTargetWin32::Drop(IDataObject *pDataObject, DWORD gr
}
if (data)
m_system->pushDragDropEvent(GHOST_kEventDraggingDropDone, m_draggedObjectType, m_window, pt.x, pt.y, data);
-
+
m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
return S_OK;
}
-/*
+/*
* Helpers
*/
-
+
DWORD GHOST_DropTargetWin32::allowedDropEffect(DWORD dwAllowed)
{
DWORD dwEffect = DROPEFFECT_NONE;
@@ -264,7 +264,7 @@ void *GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject *pDataObject)
// Free up memory.
::GlobalUnlock(stgmed.hGlobal);
::ReleaseStgMedium(&stgmed);
-
+
return strArray;
}
}
@@ -301,7 +301,7 @@ void *GHOST_DropTargetWin32::getDropDataAsString(IDataObject *pDataObject)
if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
if (pDataObject->GetData(&fmtetc, &stgmed) == S_OK) {
char *str = (char *)::GlobalLock(stgmed.hGlobal);
-
+
tmp_string = (char *)::malloc(::strlen(str) + 1);
if (!tmp_string) {
::GlobalUnlock(stgmed.hGlobal);
@@ -320,7 +320,7 @@ void *GHOST_DropTargetWin32::getDropDataAsString(IDataObject *pDataObject)
return tmp_string;
}
}
-
+
return NULL;
}
@@ -338,7 +338,7 @@ int GHOST_DropTargetWin32::WideCharToANSI(LPCWSTR in, char * &out)
0,
NULL, NULL
);
-
+
if (!size) {
#ifdef GHOST_DEBUG
::printLastError();
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.h b/intern/ghost/intern/GHOST_DropTargetWin32.h
index 56bae1fd1b2..3d7be45799f 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.h
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.h
@@ -41,11 +41,11 @@ class GHOST_DropTargetWin32 : public IDropTarget
{
public:
/* IUnknownd implementation.
- * Enables clients to get pointers to other interfaces on a given object
+ * Enables clients to get pointers to other interfaces on a given object
* through the QueryInterface method, and manage the existence of the object
- * through the AddRef and Release methods. All other COM interfaces are
- * inherited, directly or indirectly, from IUnknown. Therefore, the three
- * methods in IUnknown are the first entries in the VTable for every interface.
+ * through the AddRef and Release methods. All other COM interfaces are
+ * inherited, directly or indirectly, from IUnknown. Therefore, the three
+ * methods in IUnknown are the first entries in the VTable for every interface.
*/
HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObj);
ULONG __stdcall AddRef(void);
@@ -56,20 +56,20 @@ public:
* provide drag-and-drop operations in your application. It contains methods
* used in any application that can be a target for data during a
* drag-and-drop operation. A drop-target application is responsible for:
- *
+ *
* - Determining the effect of the drop on the target application.
* - Incorporating any valid dropped data when the drop occurs.
* - Communicating target feedback to the source so the source application
* can provide appropriate visual feedback such as setting the cursor.
* - Implementing drag scrolling.
* - Registering and revoking its application windows as drop targets.
- *
- * The IDropTarget interface contains methods that handle all these
- * responsibilities except registering and revoking the application window
- * as a drop target, for which you must call the RegisterDragDrop and the
+ *
+ * The IDropTarget interface contains methods that handle all these
+ * responsibilities except registering and revoking the application window
+ * as a drop target, for which you must call the RegisterDragDrop and the
* RevokeDragDrop functions.
*/
-
+
HRESULT __stdcall DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
HRESULT __stdcall DragLeave(void);
@@ -133,7 +133,7 @@ private:
/**
* Convert Unicode to ANSI, replacing unconvertable chars with '?'.
- * The ANSI codepage is the system default codepage,
+ * The ANSI codepage is the system default codepage,
* and can change from system to system.
* \param in LPCWSTR.
* \param out char *. Is set to NULL on failure.
diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h
index 6a715498b87..278870738c2 100644
--- a/intern/ghost/intern/GHOST_Event.h
+++ b/intern/ghost/intern/GHOST_Event.h
@@ -60,7 +60,7 @@ public:
* \return The event type.
*/
GHOST_TEventType getType()
- {
+ {
return m_type;
}
@@ -74,7 +74,7 @@ public:
}
/**
- * Returns the window this event was generated on,
+ * Returns the window this event was generated on,
* or NULL if it is a 'system' event.
* \return The generating window.
*/
diff --git a/intern/ghost/intern/GHOST_EventDragnDrop.h b/intern/ghost/intern/GHOST_EventDragnDrop.h
index b7bf37c99d8..c9f4f08b53c 100644
--- a/intern/ghost/intern/GHOST_EventDragnDrop.h
+++ b/intern/ghost/intern/GHOST_EventDragnDrop.h
@@ -41,9 +41,9 @@ extern "C" {
/**
* Drag & drop event
- *
+ *
* The dragging sequence is performed in four phases:
- *
+ *
* <li> Start sequence (GHOST_kEventDraggingEntered) that tells a drag'n'drop operation has started.
* Already gives the object data type, and the entering mouse location
*
@@ -93,13 +93,13 @@ public:
m_dragnDropEventData.data = data;
m_data = &m_dragnDropEventData;
}
-
+
~GHOST_EventDragnDrop()
{
//Free the dropped object data
if (m_dragnDropEventData.data == NULL)
return;
-
+
switch (m_dragnDropEventData.dataType) {
case GHOST_kDragnDropTypeBitmap:
IMB_freeImBuf((ImBuf *)m_dragnDropEventData.data);
@@ -108,10 +108,10 @@ public:
{
GHOST_TStringArray *strArray = (GHOST_TStringArray *)m_dragnDropEventData.data;
int i;
-
+
for (i = 0; i < strArray->count; i++)
free(strArray->strings[i]);
-
+
free(strArray->strings);
free(strArray);
}
@@ -124,8 +124,8 @@ public:
break;
}
}
-
-
+
+
protected:
/** The x,y-coordinates of the cursor position. */
diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h
index 54e38c00d05..7e867596503 100644
--- a/intern/ghost/intern/GHOST_EventKey.h
+++ b/intern/ghost/intern/GHOST_EventKey.h
@@ -60,7 +60,7 @@ public:
m_keyEventData.utf8_buf[0] = '\0';
m_data = &m_keyEventData;
}
-
+
/**
* Constructor.
* \param msec The time this event was generated.
@@ -82,7 +82,7 @@ public:
else m_keyEventData.utf8_buf[0] = '\0';
m_data = &m_keyEventData;
}
-
+
protected:
/** The key event data. */
GHOST_TEventKeyData m_keyEventData;
diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp
index 0675ac734ed..bf92fa4517b 100644
--- a/intern/ghost/intern/GHOST_EventManager.cpp
+++ b/intern/ghost/intern/GHOST_EventManager.cpp
@@ -127,7 +127,7 @@ GHOST_TSuccess GHOST_EventManager::addConsumer(GHOST_IEventConsumer *consumer)
{
GHOST_TSuccess success;
GHOST_ASSERT(consumer, "invalid consumer");
-
+
// Check to see whether the consumer is already in our list
TConsumerVector::const_iterator iter = std::find(m_consumers.begin(), m_consumers.end(), consumer);
diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h
index ae2971ea1a8..efad19616ad 100644
--- a/intern/ghost/intern/GHOST_EventManager.h
+++ b/intern/ghost/intern/GHOST_EventManager.h
@@ -143,7 +143,7 @@ protected:
/** A stack with events. */
typedef std::deque<GHOST_IEvent *> TEventStack;
-
+
/** The event stack. */
std::deque<GHOST_IEvent *> m_events;
std::deque<GHOST_IEvent *> m_handled_events;
diff --git a/intern/ghost/intern/GHOST_EventNDOF.h b/intern/ghost/intern/GHOST_EventNDOF.h
index 754e1091860..b81f74becee 100644
--- a/intern/ghost/intern/GHOST_EventNDOF.h
+++ b/intern/ghost/intern/GHOST_EventNDOF.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/intern/ghost/intern/GHOST_EventPrinter.cpp b/intern/ghost/intern/GHOST_EventPrinter.cpp
index a6adba12152..221b85b80ba 100644
--- a/intern/ghost/intern/GHOST_EventPrinter.cpp
+++ b/intern/ghost/intern/GHOST_EventPrinter.cpp
@@ -41,7 +41,7 @@
bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
{
bool handled = true;
-
+
GHOST_ASSERT(event, "event==0");
if (event->getType() == GHOST_kEventWindowUpdate) return false;
@@ -95,7 +95,7 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
std::cout << "GHOST_kEventKeyDown, key: " << str;
}
break;
-
+
case GHOST_kEventDraggingEntered:
{
GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
@@ -103,7 +103,7 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
}
break;
-
+
case GHOST_kEventDraggingUpdated:
{
GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
@@ -118,7 +118,7 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
std::cout << "GHOST_kEventDraggingExited, dragged object type : " << dragnDropData->dataType;
}
break;
-
+
case GHOST_kEventDraggingDropDone:
{
GHOST_TEventDragnDropData *dragnDropData = (GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
@@ -148,14 +148,14 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
case GHOST_kEventOpenMainFile:
{
GHOST_TEventDataPtr eventData = ((GHOST_IEvent *)event)->getData();
-
+
if (eventData)
std::cout << "GHOST_kEventOpenMainFile for path : " << (char *)eventData;
else
std::cout << "GHOST_kEventOpenMainFile with no path specified!!";
}
break;
-
+
case GHOST_kEventQuit:
std::cout << "GHOST_kEventQuit";
break;
diff --git a/intern/ghost/intern/GHOST_ISystemPaths.cpp b/intern/ghost/intern/GHOST_ISystemPaths.cpp
index 93ca0bc3880..8bd7fbe4f9b 100644
--- a/intern/ghost/intern/GHOST_ISystemPaths.cpp
+++ b/intern/ghost/intern/GHOST_ISystemPaths.cpp
@@ -67,7 +67,7 @@ GHOST_TSuccess GHOST_ISystemPaths::create()
# else
m_systemPaths = new GHOST_SystemPathsUnix();
# endif
-#endif
+#endif
success = m_systemPaths != NULL ? GHOST_kSuccess : GHOST_kFailure;
}
else {
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index cab9bf45b80..1f2af73b743 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index 0c0b945d548..78f24e07a6e 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
index 3f1bfcf57fc..6e676faba1e 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
index fff5aba6f9e..624d39b6347 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.h b/intern/ghost/intern/GHOST_NDOFManagerUnix.h
index 3fd171d9e76..8d83ac7b670 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerUnix.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -20,7 +20,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-
+
#ifndef __GHOST_NDOFMANAGERUNIX_H__
#define __GHOST_NDOFMANAGERUNIX_H__
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
index 0023ee7e1d0..fbdac249eb0 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
@@ -1,11 +1,11 @@
/*
- *
+ *
* ***** 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.
+ * 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
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.h b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
index 2f7bc9ee732..522a79ffc0c 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerWin32.h
+++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/intern/ghost/intern/GHOST_Rect.cpp b/intern/ghost/intern/GHOST_Rect.cpp
index 9af4f30ebc1..646dae9f242 100644
--- a/intern/ghost/intern/GHOST_Rect.cpp
+++ b/intern/ghost/intern/GHOST_Rect.cpp
@@ -108,7 +108,7 @@ void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy)
void GHOST_Rect::setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h)
{
long w_2, h_2;
-
+
w_2 = w >> 1;
h_2 = h >> 1;
m_l = cx - w_2;
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 4db2f0616d7..f849993ae6d 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -113,7 +113,7 @@ GHOST_TSuccess GHOST_System::disposeWindow(GHOST_IWindow *window)
/*
* Remove all pending events for the window.
- */
+ */
if (m_windowManager->getWindowFound(window)) {
m_eventManager->removeWindowEvents(window);
}
@@ -272,7 +272,7 @@ GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent *event)
GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const
{
GHOST_ModifierKeys keys;
- // Get the state of all modifier keys
+ // Get the state of all modifier keys
GHOST_TSuccess success = getModifierKeys(keys);
if (success) {
// Isolate the state of the key requested
@@ -306,7 +306,7 @@ GHOST_TSuccess GHOST_System::init()
m_timerManager = new GHOST_TimerManager();
m_windowManager = new GHOST_WindowManager();
m_eventManager = new GHOST_EventManager();
-
+
#ifdef GHOST_DEBUG
if (m_eventManager) {
m_eventPrinter = new GHOST_EventPrinter();
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 50c893b1113..6831b3d07d9 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -91,7 +91,7 @@ public:
/**
* Installs a timer.
- * Note that, on most operating systems, messages need to be processed in order
+ * Note that, on most operating systems, messages need to be processed in order
* for the timer callbacks to be invoked.
* \param delay The time to wait for the first call to the timerProc (in milliseconds)
* \param interval The interval between calls to the timerProc
@@ -114,7 +114,7 @@ public:
/***************************************************************************************
* Display/window management functionality
***************************************************************************************/
-
+
/**
* Inherited from GHOST_ISystem but left pure virtual
*
@@ -169,7 +169,7 @@ public:
*/
bool getFullScreen(void);
-
+
/**
* Native pixel size support (MacBook 'retina').
* \return The pixel size in float.
@@ -237,7 +237,7 @@ public:
* \return Indication of success.
*/
GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const;
-
+
#ifdef WITH_INPUT_NDOF
/***************************************************************************************
* Access to 3D mouse.
@@ -305,7 +305,7 @@ public:
*
*/
virtual GHOST_TUns8 *getClipboard(bool selection) const = 0;
-
+
/**
* Put data to the Clipboard
* \param buffer The buffer to copy to the clipboard
@@ -324,7 +324,7 @@ public:
*/
virtual bool supportsNativeDialogs(void);
-
+
protected:
/**
* Initialize the system.
@@ -362,7 +362,7 @@ protected:
/** The N-degree of freedom device manager */
GHOST_NDOFManager *m_ndofManager;
#endif
-
+
/** Prints all the events. */
#ifdef GHOST_DEBUG
GHOST_EventPrinter *m_eventPrinter;
@@ -370,7 +370,7 @@ protected:
/** Settings of the display before the display went fullscreen. */
GHOST_DisplaySetting m_preFullScreenSetting;
-
+
};
inline GHOST_TimerManager *GHOST_System::getTimerManager() const
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 8586c91b615..f0702737b46 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -88,7 +88,7 @@ public:
* \return The dimension of the main display.
*/
void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
-
+
/** Returns the combine dimensions of all monitors.
* \return The dimension of the workspace.
*/
@@ -122,7 +122,7 @@ public:
const bool exclusive = false,
const GHOST_TEmbedderWindowID parentWindow = 0
);
-
+
/**
* Create a new offscreen context.
* Never explicitly delete the context, use disposeContext() instead.
@@ -152,19 +152,19 @@ public:
* \return Indication of the presence of events.
*/
bool processEvents(bool waitForEvent);
-
+
/**
* Handle User request to quit, from Menu bar Quit, and Cmd+Q
* Display alert panel if changes performed since last save
*/
GHOST_TUns8 handleQuitRequest();
-
+
/**
* Handle Cocoa openFile event
* Display confirmation request panel if changes performed since last save
*/
bool handleOpenDocumentRequest(void *filepathStr);
-
+
/**
* Handles a drag'n'drop destination event. Called by GHOST_WindowCocoa window subclass
* \param eventType The type of drag'n'drop event
@@ -176,7 +176,7 @@ public:
*/
GHOST_TSuccess handleDraggingEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType,
GHOST_WindowCocoa *window, int mouseX, int mouseY, void *data);
-
+
/***************************************************************************************
* Cursor management functionality
***************************************************************************************/
@@ -196,7 +196,7 @@ public:
* \return Indication of success.
*/
GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
-
+
/***************************************************************************************
* Access to mouse button and keyboard states.
***************************************************************************************/
@@ -221,7 +221,7 @@ public:
* \return Returns the selected buffer
*/
GHOST_TUns8 *getClipboard(bool selection) const;
-
+
/**
* Puts buffer to system clipboard
* \param buffer The buffer to be copied
@@ -236,7 +236,7 @@ public:
* \return Indication whether the event was handled.
*/
GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa *window);
-
+
/**
* Handles the Cocoa event telling the application has become active (again)
* \return Indication whether the event was handled.
@@ -254,7 +254,7 @@ public:
int toggleConsole(int action) {
return 0;
}
-
+
/**
* Handles a tablet event.
* \param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
@@ -279,7 +279,7 @@ public:
* \return Indication whether the event was handled.
*/
GHOST_TSuccess handleKeyEvent(void *eventPtr);
-
+
/**
* Informs if the system provides native dialogs (eg. confirm quit)
*/
@@ -303,19 +303,19 @@ protected:
/** Start time at initialization. */
GHOST_TUns64 m_start_time;
-
+
/** Event has been processed directly by Cocoa (or NDOF manager) and has sent a ghost event to be dispatched */
bool m_outsideLoopEventProcessed;
-
+
/** Raised window is not yet known by the window manager, so delay application become active event handling */
bool m_needDelayedApplicationBecomeActiveEventProcessing;
-
+
/** State of the modifiers. */
GHOST_TUns32 m_modifierMask;
/** Ignores window size messages (when window is dragged). */
bool m_ignoreWindowSizedMessages;
-
+
/** Temporarily ignore momentum scroll events */
bool m_ignoreMomentumScroll;
/** Is the scroll wheel event generated by a multitouch trackpad or mouse? */
diff --git a/intern/ghost/intern/GHOST_SystemPaths.h b/intern/ghost/intern/GHOST_SystemPaths.h
index 22879c71e1e..fbaa8ad8ba5 100644
--- a/intern/ghost/intern/GHOST_SystemPaths.h
+++ b/intern/ghost/intern/GHOST_SystemPaths.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,7 +18,7 @@
* The Original Code is Copyright (C) 2009 Blender Foundation.
* All rights reserved.
*
- *
+ *
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.h b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
index 1c76284857c..3a1f3e1aacf 100644
--- a/intern/ghost/intern/GHOST_SystemPathsCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,7 +18,7 @@
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
- *
+ *
* Contributor(s): Damien Plisson 2010
*
* ***** END GPL LICENSE BLOCK *****
diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
index 8738b8dd0fe..b4e1259d824 100644
--- a/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsUnix.cpp
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,7 +18,7 @@
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
- *
+ *
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
diff --git a/intern/ghost/intern/GHOST_SystemPathsUnix.h b/intern/ghost/intern/GHOST_SystemPathsUnix.h
index 1502160c8d6..69c37c00ce0 100644
--- a/intern/ghost/intern/GHOST_SystemPathsUnix.h
+++ b/intern/ghost/intern/GHOST_SystemPathsUnix.h
@@ -4,7 +4,7 @@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,7 +18,7 @@
* The Original Code is Copyright (C) 2010 Blender Foundation.
* All rights reserved.
*
- *
+ *
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
@@ -44,7 +44,7 @@ public:
* this class should only be instanciated by GHOST_ISystem.
*/
GHOST_SystemPathsUnix();
-
+
/**
* Destructor.
*/
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
index 8056bc76edb..d122d3dd51f 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
@@ -17,7 +17,7 @@
*
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
- *
+ *
* Contributor(s): Blender Foundation
* Andrea Weikert
*
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index ccc90e363b7..625a34aa142 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -240,7 +240,7 @@ GHOST_TUns64 GHOST_SystemWin32::getMilliSeconds() const
__int64 delta = 1000 * (count - m_start);
GHOST_TUns64 t = (GHOST_TUns64)(delta / m_freq);
- return t;
+ return t;
}
@@ -407,7 +407,7 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent)
#else
GHOST_TUns64 next = timerMgr->nextFireTime();
GHOST_TInt64 maxSleep = next - getMilliSeconds();
-
+
if (next == GHOST_kFireTimeNever) {
::WaitMessage();
}
@@ -469,17 +469,17 @@ GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) cons
keys.set(GHOST_kModifierKeyLeftShift, down);
down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
keys.set(GHOST_kModifierKeyRightShift, down);
-
+
down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
keys.set(GHOST_kModifierKeyLeftAlt, down);
down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
keys.set(GHOST_kModifierKeyRightAlt, down);
-
+
down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
keys.set(GHOST_kModifierKeyLeftControl, down);
down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
keys.set(GHOST_kModifierKeyRightControl, down);
-
+
bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
if (lwindown || rwindown)
@@ -512,7 +512,7 @@ GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons &buttons) const
GHOST_TSuccess GHOST_SystemWin32::init()
{
GHOST_TSuccess success = GHOST_System::init();
-
+
/* Disable scaling on high DPI displays on Vista */
HMODULE
user32 = ::LoadLibraryA("user32.dll");
@@ -542,12 +542,12 @@ GHOST_TSuccess GHOST_SystemWin32::init()
wc.cbWndExtra = 0;
wc.hInstance = ::GetModuleHandle(0);
wc.hIcon = ::LoadIcon(wc.hInstance, "APPICON");
-
+
if (!wc.hIcon) {
::LoadIcon(NULL, IDI_APPLICATION);
}
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
- wc.hbrBackground =
+ wc.hbrBackground =
#ifdef INW32_COMPISITING
(HBRUSH)CreateSolidBrush
#endif
@@ -560,7 +560,7 @@ GHOST_TSuccess GHOST_SystemWin32::init()
success = GHOST_kFailure;
}
}
-
+
return success;
}
@@ -583,7 +583,7 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, int *keyDown, char *v
*keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP;
key = this->convertKey(raw.data.keyboard.VKey, raw.data.keyboard.MakeCode, (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0)));
-
+
// extra handling of modifier keys: don't send repeats out from GHOST
if (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt) {
bool changed = false;
@@ -628,7 +628,7 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, int *keyDown, char *v
default:
break;
}
-
+
if (changed) {
modifiers.set(modifier, (bool)*keyDown);
system->storeModifierKeys(modifiers);
@@ -637,7 +637,7 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, int *keyDown, char *v
key = GHOST_kKeyUnknown;
}
}
-
+
if (vk) *vk = raw.data.keyboard.VKey;
@@ -682,7 +682,7 @@ GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short exten
switch (vKey) {
case VK_RETURN:
key = (extend) ? GHOST_kKeyNumpadEnter : GHOST_kKeyEnter; break;
-
+
case VK_BACK: key = GHOST_kKeyBackSpace; break;
case VK_TAB: key = GHOST_kKeyTab; break;
case VK_ESCAPE: key = GHOST_kKeyEsc; break;
@@ -782,7 +782,7 @@ GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short exten
break;
}
}
-
+
return key;
}
@@ -799,7 +799,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type,
{
GHOST_TInt32 x_screen, y_screen;
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *) getSystem();
-
+
system->getCursorPosition(x_screen, y_screen);
/* TODO: CHECK IF THIS IS A TABLET EVENT */
@@ -856,7 +856,7 @@ void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wPar
int acc = system->m_wheelDeltaAccum;
int delta = GET_WHEEL_DELTA_WPARAM(wParam);
-
+
if (acc * delta < 0) {
// scroll direction reversed.
acc = 0;
@@ -864,7 +864,7 @@ void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wPar
acc += delta;
int direction = (acc >= 0) ? 1 : -1;
acc = abs(acc);
-
+
while (acc >= WHEEL_DELTA) {
system->pushEvent(new GHOST_EventWheel(system->getMilliSeconds(), window, direction));
acc -= WHEEL_DELTA;
@@ -1178,10 +1178,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
*/
case WM_DEADCHAR:
/* The WM_DEADCHAR message is posted to the window with the keyboard focus when a
- * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR
- * specifies a character code generated by a dead key. A dead key is a key that
- * generates a character, such as the umlaut (double-dot), that is combined with
- * another character to form a composite character. For example, the umlaut-O
+ * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR
+ * specifies a character code generated by a dead key. A dead key is a key that
+ * generates a character, such as the umlaut (double-dot), that is combined with
+ * another character to form a composite character. For example, the umlaut-O
* character (Ö) is generated by typing the dead key for the umlaut character, and
* then typing the O key.
*/
@@ -1193,16 +1193,16 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* a dead key that is pressed while holding down the alt key.
*/
case WM_SYSCHAR:
- /* The WM_SYSCHAR message is sent to the window with the keyboard focus when
- * a WM_SYSCHAR message is translated by the TranslateMessage function.
- * WM_SYSCHAR specifies the character code of a dead key - that is,
+ /* The WM_SYSCHAR message is sent to the window with the keyboard focus when
+ * a WM_SYSCHAR message is translated by the TranslateMessage function.
+ * WM_SYSCHAR specifies the character code of a dead key - that is,
* a dead key that is pressed while holding down the alt key.
* To prevent the sound, DefWindowProc must be avoided by return
*/
break;
case WM_SYSCOMMAND:
- /* The WM_SYSCHAR message is sent to the window when system commands such as
- * maximize, minimize or close the window are triggered. Also it is sent when ALT
+ /* The WM_SYSCHAR message is sent to the window when system commands such as
+ * maximize, minimize or close the window are triggered. Also it is sent when ALT
* button is press for menu. To prevent this we must return preventing DefWindowProc.
*/
if (wParam == SC_KEYMENU) {
@@ -1269,11 +1269,11 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
case WM_MOUSEWHEEL:
{
- /* The WM_MOUSEWHEEL message is sent to the focus window
- * when the mouse wheel is rotated. The DefWindowProc
+ /* The WM_MOUSEWHEEL message is sent to the focus window
+ * when the mouse wheel is rotated. The DefWindowProc
* function propagates the message to the window's parent.
- * There should be no internal forwarding of the message,
- * since DefWindowProc propagates it up the parent chain
+ * There should be no internal forwarding of the message,
+ * since DefWindowProc propagates it up the parent chain
* until it finds a window that processes it.
*/
@@ -1281,7 +1281,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
POINT mouse_pos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
HWND mouse_hwnd = ChildWindowFromPoint(HWND_DESKTOP, mouse_pos);
GHOST_WindowWin32 *mouse_window = (GHOST_WindowWin32 *)::GetWindowLongPtr(mouse_hwnd, GWLP_USERDATA);
-
+
processWheelEvent(mouse_window ? mouse_window : window , wParam, lParam);
eventHandled = true;
#ifdef BROKEN_PEEK_TOUCHPAD
@@ -1293,7 +1293,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
/* The WM_SETCURSOR message is sent to a window if the mouse causes the cursor
* to move within a window and mouse input is not captured.
* This means we have to set the cursor shape every time the mouse moves!
- * The DefWindowProc function uses this message to set the cursor to an
+ * The DefWindowProc function uses this message to set the cursor to an
* arrow if it is not in the client area.
*/
if (LOWORD(lParam) == HTCLIENT) {
@@ -1301,7 +1301,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
// Bypass call to DefWindowProc
return 0;
- }
+ }
else {
// Outside of client area show standard cursor
window->loadCursor(true, GHOST_kStandardCursorDefault);
@@ -1317,10 +1317,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* that contains the cursor. If a window has captured the mouse, this message is not posted.
*/
case WM_NCHITTEST:
- /* The WM_NCHITTEST message is sent to a window when the cursor moves, or
- * when a mouse button is pressed or released. If the mouse is not captured,
- * the message is sent to the window beneath the cursor. Otherwise, the message
- * is sent to the window that has captured the mouse.
+ /* The WM_NCHITTEST message is sent to a window when the cursor moves, or
+ * when a mouse button is pressed or released. If the mouse is not captured,
+ * the message is sent to the window beneath the cursor. Otherwise, the message
+ * is sent to the window that has captured the mouse.
*/
break;
@@ -1332,11 +1332,11 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
event = processWindowEvent(GHOST_kEventWindowClose, window);
break;
case WM_ACTIVATE:
- /* The WM_ACTIVATE message is sent to both the window being activated and the window being
- * deactivated. If the windows use the same input queue, the message is sent synchronously,
+ /* The WM_ACTIVATE message is sent to both the window being activated and the window being
+ * deactivated. If the windows use the same input queue, the message is sent synchronously,
* first to the window procedure of the top-level window being deactivated, then to the window
* procedure of the top-level window being activated. If the windows use different input queues,
- * the message is sent asynchronously, so the window is activated immediately.
+ * the message is sent asynchronously, so the window is activated immediately.
*/
{
GHOST_ModifierKeys modifiers;
@@ -1353,12 +1353,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
}
case WM_ENTERSIZEMOVE:
- /* The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving
- * or sizing modal loop. The window enters the moving or sizing modal loop when the user
- * clicks the window's title bar or sizing border, or when the window passes the
- * WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the
- * message specifies the SC_MOVE or SC_SIZE value. The operation is complete when
- * DefWindowProc returns.
+ /* The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving
+ * or sizing modal loop. The window enters the moving or sizing modal loop when the user
+ * clicks the window's title bar or sizing border, or when the window passes the
+ * WM_SYSCOMMAND message to the DefWindowProc function and the wParam parameter of the
+ * message specifies the SC_MOVE or SC_SIZE value. The operation is complete when
+ * DefWindowProc returns.
*/
window->m_inLiveResize = 1;
break;
@@ -1366,11 +1366,11 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
window->m_inLiveResize = 0;
break;
case WM_PAINT:
- /* An application sends the WM_PAINT message when the system or another application
+ /* An application sends the WM_PAINT message when the system or another application
* makes a request to paint a portion of an application's window. The message is sent
- * when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage
- * function when the application obtains a WM_PAINT message by using the GetMessage or
- * PeekMessage function.
+ * when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage
+ * function when the application obtains a WM_PAINT message by using the GetMessage or
+ * PeekMessage function.
*/
if (!window->m_inLiveResize) {
event = processWindowEvent(GHOST_kEventWindowUpdate, window);
@@ -1381,10 +1381,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
break;
case WM_GETMINMAXINFO:
- /* The WM_GETMINMAXINFO message is sent to a window when the size or
- * position of the window is about to change. An application can use
- * this message to override the window's default maximized size and
- * position, or its default minimum or maximum tracking size.
+ /* The WM_GETMINMAXINFO message is sent to a window when the size or
+ * position of the window is about to change. An application can use
+ * this message to override the window's default maximized size and
+ * position, or its default minimum or maximum tracking size.
*/
processMinMaxInfo((MINMAXINFO *) lParam);
/* Let DefWindowProc handle it. */
@@ -1392,9 +1392,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_SIZING:
case WM_SIZE:
/* The WM_SIZE message is sent to a window after its size has changed.
- * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
+ * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
* WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
- * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
+ * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
* message without calling DefWindowProc.
*/
/* we get first WM_SIZE before we fully init. So, do not dispatch before we continiously resizng */
@@ -1415,10 +1415,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* and, if needed, change its size or position.
*/
case WM_MOVE:
- /* The WM_SIZE and WM_MOVE messages are not sent if an application handles the
+ /* The WM_SIZE and WM_MOVE messages are not sent if an application handles the
* WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient
- * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
- * message without calling DefWindowProc.
+ * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
+ * message without calling DefWindowProc.
*/
/* see WM_SIZE comment*/
if (window->m_inLiveResize) {
@@ -1487,13 +1487,13 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* that all child windows still exist.
*/
case WM_NCDESTROY:
- /* The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The
+ /* The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The
* DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY
- * message. WM_DESTROY is used to free the allocated memory object associated with the window.
+ * message. WM_DESTROY is used to free the allocated memory object associated with the window.
*/
break;
case WM_KILLFOCUS:
- /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus.
+ /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus.
* We want to prevent this if a window is still active and it loses focus to nowhere*/
if (!wParam && hwnd == ::GetActiveWindow())
::SetFocus(hwnd);
@@ -1526,7 +1526,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* when a timer expires. You can process the message by providing a WM_TIMER
* case in the window procedure. Otherwise, the default window procedure will
* call the TimerProc callback function specified in the call to the SetTimer
- * function used to install the timer.
+ * function used to install the timer.
*
* In GHOST, we let DefWindowProc call the timer callback.
*/
@@ -1565,7 +1565,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
GHOST_TUns8 *GHOST_SystemWin32::getClipboard(bool selection) const
{
char *temp_buff;
-
+
if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL) ) {
wchar_t *buffer;
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
@@ -1578,14 +1578,14 @@ GHOST_TUns8 *GHOST_SystemWin32::getClipboard(bool selection) const
CloseClipboard();
return NULL;
}
-
+
temp_buff = alloc_utf_8_from_16(buffer, 0);
-
+
/* Buffer mustn't be accessed after CloseClipboard
* it would like accessing free-d memory */
GlobalUnlock(hData);
CloseClipboard();
-
+
return (GHOST_TUns8 *)temp_buff;
}
else if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL) ) {
@@ -1601,17 +1601,17 @@ GHOST_TUns8 *GHOST_SystemWin32::getClipboard(bool selection) const
CloseClipboard();
return NULL;
}
-
+
len = strlen(buffer);
temp_buff = (char *) malloc(len + 1);
strncpy(temp_buff, buffer, len);
temp_buff[len] = '\0';
-
+
/* Buffer mustn't be accessed after CloseClipboard
* it would like accessing free-d memory */
GlobalUnlock(hData);
CloseClipboard();
-
+
return (GHOST_TUns8 *)temp_buff;
}
else {
@@ -1626,11 +1626,11 @@ void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const
if (OpenClipboard(NULL)) {
HLOCAL clipbuffer;
wchar_t *data;
-
+
if (buffer) {
size_t len = count_utf_16_from_8(buffer);
EmptyClipboard();
-
+
clipbuffer = LocalAlloc(LMEM_FIXED, sizeof(wchar_t) * len);
data = (wchar_t *)GlobalLock(clipbuffer);
@@ -1686,7 +1686,7 @@ static bool getProcessName(int pid, char *buffer, int max_len)
static bool isStartedFromCommandPrompt()
{
HWND hwnd = GetConsoleWindow();
-
+
if (hwnd) {
DWORD pid = (DWORD)-1;
DWORD ppid = GetParentProcessID();
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 0f15f9180ae..e1fd82ec239 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -110,7 +110,7 @@ public:
/**
* Create a new window.
- * The new window is added to the list of windows managed.
+ * The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
* \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.
@@ -157,7 +157,7 @@ public:
* \return Indication of the presence of events.
*/
bool processEvents(bool waitForEvent);
-
+
/***************************************************************************************
** Cursor management functionality
@@ -203,7 +203,7 @@ public:
* \return Returns the Clipboard
*/
GHOST_TUns8 *getClipboard(bool selection) const;
-
+
/**
* Puts buffer to system clipboard
* \param selection Used by X11 only
@@ -212,7 +212,7 @@ public:
void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
/**
- * Creates a drag'n'drop event and pushes it immediately onto the event queue.
+ * Creates a drag'n'drop event and pushes it immediately onto the event queue.
* Called by GHOST_DropTargetWin32 class.
* \param eventType The type of drag'n'drop event
* \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap)
@@ -222,7 +222,7 @@ public:
* \return Indication whether the event was handled.
*/
static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_WindowWin32 *window, int mouseX, int mouseY, void *data);
-
+
/**
* Confirms quitting he program when there is just one window left open
* in the application
@@ -242,7 +242,7 @@ protected:
* \return A success value.
*/
GHOST_TSuccess exit();
-
+
/**
* Converts raw WIN32 key codes from the wndproc to GHOST keys.
* \param vKey The virtual key from hardKey
@@ -303,7 +303,7 @@ protected:
*/
GHOST_TKey processSpecialKey(short vKey, short scanCode) const;
- /**
+ /**
* Creates a window event.
* \param type The type of event to create.
* \param window The window receiving the event (the active window).
@@ -351,7 +351,7 @@ protected:
* param keys The new state of the modifier keys.
*/
inline void storeModifierKeys(const GHOST_ModifierKeys& keys);
-
+
/**
* Check current key layout for AltGr
*/
@@ -373,7 +373,7 @@ protected:
* \return current status (1 -visible, 0 - hidden)
*/
int toggleConsole(int action);
-
+
/** The current state of the modifier keys. */
GHOST_ModifierKeys m_modifierKeys;
/** State variable set at initialization. */
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 69aa3a09977..fcda5d8b72d 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -101,7 +101,12 @@
* See T47228 and D1746 */
#define USE_NON_LATIN_KB_WORKAROUND
-static GHOST_TKey convertXKey(KeySym key);
+static GHOST_TKey ghost_key_from_keysym(
+ const KeySym key);
+static GHOST_TKey ghost_key_from_keycode(
+ const XkbDescPtr xkb_descr, const KeyCode keycode);
+static GHOST_TKey ghost_key_from_keysym_or_keycode(
+ const KeySym key, const XkbDescPtr xkb_descr, const KeyCode keycode);
/* these are for copy and select copy */
static char *txt_cut_buffer = NULL;
@@ -117,11 +122,12 @@ GHOST_SystemX11::
GHOST_SystemX11(
)
: GHOST_System(),
+ m_xkb_descr(NULL),
m_start_time(0)
{
XInitThreads();
m_display = XOpenDisplay(NULL);
-
+
if (!m_display) {
std::cerr << "Unable to open a display" << std::endl;
abort(); /* was return before, but this would just mean it will crash later */
@@ -179,19 +185,24 @@ GHOST_SystemX11(
if (gettimeofday(&tv, NULL) == -1) {
GHOST_ASSERT(false, "Could not instantiate timer!");
}
-
+
/* 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 autorepeate, mac and windows also do this */
int use_xkb;
int xkb_opcode, xkb_event, xkb_error;
int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion;
-
+
use_xkb = XkbQueryExtension(m_display, &xkb_opcode, &xkb_event, &xkb_error, &xkb_major, &xkb_minor);
if (use_xkb) {
XkbSetDetectableAutoRepeat(m_display, true, NULL);
+
+ m_xkb_descr = XkbGetMap(m_display, 0, XkbUseCoreKbd);
+ if (m_xkb_descr) {
+ XkbGetNames(m_display, XkbKeyNamesMask, m_xkb_descr);
+ }
}
#ifdef WITH_XWAYLAND_HACK
@@ -244,11 +255,15 @@ GHOST_SystemX11::
/* close tablet devices */
if (m_xtablet.StylusDevice)
XCloseDevice(m_display, m_xtablet.StylusDevice);
-
+
if (m_xtablet.EraserDevice)
XCloseDevice(m_display, m_xtablet.EraserDevice);
#endif /* WITH_X11_XINPUT */
+ if (m_xkb_descr) {
+ XkbFreeNames(m_xkb_descr, XkbKeyNamesMask, false);
+ }
+
XCloseDisplay(m_display);
}
@@ -285,7 +300,7 @@ getMilliSeconds() const
/* Taking care not to overflow the tv.tv_sec * 1000 */
return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
}
-
+
GHOST_TUns8
GHOST_SystemX11::
getNumDisplays() const
@@ -358,9 +373,9 @@ createWindow(const STR_String& title,
const GHOST_TEmbedderWindowID parentWindow)
{
GHOST_WindowX11 *window = NULL;
-
+
if (!m_display) return 0;
-
+
window = new GHOST_WindowX11(this, m_display, title,
left, top, width, height,
state, parentWindow, type,
@@ -386,7 +401,7 @@ createWindow(const STR_String& title,
return window;
}
-bool GHOST_SystemX11::supportsNativeDialogs(void)
+bool GHOST_SystemX11::supportsNativeDialogs(void)
{
return false;
}
@@ -516,7 +531,7 @@ GHOST_SystemX11::
findGhostWindow(
Window xwind) const
{
-
+
if (xwind == 0) return NULL;
/* It is not entirely safe to do this as the backptr may point
@@ -528,7 +543,7 @@ findGhostWindow(
vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
-
+
for (; win_it != win_end; ++win_it) {
GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
if (window->getXWindow() == xwind) {
@@ -536,14 +551,14 @@ findGhostWindow(
}
}
return NULL;
-
+
}
static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep)
{
int fd = ConnectionNumber(display);
fd_set fds;
-
+
FD_ZERO(&fds);
FD_SET(fd, &fds);
@@ -555,7 +570,7 @@ static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep)
tv.tv_sec = maxSleep / 1000;
tv.tv_usec = (maxSleep - tv.tv_sec * 1000) * 1000;
-
+
select(fd + 1, &fds, NULL, NULL, &tv);
}
}
@@ -618,15 +633,15 @@ processEvents(
{
/* Get all the current events -- translate them into
* ghost events and call base class pushEvent() method. */
-
+
bool anyProcessed = false;
-
+
do {
GHOST_TimerManager *timerMgr = getTimerManager();
-
+
if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) {
GHOST_TUns64 next = timerMgr->nextFireTime();
-
+
if (next == GHOST_kFireTimeNever) {
SleepTillEvent(m_display, -1);
}
@@ -637,11 +652,11 @@ processEvents(
SleepTillEvent(m_display, next - getMilliSeconds());
}
}
-
+
if (timerMgr->fireTimers(getMilliSeconds())) {
anyProcessed = true;
}
-
+
while (XPending(m_display)) {
XEvent xevent;
XNextEvent(m_display, &xevent);
@@ -669,10 +684,8 @@ processEvents(
}
/* dispatch event to XIM server */
- if ((XFilterEvent(&xevent, (Window)NULL) == True) && (xevent.type != KeyRelease)) {
- /* do nothing now, the event is consumed by XIM.
- * however, KeyRelease event should be processed
- * here, otherwise modifiers remain activated. */
+ if ((XFilterEvent(&xevent, (Window)NULL) == True)) {
+ /* do nothing now, the event is consumed by XIM. */
continue;
}
#endif
@@ -726,7 +739,7 @@ processEvents(
getMilliSeconds(),
GHOST_kEventKeyDown,
window,
- convertXKey(modifiers[i]),
+ ghost_key_from_keysym(modifiers[i]),
'\0',
NULL));
}
@@ -738,7 +751,7 @@ processEvents(
#endif /* USE_UNITY_WORKAROUND */
}
-
+
if (generateWindowExposeEvents()) {
anyProcessed = true;
}
@@ -748,9 +761,9 @@ processEvents(
anyProcessed = true;
}
#endif
-
+
} while (waitForEvent && !anyProcessed);
-
+
return anyProcessed;
}
@@ -956,7 +969,6 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{
XKeyEvent *xke = &(xe->xkey);
KeySym key_sym;
- KeySym key_sym_str;
char ascii;
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
/* utf8_array[] is initial buffer used for Xutf8LookupString().
@@ -971,7 +983,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
#else
char *utf8_buf = NULL;
#endif
-
+
GHOST_TEventType type = (xke->type == KeyPress) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
GHOST_TKey gkey;
@@ -983,7 +995,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
* is unmodified (or anyone swapping the keys with xmodmap).
*
* - XLookupKeysym seems to always use first defined keymap (see T47228), which generates
- * keycodes unusable by convertXKey for non-latin-compatible keymaps.
+ * keycodes unusable by ghost_key_from_keysym for non-latin-compatible keymaps.
*
* To address this, we:
*
@@ -1001,6 +1013,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
*
* [1] http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/KeyBind.c
*/
+ KeySym key_sym_str;
/* Mode_switch 'modifier' is AltGr - when this one or Shift are enabled, we do not want to apply
* that 'forced number' hack. */
const unsigned int mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch);
@@ -1021,7 +1034,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
/* Only allow a limited set of keys from XLookupKeysym, all others we take from XLookupString,
* unless it gives unknown key... */
- gkey = convertXKey(key_sym);
+ gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode);
switch (gkey) {
case GHOST_kKeyRightAlt:
case GHOST_kKeyLeftAlt:
@@ -1058,10 +1071,12 @@ GHOST_SystemX11::processEvent(XEvent *xe)
case GHOST_kKeyNumpadSlash:
break;
default:
- GHOST_TKey gkey_str = convertXKey(key_sym_str);
+ {
+ GHOST_TKey gkey_str = ghost_key_from_keysym(key_sym_str);
if (gkey_str != GHOST_kKeyUnknown) {
gkey = gkey_str;
}
+ }
}
#else
/* In keyboards like latin ones,
@@ -1083,8 +1098,8 @@ GHOST_SystemX11::processEvent(XEvent *xe)
key_sym = XLookupKeysym(xke, 0);
}
- gkey = convertXKey(key_sym);
-
+ gkey = ghost_key_from_keysym_or_keycode(key_sym, m_xkb_descr, xke->keycode);
+
if (!XLookupString(xke, &ascii, 1, NULL, NULL)) {
ascii = '\0';
}
@@ -1178,7 +1193,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
if (utf8_buf != utf8_array)
free(utf8_buf);
#endif
-
+
break;
}
@@ -1187,7 +1202,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{
XButtonEvent & xbe = xe->xbutton;
GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
- GHOST_TEventType type = (xbe.type == ButtonPress) ?
+ GHOST_TEventType type = (xbe.type == ButtonPress) ?
GHOST_kEventButtonDown : GHOST_kEventButtonUp;
/* process wheel mouse events and break, only pass on press events */
@@ -1201,7 +1216,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1);
break;
}
-
+
/* process rest of normal mouse buttons */
if (xbe.button == Button1)
gbmask = GHOST_kButtonMaskLeft;
@@ -1233,13 +1248,13 @@ GHOST_SystemX11::processEvent(XEvent *xe)
);
break;
}
-
+
/* change of size, border, layer etc. */
case ConfigureNotify:
{
/* XConfigureEvent & xce = xe->xconfigure; */
- g_event = new
+ g_event = new
GHOST_Event(
getMilliSeconds(),
GHOST_kEventWindowSize,
@@ -1255,10 +1270,10 @@ GHOST_SystemX11::processEvent(XEvent *xe)
/* TODO: make sure this is the correct place for activate/deactivate */
// printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window);
-
+
/* May have to look at the type of event and filter some out. */
- GHOST_TEventType gtype = (xfe.type == FocusIn) ?
+ GHOST_TEventType gtype = (xfe.type == FocusIn) ?
GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate;
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
@@ -1271,7 +1286,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
}
#endif
- g_event = new
+ g_event = new
GHOST_Event(
getMilliSeconds(),
gtype,
@@ -1285,7 +1300,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
XClientMessageEvent & xcme = xe->xclient;
if (((Atom)xcme.data.l[0]) == m_atom.WM_DELETE_WINDOW) {
- g_event = new
+ g_event = new
GHOST_Event(
getMilliSeconds(),
GHOST_kEventWindowClose,
@@ -1329,14 +1344,14 @@ GHOST_SystemX11::processEvent(XEvent *xe)
break;
}
-
+
case DestroyNotify:
::exit(-1);
/* We're not interested in the following things.(yet...) */
case NoExpose:
case GraphicsExpose:
break;
-
+
case EnterNotify:
case LeaveNotify:
{
@@ -1349,7 +1364,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
*/
XCrossingEvent &xce = xe->xcrossing;
if (xce.mode == NotifyNormal) {
- g_event = new
+ g_event = new
GHOST_EventCursor(
getMilliSeconds(),
GHOST_kEventCursorMove,
@@ -1397,18 +1412,18 @@ GHOST_SystemX11::processEvent(XEvent *xe)
XEvent nxe;
Atom target, utf8_string, string, compound_text, c_string;
XSelectionRequestEvent *xse = &xe->xselectionrequest;
-
+
target = XInternAtom(m_display, "TARGETS", False);
utf8_string = XInternAtom(m_display, "UTF8_STRING", False);
string = XInternAtom(m_display, "STRING", False);
compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
c_string = XInternAtom(m_display, "C_STRING", False);
-
+
/* support obsolete clients */
if (xse->property == None) {
xse->property = xse->target;
}
-
+
nxe.xselection.type = SelectionNotify;
nxe.xselection.requestor = xse->requestor;
nxe.xselection.property = xse->property;
@@ -1416,7 +1431,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
nxe.xselection.selection = xse->selection;
nxe.xselection.target = xse->target;
nxe.xselection.time = xse->time;
-
+
/* Check to see if the requestor is asking for String */
if (xse->target == utf8_string ||
xse->target == string ||
@@ -1447,13 +1462,13 @@ GHOST_SystemX11::processEvent(XEvent *xe)
/* Change property to None because we do not support anything but STRING */
nxe.xselection.property = None;
}
-
+
/* Send the event to the client 0 0 == False, SelectionNotify */
XSendEvent(m_display, xse->requestor, 0, 0, &nxe);
XFlush(m_display);
break;
}
-
+
default:
{
#ifdef WITH_X11_XINPUT
@@ -1584,7 +1599,7 @@ getButtons(
}
else {
return GHOST_kFailure;
- }
+ }
return GHOST_kSuccess;
}
@@ -1688,7 +1703,7 @@ setCursorPosition(
#endif
XSync(m_display, 0); /* Sync to process all requests */
-
+
return GHOST_kSuccess;
}
@@ -1699,7 +1714,7 @@ addDirtyWindow(
GHOST_WindowX11 *bad_wind)
{
GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
-
+
m_dirty_windows.push_back(bad_wind);
}
@@ -1711,7 +1726,7 @@ generateWindowExposeEvents()
vector<GHOST_WindowX11 *>::iterator w_start = m_dirty_windows.begin();
vector<GHOST_WindowX11 *>::const_iterator w_end = m_dirty_windows.end();
bool anyProcessed = false;
-
+
for (; w_start != w_end; ++w_start) {
GHOST_Event *g_event = new
GHOST_Event(
@@ -1721,7 +1736,7 @@ generateWindowExposeEvents()
);
(*w_start)->validate();
-
+
if (g_event) {
pushEvent(g_event);
anyProcessed = true;
@@ -1732,10 +1747,22 @@ generateWindowExposeEvents()
return anyProcessed;
}
+static GHOST_TKey
+ghost_key_from_keysym_or_keycode(const KeySym keysym, XkbDescPtr xkb_descr, const KeyCode keycode)
+{
+ GHOST_TKey type = ghost_key_from_keysym(keysym);
+ if (type == GHOST_kKeyUnknown) {
+ if (xkb_descr) {
+ type = ghost_key_from_keycode(xkb_descr, keycode);
+ }
+ }
+ return type;
+}
+
#define GXMAP(k, x, y) case x: k = y; break
static GHOST_TKey
-convertXKey(KeySym key)
+ghost_key_from_keysym(const KeySym key)
{
GHOST_TKey type;
@@ -1844,6 +1871,9 @@ convertXKey(KeySym key)
#endif
#endif
default:
+#ifdef GHOST_DEBUG
+ printf("%s: unknown key: %lu / 0x%lx\n", __func__, key, key);
+#endif
type = GHOST_kKeyUnknown;
break;
}
@@ -1854,6 +1884,33 @@ convertXKey(KeySym key)
#undef GXMAP
+#define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
+
+static GHOST_TKey
+ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode)
+{
+ GHOST_ASSERT(XkbKeyNameLength == 4, "Name length is invalid!");
+ if (keycode >= xkb_descr->min_key_code && keycode <= xkb_descr->max_key_code) {
+ const char *id_str = xkb_descr->names->keys[keycode].name;
+ const uint32_t id = MAKE_ID(id_str[0], id_str[1], id_str[2], id_str[3]);
+ switch (id) {
+ case MAKE_ID('T', 'L', 'D', 'E'):
+ return GHOST_kKeyAccentGrave;
+#ifdef GHOST_DEBUG
+ default:
+ printf("%s unhandled keycode: %.*s\n", __func__, XkbKeyNameLength, id_str);
+ break;
+#endif
+ }
+ }
+ else {
+ GHOST_ASSERT(false, "KeyCode out of range!");
+ }
+ return GHOST_kKeyUnknown;
+}
+
+#undef MAKE_ID
+
/* from xclip.c xcout() v0.11 */
#define XCLIB_XCOUT_NONE 0 /* no context */
@@ -2110,12 +2167,12 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
unsigned char *tmp_data = (unsigned char *) malloc(sel_len + 1);
memcpy((char *)tmp_data, (char *)sel_buf, sel_len);
tmp_data[sel_len] = '\0';
-
+
if (sseln == m_atom.STRING)
XFree(sel_buf);
else
free(sel_buf);
-
+
return tmp_data;
}
return(NULL);
@@ -2156,7 +2213,7 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
}
#ifdef WITH_XDND
-GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
+GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
GHOST_TDragnDropTypes draggedObjectType,
GHOST_IWindow *window,
int mouseX, int mouseY,
@@ -2322,7 +2379,7 @@ void GHOST_SystemX11::refreshXInputDevices()
for (int i = 0; i < device_count; ++i) {
char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
-
+
// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
@@ -2355,7 +2412,7 @@ void GHOST_SystemX11::refreshXInputDevices()
break;
}
-
+
ici = (XAnyClassPtr)(((char *)ici) + ici->length);
}
}
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index b910589a1ad..d318b894d87 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -34,6 +34,7 @@
#define __GHOST_SYSTEMX11_H__
#include <X11/Xlib.h>
+#include <X11/XKBlib.h> /* allow detectable autorepeate */
#include "GHOST_System.h"
#include "../GHOST_Types.h"
@@ -86,7 +87,7 @@ public:
GHOST_SystemX11(
);
-
+
/**
* Destructor.
*/
@@ -114,7 +115,7 @@ public:
GHOST_TUns64
getMilliSeconds(
) const;
-
+
/**
* Returns the number of displays on this system.
@@ -146,7 +147,7 @@ public:
/**
* Create a new window.
- * The new window is added to the list of windows managed.
+ * The new window is added to the list of windows managed.
* Never explicitly delete the window, use disposeWindow() instead.
* \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.
@@ -210,7 +211,7 @@ public:
GHOST_TInt32& x,
GHOST_TInt32& y
) const;
-
+
GHOST_TSuccess
setCursorPosition(
GHOST_TInt32 x,
@@ -239,15 +240,15 @@ public:
/**
* Flag a window as dirty. This will
- * generate a GHOST window update event on a call to processEvents()
+ * generate a GHOST window update event on a call to processEvents()
*/
void
addDirtyWindow(
GHOST_WindowX11 *bad_wind
);
-
-
+
+
/**
* return a pointer to the X11 display structure
*/
@@ -256,7 +257,7 @@ public:
getXDisplay(
) {
return m_display;
- }
+ }
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
XIM
@@ -277,7 +278,7 @@ public:
* \return Returns the Clipboard indicated by Flag
*/
GHOST_TUns8 *getClipboard(bool selection) const;
-
+
/**
* Puts buffer to system clipboard
* \param buffer The buffer to copy to the clipboard
@@ -287,14 +288,14 @@ public:
#ifdef WITH_XDND
/**
- * Creates a drag'n'drop event and pushes it immediately onto the event queue.
+ * Creates a drag'n'drop event and pushes it immediately onto the event queue.
* Called by GHOST_DropTargetX11 class.
* \param eventType The type of drag'n'drop event
* \param draggedObjectType The type object concerned (currently array of file names, string, ?bitmap)
* \param mouseX x mouse coordinate (in window coordinates)
* \param mouseY y mouse coordinate
* \param window The window on which the event occurred
- * \return Indication whether the event was handled.
+ * \return Indication whether the event was handled.
*/
static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_IWindow *window, int mouseX, int mouseY, void *data);
#endif
@@ -373,6 +374,10 @@ public:
private:
Display *m_display;
+
+ /* Use for scancode lookups. */
+ XkbDescRec *m_xkb_descr;
+
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
XIM m_xim;
#endif
diff --git a/intern/ghost/intern/GHOST_TaskbarWin32.h b/intern/ghost/intern/GHOST_TaskbarWin32.h
index 0ef71754717..f65207af706 100644
--- a/intern/ghost/intern/GHOST_TaskbarWin32.h
+++ b/intern/ghost/intern/GHOST_TaskbarWin32.h
@@ -87,7 +87,7 @@ typedef enum TBPFLAG {
TBPF_PAUSED = 0x8,
} TBPFLAG;
-#define THBN_CLICKED 0x1800
+#define THBN_CLICKED 0x1800
extern "C" {
const GUID IID_ITaskList3 = {0xEA1AFB91, 0x9E28, 0x4B86, {0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF}};
diff --git a/intern/ghost/intern/GHOST_TaskbarX11.cpp b/intern/ghost/intern/GHOST_TaskbarX11.cpp
index b47068df39f..2ef82dc6636 100644
--- a/intern/ghost/intern/GHOST_TaskbarX11.cpp
+++ b/intern/ghost/intern/GHOST_TaskbarX11.cpp
@@ -127,4 +127,4 @@ void GHOST_TaskBarX11::set_progress_enabled(bool enabled)
assert(is_valid());
unity_set_progress_visible(handle, enabled ? 1 : 0);
unity_event_loop(NULL, 0);
-} \ No newline at end of file
+}
diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp
index f6ec9d3febe..1918fc26151 100644
--- a/intern/ghost/intern/GHOST_TimerManager.cpp
+++ b/intern/ghost/intern/GHOST_TimerManager.cpp
@@ -102,14 +102,14 @@ GHOST_TUns64 GHOST_TimerManager::nextFireTime()
{
GHOST_TUns64 smallest = GHOST_kFireTimeNever;
TTimerVector::iterator iter;
-
+
for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) {
GHOST_TUns64 next = (*iter)->getNext();
-
+
if (next < smallest)
smallest = next;
}
-
+
return smallest;
}
diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h
index 6cf4bcf40eb..78026a743eb 100644
--- a/intern/ghost/intern/GHOST_TimerManager.h
+++ b/intern/ghost/intern/GHOST_TimerManager.h
@@ -90,11 +90,11 @@ public:
/**
* Finds the soonest time the next timer would fire.
- * \return The soonest time the next timer would fire,
+ * \return The soonest time the next timer would fire,
* or GHOST_kFireTimeNever if no timers exist.
*/
GHOST_TUns64 nextFireTime();
-
+
/**
* Checks all timer tasks to see if they are expired and fires them if needed.
* \param time The current time.
diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h
index 45aa66e4630..fa35fd134f5 100644
--- a/intern/ghost/intern/GHOST_TimerTask.h
+++ b/intern/ghost/intern/GHOST_TimerTask.h
@@ -78,7 +78,7 @@ public:
* \param start The timer start time.
*/
void setStart(GHOST_TUns64 start)
- {
+ {
m_start = start;
}
@@ -96,7 +96,7 @@ public:
* \param interval The timer interval.
*/
void setInterval(GHOST_TUns64 interval)
- {
+ {
m_interval = interval;
}
@@ -114,7 +114,7 @@ public:
* \param next The time the timerProc will be called.
*/
void setNext(GHOST_TUns64 next)
- {
+ {
m_next = next;
}
@@ -144,7 +144,7 @@ public:
{
return m_userData;
}
-
+
/**
* Changes the time user data.
* \param userData: The timer user data.
@@ -168,7 +168,7 @@ public:
* \param auxData The auxiliary storage room.
*/
void setAuxData(GHOST_TUns32 auxData)
- {
+ {
m_auxData = auxData;
}
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index 71fa260f0f2..6596028d5a1 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -58,12 +58,12 @@ GHOST_Window::GHOST_Window(
{
m_isUnsavedChanges = false;
m_canAcceptDragOperation = false;
-
+
m_progressBarVisible = false;
-
+
m_cursorGrabAccumPos[0] = 0;
m_cursorGrabAccumPos[1] = 0;
-
+
m_nativePixelSize = 1.0f;
m_fullScreen = state == GHOST_kWindowStateFullScreen;
@@ -208,7 +208,7 @@ GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHO
16, 16, hotX, hotY, 0, 1);
}
-GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
+GHOST_TSuccess GHOST_Window::setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
int sizex, int sizey, int hotX, int hotY,
int fg_color, int bg_color)
{
@@ -234,7 +234,7 @@ bool GHOST_Window::canAcceptDragOperation() const
GHOST_TSuccess GHOST_Window::setModifiedState(bool isUnsavedChanges)
{
m_isUnsavedChanges = isUnsavedChanges;
-
+
return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 2798bdf72f3..413a3315225 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -40,7 +40,7 @@ class GHOST_Context;
/**
* Platform independent implementation of GHOST_IWindow.
- * Dimensions are given in screen coordinates that are relative to the
+ * Dimensions are given in screen coordinates that are relative to the
* upper-left corner of the screen.
* Implements part of the GHOST_IWindow interface and adds some methods to
* be implemented by childs of this class.
@@ -94,7 +94,7 @@ public:
* virtual GHOST_TSuccess activateDrawingContext() = 0;
* virtual GHOST_TSuccess invalidate() = 0;
*/
-
+
/**
* Destructor.
* Closes the window and disposes resources allocated.
@@ -105,7 +105,7 @@ public:
* Returns indication as to whether the window is valid.
* \return The validity of the window.
*/
- virtual bool getValid() const {
+ virtual bool getValid() const {
return m_context != NULL;
}
@@ -114,7 +114,7 @@ public:
* \return The associated OS object/handle
*/
virtual void *getOSWindow() const;
-
+
/**
* Returns the current cursor shape.
* \return The current cursor shape.
@@ -185,14 +185,14 @@ public:
virtual GHOST_TSuccess setProgressBar(float /*progress*/) {
return GHOST_kFailure;
}
-
+
/**
* Hides the progress bar in the icon
*/
virtual GHOST_TSuccess endProgressBar() {
return GHOST_kFailure;
}
-
+
/**
* Sets the swap interval for swapBuffers.
* \param interval The swap interval to use.
@@ -216,26 +216,26 @@ public:
* Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
*/
void setAcceptDragOperation(bool canAccept);
-
+
/**
* Returns acceptance of the dropped object
* Usually called by the "object dropped" event handling function
*/
bool canAcceptDragOperation() const;
-
+
/**
* Sets the window "modified" status, indicating unsaved changes
* \param isUnsavedChanges Unsaved changes or not
* \return Indication of success.
*/
virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
-
+
/**
* Gets the window "modified" status, indicating unsaved changes
* \return True if there are unsaved changes
*/
virtual bool getModifiedState();
-
+
/**
* Returns the type of drawing context used in this window.
* \return The current type of drawing context.
@@ -278,7 +278,7 @@ public:
{
return m_userData;
}
-
+
/**
* Changes the window user data.
* \param userData: The window user data.
@@ -287,7 +287,7 @@ public:
{
m_userData = userData;
}
-
+
float getNativePixelSize(void)
{
if (m_nativePixelSize > 0.0f)
@@ -341,7 +341,7 @@ protected:
virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/) {
return GHOST_kSuccess;
}
-
+
/**
* Sets the cursor shape on the window using
* native window system calls.
@@ -355,15 +355,15 @@ protected:
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
GHOST_TUns8 mask[16][2],
int hotX, int hotY) = 0;
-
- virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
+
+ virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
int szx, int szy, int hotX, int hotY, int fg, int bg) = 0;
GHOST_TSuccess releaseNativeHandles();
/** The drawing context installed in this window. */
GHOST_TDrawingContextType m_drawingContextType;
-
+
/** The window user data */
GHOST_TUserDataPtr m_userData;
@@ -384,16 +384,16 @@ protected:
/** The current shape of the cursor */
GHOST_TStandardCursor m_cursorShape;
-
+
/** The presence of progress indicator with the application icon */
bool m_progressBarVisible;
-
+
/** The acceptance of the "drop candidate" of the current drag'n'drop operation */
bool m_canAcceptDragOperation;
-
+
/** Modified state : are there unsaved changes */
bool m_isUnsavedChanges;
-
+
/** Stores whether this is a full screen window. */
bool m_fullScreen;
@@ -407,7 +407,7 @@ protected:
GHOST_TUns32 m_fullScreenWidth;
/** Full-screen height */
GHOST_TUns32 m_fullScreenHeight;
-
+
/* OSX only, retina screens */
float m_nativePixelSize;
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index 9dbc85d91e2..54ecd2b44c8 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -89,7 +89,7 @@ public:
* \return The validity of the window.
*/
bool getValid() const;
-
+
/**
* Returns the associated NSWindow object
* \return The associated NSWindow object
@@ -110,11 +110,11 @@ public:
/**
* Returns the window rectangle dimensions.
- * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
* \param bounds The bounding rectangle of the window.
*/
void getWindowBounds(GHOST_Rect& bounds) const;
-
+
/**
* Returns the client rectangle dimensions.
* The left and top members of the rectangle are always zero.
@@ -153,7 +153,7 @@ public:
* \return Indication of success.
*/
GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
-
+
/**
* Converts a point in screen coordinates to client rectangle coordinates
* \param inX The x-coordinate on the screen.
@@ -197,7 +197,7 @@ public:
* \return The NSScreen object
*/
NSScreen *getScreen();
-
+
/**
* Sets the state of the window (normal, minimized, maximized).
* \param state The state of the window.
@@ -213,7 +213,7 @@ public:
GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
-
+
const GHOST_TabletData *GetTabletData()
{
return &m_tablet;
@@ -223,32 +223,32 @@ public:
{
return m_tablet;
}
-
+
/**
* Sets the progress bar value displayed in the window/application icon
* \param progress The progress % (0.0 to 1.0)
*/
GHOST_TSuccess setProgressBar(float progress);
-
+
/**
* Hides the progress bar icon
*/
GHOST_TSuccess endProgressBar();
-
-
+
+
void setNativePixelSize(void);
GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;}
GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
-
+
/** public function to get the window containing the OpenGL view */
CocoaWindow *getCocoaWindow() const {return m_window;};
/* Internal value to ensure proper redraws during animations */
void setImmediateDraw(bool value) { m_immediateDraw = value; }
bool getImmediateDraw(void) const { return m_immediateDraw; }
-
+
protected:
/**
@@ -268,13 +268,13 @@ protected:
* native window system calls.
*/
GHOST_TSuccess setWindowCursorVisibility(bool visible);
-
+
/**
* Sets the cursor grab on the window using
* native window system calls.
*/
GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
-
+
/**
* Sets the cursor shape on the window using
* native window system calls.
@@ -287,14 +287,14 @@ protected:
*/
GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
-
+
GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
/** The window containing the OpenGL view */
CocoaWindow *m_window;
-
+
/** The openGL view */
- CocoaOpenGLView *m_openGLView;
+ CocoaOpenGLView *m_openGLView;
/** The mother SystemCocoa class to send events */
GHOST_SystemCocoa *m_systemCocoa;
diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp
index 790c73deca5..31e1b0401f1 100644
--- a/intern/ghost/intern/GHOST_WindowManager.cpp
+++ b/intern/ghost/intern/GHOST_WindowManager.cpp
@@ -42,7 +42,7 @@
#include "GHOST_Window.h"
-GHOST_WindowManager::GHOST_WindowManager() :
+GHOST_WindowManager::GHOST_WindowManager() :
m_fullScreenWindow(0),
m_activeWindow(0),
m_activeWindowBeforeFullScreen(0)
@@ -61,7 +61,7 @@ GHOST_TSuccess GHOST_WindowManager::addWindow(GHOST_IWindow *window)
GHOST_TSuccess success = GHOST_kFailure;
if (window) {
if (!getWindowFound(window)) {
- // Store the pointer to the window
+ // Store the pointer to the window
m_windows.push_back(window);
success = GHOST_kSuccess;
}
@@ -170,7 +170,7 @@ GHOST_TSuccess GHOST_WindowManager::setActiveWindow(GHOST_IWindow *window)
}
return success;
}
-
+
GHOST_IWindow *GHOST_WindowManager::getActiveWindow(void) const
{
@@ -200,7 +200,7 @@ GHOST_IWindow *GHOST_WindowManager::getWindowAssociatedWithOSWindow(void *osWind
if ((*iter)->getOSWindow() == osWindow)
return *iter;
}
-
+
return NULL;
}
@@ -208,7 +208,7 @@ bool GHOST_WindowManager::getAnyModifiedState()
{
bool isAnyModified = false;
std::vector<GHOST_IWindow *>::iterator iter;
-
+
for (iter = m_windows.begin(); iter != m_windows.end(); ++iter) {
if ((*iter)->getModifiedState())
isAnyModified = true;
diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h
index e868a9b0416..a7dde2af39c 100644
--- a/intern/ghost/intern/GHOST_WindowManager.h
+++ b/intern/ghost/intern/GHOST_WindowManager.h
@@ -110,38 +110,38 @@ public:
* \param window The new active window.
*/
GHOST_TSuccess setActiveWindow(GHOST_IWindow *window);
-
+
/**
* Returns the active window (the window receiving events).
* There can be only one window active which should be in the current window list.
* \return window The active window (or NULL if there is none).
*/
GHOST_IWindow *getActiveWindow(void) const;
-
+
/**
* Set this window to be inactive (not receiving events).
* \param window The window to deactivate.
*/
void setWindowInactive(const GHOST_IWindow *window);
-
+
/**
- * Return a vector of the windows currently managed by this
- * class.
+ * Return a vector of the windows currently managed by this
+ * class.
* \warning It is very dangerous to mess with the contents of
- * this vector. Please do not destroy or add windows use the
+ * this vector. Please do not destroy or add windows use the
* interface above for this,
*/
std::vector<GHOST_IWindow *> & getWindows();
-
+
/**
* Finds the window associated with an OS window object/handle
* \param osWindow The OS window object/handle
* \return The associated window, null if none corresponds
*/
GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow);
-
+
/**
* Return true if any windows has a modified status
* \return True if any window has unsaved changes
@@ -164,7 +164,7 @@ protected:
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_WindowManager")
#endif
-
+
};
#endif // __GHOST_WINDOWMANAGER_H__
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 3c9c7c415bb..676a29f28d4 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -99,7 +99,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
if (state != GHOST_kWindowStateFullScreen) {
RECT rect;
MONITORINFO monitor;
- GHOST_TUns32 tw, th;
+ GHOST_TUns32 tw, th;
#ifndef _MSC_VER
int cxsizeframe = GetSystemMetrics(SM_CXSIZEFRAME);
@@ -158,7 +158,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
width = rect.right - rect.left;
height = rect.bottom - rect.top;
}
-
+
wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0);
m_hWnd = ::CreateWindowW(
s_windowClassName, // pointer to registered class name
@@ -225,7 +225,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
::ShowWindow(m_hWnd, nCmdShow);
#ifdef WIN32_COMPOSITING
if (alphaBackground && parentwindowhwnd == 0) {
-
+
HRESULT hr = S_OK;
// Create and populate the Blur Behind structure
@@ -817,7 +817,7 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode
m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
registerMouseClickEvent(3);
}
-
+
return GHOST_kSuccess;
}
@@ -1041,7 +1041,7 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(
GHOST_TSuccess GHOST_WindowWin32::setProgressBar(float progress)
-{
+{
/*SetProgressValue sets state to TBPF_NORMAL automaticly*/
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 75a33951ff4..d998e86c9b1 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -132,11 +132,11 @@ public:
/**
* Returns the window rectangle dimensions.
- * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
* \param bounds The bounding rectangle of the window.
*/
void getWindowBounds(GHOST_Rect& bounds) const;
-
+
/**
* Returns the client rectangle dimensions.
* The left and top members of the rectangle are always zero.
@@ -211,19 +211,19 @@ public:
* \param progress The progress %
*/
GHOST_TSuccess setProgressBar(float progress);
-
+
/**
* Hides the progress bar in the icon
*/
GHOST_TSuccess endProgressBar();
-
+
/**
- * Register a mouse click event (should be called
+ * Register a mouse click event (should be called
* for any real button press, controls mouse
* capturing).
*
- * \param press
+ * \param press
* 0 - mouse pressed
* 1 - mouse released
* 2 - operator grab
@@ -286,14 +286,14 @@ private:
* native window system calls.
*/
GHOST_TSuccess setWindowCursorVisibility(bool visible);
-
+
/**
* Sets the cursor grab on the window using native window system calls.
* Using registerMouseClickEvent.
* \param mode GHOST_TGrabCursorMode.
*/
GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
-
+
/**
* Sets the cursor shape on the window using
* native window system calls.
@@ -318,7 +318,7 @@ private:
int fg_color,
int bg_color
);
-
+
/** Pointer to system */
GHOST_SystemWin32 *m_system;
/** Pointer to COM IDropTarget implementor */
@@ -330,7 +330,7 @@ private:
/** Flag for if window has captured the mouse */
bool m_hasMouseCaptured;
- /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab()
+ /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab()
* Multiple grabs must be released with a single ungrab */
bool m_hasGrabMouse;
/** Count of number of pressed buttons */
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 3c291bd5ec6..ade4799a52d 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -204,7 +204,7 @@ static XVisualInfo *x11_visualinfo_from_glx(
numOfAASamples = 0;
actualSamples = 0;
}
-
+
#ifdef WITH_X11_ALPHA
if ( needAlpha
&& glx_version >= 103
@@ -276,7 +276,7 @@ static XVisualInfo *x11_visualinfo_from_glx(
/* legacy, don't use extension */
for (;;) {
GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, false);
-
+
visual = glXChooseVisual(display, DefaultScreen(display), glx_attribs);
/* Any sample level or even zero, which means oversampling disabled, is good
@@ -408,7 +408,7 @@ GHOST_WindowX11(GHOST_SystemX11 *system,
Window root_return;
int x_return, y_return;
unsigned int w_return, h_return, border_w_return, depth_return;
-
+
XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return,
&w_return, &h_return, &border_w_return, &depth_return);
@@ -430,8 +430,8 @@ GHOST_WindowX11(GHOST_SystemX11 *system,
&xattributes);
XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
-
- }
+
+ }
#ifdef WITH_XDND
/* initialize drop target for newly created window */
@@ -717,12 +717,12 @@ getTitle(
STR_String& title) const
{
char *name = NULL;
-
+
XFetchName(m_display, m_window, &name);
title = name ? name : "untitled";
XFree(name);
}
-
+
void
GHOST_WindowX11::
getWindowBounds(
@@ -742,12 +742,12 @@ getClientBounds(
int x_return, y_return;
unsigned int w_return, h_return, border_w_return, depth_return;
GHOST_TInt32 screen_x, screen_y;
-
+
XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return,
&w_return, &h_return, &border_w_return, &depth_return);
clientToScreen(0, 0, screen_x, screen_y);
-
+
bounds.m_l = screen_x;
bounds.m_r = bounds.m_l + w_return;
bounds.m_t = screen_y;
@@ -794,7 +794,7 @@ setClientSize(
XConfigureWindow(m_display, m_window, value_mask, &values);
return GHOST_kSuccess;
-}
+}
void
GHOST_WindowX11::
@@ -818,7 +818,7 @@ screenToClient(
outX = ax;
outY = ay;
}
-
+
void
GHOST_WindowX11::
clientToScreen(
@@ -1159,7 +1159,7 @@ setOrder(
GHOST_TWindowOrder order)
{
if (order == GHOST_kWindowOrderTop) {
- XWindowAttributes attr;
+ XWindowAttributes attr;
Atom atom;
/* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some
@@ -1209,7 +1209,7 @@ setOrder(
else {
return GHOST_kFailure;
}
-
+
return GHOST_kSuccess;
}
@@ -1233,8 +1233,8 @@ invalidate()
if (m_invalid_window == false) {
m_system->addDirtyWindow(this);
m_invalid_window = true;
- }
-
+ }
+
return GHOST_kSuccess;
}
@@ -1242,15 +1242,15 @@ invalidate()
* called by the X11 system implementation when expose events
* for the window have been pushed onto the GHOST queue
*/
-
+
void
GHOST_WindowX11::
validate()
{
m_invalid_window = false;
-}
-
-
+}
+
+
/**
* Destructor.
* Closes the window and disposes resources allocated.
@@ -1289,7 +1289,7 @@ GHOST_WindowX11::
XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
}
}
-
+
if (m_visualInfo) {
XFree(m_visualInfo);
}
@@ -1425,13 +1425,13 @@ getStandardCursor(
if (xcursor_id) {
Cursor xcursor = m_standard_cursors[xcursor_id];
-
+
if (!xcursor) {
xcursor = XCreateFontCursor(m_display, xcursor_id);
m_standard_cursors[xcursor_id] = xcursor;
}
-
+
return xcursor;
}
else {
@@ -1447,7 +1447,7 @@ getEmptyCursor(
Pixmap blank;
XColor dummy = {0};
char data[1] = {0};
-
+
/* make a blank cursor */
blank = XCreateBitmapFromData(
m_display,
@@ -1468,7 +1468,7 @@ setWindowCursorVisibility(
bool visible)
{
Cursor xcursor;
-
+
if (visible) {
if (m_visible_cursor)
xcursor = m_visible_cursor;
@@ -1481,7 +1481,7 @@ setWindowCursorVisibility(
XDefineCursor(m_display, m_window, xcursor);
XFlush(m_display);
-
+
return GHOST_kSuccess;
}
@@ -1544,7 +1544,7 @@ setWindowCursorGrab(
}
XFlush(m_display);
-
+
return GHOST_kSuccess;
}
@@ -1556,7 +1556,7 @@ setWindowCursorShape(
Cursor xcursor = getStandardCursor(shape);
m_visible_cursor = xcursor;
-
+
XDefineCursor(m_display, m_window, xcursor);
XFlush(m_display);
@@ -1578,7 +1578,7 @@ setWindowCustomCursorShape(
GHOST_TSuccess
GHOST_WindowX11::
-setWindowCustomCursorShape(
+setWindowCustomCursorShape(
GHOST_TUns8 *bitmap,
GHOST_TUns8 *mask,
int sizex,
@@ -1591,7 +1591,7 @@ setWindowCustomCursorShape(
Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen);
Pixmap bitmap_pix, mask_pix;
XColor fg, bg;
-
+
if (XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) return GHOST_kFailure;
if (XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) return GHOST_kFailure;
@@ -1601,13 +1601,13 @@ setWindowCustomCursorShape(
bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char *) bitmap, sizex, sizey);
mask_pix = XCreateBitmapFromData(m_display, m_window, (char *) mask, sizex, sizey);
-
+
m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
XDefineCursor(m_display, m_window, m_custom_cursor);
XFlush(m_display);
m_visible_cursor = m_custom_cursor;
-
+
XFreePixmap(m_display, bitmap_pix);
XFreePixmap(m_display, mask_pix);
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 236fe0b76b0..bf2497ee6d6 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -54,7 +54,7 @@ class GHOST_DropTargetX11;
/**
* X11 implementation of GHOST_IWindow.
- * Dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
+ * Dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
* \author Laurence Bourn
* \date October 26, 2001
*/
@@ -112,7 +112,7 @@ public:
getWindowBounds(
GHOST_Rect& bounds
) const;
-
+
void
getClientBounds(
GHOST_Rect& bounds
@@ -149,7 +149,7 @@ public:
GHOST_TInt32& outX,
GHOST_TInt32& outY
) const;
-
+
GHOST_TWindowState
getState(
) const;
@@ -158,12 +158,12 @@ public:
setState(
GHOST_TWindowState state
);
-
+
GHOST_TSuccess
setOrder(
GHOST_TWindowOrder order
);
-
+
GHOST_TSuccess
invalidate(
);
@@ -191,7 +191,7 @@ public:
validate(
);
- /**
+ /**
* Return a handle to the x11 window type.
*/
Window
@@ -257,7 +257,7 @@ protected:
setWindowCursorVisibility(
bool visible
);
-
+
/**
* Sets the cursor grab on the window using
* native window system calls.
@@ -290,7 +290,7 @@ protected:
int hotX,
int hotY
);
-
+
/**
* Sets the cursor shape on the window using
* native window system calls (Arbitrary size/color).
@@ -310,7 +310,7 @@ protected:
private:
/// Force use of public constructor.
-
+
GHOST_WindowX11(
);
@@ -322,11 +322,11 @@ private:
getStandardCursor(
GHOST_TStandardCursor g_cursor
);
-
+
Cursor
getEmptyCursor(
);
-
+
Window m_window;
Display *m_display;
XVisualInfo *m_visualInfo;
@@ -342,13 +342,13 @@ private:
/** XCursor structure of an empty (blank) cursor */
Cursor m_empty_cursor;
-
+
/** XCursor structure of the custom cursor */
Cursor m_custom_cursor;
/** XCursor to show when cursor is visible */
Cursor m_visible_cursor;
-
+
/** Cache of XC_* ID's to XCursor structures */
std::map<unsigned int, Cursor> m_standard_cursors;
diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt
index 0cec217630c..9f714ae4fba 100644
--- a/intern/ghost/test/CMakeLists.txt
+++ b/intern/ghost/test/CMakeLists.txt
@@ -103,7 +103,7 @@ suffix_relpaths(SRC_NEW "${SRC}" "../../guardedalloc/")
include_directories(${INC_NEW})
add_library(guardedalloc_lib ${SRC_NEW})
-# blenfont
+# blenfont
include(${CMAKE_SOURCE_DIR}/../../../source/blender/blenfont/CMakeLists.txt)
suffix_relpaths(INC_NEW "${INC}" "../../../source/blender/blenfont/")
suffix_relpaths(SRC_NEW "${SRC}" "../../../source/blender/blenfont/")
@@ -128,7 +128,7 @@ add_library(glewmx_lib ${SRC_NEW})
include_directories(
"../../../source/blender/blenlib"
)
-add_library(bli_lib
+add_library(bli_lib
"../../../source/blender/blenlib/intern/fileops.c"
"../../../source/blender/blenlib/intern/gsqueue.c"
"../../../source/blender/blenlib/intern/rct.c"
diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c
index c635ab9be5b..abaa6258122 100644
--- a/intern/ghost/test/gears/GHOST_C-Test.c
+++ b/intern/ghost/test/gears/GHOST_C-Test.c
@@ -84,16 +84,16 @@ static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GL
GLfloat angle, da;
GLfloat u, v, len;
const double pi = 3.14159264;
-
+
r0 = inner_radius;
r1 = (float)(outer_radius - tooth_depth / 2.0);
r2 = (float)(outer_radius + tooth_depth / 2.0);
-
+
da = (float)(2.0 * pi / teeth / 4.0);
-
+
glShadeModel(GL_FLAT);
glNormal3f(0.0, 0.0, 1.0);
-
+
/* draw front face */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
@@ -104,7 +104,7 @@ static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GL
glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(width * 0.5));
}
glEnd();
-
+
/* draw front sides of teeth */
glBegin(GL_QUADS);
da = (float)(2.0 * pi / teeth / 4.0);
@@ -116,9 +116,9 @@ static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GL
glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(width * 0.5));
}
glEnd();
-
+
glNormal3f(0.0, 0.0, -1.0);
-
+
/* draw back face */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
@@ -129,7 +129,7 @@ static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GL
glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
}
glEnd();
-
+
/* draw back sides of teeth */
glBegin(GL_QUADS);
da = (float)(2.0 * pi / teeth / 4.0);
@@ -141,7 +141,7 @@ static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GL
glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
}
glEnd();
-
+
/* draw outward faces of teeth */
glBegin(GL_QUAD_STRIP);
for (i = 0; i < teeth; i++) {
@@ -169,9 +169,9 @@ static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GL
glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(width * 0.5));
glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(-width * 0.5));
glEnd();
-
+
glShadeModel(GL_SMOOTH);
-
+
/* draw inside radius cylinder */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
@@ -191,13 +191,13 @@ static void drawGearGL(int id)
static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
-
+
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
-
+
switch (id)
{
case 1:
@@ -222,32 +222,32 @@ static void drawGearGL(int id)
static void drawGL(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
+
glPushMatrix();
-
+
glRotatef(view_rotx, 1.0, 0.0, 0.0);
glRotatef(view_roty, 0.0, 1.0, 0.0);
glRotatef(view_rotz, 0.0, 0.0, 1.0);
-
+
glPushMatrix();
glTranslatef(-3.0, -2.0, 0.0);
glRotatef(fAngle, 0.0, 0.0, 1.0);
drawGearGL(1);
glPopMatrix();
-
+
glPushMatrix();
glTranslatef(3.1f, -2.0f, 0.0f);
glRotatef((float)(-2.0 * fAngle - 9.0), 0.0, 0.0, 1.0);
drawGearGL(2);
glPopMatrix();
-
+
glPushMatrix();
glTranslatef(-3.1f, 2.2f, -1.8f);
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
glRotatef((float)(2.0 * fAngle - 2.0), 0.0, 0.0, 1.0);
drawGearGL(3);
glPopMatrix();
-
+
glPopMatrix();
}
@@ -256,13 +256,13 @@ static void setViewPortGL(GHOST_WindowHandle hWindow)
{
GHOST_RectangleHandle hRect = NULL;
GLfloat w, h;
-
+
GHOST_ActivateWindowDrawingContext(hWindow);
hRect = GHOST_GetClientBounds(hWindow);
-
+
w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
h = 1.0;
-
+
glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
glMatrixMode(GL_PROJECTION);
@@ -272,7 +272,7 @@ static void setViewPortGL(GHOST_WindowHandle hWindow)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -40.0);
-
+
glClearColor(.2f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
@@ -290,7 +290,7 @@ int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
GHOST_TEventWheelData *wheelData = NULL;
GHOST_DisplaySetting setting;
GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
-
+
switch (GHOST_GetEventType(hEvent))
{
#if 0
@@ -316,7 +316,7 @@ int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
case GHOST_kEventKeyUp:
break;
-
+
case GHOST_kEventKeyDown:
{
keyData = (GHOST_TEventKeyData *)GHOST_GetEventData(hEvent);
@@ -391,7 +391,7 @@ int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
sprintf(ntitle, "%s-", title);
GHOST_SetTitle(sMainWindow, ntitle);
-
+
free(ntitle);
free(title);
}
@@ -402,7 +402,7 @@ int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
}
}
break;
-
+
case GHOST_kEventWindowClose:
{
GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
@@ -420,7 +420,7 @@ int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
}
}
break;
-
+
case GHOST_kEventWindowActivate:
handled = 0;
break;
@@ -437,7 +437,7 @@ int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
GHOST_SwapWindowBuffers(window2);
}
break;
-
+
default:
handled = 0;
break;
@@ -456,7 +456,7 @@ int main(int argc, char **argv)
/* Create the system */
shSystem = GHOST_CreateSystem();
GHOST_AddEventConsumer(shSystem, consumer);
-
+
if (shSystem)
{
/* Create the main window */
@@ -471,7 +471,7 @@ int main(int argc, char **argv)
printf("could not create main window\n");
exit(-1);
}
-
+
/* Create a secondary window */
sSecondaryWindow = GHOST_CreateWindow(
shSystem,
@@ -485,7 +485,7 @@ int main(int argc, char **argv)
printf("could not create secondary window\n");
exit(-1);
}
-
+
/* Install a timer to have the gears running */
sGearsTimer = GHOST_InstallTimer(shSystem,
0,
@@ -496,7 +496,7 @@ int main(int argc, char **argv)
/* Enter main loop */
while (!sExitRequested)
{
- if (!GHOST_ProcessEvents(shSystem, 0))
+ if (!GHOST_ProcessEvents(shSystem, 0))
{
#ifdef WIN32
/* If there were no events, be nice to other applications */
@@ -519,7 +519,7 @@ int main(int argc, char **argv)
/* Dispose the system */
GHOST_DisposeSystem(shSystem);
-
+
return 0;
}
diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp
index f58a220055f..8c4d93fcbc4 100644
--- a/intern/ghost/test/gears/GHOST_Test.cpp
+++ b/intern/ghost/test/gears/GHOST_Test.cpp
@@ -273,7 +273,7 @@ static void View(GHOST_IWindow *window, bool stereo, int eye = 0)
if (stereo)
{
if (nVidiaWindows)
- {
+ {
// handled by nVidia driver so act as normal (explicitly put here since
// it -is- stereo)
glViewport(0, 0, bnds.getWidth(), bnds.getHeight());
@@ -666,7 +666,7 @@ bool Application::processEvent(GHOST_IEvent *event)
window2->swapBuffers();
}
break;
-
+
default:
handled = false;
break;
diff --git a/intern/ghost/test/multitest/Basic.h b/intern/ghost/test/multitest/Basic.h
index c8f61d40c57..86d68ef06cb 100644
--- a/intern/ghost/test/multitest/Basic.h
+++ b/intern/ghost/test/multitest/Basic.h
@@ -28,11 +28,11 @@
int min_i (int a, int b);
int max_i (int a, int b);
-int clamp_i (int val, int min, int max);
+int clamp_i (int val, int min, int max);
-float min_f (float a, float b);
-float max_f (float a, float b);
-float clamp_f (float val, float min, float max);
+float min_f (float a, float b);
+float max_f (float a, float b);
+float clamp_f (float val, float min, float max);
void rect_copy (int dst[2][2], int src[2][2]);
int rect_contains_pt (int rect[2][2], int pt[2]);
diff --git a/intern/ghost/test/multitest/EventToBuf.c b/intern/ghost/test/multitest/EventToBuf.c
index 49255de5e64..7401ab83dbf 100644
--- a/intern/ghost/test/multitest/EventToBuf.c
+++ b/intern/ghost/test/multitest/EventToBuf.c
@@ -47,7 +47,7 @@ char *eventtype_to_string(GHOST_TEventType type)
case GHOST_kEventQuit: return "Quit";
case GHOST_kEventWindowClose: return "WindowClose";
- case GHOST_kEventWindowActivate: return "WindowActivate";
+ case GHOST_kEventWindowActivate: return "WindowActivate";
case GHOST_kEventWindowDeactivate: return "WindowDeactivate";
case GHOST_kEventWindowUpdate: return "WindowUpdate";
case GHOST_kEventWindowSize: return "WindowSize";
@@ -188,7 +188,7 @@ static char *keytype_to_string(GHOST_TKey key)
K(KeyF22);
K(KeyF23);
K(KeyF24);
-
+
default:
return "KeyUnknown";
}
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
index 833b5c720a1..8cd31c3137e 100644
--- a/intern/ghost/test/multitest/MultiTest.c
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -79,7 +79,7 @@ void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, const float
int ltidx = (side / 2) % 4;
int dkidx = (ltidx + 1 + (side & 1)) % 4;
int i, corner;
-
+
glBegin(GL_LINES);
for (i = 0; i < width; i++) {
float ltf = pow(lt[i], 1.0 / 2.2), dkf = pow(dk[i], 1.0 / 2.2);
@@ -102,7 +102,7 @@ void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, const float
}
}
glEnd();
-
+
glColor3fv(col);
glRecti(rect[0][0] + width, rect[0][1] + width, rect[1][0] - width, rect[1][1] - width);
}
@@ -113,17 +113,17 @@ void rect_bevel_smooth(int rect[2][2], int width)
float *dk = malloc(sizeof(*dk) * width);
float col[4];
int i;
-
+
for (i = 0; i < width; i++) {
float v = width - 1 ? ((float) i / (width - 1)) : 0;
lt[i] = 1.2 + (1.0 - 1.2) * v;
dk[i] = 0.2 + (1.0 - 0.2) * v;
}
-
+
glGetFloatv(GL_CURRENT_COLOR, col);
-
+
rect_bevel_side(rect, 3, lt, dk, col, width);
-
+
free(lt);
free(dk);
}
@@ -136,11 +136,11 @@ typedef struct {
MultiTestApp *app;
GHOST_WindowHandle win;
-
+
int size[2];
-
+
int lmouse[2], lmbut[3];
-
+
int tmouse[2];
} MainWindow;
@@ -152,18 +152,18 @@ static void mainwindow_log(MainWindow *mw, char *str)
static void mainwindow_do_draw(MainWindow *mw)
{
GHOST_ActivateWindowDrawingContext(mw->win);
-
+
if (mw->lmbut[0]) {
glClearColor(0.5, 0.5, 0.5, 1);
}
else {
glClearColor(1, 1, 1, 1);
- }
+ }
glClear(GL_COLOR_BUFFER_BIT);
-
+
glColor3f(0.5, 0.6, 0.8);
glRecti(mw->tmouse[0] - 5, mw->tmouse[1] - 5, mw->tmouse[0] + 5, mw->tmouse[1] + 5);
-
+
GHOST_SwapWindowBuffers(mw->win);
}
@@ -175,7 +175,7 @@ static void mainwindow_do_reshape(MainWindow *mw)
mw->size[0] = GHOST_GetWidthRectangle(bounds);
mw->size[1] = GHOST_GetHeightRectangle(bounds);
-
+
glViewport(0, 0, mw->size[0], mw->size[1]);
glMatrixMode(GL_PROJECTION);
@@ -234,7 +234,7 @@ static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press)
static void mainwindow_do_move(MainWindow *mw, int x, int y)
{
mw->lmouse[0] = x, mw->lmouse[1] = y;
-
+
if (mw->lmbut[0]) {
mw->tmouse[0] = x, mw->tmouse[1] = y;
GHOST_InvalidateWindow(mw->win);
@@ -261,10 +261,10 @@ static void mainwindow_handle(void *priv, GHOST_EventHandle evt)
MainWindow *mw = priv;
GHOST_TEventType type = GHOST_GetEventType(evt);
char buf[256];
-
+
event_to_buf(evt, buf);
mainwindow_log(mw, buf);
-
+
switch (type) {
case GHOST_kEventCursorMove:
{
@@ -304,7 +304,7 @@ static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, GHOST_TUns64 time)
{
MainWindow *mw = GHOST_GetTimerTaskUserData(task);
char buf[64];
-
+
sprintf(buf, "timer: %6.2f", (double) ((GHOST_TInt64) time) / 1000);
mainwindow_log(mw, buf);
}
@@ -314,23 +314,23 @@ MainWindow *mainwindow_new(MultiTestApp *app)
GHOST_SystemHandle sys = multitestapp_get_system(app);
GHOST_WindowHandle win;
GHOST_GLSettings glSettings = {0};
-
+
win = GHOST_CreateWindow(
sys, "MultiTest:Main",
40, 40, 400, 400,
GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
-
+
if (win) {
MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new");
mw->app = app;
mw->win = win;
-
+
GHOST_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle));
-
+
GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw);
-
+
return mw;
}
else {
@@ -356,23 +356,23 @@ struct _LoggerWindow {
GHOST_WindowHandle win;
-#ifdef USE_BMF
+#ifdef USE_BMF
BMF_Font *font;
#else
int font;
#endif
int fonttexid;
int fontheight;
-
+
int size[2];
-
+
int ndisplines;
int textarea[2][2];
ScrollBar *scroll;
-
+
char **loglines;
int nloglines, logsize;
-
+
int lmbut[3];
int lmouse[2];
};
@@ -383,7 +383,7 @@ struct _LoggerWindow {
static void loggerwindow_recalc_regions(LoggerWindow *lw)
{
int nscroll[2][2];
-
+
nscroll[0][0] = SCROLLBAR_PAD;
nscroll[0][1] = SCROLLBAR_PAD;
nscroll[1][0] = nscroll[0][0] + SCROLLBAR_WIDTH;
@@ -418,10 +418,10 @@ static void loggerwindow_do_reshape(LoggerWindow *lw)
GHOST_RectangleHandle bounds = GHOST_GetClientBounds(lw->win);
GHOST_ActivateWindowDrawingContext(lw->win);
-
+
lw->size[0] = GHOST_GetWidthRectangle(bounds);
lw->size[1] = GHOST_GetHeightRectangle(bounds);
-
+
loggerwindow_recalc_regions(lw);
loggerwindow_setup_window_gl(lw);
}
@@ -430,21 +430,21 @@ static void loggerwindow_do_draw(LoggerWindow *lw)
{
int i, ndisplines, startline;
int sb_rect[2][2], sb_thumb[2][2];
-
+
GHOST_ActivateWindowDrawingContext(lw->win);
-
+
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.8, 0.8, 0.8);
rect_bevel_smooth(lw->textarea, 4);
-
+
scrollbar_get_rect(lw->scroll, sb_rect);
scrollbar_get_thumb(lw->scroll, sb_thumb);
-
+
glColor3f(0.6, 0.6, 0.6);
rect_bevel_smooth(sb_rect, 1);
-
+
if (scrollbar_is_scrolling(lw->scroll)) {
glColor3f(0.6, 0.7, 0.5);
}
@@ -452,16 +452,16 @@ static void loggerwindow_do_draw(LoggerWindow *lw)
glColor3f(0.9, 0.9, 0.92);
}
rect_bevel_smooth(sb_thumb, 1);
-
+
startline = scrollbar_get_thumbpos(lw->scroll) * (lw->nloglines - 1);
ndisplines = min_i(lw->ndisplines, lw->nloglines - startline);
if (lw->fonttexid != -1) {
glBindTexture(GL_TEXTURE_2D, lw->fonttexid);
-
+
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
+ glEnable(GL_TEXTURE_2D);
}
glColor3f(0, 0, 0);
for (i = 0; i < ndisplines; i++) {
@@ -470,7 +470,7 @@ static void loggerwindow_do_draw(LoggerWindow *lw)
int x_pos = lw->textarea[0][0] + 4;
int y_pos = lw->textarea[0][1] + 4 + i * lw->fontheight;
-#ifdef USE_BMF
+#ifdef USE_BMF
if (lw->fonttexid == -1) {
glRasterPos2i(x_pos, y_pos);
BMF_DrawString(lw->font, line);
@@ -486,7 +486,7 @@ static void loggerwindow_do_draw(LoggerWindow *lw)
#ifdef USE_BMF
if (lw->fonttexid != -1) {
- glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}
#endif
@@ -497,7 +497,7 @@ static void loggerwindow_do_draw(LoggerWindow *lw)
static void loggerwindow_do_move(LoggerWindow *lw, int x, int y)
{
lw->lmouse[0] = x, lw->lmouse[1] = y;
-
+
if (scrollbar_is_scrolling(lw->scroll)) {
scrollbar_keep_scrolling(lw->scroll, y);
GHOST_InvalidateWindow(lw->win);
@@ -508,10 +508,10 @@ static void loggerwindow_do_button(LoggerWindow *lw, int which, int press)
{
if (which == GHOST_kButtonMaskLeft) {
lw->lmbut[0] = press;
-
+
if (press) {
if (scrollbar_contains_pt(lw->scroll, lw->lmouse)) {
- scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]);
+ scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]);
GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorUpDown);
GHOST_InvalidateWindow(lw->win);
}
@@ -546,7 +546,7 @@ static void loggerwindow_handle(void *priv, GHOST_EventHandle evt)
{
LoggerWindow *lw = priv;
GHOST_TEventType type = GHOST_GetEventType(evt);
-
+
switch (type) {
case GHOST_kEventCursorMove:
{
@@ -588,7 +588,7 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
GHOST_SystemHandle sys = multitestapp_get_system(app);
GHOST_TUns32 screensize[2];
GHOST_WindowHandle win;
-
+
GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]);
win = GHOST_CreateWindow(
sys, "MultiTest:Logger",
@@ -596,7 +596,7 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
-
+
if (win) {
LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new");
int bbox[2][2];
@@ -614,12 +614,12 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
BLF_size(lw->font, 11, 72);
lw->fontheight = BLF_height(lw->font, "A_", 2);
#endif
-
+
lw->nloglines = lw->logsize = 0;
lw->loglines = MEM_mallocN(sizeof(*lw->loglines) * lw->nloglines, "loglines");
-
+
lw->scroll = scrollbar_new(2, 40);
-
+
GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle));
loggerwindow_do_reshape(lw);
@@ -636,10 +636,10 @@ void loggerwindow_log(LoggerWindow *lw, char *line)
if (lw->nloglines == lw->logsize) {
lw->loglines = memdbl(lw->loglines, &lw->logsize, sizeof(*lw->loglines));
}
-
+
lw->loglines[lw->nloglines++] = string_dup(line);
scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines / lw->nloglines);
-
+
GHOST_InvalidateWindow(lw->win);
}
@@ -652,7 +652,7 @@ void loggerwindow_free(LoggerWindow *lw)
MEM_freeN(lw->loglines[i]);
}
MEM_freeN(lw->loglines);
-
+
windowdata_free(GHOST_GetWindowUserData(lw->win));
GHOST_DisposeWindow(sys, lw->win);
MEM_freeN(lw);
@@ -667,7 +667,7 @@ typedef struct {
MultiTestApp *app;
GHOST_WindowHandle win;
-
+
int size[2];
} ExtraWindow;
@@ -677,10 +677,10 @@ static void extrawindow_do_draw(ExtraWindow *ew)
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
-
+
glColor3f(0.8, 0.8, 0.8);
glRecti(10, 10, ew->size[0] - 10, ew->size[1] - 10);
-
+
GHOST_SwapWindowBuffers(ew->win);
}
@@ -692,7 +692,7 @@ static void extrawindow_do_reshape(ExtraWindow *ew)
ew->size[0] = GHOST_GetWidthRectangle(bounds);
ew->size[1] = GHOST_GetHeightRectangle(bounds);
-
+
glViewport(0, 0, ew->size[0], ew->size[1]);
glMatrixMode(GL_PROJECTION);
@@ -721,15 +721,15 @@ static void extrawindow_spin_cursor(ExtraWindow *ew, GHOST_TUns64 time)
double ftime = (double) ((GHOST_TInt64) time) / 1000;
float angle = fmod(ftime, 1.0) * 3.1415 * 2;
int i;
-
+
memset(&bitmap, 0, sizeof(bitmap));
memset(&mask, 0, sizeof(mask));
-
+
bitmap[0][0] |= mask[0][0] |= 0xF;
bitmap[1][0] |= mask[1][0] |= 0xF;
bitmap[2][0] |= mask[2][0] |= 0xF;
bitmap[3][0] |= mask[3][0] |= 0xF;
-
+
for (i = 0; i < 7; i++) {
int x = 7 + cos(angle) * i;
int y = 7 + sin(angle) * i;
@@ -740,10 +740,10 @@ static void extrawindow_spin_cursor(ExtraWindow *ew, GHOST_TUns64 time)
float v = (i / 63.0) * 3.1415 * 2;
int x = 7 + cos(v) * 7;
int y = 7 + sin(v) * 7;
-
+
mask[y][x / 8] |= (1 << (x % 8));
}
-
+
GHOST_SetCustomCursorShape(ew->win, bitmap, mask, 0, 0);
}
@@ -752,10 +752,10 @@ static void extrawindow_handle(void *priv, GHOST_EventHandle evt)
ExtraWindow *ew = priv;
GHOST_TEventType type = GHOST_GetEventType(evt);
char buf[256];
-
+
event_to_buf(evt, buf);
loggerwindow_log(multitestapp_get_logger(ew->app), buf);
-
+
switch (type) {
case GHOST_kEventKeyDown:
case GHOST_kEventKeyUp:
@@ -790,21 +790,21 @@ ExtraWindow *extrawindow_new(MultiTestApp *app)
GHOST_GLSettings glSettings = {0};
GHOST_SystemHandle sys = multitestapp_get_system(app);
GHOST_WindowHandle win;
-
+
win = GHOST_CreateWindow(
sys, "MultiTest:Extra",
500, 40, 400, 400,
GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
-
+
if (win) {
ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new");
ew->app = app;
ew->win = win;
-
+
GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle));
-
+
return ew;
}
else {
@@ -824,13 +824,13 @@ void extrawindow_free(ExtraWindow *ew)
/*
* MultiTestApp
*/
-
+
struct _MultiTestApp {
GHOST_SystemHandle sys;
MainWindow *main;
LoggerWindow *logger;
ExtraWindow *extra;
-
+
int exit;
};
@@ -838,21 +838,21 @@ static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr dat
{
MultiTestApp *app = data;
GHOST_WindowHandle win;
-
+
win = GHOST_GetEventWindow(evt);
if (win && !GHOST_ValidWindow(app->sys, win)) {
loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n");
return 1;
}
-
+
if (win) {
WindowData *wb = GHOST_GetWindowUserData(win);
-
+
windowdata_handle(wb, evt);
}
else {
GHOST_TEventType type = GHOST_GetEventType(evt);
-
+
/* GHOST_kEventQuit are the only 'system' events,
* that is, events without a window.
*/
@@ -866,7 +866,7 @@ static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr dat
break;
}
}
-
+
return 1;
}
@@ -880,25 +880,25 @@ MultiTestApp *multitestapp_new(void) {
if (!app->sys)
fatal("Unable to create ghost system");
- if (!GHOST_AddEventConsumer(app->sys, consumer))
+ if (!GHOST_AddEventConsumer(app->sys, consumer))
fatal("Unable to add multitest event consumer ");
-
+
app->main = mainwindow_new(app);
- if (!app->main)
+ if (!app->main)
fatal("Unable to create main window");
-
+
app->logger = loggerwindow_new(app);
if (!app->logger)
fatal("Unable to create logger window");
app->extra = NULL;
app->exit = 0;
-
+
return app;
}
LoggerWindow *multitestapp_get_logger(MultiTestApp *app) {
- return app->logger;
+ return app->logger;
}
GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app) {
@@ -943,7 +943,7 @@ void multitestapp_free(MultiTestApp *app)
}
/***/
-
+
int main(int argc, char **argv)
{
MultiTestApp *app;
@@ -953,9 +953,9 @@ int main(int argc, char **argv)
#endif
app = multitestapp_new();
-
+
multitestapp_run(app);
multitestapp_free(app);
-
+
return 0;
}
diff --git a/intern/ghost/test/multitest/ScrollBar.c b/intern/ghost/test/multitest/ScrollBar.c
index 8964d304920..2a363f3ce5d 100644
--- a/intern/ghost/test/multitest/ScrollBar.c
+++ b/intern/ghost/test/multitest/ScrollBar.c
@@ -37,7 +37,7 @@
struct _ScrollBar {
int rect[2][2];
float thumbpos, thumbpct;
-
+
int inset;
int minthumb;
@@ -48,7 +48,7 @@ struct _ScrollBar {
static int scrollbar_get_thumbH(ScrollBar *sb)
{
int scrollable_h = rect_height(sb->rect) - 2 * sb->inset;
-
+
return clamp_i(sb->thumbpct * scrollable_h, sb->minthumb, scrollable_h);
}
@@ -56,7 +56,7 @@ static int scrollbar_get_thumbableH(ScrollBar *sb)
{
int scrollable_h = rect_height(sb->rect) - 2 * sb->inset;
int thumb_h = scrollbar_get_thumbH(sb);
-
+
return scrollable_h - thumb_h;
}
@@ -76,7 +76,7 @@ ScrollBar *scrollbar_new(int inset, int minthumb)
ScrollBar *sb = MEM_callocN(sizeof(*sb), "scrollbar_new");
sb->inset = inset;
sb->minthumb = minthumb;
-
+
return sb;
}
diff --git a/intern/ghost/test/multitest/ScrollBar.h b/intern/ghost/test/multitest/ScrollBar.h
index 8c8d02d197e..dd737539bf2 100644
--- a/intern/ghost/test/multitest/ScrollBar.h
+++ b/intern/ghost/test/multitest/ScrollBar.h
@@ -29,7 +29,7 @@ typedef struct _ScrollBar ScrollBar;
/***/
-
+
ScrollBar* scrollbar_new (int inset, int minthumb);
int scrollbar_is_scrolling (ScrollBar *sb);
diff --git a/intern/ghost/test/multitest/Util.c b/intern/ghost/test/multitest/Util.c
index bacd0a313d4..9ac7ae0263d 100644
--- a/intern/ghost/test/multitest/Util.c
+++ b/intern/ghost/test/multitest/Util.c
@@ -40,10 +40,10 @@ void *memdbl(void *mem, int *size_pr, int item_size)
int cur_size = *size_pr;
int new_size = cur_size ? (cur_size * 2) : 1;
void *nmem = MEM_mallocN(new_size * item_size, "memdbl");
-
+
memcpy(nmem, mem, cur_size * item_size);
MEM_freeN(mem);
-
+
*size_pr = new_size;
return nmem;
}
@@ -54,19 +54,19 @@ char *string_dup(char *str)
char *nstr = MEM_mallocN(len + 1, "string_dup");
memcpy(nstr, str, len + 1);
-
+
return nstr;
}
void fatal(char *fmt, ...)
{
va_list ap;
-
+
fprintf(stderr, "FATAL: ");
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
-
+
exit(1);
}
diff --git a/intern/ghost/test/multitest/WindowData.c b/intern/ghost/test/multitest/WindowData.c
index de4992ab2a0..07078cd9238 100644
--- a/intern/ghost/test/multitest/WindowData.c
+++ b/intern/ghost/test/multitest/WindowData.c
@@ -43,7 +43,7 @@ WindowData *windowdata_new(void *data, WindowDataHandler handler)
WindowData *wb = MEM_mallocN(sizeof(*wb), "windowdata_new");
wb->data = data;
wb->handler = handler;
-
+
return wb;
}
diff --git a/intern/ghost/test/multitest/WindowData.h b/intern/ghost/test/multitest/WindowData.h
index f8198101b8d..0e6c7518843 100644
--- a/intern/ghost/test/multitest/WindowData.h
+++ b/intern/ghost/test/multitest/WindowData.h
@@ -27,9 +27,9 @@
typedef void (*WindowDataHandler)(void *priv, GHOST_EventHandle evt);
typedef struct _WindowData WindowData;
-
+
/***/
-
+
WindowData* windowdata_new (void *data, WindowDataHandler handler);
void windowdata_handle (WindowData *wb, GHOST_EventHandle evt);
void windowdata_free (WindowData *wb);
diff --git a/release/datafiles/studiolights/matcap/license.txt b/release/datafiles/studiolights/matcap/license.txt
new file mode 100644
index 00000000000..358c8dcd832
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/license.txt
@@ -0,0 +1,3 @@
+These matcap images are licensed as GNU GPL 2 or later, like the rest of Blender's code.
+
+Thanks to Kent Trammell, Aidy Burrows, John Herreno , Terry Wallwork and David Silverman for making the pictures.
diff --git a/release/datafiles/studiolights/matcap/mc01.jpg b/release/datafiles/studiolights/matcap/mc01.jpg
new file mode 100644
index 00000000000..8c7aef287ee
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc01.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc02.jpg b/release/datafiles/studiolights/matcap/mc02.jpg
new file mode 100644
index 00000000000..11deddfeaed
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc02.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc03.jpg b/release/datafiles/studiolights/matcap/mc03.jpg
new file mode 100644
index 00000000000..64d992fb61a
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc03.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc04.jpg b/release/datafiles/studiolights/matcap/mc04.jpg
new file mode 100644
index 00000000000..42be580ee93
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc04.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc05.jpg b/release/datafiles/studiolights/matcap/mc05.jpg
new file mode 100644
index 00000000000..586d233ef31
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc05.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc06.jpg b/release/datafiles/studiolights/matcap/mc06.jpg
new file mode 100644
index 00000000000..657883d0866
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc06.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc07.jpg b/release/datafiles/studiolights/matcap/mc07.jpg
new file mode 100644
index 00000000000..372caf7e87c
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc07.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc08.jpg b/release/datafiles/studiolights/matcap/mc08.jpg
new file mode 100644
index 00000000000..50eec402812
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc08.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc09.jpg b/release/datafiles/studiolights/matcap/mc09.jpg
new file mode 100644
index 00000000000..e05d441aaf9
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc09.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc10.jpg b/release/datafiles/studiolights/matcap/mc10.jpg
new file mode 100644
index 00000000000..ab82f17bb93
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc10.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc11.jpg b/release/datafiles/studiolights/matcap/mc11.jpg
new file mode 100644
index 00000000000..053550f082c
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc11.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc12.jpg b/release/datafiles/studiolights/matcap/mc12.jpg
new file mode 100644
index 00000000000..beb16f3742e
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc12.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc13.jpg b/release/datafiles/studiolights/matcap/mc13.jpg
new file mode 100644
index 00000000000..7fb8fa58e8f
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc13.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc14.jpg b/release/datafiles/studiolights/matcap/mc14.jpg
new file mode 100644
index 00000000000..ba868d2f95a
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc14.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc15.jpg b/release/datafiles/studiolights/matcap/mc15.jpg
new file mode 100644
index 00000000000..b10ea326a42
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc15.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc16.jpg b/release/datafiles/studiolights/matcap/mc16.jpg
new file mode 100644
index 00000000000..c6ce02d59df
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc16.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc17.jpg b/release/datafiles/studiolights/matcap/mc17.jpg
new file mode 100644
index 00000000000..14f15f70460
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc17.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc18.jpg b/release/datafiles/studiolights/matcap/mc18.jpg
new file mode 100644
index 00000000000..db572856b07
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc18.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc19.jpg b/release/datafiles/studiolights/matcap/mc19.jpg
new file mode 100644
index 00000000000..56d2efb1734
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc19.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc20.jpg b/release/datafiles/studiolights/matcap/mc20.jpg
new file mode 100644
index 00000000000..002a0910dd9
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc20.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc21.jpg b/release/datafiles/studiolights/matcap/mc21.jpg
new file mode 100644
index 00000000000..cb2fea573b8
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc21.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc22.jpg b/release/datafiles/studiolights/matcap/mc22.jpg
new file mode 100644
index 00000000000..2fc71b98c5a
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc22.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc23.jpg b/release/datafiles/studiolights/matcap/mc23.jpg
new file mode 100644
index 00000000000..3793c0fcaa5
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc23.jpg
Binary files differ
diff --git a/release/datafiles/studiolights/matcap/mc24.jpg b/release/datafiles/studiolights/matcap/mc24.jpg
new file mode 100644
index 00000000000..2a9618d8fe1
--- /dev/null
+++ b/release/datafiles/studiolights/matcap/mc24.jpg
Binary files differ
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 4b91309b122bcdcddd1854b1137407b2c4f55c7
+Subproject ebd058d7a6438d137522063bb3286c8acc325ca
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
-Subproject cd57934bd04c174fc3402888d01a74e6e6653b2
+Subproject 474702157831f1a58bb50f5240ab8b1b02b6ba3
diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py
index 6a538f0ae33..c2ca271de66 100644
--- a/release/scripts/startup/bl_operators/image.py
+++ b/release/scripts/startup/bl_operators/image.py
@@ -249,4 +249,4 @@ classes = (
ProjectApply,
ProjectEdit,
SaveDirty,
-) \ No newline at end of file
+)
diff --git a/release/scripts/startup/bl_operators/mask.py b/release/scripts/startup/bl_operators/mask.py
index 78a4bd9af27..3ce1abad9b8 100644
--- a/release/scripts/startup/bl_operators/mask.py
+++ b/release/scripts/startup/bl_operators/mask.py
@@ -35,4 +35,4 @@ class MASK_MT_add(Menu):
classes = (
MASK_MT_add,
-) \ No newline at end of file
+)
diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
index f4d6c7065a9..e32c1ac0f81 100644
--- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
+++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
@@ -184,4 +184,4 @@ class PlayRenderedAnim(Operator):
classes = (
PlayRenderedAnim,
-) \ No newline at end of file
+)
diff --git a/release/scripts/startup/bl_operators/sequencer.py b/release/scripts/startup/bl_operators/sequencer.py
index 7209b6b478f..337492bc8a7 100644
--- a/release/scripts/startup/bl_operators/sequencer.py
+++ b/release/scripts/startup/bl_operators/sequencer.py
@@ -140,4 +140,4 @@ classes = (
SequencerCrossfadeSounds,
SequencerCutMulticam,
SequencerDeinterlaceSelectedMovies,
-) \ No newline at end of file
+)
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index ee101bb3cc6..b0a5e19d269 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -19,13 +19,17 @@
# <pep8 compliant>
import bpy
-from bpy.types import Operator
+from bpy.types import (
+ Operator,
+ OperatorFileListElement
+)
from bpy.props import (
BoolProperty,
EnumProperty,
FloatProperty,
IntProperty,
StringProperty,
+ CollectionProperty,
)
from bpy.app.translations import pgettext_tip as tip_
@@ -2394,12 +2398,126 @@ class WM_OT_toolbar(Operator):
def draw_menu(popover, context):
layout = popover.layout
- cls.draw_cls(layout, context, detect_layout=False)
+ cls.draw_cls(layout, context, detect_layout=False, scale_y=1.0)
wm.popover(draw_menu, keymap=keymap)
return {'FINISHED'}
+# Studio Light operations
+class WM_OT_studiolight_install(Operator):
+ """Install a user defined studio light"""
+ bl_idname = "wm.studiolight_install"
+ bl_label = "Install Custom Studio Light"
+
+ files = CollectionProperty(
+ name="File Path",
+ type=OperatorFileListElement,
+ )
+ directory = StringProperty(
+ subtype='DIR_PATH',
+ )
+ filter_folder = BoolProperty(
+ name="Filter folders",
+ default=True,
+ options={'HIDDEN'},
+ )
+ filter_glob = StringProperty(
+ default="*.png;*.jpg;*.hdr;*.exr",
+ options={'HIDDEN'},
+ )
+ orientation = EnumProperty(
+ items=(
+ ("MATCAP", "MatCap", ""),
+ ("WORLD", "World", ""),
+ ("CAMERA", "Camera", ""),
+ )
+ )
+
+ def execute(self, context):
+ import traceback
+ import shutil
+ import pathlib
+ userpref = context.user_preferences
+
+ filepaths = [pathlib.Path(self.directory, e.name) for e in self.files]
+ path_studiolights = bpy.utils.user_resource('DATAFILES')
+
+ if not path_studiolights:
+ self.report({'ERROR'}, "Failed to get Studio Light path")
+ return {'CANCELLED'}
+
+ path_studiolights = pathlib.Path(path_studiolights, "studiolights", self.orientation.lower())
+ if not path_studiolights.exists():
+ try:
+ path_studiolights.mkdir(parents=True, exist_ok=True)
+ except:
+ traceback.print_exc()
+
+ for filepath in filepaths:
+ shutil.copy(str(filepath), str(path_studiolights))
+ userpref.studio_lights_refresh()
+
+ # print message
+ msg = (
+ tip_("StudioLight Installed %r into %r") %
+ (", ".join(str(x.name) for x in self.files), str(path_studiolights))
+ )
+ print(msg)
+ self.report({'INFO'}, msg)
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ wm.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
+
+class WM_OT_studiolight_uninstall(Operator):
+ bl_idname = 'wm.studiolight_uninstall'
+ bl_label = "Uninstall Studio Light"
+ index = bpy.props.IntProperty()
+
+ def execute(self, context):
+ import pathlib
+ userpref = context.user_preferences
+ for studio_light in userpref.studio_lights:
+ if studio_light.index == self.index:
+ path = pathlib.Path(studio_light.path)
+ if path.exists():
+ path.unlink()
+ userpref.studio_lights_refresh()
+ return {'FINISHED'}
+ return {'CANCELLED'}
+
+
+class WM_OT_studiolight_expand(Operator):
+ bl_idname = "wm.studiolight_expand"
+ bl_label = "Expand Studio Light"
+ index = bpy.props.IntProperty()
+
+ def execute(self, context):
+ userpref = context.user_preferences
+ for studio_light in userpref.studio_lights:
+ if studio_light.index == self.index:
+ studio_light.show_expanded = not studio_light.show_expanded
+ break
+
+ return {'FINISHED'}
+
+
+class WM_OT_studiolight_userpref_show(Operator):
+ """Show light user preferences"""
+ bl_idname = "wm.studiolight_userpref_show"
+ bl_label = ""
+ bl_options = {'INTERNAL'}
+
+ def execute(self, context):
+ context.user_preferences.active_section = 'LIGHTS'
+ bpy.ops.screen.userpref_show('INVOKE_DEFAULT')
+ return {'FINISHED'}
+
+
classes = (
BRUSH_OT_active_index_set,
WM_OT_addon_disable,
@@ -2454,6 +2572,10 @@ classes = (
WM_OT_owner_disable,
WM_OT_owner_enable,
WM_OT_url_open,
+ WM_OT_studiolight_expand,
+ WM_OT_studiolight_install,
+ WM_OT_studiolight_uninstall,
+ WM_OT_studiolight_userpref_show,
WM_OT_tool_set_by_name,
WM_OT_toolbar,
)
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index dd99195f12a..da9054fb681 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -88,7 +88,7 @@ _modules = [
"space_userpref",
"space_view3d",
"space_view3d_toolbar",
- ]
+]
import bpy
@@ -167,6 +167,8 @@ def unregister():
# Define a default UIList, when a list does not need any custom drawing...
# Keep in sync with its #defined name in UI_interface.h
+
+
class UI_UL_list(bpy.types.UIList):
# These are common filtering or ordering operations (same as the default C ones!).
@staticmethod
diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py
index 9782d5a072c..901e15c181a 100644
--- a/release/scripts/startup/bl_ui/properties_animviz.py
+++ b/release/scripts/startup/bl_ui/properties_animviz.py
@@ -37,27 +37,26 @@ class MotionPathButtonsPanel:
mps = avs.motion_path
# Display Range
- layout.row().prop(mps, "type", expand=True)
+ layout.use_property_split = True
+ layout.row().prop(mps, "type")
- split = layout.split()
+ col = layout.column()
- col = split.column()
- col.label(text="Display Range:")
sub = col.column(align=True)
if mps.type == 'CURRENT_FRAME':
- sub.prop(mps, "frame_before", text="Before")
+ sub.prop(mps, "frame_before", text="Frame Range Before")
sub.prop(mps, "frame_after", text="After")
elif mps.type == 'RANGE':
- sub.prop(mps, "frame_start", text="Start")
+ sub.prop(mps, "frame_start", text="Frame Range Start")
sub.prop(mps, "frame_end", text="End")
sub.prop(mps, "frame_step", text="Step")
- col = split.column()
+ col = layout.column(align=True)
if bones:
col.label(text="Cache for Bone:")
else:
- col.label(text="Cache:")
+ col.label(text="Cache")
if mpath:
sub = col.column(align=True)
@@ -81,17 +80,15 @@ class MotionPathButtonsPanel:
sub.operator("object.paths_calculate", text="Calculate...", icon='OBJECT_DATA')
# Display Settings
- split = layout.split()
- col = split.column()
- col.label(text="Show:")
+ layout.label(text="Display")
+
+ col = layout.column()
col.prop(mps, "show_frame_numbers", text="Frame Numbers")
if mpath is not None:
col.prop(mpath, "lines", text="Lines")
col.prop(mpath, "line_thickness", text="Thickness")
- col = split.column()
- col.label("")
col.prop(mps, "show_keyframe_highlight", text="Keyframes")
sub = col.column()
sub.enabled = mps.show_keyframe_highlight
@@ -101,11 +98,11 @@ class MotionPathButtonsPanel:
# Customize path
if mpath is not None:
- row = layout.row(align=True)
- row.prop(mpath, "use_custom_color", text="", toggle=True, icon='COLOR')
- sub = row.row(align=True)
+
+ col.prop(mpath, "use_custom_color", text="Custom Color")
+ sub = col.column()
sub.enabled = mpath.use_custom_color
- sub.prop(mpath, "color", text="")
+ sub.prop(mpath, "color")
# FIXME: this panel still needs to be ported so that it will work correctly with animviz
diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index 9b61101778f..b7880e605b3 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -941,6 +941,7 @@ class BONE_PT_constraints(ConstraintButtonsPanel, Panel):
for con in context.pose_bone.constraints:
self.draw_constraint(context, con)
+
classes = (
OBJECT_PT_constraints,
BONE_PT_constraints,
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 79a18d743a1..47c53d6ffb5 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -180,9 +180,20 @@ class DATA_PT_geometry_curve(CurveButtonsPanelCurve, Panel):
sub.active = curve.taper_object is not None
sub.prop(curve, "use_map_taper")
- col.separator()
- layout.label(text="Bevel")
+class DATA_PT_geometry_curve_bevel(CurveButtonsPanelCurve, Panel):
+ bl_label = "Bevel"
+ bl_parent_id = "DATA_PT_geometry_curve"
+
+ @classmethod
+ def poll(cls, context):
+ return (type(context.curve) in {Curve, TextCurve})
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ curve = context.curve
col = layout.column()
sub = col.column()
@@ -338,8 +349,18 @@ class DATA_PT_font(CurveButtonsPanelText, Panel):
row.prop(char, "use_underline", toggle=True)
row.prop(char, "use_small_caps", toggle=True)
+
+class DATA_PT_font_transform(CurveButtonsPanelText, Panel):
+ bl_label = "Transform"
+ bl_parent_id = "DATA_PT_font"
+
+ def draw(self, context):
+ layout = self.layout
+
+ text = context.curve
+ char = context.curve.edit_format
+
layout.use_property_split = True
- # layout.prop(text, "font")
col = layout.column()
@@ -370,12 +391,31 @@ class DATA_PT_paragraph(CurveButtonsPanelText, Panel):
text = context.curve
- layout.label(text="Alignment")
+
+class DATA_PT_paragraph_alignment(CurveButtonsPanelText, Panel):
+ bl_parent_id = "DATA_PT_paragraph"
+ bl_label = "Alignment"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = False
+
+ text = context.curve
+
layout.row().prop(text, "align_x", expand=True)
layout.row().prop(text, "align_y", expand=True)
+
+class DATA_PT_paragraph_spacing(CurveButtonsPanelText, Panel):
+ bl_parent_id = "DATA_PT_paragraph"
+ bl_label = "Spacing"
+
+ def draw(self, context):
+ layout = self.layout
layout.use_property_split = True
+ text = context.curve
+
col = layout.column(align=True)
col.prop(text, "space_character", text="Character Spacing")
col.prop(text, "space_word", text="Word Spacing")
@@ -429,10 +469,14 @@ classes = (
DATA_PT_shape_curve,
DATA_PT_curve_texture_space,
DATA_PT_geometry_curve,
+ DATA_PT_geometry_curve_bevel,
DATA_PT_pathanim,
DATA_PT_active_spline,
DATA_PT_font,
+ DATA_PT_font_transform,
DATA_PT_paragraph,
+ DATA_PT_paragraph_alignment,
+ DATA_PT_paragraph_spacing,
DATA_PT_text_boxes,
DATA_PT_custom_props_curve,
)
diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index d47160de8a0..2727c84e820 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -181,23 +181,59 @@ class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel):
col.prop(lamp, "shadow_buffer_exp", text="Exponent")
col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias")
- col.separator()
- if lamp.type == 'SUN':
- col.label("Cascaded Shadow Map")
+class DATA_PT_EEVEE_shadow_cascaded_shadow_map(DataButtonsPanel, Panel):
+ bl_label = "Cascaded Shadow Map"
+ bl_parent_id = "DATA_PT_EEVEE_shadow"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ lamp = context.lamp
+ engine = context.engine
+
+ return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ lamp = context.lamp
+ layout.use_property_split = True
+
+ col = layout.column()
+
+ col.prop(lamp, "shadow_cascade_count", text="Count")
+ col.prop(lamp, "shadow_cascade_fade", text="Fade")
- col.prop(lamp, "shadow_cascade_count", text="Count")
- col.prop(lamp, "shadow_cascade_fade", text="Fade")
+ col.prop(lamp, "shadow_cascade_max_distance", text="Max Distance")
+ col.prop(lamp, "shadow_cascade_exponent", text="Distribution")
- col.prop(lamp, "shadow_cascade_max_distance", text="Max Distance")
- col.prop(lamp, "shadow_cascade_exponent", text="Distribution")
- layout.separator()
+class DATA_PT_EEVEE_shadow_contact(DataButtonsPanel, Panel):
+ bl_label = "Contact Shadows"
+ bl_parent_id = "DATA_PT_EEVEE_shadow"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
- layout.prop(lamp, "use_contact_shadow")
+ @classmethod
+ def poll(cls, context):
+ lamp = context.lamp
+ engine = context.engine
+ return (lamp and lamp.type in {'POINT', 'SUN', 'SPOT', 'AREA'}) and (engine in cls.COMPAT_ENGINES)
+
+ def draw_header(self, context):
+ lamp = context.lamp
+
+ layout = self.layout
+ layout.active = lamp.use_shadow
+ layout.prop(lamp, "use_contact_shadow", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ lamp = context.lamp
+ layout.use_property_split = True
col = layout.column()
- col.active = lamp.use_contact_shadow
+ col.active = lamp.use_shadow and lamp.use_contact_shadow
col.prop(lamp, "contact_shadow_distance", text="Distance")
col.prop(lamp, "contact_shadow_soft_size", text="Softness")
@@ -268,6 +304,7 @@ class DATA_PT_spot(DataButtonsPanel, Panel):
class DATA_PT_spot(DataButtonsPanel, Panel):
bl_label = "Spot Shape"
+ bl_parent_id = "DATA_PT_EEVEE_lamp"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
@classmethod
@@ -321,6 +358,8 @@ classes = (
DATA_PT_lamp,
DATA_PT_EEVEE_lamp,
DATA_PT_EEVEE_shadow,
+ DATA_PT_EEVEE_shadow_contact,
+ DATA_PT_EEVEE_shadow_cascaded_shadow_map,
DATA_PT_area,
DATA_PT_spot,
DATA_PT_falloff_curve,
diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py
index a9c9d512335..12ecbeb3e6b 100644
--- a/release/scripts/startup/bl_ui/properties_freestyle.py
+++ b/release/scripts/startup/bl_ui/properties_freestyle.py
@@ -629,7 +629,7 @@ class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Pan
row = layout.row(align=True)
row.prop(linestyle, "panel", expand=True)
if linestyle.panel == 'STROKES':
- ## Chaining
+ # Chaining
layout.prop(linestyle, "use_chaining", text="Chaining:")
split = layout.split(align=True)
split.active = linestyle.use_chaining
@@ -643,7 +643,7 @@ class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Pan
col = split.column()
col.prop(linestyle, "use_same_object")
- ## Splitting
+ # Splitting
layout.label(text="Splitting:")
split = layout.split(align=True)
# First column
@@ -679,7 +679,7 @@ class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Pan
sub.prop(linestyle, "split_dash3", text="D3")
sub.prop(linestyle, "split_gap3", text="G3")
- ## Sorting
+ # Sorting
layout.prop(linestyle, "use_sorting", text="Sorting:")
col = layout.column()
col.active = linestyle.use_sorting
@@ -693,7 +693,7 @@ class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Pan
row = col.row(align=True)
row.prop(linestyle, "sort_order", expand=True)
- ## Selection
+ # Selection
layout.label(text="Selection:")
split = layout.split(align=True)
# First column
@@ -716,12 +716,12 @@ class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Pan
sub.active = linestyle.use_chain_count
sub.prop(linestyle, "chain_count")
- ## Caps
+ # Caps
layout.label(text="Caps:")
row = layout.row(align=True)
row.prop(linestyle, "caps", expand=True)
- ## Dashed lines
+ # Dashed lines
layout.prop(linestyle, "use_dashed_line", text="Dashed Line:")
row = layout.row(align=True)
row.active = linestyle.use_dashed_line
@@ -786,9 +786,10 @@ class VIEWLAYER_PT_freestyle_linestyle(ViewLayerFreestyleEditorButtonsPanel, Pan
row = layout.row()
props = row.operator(
- "wm.properties_context_change",
- text="Go to Linestyle Textures Properties",
- icon='TEXTURE')
+ "wm.properties_context_change",
+ text="Go to Linestyle Textures Properties",
+ icon='TEXTURE',
+ )
props.context = 'TEXTURE'
elif linestyle.panel == 'MISC':
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 decbbff5d60..a2ccfb4f1b8 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -242,7 +242,6 @@ class GreasePencilStrokeEditPanel:
if is_3d_view:
layout.separator()
-
layout.separator()
col = layout.column(align=True)
col.operator("gpencil.stroke_subdivide", text="Subdivide")
@@ -1100,11 +1099,11 @@ class GreasePencilPaletteColorPanel:
row = layout.row()
sub = row.row(align=True)
- sub.label(text="Isolate:") # based on active color only
+ sub.label(text="Isolate:") # based on active color only
sub.operator("gpencil.palettecolor_isolate", icon='LOCKED', text="").affect_visibility = False
sub.operator("gpencil.palettecolor_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
sub = row.row(align=True)
- sub.label(text="Lock:") # based on other stuff...
+ sub.label(text="Lock:") # based on other stuff...
sub.operator("gpencil.stroke_lock_color", icon='BORDER_RECT', text="")
sub.operator("gpencil.palette_lock_layer", icon='COLOR', text="")
diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py
index a7a67130f2f..450ca80bbc2 100644
--- a/release/scripts/startup/bl_ui/properties_mask_common.py
+++ b/release/scripts/startup/bl_ui/properties_mask_common.py
@@ -43,8 +43,8 @@ class MASK_UL_layers(UIList):
class MASK_PT_mask:
# subclasses must define...
- #~ bl_space_type = 'CLIP_EDITOR'
- #~ bl_region_type = 'UI'
+ # ~ bl_space_type = 'CLIP_EDITOR'
+ # ~ bl_region_type = 'UI'
bl_label = "Mask Settings"
bl_options = {'DEFAULT_CLOSED'}
@@ -66,8 +66,8 @@ class MASK_PT_mask:
class MASK_PT_layers:
# subclasses must define...
- #~ bl_space_type = 'CLIP_EDITOR'
- #~ bl_region_type = 'UI'
+ # ~ bl_space_type = 'CLIP_EDITOR'
+ # ~ bl_region_type = 'UI'
bl_label = "Mask Layers"
@classmethod
@@ -114,8 +114,8 @@ class MASK_PT_layers:
class MASK_PT_spline:
# subclasses must define...
- #~ bl_space_type = 'CLIP_EDITOR'
- #~ bl_region_type = 'UI'
+ # ~ bl_space_type = 'CLIP_EDITOR'
+ # ~ bl_region_type = 'UI'
bl_label = "Active Spline"
@classmethod
@@ -148,8 +148,8 @@ class MASK_PT_spline:
class MASK_PT_point:
# subclasses must define...
- #~ bl_space_type = 'CLIP_EDITOR'
- #~ bl_region_type = 'UI'
+ # ~ bl_space_type = 'CLIP_EDITOR'
+ # ~ bl_region_type = 'UI'
bl_label = "Active Point"
@classmethod
@@ -203,8 +203,8 @@ class MASK_PT_point:
class MASK_PT_display:
# subclasses must define...
- #~ bl_space_type = 'CLIP_EDITOR'
- #~ bl_region_type = 'UI'
+ # ~ bl_space_type = 'CLIP_EDITOR'
+ # ~ bl_region_type = 'UI'
bl_label = "Mask Display"
bl_options = {'DEFAULT_CLOSED'}
@@ -229,8 +229,8 @@ class MASK_PT_display:
class MASK_PT_transforms:
# subclasses must define...
- #~ bl_space_type = 'CLIP_EDITOR'
- #~ bl_region_type = 'TOOLS'
+ # ~ bl_space_type = 'CLIP_EDITOR'
+ # ~ bl_region_type = 'TOOLS'
bl_label = "Transforms"
bl_category = "Mask"
bl_options = {'DEFAULT_CLOSED'}
@@ -253,8 +253,8 @@ class MASK_PT_transforms:
class MASK_PT_tools:
# subclasses must define...
- #~ bl_space_type = 'CLIP_EDITOR'
- #~ bl_region_type = 'TOOLS'
+ # ~ bl_space_type = 'CLIP_EDITOR'
+ # ~ bl_region_type = 'TOOLS'
bl_label = "Mask Tools"
bl_category = "Mask"
@@ -291,8 +291,8 @@ class MASK_PT_tools:
class MASK_PT_add:
# subclasses must define...
- #~ bl_space_type = 'CLIP_EDITOR'
- #~ bl_region_type = 'TOOLS'
+ # ~ bl_space_type = 'CLIP_EDITOR'
+ # ~ bl_region_type = 'TOOLS'
bl_label = "Add"
bl_category = "Mask"
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 369772f7258..75cdd2d68c6 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -23,6 +23,7 @@ from rna_prop_ui import PropertyPanel
from bpy.app.translations import pgettext_iface as iface_
from bpy_extras.node_utils import find_node_input, find_output_node
+
class MATERIAL_MT_specials(Menu):
bl_label = "Material Specials"
@@ -172,6 +173,7 @@ class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
if mat.use_nodes:
panel_node_draw(layout, mat.node_tree, ('OUTPUT_EEVEE_MATERIAL', 'OUTPUT_MATERIAL'))
else:
+ layout.use_property_split = True
layout.prop(mat, "diffuse_color", text="Base Color")
layout.prop(mat, "metallic")
layout.prop(mat, "specular_intensity", text="Specular")
@@ -190,6 +192,7 @@ class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
mat = context.material
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 6486fbf0d63..9bcb1099a79 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -86,6 +86,7 @@ class OBJECT_PT_transform(ObjectButtonsPanel, Panel):
class OBJECT_PT_delta_transform(ObjectButtonsPanel, Panel):
bl_label = "Delta Transform"
+ bl_parent_id = "OBJECT_PT_transform"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index bc8bc523e12..f1e5102f061 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -126,7 +126,7 @@ def brush_texpaint_common(panel, context, layout, brush, settings, projpaint=Fal
col.prop(brush, "gradient_stroke_mode", text="Mode")
if brush.gradient_stroke_mode in {'SPACING_REPEAT', 'SPACING_CLAMP'}:
col.prop(brush, "grad_spacing")
- else: # if brush.image_tool == 'FILL':
+ else: # if brush.image_tool == 'FILL':
col.prop(brush, "gradient_fill_mode")
else:
row = col.row(align=True)
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index f470a81dca1..00eb13dd222 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -255,56 +255,70 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
psys = context.particle_system
part = particle_get_settings(context)
+ layout.use_property_split = True
+
layout.enabled = particle_panel_enabled(context, psys) and (psys is None or not psys.has_multiple_caches)
- row = layout.row()
- row.active = part.emit_from == 'VERT' or part.distribution != 'GRID'
- row.prop(part, "count")
+ col = layout.column()
+ col.active = part.emit_from == 'VERT' or part.distribution != 'GRID'
+ col.prop(part, "count")
if part.type == 'HAIR':
- row.prop(part, "hair_length")
+ col.prop(part, "hair_length")
if not part.use_advanced_hair:
row = layout.row()
- row.prop(part, "use_modifier_stack")
+ col.prop(part, "use_modifier_stack")
return
if part.type != 'HAIR':
- split = layout.split()
- col = split.column(align=True)
- col.prop(part, "frame_start")
- col.prop(part, "frame_end")
+ col = layout.column()
+
+ sub = col.column(align=True)
+ sub.prop(part, "frame_start", text="Frame Start")
+ sub.prop(part, "frame_end", text="End")
- col = split.column(align=True)
col.prop(part, "lifetime")
- col.prop(part, "lifetime_random", slider=True)
+ col.prop(part, "lifetime_random", slider=True, text="Lifetime Randomness")
- layout.label(text="Emit From:")
- layout.row().prop(part, "emit_from", expand=True)
- row = layout.row()
+class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel):
+ bl_label = "Source"
+ bl_parent_id = "PARTICLE_PT_emission"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ part = particle_get_settings(context)
+
+ layout.use_property_split = True
+
+ col = layout.column()
+ col.prop(part, "emit_from")
+ col.prop(part, "use_modifier_stack")
+ if part.emit_from == 'FACE' or part.emit_from == 'VOLUME':
+ col.prop(part, "distribution")
+
if part.emit_from == 'VERT':
- row.prop(part, "use_emit_random")
+ col.prop(part, "use_emit_random", text="Random Order")
elif part.distribution == 'GRID':
- row.prop(part, "invert_grid")
- row.prop(part, "hexagonal_grid")
+ col.label(text="Grid")
+ col.prop(part, "invert_grid")
+ col.prop(part, "hexagonal_grid")
else:
- row.prop(part, "use_emit_random")
- row.prop(part, "use_even_distribution")
+ col.prop(part, "use_emit_random")
+ col.prop(part, "use_even_distribution")
if part.emit_from == 'FACE' or part.emit_from == 'VOLUME':
- layout.row().prop(part, "distribution", expand=True)
- row = layout.row()
if part.distribution == 'JIT':
- row.prop(part, "userjit", text="Particles/Face")
- row.prop(part, "jitter_factor", text="Jittering Amount", slider=True)
+ col.prop(part, "userjit", text="Particles/Face")
+ col.prop(part, "jitter_factor", text="Jittering Amount", slider=True)
elif part.distribution == 'GRID':
- row.prop(part, "grid_resolution")
- row.prop(part, "grid_random", text="Random", slider=True)
-
- row = layout.row()
- row.prop(part, "use_modifier_stack")
+ col.prop(part, "grid_resolution")
+ col.prop(part, "grid_random", text="Random", slider=True)
class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
@@ -332,6 +346,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
psys = context.particle_system
if not psys.cloth:
+ layout.label(text="Hair dynamics disabled")
return
cloth_md = psys.cloth
@@ -345,44 +360,20 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
row.operator("particle.hair_dynamics_preset_add", text="", icon='ZOOMIN')
row.operator("particle.hair_dynamics_preset_add", text="", icon='ZOOMOUT').remove_active = True
- split = layout.column()
-
- col = split.column()
- col.label(text="Structure")
- col.prop(cloth, "mass")
- sub = col.column(align=True)
- subsub = sub.row(align=True)
- subsub.prop(cloth, "bending_stiffness", text="Stiffness")
- subsub.prop(psys.settings, "bending_random", text="Random")
- sub.prop(cloth, "bending_damping", text="Damping")
- # XXX has no noticeable effect with stiff hair structure springs
- #col.prop(cloth, "spring_damping", text="Damping")
-
- split.separator()
-
- col = split.column()
- col.label(text="Volume")
- col.prop(cloth, "air_damping", text="Air Drag")
- col.prop(cloth, "internal_friction", slider=True)
- sub = col.column(align=True)
- sub.prop(cloth, "density_target", text="Density Target")
- sub.prop(cloth, "density_strength", slider=True, text="Strength")
- col.prop(cloth, "voxel_cell_size")
+ layout.use_property_split = True
- split.separator()
+ layout.separator()
- col = split.column()
- col.label(text="Pinning")
- col.prop(cloth, "pin_stiffness", text="Goal Strength")
+ col = layout.column()
+ col.prop(cloth, "quality", text="Quality Steps", slider=True)
+ col.prop(psys.settings, "show_hair_grid", text="Display Hair Grid")
- split.separator()
+ layout.separator()
- col = split.column()
- col.label(text="Quality:")
- col.prop(cloth, "quality", text="Steps", slider=True)
+ col = layout.column()
+ col.prop(cloth, "pin_stiffness", text="Pin Goal Strength")
- row = col.row()
- row.prop(psys.settings, "show_hair_grid", text="HairGrid")
+ layout.separator()
if result:
box = layout.box()
@@ -405,6 +396,71 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
box.label("Error: %.5f .. %.5f (avg. %.5f)" % (result.min_error, result.max_error, result.avg_error))
+class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel):
+ bl_label = "Structure"
+ bl_parent_id = "PARTICLE_PT_hair_dynamics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.particle_system.cloth is not None
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ cloth_md = psys.cloth
+ cloth = cloth_md.settings
+ result = cloth_md.solver_result
+
+ layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked is False
+
+ layout.use_property_split = True
+
+ col = layout.column()
+ col.prop(cloth, "mass")
+ sub = col.column(align=True)
+ sub.prop(cloth, "bending_stiffness", text="Stiffness")
+ sub.prop(psys.settings, "bending_random", text="Random")
+ col.prop(cloth, "bending_damping", text="Damping")
+ # XXX has no noticeable effect with stiff hair structure springs
+ #col.prop(cloth, "spring_damping", text="Damping")
+
+
+class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel):
+ bl_label = "Volume"
+ bl_parent_id = "PARTICLE_PT_hair_dynamics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ return context.particle_system.cloth is not None
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ cloth_md = psys.cloth
+ cloth = cloth_md.settings
+ result = cloth_md.solver_result
+
+ layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked is False
+
+ layout.use_property_split = True
+
+ col = layout.column()
+ col.prop(cloth, "air_damping", text="Air Drag")
+ col.prop(cloth, "internal_friction", slider=True)
+ col.prop(cloth, "voxel_cell_size")
+
+ col.separator()
+
+ col.prop(cloth, "density_target", text="Density Target")
+ col.prop(cloth, "density_strength", slider=True, text="Density Strength")
+
+
class PARTICLE_PT_cache(ParticleButtonsPanel, Panel):
bl_label = "Cache"
bl_options = {'DEFAULT_CLOSED'}
@@ -459,31 +515,29 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel):
part = particle_get_settings(context)
layout.enabled = particle_panel_enabled(context, psys)
+ layout.use_property_split = True
- split = layout.split()
-
- col = split.column()
- col.label(text="Emitter Geometry:")
+ col = layout.column()
col.prop(part, "normal_factor")
sub = col.column(align=True)
- sub.prop(part, "tangent_factor")
- sub.prop(part, "tangent_phase", slider=True)
+ sub.prop(part, "tangent_factor", text="Tangent")
+ sub.prop(part, "tangent_phase", slider=True, text="Tangent Phase")
- col = split.column()
- col.label(text="Emitter Object:")
- col.prop(part, "object_align_factor", text="")
+ col.separator()
+
+ col.prop(part, "object_align_factor")
+
+ col.separator()
- layout.label(text="Other:")
- row = layout.row()
if part.emit_from == 'PARTICLE':
- row.prop(part, "particle_factor")
+ col.prop(part, "particle_factor")
else:
- row.prop(part, "object_factor", slider=True)
- row.prop(part, "factor_random")
+ col.prop(part, "object_factor", slider=True)
+ col.prop(part, "factor_random", text="Randomize")
- #if part.type=='REACTOR':
- # sub.prop(part, "reactor_factor")
- # sub.prop(part, "reaction_shape", slider=True)
+ # if part.type=='REACTOR':
+ # sub.prop(part, "reactor_factor")
+ # sub.prop(part, "reaction_shape", slider=True)
class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
@@ -522,32 +576,46 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
part = context.space_data.pin_id
layout.enabled = particle_panel_enabled(context, psys) and part.use_rotations
+ layout.use_property_split = True
- layout.label(text="Initial Orientation:")
+ col = layout.column()
- split = layout.split()
+ col.prop(part, "rotation_mode")
+ col.prop(part, "rotation_factor_random", slider=True, text="Randomize")
- col = split.column(align=True)
- col.prop(part, "rotation_mode", text="")
- col.prop(part, "rotation_factor_random", slider=True, text="Random")
+ col.separator()
- col = split.column(align=True)
col.prop(part, "phase_factor", slider=True)
- col.prop(part, "phase_factor_random", text="Random", slider=True)
+ col.prop(part, "phase_factor_random", text="Randomize Phase ", slider=True)
if part.type != 'HAIR':
- layout.label(text="Angular Velocity:")
+ col.prop(part, "use_dynamic_rotation")
- split = layout.split()
- col = split.column(align=True)
- col.prop(part, "angular_velocity_mode", text="")
- sub = col.column(align=True)
- sub.active = part.angular_velocity_mode != 'NONE'
- sub.prop(part, "angular_velocity_factor", text="")
+class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel):
+ bl_label = "Angular Velocity"
+ bl_parent_id = "PARTICLE_PT_rotation"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
- col = split.column()
- col.prop(part, "use_dynamic_rotation")
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ if psys:
+ part = psys.settings
+ else:
+ part = context.space_data.pin_id
+
+ layout.enabled = particle_panel_enabled(context, psys) and part.use_rotations
+ layout.use_property_split = True
+
+ col = layout.column()
+
+ col.prop(part, "angular_velocity_mode", text="Axis")
+ sub = col.column(align=True)
+ sub.active = part.angular_velocity_mode != 'NONE'
+ sub.prop(part, "angular_velocity_factor", text="Amount")
class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
@@ -568,127 +636,87 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
psys = context.particle_system
part = particle_get_settings(context)
layout.enabled = particle_panel_enabled(context, psys)
- layout.row().prop(part, "physics_type", expand=True)
+ layout.prop(part, "physics_type")
- row = layout.row()
+ col = layout.column()
if part.physics_type != 'NO':
- col = row.column(align=True)
+ col = col.column()
col.prop(part, "mass")
col.prop(part, "use_multiply_size_mass", text="Multiply mass with size")
- if part.physics_type in {'NEWTON', 'FLUID'}:
- split = layout.split()
+ if part.physics_type == 'FLUID':
+ fluid = part.fluid
- col = split.column()
- col.label(text="Forces:")
- col.prop(part, "brownian_factor")
- col.prop(part, "drag_factor", slider=True)
- col.prop(part, "damping", slider=True)
+ col.label(text="Fluid")
+ col.prop(fluid, "solver")
+ col.prop(fluid, "stiffness", text="Stiffness")
+ col.prop(fluid, "linear_viscosity", text="Viscosity")
+ col.prop(fluid, "buoyancy", text="Buoyancy", slider=True)
- col = split.column()
- col.label(text="Integration:")
- col.prop(part, "integrator", text="")
- col.prop(part, "timestep")
- sub = col.row()
- sub.prop(part, "subframes")
- supports_courant = part.physics_type == 'FLUID'
- subsub = sub.row()
- subsub.enabled = supports_courant
- subsub.prop(part, "use_adaptive_subframes", text="")
- if supports_courant and part.use_adaptive_subframes:
- col.prop(part, "courant_target", text="Threshold")
+ col.label(text="Advanced")
- row = layout.row()
- row.prop(part, "use_size_deflect")
- row.prop(part, "use_die_on_collision")
+ if fluid.solver == 'DDR':
+ sub = col.column()
+ sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
+ sub.prop(fluid, "factor_repulsion")
- layout.prop(part, "collision_group")
+ sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity)
+ sub.prop(fluid, "factor_stiff_viscosity")
- if part.physics_type == 'FLUID':
- fluid = part.fluid
-
- split = layout.split()
- sub = split.row()
- sub.prop(fluid, "solver", expand=True)
-
- split = layout.split()
-
- col = split.column()
- col.label(text="Fluid Properties:")
- col.prop(fluid, "stiffness", text="Stiffness")
- col.prop(fluid, "linear_viscosity", text="Viscosity")
- col.prop(fluid, "buoyancy", text="Buoyancy", slider=True)
-
- col = split.column()
- col.label(text="Advanced:")
-
- if fluid.solver == 'DDR':
- sub = col.row()
- sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
- sub.prop(fluid, "factor_repulsion", text="")
-
- sub = col.row()
- sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity)
- sub.prop(fluid, "factor_stiff_viscosity", text="")
-
- sub = col.row()
- sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius)
- sub.prop(fluid, "factor_radius", text="")
-
- sub = col.row()
- sub.prop(fluid, "rest_density", slider=fluid.use_factor_density)
- sub.prop(fluid, "use_factor_density", text="")
-
- if fluid.solver == 'CLASSICAL':
- # With the classical solver, it is possible to calculate the
- # spacing between particles when the fluid is at rest. This
- # makes it easier to set stable initial conditions.
- particle_volume = part.mass / fluid.rest_density
- spacing = pow(particle_volume, 1.0 / 3.0)
- sub = col.row()
- sub.label(text="Spacing: %g" % spacing)
-
- elif fluid.solver == 'DDR':
- split = layout.split()
-
- col = split.column()
- col.label(text="Springs:")
- col.prop(fluid, "spring_force", text="Force")
- col.prop(fluid, "use_viscoelastic_springs")
- sub = col.column(align=True)
- sub.active = fluid.use_viscoelastic_springs
- sub.prop(fluid, "yield_ratio", slider=True)
- sub.prop(fluid, "plasticity", slider=True)
-
- col = split.column()
- col.label(text="Advanced:")
- sub = col.row()
- sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
- sub.prop(fluid, "factor_rest_length", text="")
- col.label(text="")
- sub = col.column()
- sub.active = fluid.use_viscoelastic_springs
- sub.prop(fluid, "use_initial_rest_length")
- sub.prop(fluid, "spring_frames", text="Frames")
+ sub = col.column()
+ sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius)
+ sub.prop(fluid, "factor_radius")
+
+ sub.prop(fluid, "rest_density", slider=fluid.use_factor_density)
+ sub.prop(fluid, "use_factor_density")
+
+ if fluid.solver == 'CLASSICAL':
+ # With the classical solver, it is possible to calculate the
+ # spacing between particles when the fluid is at rest. This
+ # makes it easier to set stable initial conditions.
+ particle_volume = part.mass / fluid.rest_density
+ spacing = pow(particle_volume, 1.0 / 3.0)
+
+ sub.label(text="Spacing: %g" % spacing)
+
+ elif fluid.solver == 'DDR':
+
+ col.label(text="Springs")
+ col.prop(fluid, "spring_force", text="Force")
+ col.prop(fluid, "use_viscoelastic_springs")
+
+ sub = col.column()
+ sub.active = fluid.use_viscoelastic_springs
+ sub.prop(fluid, "yield_ratio", slider=True)
+ sub.prop(fluid, "plasticity", slider=True)
+
+ col.label(text="Advanced")
+ sub = col.column()
+ sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
+ sub.prop(fluid, "factor_rest_length", text="")
+
+ sub = col.column()
+ sub.active = fluid.use_viscoelastic_springs
+ sub.prop(fluid, "use_initial_rest_length")
+ sub.prop(fluid, "spring_frames", text="Frames")
elif part.physics_type == 'KEYED':
- split = layout.split()
- sub = split.column()
- row = layout.row()
- col = row.column()
- col.active = not psys.use_keyed_timing
- col.prop(part, "keyed_loops", text="Loops")
+ sub = col.column()
+ sub.active = not psys.use_keyed_timing
+ sub.prop(part, "keyed_loops", text="Loops")
if psys:
- row.prop(psys, "use_keyed_timing", text="Use Timing")
+ col.prop(psys, "use_keyed_timing", text="Use Timing")
+
+ col.label(text="Keys")
- layout.label(text="Keys:")
elif part.physics_type == 'BOIDS':
boids = part.boids
@@ -786,6 +814,93 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
sub.prop(key, "system", text="System")
+class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel):
+ bl_label = "Deflection"
+ bl_parent_id = "PARTICLE_PT_physics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.physics_type in {'NEWTON', 'FLUID'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+ layout.enabled = particle_panel_enabled(context, psys)
+
+ col = layout.column()
+ col.prop(part, "use_size_deflect")
+ col.prop(part, "use_die_on_collision")
+
+ col.prop(part, "collision_group")
+
+
+class PARTICLE_PT_physics_forces(ParticleButtonsPanel, Panel):
+ bl_label = "Forces"
+ bl_parent_id = "PARTICLE_PT_physics"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.physics_type == 'NEWTON'
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+ layout.enabled = particle_panel_enabled(context, psys)
+
+ col = layout.column()
+
+ col.prop(part, "brownian_factor")
+ col.prop(part, "drag_factor", slider=True)
+ col.prop(part, "damping", slider=True)
+
+
+class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel):
+ bl_label = "Integration"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "PARTICLE_PT_physics"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.physics_type == 'NEWTON'
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+ layout.enabled = particle_panel_enabled(context, psys)
+
+ col = layout.column()
+
+ col.prop(part, "integrator")
+ col.prop(part, "timestep")
+ sub = col.row()
+ sub.prop(part, "subframes")
+ supports_courant = part.physics_type == 'FLUID'
+ subsub = sub.row()
+ subsub.enabled = supports_courant
+ subsub.prop(part, "use_adaptive_subframes", text="")
+ if supports_courant and part.use_adaptive_subframes:
+ col.prop(part, "courant_target", text="Threshold")
+
+
class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
bl_label = "Boid Brain"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@@ -811,7 +926,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
# Currently boids can only use the first state so these are commented out for now.
#row = layout.row()
- #row.template_list("UI_UL_list", "particle_boids", boids, "states",
+ # row.template_list("UI_UL_list", "particle_boids", boids, "states",
# boids, "active_boid_state_index", compact="True")
#col = row.row()
#sub = col.row(align=True)
@@ -904,175 +1019,387 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
psys = context.particle_system
part = particle_get_settings(context)
+ layout.prop(part, "render_type", text="Render As")
+
+ if part.type == 'EMITTER' or \
+ (part.render_type in {'OBJECT', 'COLLECTION'} and part.type == 'HAIR'):
+ if part.render_type not in {'NONE'}:
+
+ col = layout.column(align=True)
+ col.prop(part, "particle_size", text="Scale")
+ col.prop(part, "size_random", slider=True, text="Scale Randomness")
+
if psys:
- row = layout.row()
- if part.render_type in {'OBJECT', 'GROUP'}:
- row.enabled = False
- row.prop(part, "material_slot", text="")
- row.prop(psys, "parent")
+ col = layout.column()
+ if part.render_type not in {'OBJECT', 'COLLECTION', 'NONE'}:
+ # col.enabled = False
+ col.prop(part, "material_slot", text="Material")
+ col.prop(psys, "parent", text="Coordinate System")
- split = layout.split()
- col = split.column()
- col.prop(part, "use_parent_particles")
+class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel):
+ bl_label = "Extra"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
- col = split.column()
- col.prop(part, "show_unborn")
- col.prop(part, "use_dead")
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type != 'NONE'
- layout.row().prop(part, "render_type", expand=True)
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
- split = layout.split()
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
- col = split.column()
+ col = layout.column()
- if part.render_type == 'LINE':
- col.prop(part, "line_length_tail")
- col.prop(part, "line_length_head")
+ col = layout.column()
+ col.prop(part, "use_parent_particles", text="Parent Particles")
+ col.prop(part, "show_unborn", text="Unborn")
+ col.prop(part, "use_dead", text="Dead")
- split.prop(part, "use_velocity_length")
- elif part.render_type == 'PATH':
- col.prop(part, "use_strand_primitive")
- sub = col.column()
- sub.active = (part.use_strand_primitive is False)
- sub.prop(part, "use_render_adaptive")
- sub = col.column()
- sub.active = part.use_render_adaptive or part.use_strand_primitive is True
- sub.prop(part, "adaptive_angle")
- sub = col.column()
- sub.active = (part.use_render_adaptive is True and part.use_strand_primitive is False)
- sub.prop(part, "adaptive_pixel")
- col.prop(part, "use_hair_bspline")
- col.prop(part, "render_step", text="Steps")
- col = split.column()
- col.label(text="Timing:")
- col.prop(part, "use_absolute_path_time")
+class PARTICLE_PT_render_line(ParticleButtonsPanel, Panel):
+ bl_label = "Line"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
- if part.type == 'HAIR' or psys.point_cache.is_baked:
- col.prop(part, "path_start", text="Start", slider=not part.use_absolute_path_time)
- else:
- col.prop(part, "trail_count")
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'LINE'
- col.prop(part, "path_end", text="End", slider=not part.use_absolute_path_time)
- col.prop(part, "length_random", text="Random", slider=True)
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
- elif part.render_type == 'OBJECT':
- col.prop(part, "dupli_object")
- sub = col.row()
- sub.prop(part, "use_global_dupli")
- sub.prop(part, "use_rotation_dupli")
- sub.prop(part, "use_scale_dupli")
- elif part.render_type == 'GROUP':
- col.prop(part, "dupli_group")
- split = layout.split()
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
- col = split.column()
- col.prop(part, "use_whole_group")
- sub = col.column()
- sub.active = (part.use_whole_group is False)
- sub.prop(part, "use_group_pick_random")
- sub.prop(part, "use_group_count")
+ col = layout.column()
- col = split.column()
- sub = col.column()
- sub.active = (part.use_whole_group is False)
- sub.prop(part, "use_global_dupli")
- sub.prop(part, "use_rotation_dupli")
- sub.prop(part, "use_scale_dupli")
+ col.separator()
+ sub = col.column(align=True)
+ sub.prop(part, "line_length_tail", text="Length Tail")
+ sub.prop(part, "line_length_head", text="Head")
+ col.prop(part, "use_velocity_length", text="Velocity Length")
- if part.use_group_count and not part.use_whole_group:
- row = layout.row()
- row.template_list("UI_UL_list", "particle_dupli_weights", part, "dupli_weights",
- part, "active_dupliweight_index")
- col = row.column()
- sub = col.row()
- subsub = sub.column(align=True)
- subsub.operator("particle.dupliob_copy", icon='ZOOMIN', text="")
- subsub.operator("particle.dupliob_remove", icon='ZOOMOUT', text="")
- subsub.operator("particle.dupliob_move_up", icon='TRIA_UP', text="")
- subsub.operator("particle.dupliob_move_down", icon='TRIA_DOWN', text="")
+class PARTICLE_PT_render_path(ParticleButtonsPanel, Panel):
+ bl_label = "Path"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
- weight = part.active_dupliweight
- if weight:
- row = layout.row()
- row.prop(weight, "count")
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'PATH'
- elif part.render_type == 'BILLBOARD':
- ob = context.object
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
- col.label(text="Align:")
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
- row = layout.row()
- row.prop(part, "billboard_align", expand=True)
- row.prop(part, "lock_billboard", text="Lock")
- row = layout.row()
- row.prop(part, "billboard_object")
+ col = layout.column()
- row = layout.row()
- col = row.column(align=True)
- col.label(text="Tilt:")
- col.prop(part, "billboard_tilt", text="Angle", slider=True)
- col.prop(part, "billboard_tilt_random", text="Random", slider=True)
- col = row.column()
- col.prop(part, "billboard_offset")
+ col.prop(part, "use_strand_primitive")
+ sub = col.column()
+ sub.active = (part.use_strand_primitive is False)
+ sub.prop(part, "use_render_adaptive")
+ sub = col.column()
+ sub.active = part.use_render_adaptive or part.use_strand_primitive is True
+ sub.prop(part, "adaptive_angle")
+ sub = col.column()
+ sub.active = (part.use_render_adaptive is True and part.use_strand_primitive is False)
+ sub.prop(part, "adaptive_pixel")
+ col.prop(part, "use_hair_bspline")
+ col.prop(part, "render_step", text="Steps")
+
+
+class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel):
+ bl_label = "Timing"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
- row = layout.row()
- col = row.column()
- col.prop(part, "billboard_size", text="Scale")
- if part.billboard_align == 'VEL':
- col = row.column(align=True)
- col.label("Velocity Scale:")
- col.prop(part, "billboard_velocity_head", text="Head")
- col.prop(part, "billboard_velocity_tail", text="Tail")
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'PATH'
- if psys:
- col = layout.column()
- col.prop_search(psys, "billboard_normal_uv", ob.data, "uv_layers")
- col.prop_search(psys, "billboard_time_index_uv", ob.data, "uv_layers")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
- split = layout.split(percentage=0.33)
- split.label(text="Split UVs:")
- split.prop(part, "billboard_uv_split", text="Number of splits")
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
- if psys:
- col = layout.column()
- col.active = part.billboard_uv_split > 1
- col.prop_search(psys, "billboard_split_uv", ob.data, "uv_layers")
+ col = layout.column()
- row = col.row()
- row.label(text="Animate:")
- row.prop(part, "billboard_animation", text="")
- row.label(text="Offset:")
- row.prop(part, "billboard_offset_split", text="")
+ col.prop(part, "use_absolute_path_time")
- if part.render_type == 'HALO' or part.render_type == 'LINE' or part.render_type == 'BILLBOARD':
- row = layout.row()
- col = row.column()
+ if part.type == 'HAIR' or psys.point_cache.is_baked:
+ col.prop(part, "path_start", text="Start", slider=not part.use_absolute_path_time)
+ else:
col.prop(part, "trail_count")
- if part.trail_count > 1:
- col.prop(part, "use_absolute_path_time", text="Length in Frames")
- col = row.column()
- col.prop(part, "path_end", text="Length", slider=not part.use_absolute_path_time)
- col.prop(part, "length_random", text="Random", slider=True)
- else:
- col = row.column()
- col.label(text="")
- if part.type == 'EMITTER' or \
- (part.render_type in {'OBJECT', 'GROUP'} and part.type == 'HAIR'):
- row = layout.row(align=True)
- row.prop(part, "particle_size")
- row.prop(part, "size_random", slider=True)
+ col.prop(part, "path_end", text="End", slider=not part.use_absolute_path_time)
+ col.prop(part, "length_random", text="Random", slider=True)
+
+
+class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel):
+ bl_label = "Object"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'OBJECT'
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
+
+ col = layout.column()
+
+ col.prop(part, "dupli_object", text="Instance Object")
+ sub = col.column()
+ sub.prop(part, "use_global_dupli", text="Global Coordinates")
+ sub.prop(part, "use_rotation_dupli", text="Object Rotation")
+ sub.prop(part, "use_scale_dupli", text="Object Scale")
+
+
+class PARTICLE_PT_render_collection(ParticleButtonsPanel, Panel):
+ bl_label = "Collection"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'COLLECTION'
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
+
+ col = layout.column()
+
+ col.prop(part, "dupli_group")
+
+ col.prop(part, "use_whole_group")
+ sub = col.column()
+ sub.active = (part.use_whole_group is False)
+ sub.prop(part, "use_group_pick_random")
+ sub.prop(part, "use_global_dupli", text="Global Coordinates")
+ sub.prop(part, "use_rotation_dupli", text="Object Rotation")
+ sub.prop(part, "use_scale_dupli", text="Object Scale")
+
+
+class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel):
+ bl_label = "Use Count"
+ bl_parent_id = "PARTICLE_PT_render_collection"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'COLLECTION'
+
+ def draw_header(self, context):
+ layout = self.layout
+ part = particle_get_settings(context)
+
+ layout.active = not part.use_whole_group
+
+ layout.prop(part, "use_group_count", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
+
+ col = layout.column()
+
+ layout.active = part.use_group_count and not part.use_whole_group
+
+ row = layout.row()
+ row.template_list("UI_UL_list", "particle_dupli_weights", part, "dupli_weights",
+ part, "active_dupliweight_index")
+
+ col = row.column()
+ sub = col.row()
+ subsub = sub.column(align=True)
+ subsub.operator("particle.dupliob_copy", icon='ZOOMIN', text="")
+ subsub.operator("particle.dupliob_remove", icon='ZOOMOUT', text="")
+ subsub.operator("particle.dupliob_move_up", icon='TRIA_UP', text="")
+ subsub.operator("particle.dupliob_move_down", icon='TRIA_DOWN', text="")
+
+ weight = part.active_dupliweight
+ if weight:
+ row = layout.row()
+ row.prop(weight, "count")
+
+
+class PARTICLE_PT_render_billboards_alignment(ParticleButtonsPanel, Panel):
+ bl_label = "Billboard Alignment"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'BILLBOARD'
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
+
+ col = layout.column()
+
+ col.prop(part, "billboard_align", text="Align To")
+ col.prop(part, "lock_billboard", text="Lock Axis")
+ col.prop(part, "billboard_object")
+
+
+class PARTICLE_PT_render_billboards_tilt(ParticleButtonsPanel, Panel):
+ bl_label = "Billboard Tilt"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'BILLBOARD'
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
+
+ col = layout.column()
+
+ sub = col.column(align=True)
+ sub.prop(part, "billboard_tilt", text="Angle", slider=True)
+ sub.prop(part, "billboard_tilt_random", text="Random", slider=True)
+
+ sub = col.column(align=True)
+ sub.prop(part, "billboard_offset")
+ col.prop(part, "billboard_size", text="Scale")
+ if part.billboard_align == 'VEL':
+ col = col.column(align=True)
+ col.prop(part, "billboard_velocity_head", text="Velocity ScaleHead")
+ col.prop(part, "billboard_velocity_tail", text="Tail")
+
+
+class PARTICLE_PT_render_billboards_uv(ParticleButtonsPanel, Panel):
+ bl_label = "Billboard UVs"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type == 'BILLBOARD'
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ ob = context.object
+ part = particle_get_settings(context)
+
+ col = layout.column()
+
+ if psys:
+ col.prop_search(psys, "billboard_normal_uv", ob.data, "uv_layers")
+ col.prop_search(psys, "billboard_time_index_uv", ob.data, "uv_layers")
+
+ col.prop(part, "billboard_uv_split", text="Split UVs")
+
+ if psys:
+ sub = col.column()
+ sub.active = part.billboard_uv_split > 1
+ sub.prop_search(psys, "billboard_split_uv", ob.data, "uv_layers")
+
+ sub.prop(part, "billboard_animation")
+ sub.prop(part, "billboard_offset_split")
+
+
+class PARTICLE_PT_render_trails(ParticleButtonsPanel, Panel):
+ bl_label = "Trails"
+ bl_parent_id = "PARTICLE_PT_render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.render_type in {'HALO', 'LINE', 'BILLBOARD'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+ col = layout.column()
+
+ col.prop(part, "trail_count")
+
+ sub = col.column()
+ sub.active = (part.trail_count > 1)
+ sub.prop(part, "use_absolute_path_time", text="Length in Frames")
+ sub.prop(part, "path_end", text="Length", slider=not part.use_absolute_path_time)
+ sub.prop(part, "length_random", text="Random Length", slider=True)
class PARTICLE_PT_draw(ParticleButtonsPanel, Panel):
- bl_label = "Display"
+ bl_label = "Viewport Display"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@@ -1086,53 +1413,52 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
psys = context.particle_system
part = particle_get_settings(context)
- row = layout.row()
- row.prop(part, "draw_method", expand=True)
- row.prop(part, "show_guide_hairs")
+ layout.prop(part, "draw_method", text="Display As")
if part.draw_method == 'NONE' or (part.render_type == 'NONE' and part.draw_method == 'RENDER'):
return
path = (part.render_type == 'PATH' and part.draw_method == 'RENDER') or part.draw_method == 'PATH'
- row = layout.row()
- row.prop(part, "draw_percentage", slider=True)
+ layout.separator()
+
+ col = layout.column()
+ col.prop(part, "draw_color", text="Color")
+ if part.draw_color in {'VELOCITY', 'ACCELERATION'}:
+ col.prop(part, "color_maximum", text="Fade Distance")
+
+ col = layout.column()
+
+ if path:
+ col.prop(part, "draw_step", text="Strand Steps")
+ col.prop(part, "draw_percentage", slider=True, text="Amount")
if part.draw_method != 'RENDER' or part.render_type == 'HALO':
- row.prop(part, "draw_size")
- else:
- row.label(text="")
+ col.prop(part, "draw_size", text="Size")
if part.draw_percentage != 100 and psys is not None:
if part.type == 'HAIR':
if psys.use_hair_dynamics and psys.point_cache.is_baked is False:
- layout.row().label(text="Display percentage makes dynamics inaccurate without baking!")
+ layout.row().label(text="Display percentage makes dynamics inaccurate without baking")
else:
phystype = part.physics_type
if phystype != 'NO' and phystype != 'KEYED' and psys.point_cache.is_baked is False:
- layout.row().label(text="Display percentage makes dynamics inaccurate without baking!")
+ layout.row().label(text="Display percentage makes dynamics inaccurate without baking")
+ else:
+ layout.row().label(text="")
- row = layout.row()
- col = row.column()
+ col = layout.column()
+ col.prop(part, "show_guide_hairs", text="Guide Hairs")
col.prop(part, "show_size")
col.prop(part, "show_velocity")
col.prop(part, "show_number")
if part.physics_type == 'BOIDS':
col.prop(part, "show_health")
- col = row.column(align=True)
- col.label(text="Color:")
- col.prop(part, "draw_color", text="")
- sub = col.row(align=True)
- sub.active = (part.draw_color in {'VELOCITY', 'ACCELERATION'})
- sub.prop(part, "color_maximum", text="Max")
-
- if path:
- col.prop(part, "draw_step")
-
class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
bl_label = "Children"
@@ -1151,37 +1477,91 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
layout.row().prop(part, "child_type", expand=True)
+ layout.use_property_split = True
+
if part.child_type == 'NONE':
return
- row = layout.row()
+ col = layout.column()
- col = row.column(align=True)
- col.prop(part, "child_nbr", text="Display")
- col.prop(part, "rendered_child_count", text="Render")
+ sub = col.column(align=True)
+ sub.prop(part, "child_nbr", text="Display Amount")
+ sub.prop(part, "rendered_child_count", text="Render Amount")
+
+ col.separator()
+
+ col.prop(part, "child_length", slider=True)
+ col.prop(part, "child_length_threshold", slider=True)
+ if psys:
+ col.prop(psys, "child_seed", text="Seed")
+
+ col.separator()
if part.child_type == 'INTERPOLATED':
- col = row.column()
- if psys:
- col.prop(psys, "child_seed", text="Seed")
col.prop(part, "virtual_parents", slider=True)
col.prop(part, "create_long_hair_children")
else:
- col = row.column(align=True)
- col.prop(part, "child_size", text="Size")
- col.prop(part, "child_size_random", text="Random")
+ col.separator()
+ sub = col.column(align=True)
+ sub.prop(part, "child_size", text="Size")
+ sub.prop(part, "child_size_random", text="Randomize Size", slider=True)
+
+ if part.child_type == 'SIMPLE':
+ col.separator()
+ col.prop(part, "child_radius", text="Radius")
+ col.prop(part, "child_roundness", text="Roundness", slider=True)
+ elif part.virtual_parents > 0.0:
+ sub = col.column(align=True)
+ sub.label(text="Parting not available with virtual parents")
- split = layout.split()
- col = split.column()
- col.label(text="Effects:")
+class PARTICLE_PT_children_parting(ParticleButtonsPanel, Panel):
+ bl_label = "Parting"
+ bl_parent_id = "PARTICLE_PT_children"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
- sub = col.column(align=True)
- if part.child_type == 'SIMPLE':
- sub.prop(part, "twist")
- sub.prop(part, "use_twist_curve")
- if part.use_twist_curve:
- sub.template_curve_mapping(part, "twist_curve")
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.child_type == 'INTERPOLATED'
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+ layout.use_property_split = True
+
+ col = layout.column()
+ col.prop(part, "child_parting_factor", text="Parting", slider=True)
+ col.prop(part, "child_parting_min", text="Min")
+ col.prop(part, "child_parting_max", text="Max")
+
+
+class PARTICLE_PT_children_clumping(ParticleButtonsPanel, Panel):
+ bl_label = "Clumping"
+ bl_parent_id = "PARTICLE_PT_children"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.child_type != 'NONE'
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+ layout.use_property_split = True
+
+ col = layout.column()
+
+ sub = col.column()
sub.prop(part, "use_clump_curve")
if part.use_clump_curve:
@@ -1195,28 +1575,33 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
subsub.enabled = part.use_clump_noise
subsub.prop(part, "clump_noise_size")
- sub = col.column(align=True)
- sub.prop(part, "child_length", slider=True)
- sub.prop(part, "child_length_threshold", slider=True)
-
if part.child_type == 'SIMPLE':
- sub = col.column(align=True)
- sub.prop(part, "child_radius", text="Radius")
- sub.prop(part, "child_roundness", text="Roundness", slider=True)
- if psys:
- sub.prop(psys, "child_seed", text="Seed")
- elif part.virtual_parents > 0.0:
- sub = col.column(align=True)
- sub.label(text="Parting not")
- sub.label(text="available with")
- sub.label(text="virtual parents")
- else:
- sub = col.column(align=True)
- sub.prop(part, "child_parting_factor", text="Parting", slider=True)
- sub.prop(part, "child_parting_min", text="Min")
- sub.prop(part, "child_parting_max", text="Max")
+ sub.prop(part, "twist")
+ sub.prop(part, "use_twist_curve")
+ if part.use_twist_curve:
+ sub.template_curve_mapping(part, "twist_curve")
- col = split.column()
+
+class PARTICLE_PT_children_roughness(ParticleButtonsPanel, Panel):
+ bl_label = "Roughness"
+ bl_parent_id = "PARTICLE_PT_children"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.child_type != 'NONE'
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+ layout.use_property_split = True
+
+ col = layout.column()
col.prop(part, "use_roughness_curve")
if part.use_roughness_curve:
@@ -1225,8 +1610,6 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
sub.prop(part, "roughness_1", text="Roughness")
sub.prop(part, "roughness_1_size", text="Size")
else:
- col.label(text="Roughness:")
-
sub = col.column(align=True)
sub.prop(part, "roughness_1", text="Uniform")
sub.prop(part, "roughness_1_size", text="Size")
@@ -1240,31 +1623,55 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
sub.prop(part, "roughness_2_size", text="Size")
sub.prop(part, "roughness_2_threshold", slider=True)
- layout.row().label(text="Kink:")
- layout.row().prop(part, "kink", expand=True)
- split = layout.split()
- split.active = part.kink != 'NO'
+class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel):
+ bl_label = "Kink"
+ bl_parent_id = "PARTICLE_PT_children"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.child_type != 'NONE'
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+ layout.use_property_split = True
+
+ col = layout.column()
+
+ col.prop(part, "kink", text="Kink Type")
+ col = layout.column()
+ col.active = part.kink != 'NO'
if part.kink == 'SPIRAL':
- col = split.column()
- sub = col.column(align=True)
- sub.prop(part, "kink_amplitude", text="Radius")
- sub.prop(part, "kink_amplitude_random", text="Random", slider=True)
- sub = col.column(align=True)
+
+ sub = col.column()
+ sub.prop(part, "kink_amplitude", text="Amplitude")
+ sub.prop(part, "kink_amplitude_random", text="Randomize Amplitude", slider=True)
+
+ col.separator()
+
+ sub = col.column()
sub.prop(part, "kink_axis")
- sub.prop(part, "kink_axis_random", text="Random", slider=True)
- col = split.column(align=True)
+ sub.prop(part, "kink_axis_random", text="Randomize Axis", slider=True)
+
+ col.separator()
+
col.prop(part, "kink_frequency", text="Frequency")
col.prop(part, "kink_shape", text="Shape", slider=True)
col.prop(part, "kink_extra_steps", text="Steps")
- else:
- col = split.column()
+
+ elif part.kink in {'CURL', 'RADIAL', 'WAVE', 'BRAID', 'WAVE'}:
sub = col.column(align=True)
sub.prop(part, "kink_amplitude")
sub.prop(part, "kink_amplitude_clump", text="Clump", slider=True)
col.prop(part, "kink_flat", slider=True)
- col = split.column(align=True)
col.prop(part, "kink_frequency")
col.prop(part, "kink_shape", slider=True)
@@ -1337,6 +1744,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
ob = context.object
psys = context.particle_system
@@ -1441,21 +1849,20 @@ class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
psys = context.particle_system
part = psys.settings
- row = layout.row()
- row.prop(part, "shape", text="Shape")
+ layout.prop(part, "shape", text="Strand Shape")
- layout.label(text="Thickness:")
- row = layout.row()
- row.prop(part, "root_radius", text="Root")
- row.prop(part, "tip_radius", text="Tip")
+ col = layout.column(align=True)
+ col.prop(part, "root_radius", text="Radius Root")
+ col.prop(part, "tip_radius", text="Tip")
- row = layout.row()
- row.prop(part, "radius_scale", text="Scaling")
- row.prop(part, "use_close_tip")
+ col = layout.column()
+ col.prop(part, "radius_scale", text="Radius Scaling")
+ col.prop(part, "use_close_tip")
class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel):
@@ -1470,15 +1877,36 @@ classes = (
PARTICLE_UL_particle_systems,
PARTICLE_PT_context_particles,
PARTICLE_PT_emission,
+ PARTICLE_PT_emission_source,
PARTICLE_PT_hair_dynamics,
+ PARTICLE_PT_hair_dynamics_structure,
+ PARTICLE_PT_hair_dynamics_volume,
PARTICLE_PT_cache,
PARTICLE_PT_velocity,
PARTICLE_PT_rotation,
+ PARTICLE_PT_rotation_angular_velocity,
PARTICLE_PT_physics,
+ PARTICLE_PT_physics_forces,
+ PARTICLE_PT_physics_deflection,
+ PARTICLE_PT_physics_integration,
PARTICLE_PT_boidbrain,
PARTICLE_PT_render,
+ PARTICLE_PT_render_line,
+ PARTICLE_PT_render_path,
+ PARTICLE_PT_render_path_timing,
+ PARTICLE_PT_render_object,
+ PARTICLE_PT_render_collection,
+ PARTICLE_PT_render_collection_use_count,
+ PARTICLE_PT_render_billboards_tilt,
+ PARTICLE_PT_render_billboards_uv,
+ PARTICLE_PT_render_trails,
+ PARTICLE_PT_render_extra,
PARTICLE_PT_draw,
PARTICLE_PT_children,
+ PARTICLE_PT_children_parting,
+ PARTICLE_PT_children_clumping,
+ PARTICLE_PT_children_roughness,
+ PARTICLE_PT_children_kink,
PARTICLE_PT_hair_shape,
PARTICLE_PT_field_weights,
PARTICLE_PT_force_fields,
diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index e0d0327324b..f450bc61635 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -257,6 +257,7 @@ class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel):
cloth = context.cloth.settings
effector_weights_ui(self, context, cloth.effector_weights, 'CLOTH')
+
classes = (
CLOTH_MT_presets,
PHYSICS_PT_cloth,
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index 3615f8be48c..05c72bf47ee 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -274,7 +274,7 @@ def basic_force_field_settings_ui(self, context, field):
elif field.type == 'HARMONIC':
col.prop(field, "use_multiple_springs")
if field.type == 'FORCE':
- col.prop(field, "use_gravity_falloff", text="Gravitation")
+ col.prop(field, "use_gravity_falloff", text="Gravitation")
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
index 817b0ab76ed..3cb9026fd02 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
@@ -117,7 +117,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
rbo = ob.rigid_body
#col = layout.column(align=1)
- #col.label(text="Activation:")
+ # col.label(text="Activation:")
# XXX: settings such as activate on collison/etc.
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index f1f5ec425e4..7cb0ce55be3 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -152,7 +152,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
sub.prop(rd, "use_crop_to_border", text="Crop")
col = layout.column(align=True)
- col.prop(scene, "frame_start", text="Frame Range Start")
+ col.prop(scene, "frame_start", text="Frame Start")
col.prop(scene, "frame_end", text="End")
col.prop(scene, "frame_step", text="Step")
@@ -161,8 +161,21 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
col.label(text="Frame Rate")
self.draw_framerate(col, rd)
+
+class RENDER_PT_frame_remapping(RenderButtonsPanel, Panel):
+ bl_label = "Time Remapping"
+ bl_parent_id = "RENDER_PT_dimensions"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ rd = context.scene.render
+
col = layout.column(align=True)
- col.prop(rd, "frame_map_old", text="Time Remapping Old")
+ col.prop(rd, "frame_map_old", text="Old")
col.prop(rd, "frame_map_new", text="New")
@@ -222,11 +235,25 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel):
sub.active = rd.use_stamp_note
sub.prop(rd, "stamp_note_text", text="")
- layout.use_property_split = True
- layout.separator()
+class RENDER_PT_stamp_burn(RenderButtonsPanel, Panel):
+ bl_label = "Burn Into Image"
+ bl_parent_id = "RENDER_PT_stamp"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'}
+
+ def draw_header(self, context):
+ rd = context.scene.render
+
+ self.layout.prop(rd, "use_stamp", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ rd = context.scene.render
+
+ layout.use_property_split = True
- layout.prop(rd, "use_stamp", text="Burn Into Image")
col = layout.column()
col.active = rd.use_stamp
col.prop(rd, "stamp_font_size", text="Font Size")
@@ -750,6 +777,7 @@ class RENDER_PT_hair(RenderButtonsPanel, Panel):
row = layout.row()
row.prop(rd, "hair_type", expand=True)
+ layout.use_property_split = True
layout.prop(rd, "hair_subdiv")
@@ -759,10 +787,12 @@ classes = (
RENDER_MT_framerate_presets,
RENDER_PT_context,
RENDER_PT_dimensions,
+ RENDER_PT_frame_remapping,
RENDER_PT_post_processing,
RENDER_PT_output,
RENDER_PT_encoding,
RENDER_PT_stamp,
+ RENDER_PT_stamp_burn,
RENDER_UL_renderviews,
RENDER_PT_stereoscopy,
RENDER_PT_hair,
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index 731a4586e42..4c5b1a86235 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -160,6 +160,7 @@ class SceneKeyingSetsPanel:
class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
bl_label = "Keying Sets"
+ bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
def draw(self, context):
@@ -193,7 +194,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
bl_label = "Active Keying Set"
- bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "SCENE_PT_keying_sets"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
@classmethod
@@ -258,18 +259,44 @@ class SCENE_PT_color_management(SceneButtonsPanel, Panel):
layout.use_property_split = True
scene = context.scene
+ view = scene.view_settings
col = layout.column()
col.prop(scene.display_settings, "display_device")
+ col.prop(scene.sequencer_colorspace_settings, "name", text="Sequencer Color Space")
col.separator()
col = layout.column()
- col.template_colormanaged_view_settings(scene, "view_settings")
+ col.prop(view, "view_transform")
+ col.prop(view, "exposure")
+ col.prop(view, "gamma")
+ col.prop(view, "look")
- col.separator()
- col = layout.column()
- col.prop(scene.sequencer_colorspace_settings, "name", text="Sequencer Color Space")
+
+class SCENE_PT_color_management_curves(SceneButtonsPanel, Panel):
+ bl_label = "Use Curves"
+ bl_parent_id = "SCENE_PT_color_management"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+ def draw_header(self, context):
+
+ scene = context.scene
+ view = scene.view_settings
+
+ self.layout.prop(view, "use_curve_mapping", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ view = scene.view_settings
+
+ layout.use_property_split = False
+ layout.enabled = view.use_curve_mapping
+
+ layout.template_curve_mapping(view, "curve_mapping", levels=True)
class SCENE_PT_audio(SceneButtonsPanel, Panel):
@@ -306,6 +333,7 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel):
class SCENE_PT_physics(SceneButtonsPanel, Panel):
bl_label = "Gravity"
+ bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'}
def draw_header(self, context):
@@ -368,7 +396,8 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel):
class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel):
- bl_label = "Rigid Body Cache"
+ bl_label = "Cache"
+ bl_parent_id = "SCENE_PT_rigid_body_world"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'}
@@ -385,7 +414,8 @@ class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel):
class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel):
- bl_label = "Rigid Body Field Weights"
+ bl_label = "Field Weights"
+ bl_parent_id = "SCENE_PT_rigid_body_world"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'}
@@ -446,6 +476,24 @@ class SCENE_PT_viewport_display(SceneButtonsPanel, Panel):
col.prop(scene.display, "shadow_shift")
+class SCENE_PT_viewport_display_ssao(SceneButtonsPanel, Panel):
+ bl_label = "Screen Space Ambient Occlusion"
+ bl_parent_id = "SCENE_PT_viewport_display"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ scene = context.scene
+ col = layout.column()
+ col.prop(scene.display, "matcap_ssao_samples")
+ col.prop(scene.display, "matcap_ssao_distance")
+ col.prop(scene.display, "matcap_ssao_attenuation")
+
+
class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
_context_path = "scene"
@@ -460,7 +508,9 @@ classes = (
SCENE_PT_keying_sets,
SCENE_PT_keying_set_paths,
SCENE_PT_color_management,
+ SCENE_PT_color_management_curves,
SCENE_PT_viewport_display,
+ SCENE_PT_viewport_display_ssao,
SCENE_PT_audio,
SCENE_PT_physics,
SCENE_PT_rigid_body_world,
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index b7dc8ec9d4e..55a087a8310 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -59,6 +59,7 @@ class TEXTURE_UL_texslots(UIList):
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
+
def context_tex_datablock(context):
idblock = context.brush
if idblock:
@@ -106,6 +107,7 @@ class TEXTURE_PT_preview(TextureButtonsPanel, Panel):
if isinstance(idblock, Brush):
layout.prop(tex, "use_preview_alpha")
+
class TEXTURE_PT_context(TextureButtonsPanel, Panel):
bl_label = ""
bl_context = "texture"
diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py
index 3c8552c3407..013fac3c099 100644
--- a/release/scripts/startup/bl_ui/properties_view_layer.py
+++ b/release/scripts/startup/bl_ui/properties_view_layer.py
@@ -43,7 +43,7 @@ class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel):
rd = scene.render
layer = bpy.context.view_layer
- layout.prop(layer, "use", text="Use for Rendering");
+ layout.prop(layer, "use", text="Use for Rendering")
layout.prop(rd, "use_single_layer", text="Render Single Layer")
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index a3dc401b484..40009090231 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -1018,9 +1018,11 @@ class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel):
if clip.use_proxy_custom_directory:
col.prop(clip.proxy, "directory")
- col.operator("clip.rebuild_proxy",
- text="Build Proxy / Timecode" if clip.source == 'MOVIE'
- else "Build Proxy")
+ col.operator(
+ "clip.rebuild_proxy",
+ text="Build Proxy / Timecode" if clip.source == 'MOVIE'
+ else "Build Proxy"
+ )
if clip.source == 'MOVIE':
col2 = col.column()
@@ -1189,6 +1191,7 @@ class CLIP_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
class CLIP_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
bl_space_type = 'CLIP_EDITOR'
+
class CLIP_MT_view(Menu):
bl_label = "View"
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index f3841de3ba4..0dbb3f53332 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -118,7 +118,7 @@ class DOPESHEET_HT_header(Header):
row = layout.row(align=True)
row.template_header()
-
+
# XXX: perhaps our mode menu can be retired eventually when we get editor submodes in the main menu?
layout.prop(st, "mode", text="")
@@ -425,11 +425,11 @@ class DOPESHEET_MT_gpencil_channel(Menu):
layout.operator("anim.channels_editable_toggle")
# XXX: to be enabled when these are ready for use!
- #layout.separator()
- #layout.operator("anim.channels_expand")
- #layout.operator("anim.channels_collapse")
+ # layout.separator()
+ # layout.operator("anim.channels_expand")
+ # layout.operator("anim.channels_collapse")
- #layout.separator()
+ # layout.separator()
#layout.operator_menu_enum("anim.channels_move", "direction", text="Move...")
@@ -450,9 +450,9 @@ class DOPESHEET_MT_gpencil_frame(Menu):
layout.separator()
layout.operator("action.keyframe_type")
- #layout.separator()
- #layout.operator("action.copy")
- #layout.operator("action.paste")
+ # layout.separator()
+ # layout.operator("action.copy")
+ # layout.operator("action.paste")
class DOPESHEET_MT_delete(Menu):
@@ -469,6 +469,66 @@ class DOPESHEET_MT_delete(Menu):
layout.operator("action.clean", text="Clean Channels").channels = True
+class DOPESHEET_MT_specials(Menu):
+ bl_label = "Dope Sheet Context Menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("action.copy", text="Copy")
+ layout.operator("action.paste", text="Paste")
+ layout.operator("action.paste", text="Paste Flipped").flipped = True
+
+ layout.separator()
+
+ layout.operator_menu_enum("action.handle_type", "type", text="Handle Type")
+ layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode")
+ layout.operator_menu_enum("action.easing_type", "type", text="Easing Type")
+
+ layout.separator()
+
+ layout.operator("action.keyframe_insert").type = 'SEL'
+ layout.operator("action.duplicate_move")
+ layout.operator("action.delete")
+
+ layout.separator()
+
+ layout.operator_menu_enum("action.mirror", "type", text="Mirror")
+ layout.operator_menu_enum("action.snap", "type", text="Snap")
+
+
+class DOPESHEET_MT_channel_specials(Menu):
+ bl_label = "Dope Sheet Channel Context Menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("anim.channels_setting_enable", text="Mute Channels").type = 'MUTE'
+ layout.operator("anim.channels_setting_disable", text="Unmute Channels").type = 'MUTE'
+ layout.separator()
+ layout.operator("anim.channels_setting_enable", text="Protect Channels").type = 'PROTECT'
+ layout.operator("anim.channels_setting_disable", text="Unprotect Channels").type = 'PROTECT'
+
+ layout.separator()
+ layout.operator("anim.channels_group")
+ layout.operator("anim.channels_ungroup")
+
+ layout.separator()
+ layout.operator("anim.channels_editable_toggle")
+ layout.operator_menu_enum("action.extrapolation_type", "type", text="Extrapolation Mode")
+
+ layout.separator()
+ layout.operator("anim.channels_expand")
+ layout.operator("anim.channels_collapse")
+
+ layout.separator()
+ layout.operator_menu_enum("anim.channels_move", "direction", text="Move...")
+
+ layout.separator()
+
+ layout.operator("anim.channels_delete")
+
+
classes = (
DOPESHEET_HT_header,
DOPESHEET_HT_editor_buttons,
@@ -482,6 +542,8 @@ classes = (
DOPESHEET_MT_gpencil_channel,
DOPESHEET_MT_gpencil_frame,
DOPESHEET_MT_delete,
+ DOPESHEET_MT_specials,
+ DOPESHEET_MT_channel_specials,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index 7e927bb6385..6e809c4e86a 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -299,6 +299,76 @@ class GRAPH_MT_delete(Menu):
layout.operator("graph.clean").channels = False
layout.operator("graph.clean", text="Clean Channels").channels = True
+
+class GRAPH_MT_specials(Menu):
+ bl_label = "F-Curve Context Menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("graph.copy", text="Copy")
+ layout.operator("graph.paste", text="Paste")
+ layout.operator("graph.paste", text="Paste Flipped").flipped = True
+
+ layout.separator()
+
+ layout.operator_menu_enum("graph.handle_type", "type", text="Handle Type")
+ layout.operator_menu_enum("graph.interpolation_type", "type", text="Interpolation Mode")
+ layout.operator_menu_enum("graph.easing_type", "type", text="Easing Type")
+
+ layout.separator()
+
+ layout.operator("graph.keyframe_insert").type = 'SEL'
+ layout.operator("graph.duplicate_move")
+ layout.operator("graph.delete")
+
+ layout.separator()
+
+ layout.operator_menu_enum("graph.mirror", "type", text="Mirror")
+ layout.operator_menu_enum("graph.snap", "type", text="Snap")
+
+
+class GRAPH_MT_channel_specials(Menu):
+ bl_label = "F-Curve Channel Context Menu"
+
+ def draw(self, context):
+ layout = self.layout
+ st = context.space_data
+
+ layout.separator()
+ layout.operator("anim.channels_setting_enable", text="Mute Channels").type = 'MUTE'
+ layout.operator("anim.channels_setting_disable", text="Unmute Channels").type = 'MUTE'
+ layout.separator()
+ layout.operator("anim.channels_setting_enable", text="Protect Channels").type = 'PROTECT'
+ layout.operator("anim.channels_setting_disable", text="Unprotect Channels").type = 'PROTECT'
+
+ layout.separator()
+ layout.operator("anim.channels_group")
+ layout.operator("anim.channels_ungroup")
+
+ layout.separator()
+ layout.operator("anim.channels_editable_toggle")
+ layout.operator_menu_enum("graph.extrapolation_type", "type", text="Extrapolation Mode")
+
+ layout.separator()
+ layout.operator("graph.hide", text="Hide Selected Curves").unselected = False
+ layout.operator("graph.hide", text="Hide Unselected Curves").unselected = True
+ layout.operator("graph.reveal")
+
+ layout.separator()
+ layout.operator("anim.channels_expand")
+ layout.operator("anim.channels_collapse")
+
+ layout.separator()
+ layout.operator_menu_enum("anim.channels_move", "direction", text="Move...")
+
+ layout.separator()
+
+ layout.operator("anim.channels_delete")
+ if st.mode == 'DRIVERS':
+ layout.operator("graph.driver_delete_invalid")
+
+
classes = (
GRAPH_HT_header,
GRAPH_MT_editor_menus,
@@ -309,6 +379,8 @@ classes = (
GRAPH_MT_key,
GRAPH_MT_key_transform,
GRAPH_MT_delete,
+ GRAPH_MT_specials,
+ GRAPH_MT_channel_specials,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index b1ff1618d09..4b533d2f045 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -422,6 +422,43 @@ class IMAGE_MT_uvs_select_mode(Menu):
props.data_path = "tool_settings.uv_select_mode"
+class IMAGE_MT_specials(Menu):
+ bl_label = "UV Context Menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ sima = context.space_data
+
+ # UV Edit Mode
+ if sima.show_uvedit:
+ layout.operator("uv.unwrap")
+ layout.operator("uv.follow_active_quads")
+
+ layout.separator()
+
+ layout.operator("uv.pin").clear = False
+ layout.operator("uv.pin", text="Unpin").clear = True
+
+ layout.separator()
+
+ layout.operator("uv.weld")
+ layout.operator("uv.stitch")
+
+ layout.separator()
+
+ layout.operator_enum("uv.align", "axis") # W, 2/3/4
+
+ layout.separator()
+
+ layout.operator("transform.mirror", text="Mirror X").constraint_axis[0] = True
+ layout.operator("transform.mirror", text="Mirror Y").constraint_axis[1] = True
+
+ layout.separator()
+
+ layout.menu("IMAGE_MT_uvs_snap")
+
+
class IMAGE_HT_header(Header):
bl_space_type = 'IMAGE_EDITOR'
@@ -584,6 +621,7 @@ class IMAGE_PT_tools_mask(MASK_PT_tools, Panel):
bl_region_type = 'TOOLS'
bl_category = 'Mask'
+
class IMAGE_PT_tools_mask_add(MASK_PT_add, Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
@@ -1127,8 +1165,6 @@ class IMAGE_PT_uv_sculpt(Panel, ImagePaintPanel):
col.prop(uvsculpt, "show_brush")
-
-
class IMAGE_PT_options_uvs(Panel, UVToolsPanel):
bl_label = "UV Options"
bl_category = "Options"
@@ -1308,6 +1344,7 @@ classes = (
IMAGE_MT_uvs_mirror,
IMAGE_MT_uvs_weldalign,
IMAGE_MT_uvs_select_mode,
+ IMAGE_MT_specials,
IMAGE_HT_header,
MASK_MT_editor_menus,
IMAGE_PT_mask,
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 0963613af5c..bf3fa64a852 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -290,6 +290,41 @@ class NODE_MT_node_color_specials(Menu):
layout.operator("node.node_copy_color", icon='COPY_ID')
+class NODE_MT_specials(Menu):
+ bl_label = "Node Context Menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator_context = 'INVOKE_DEFAULT'
+ layout.operator("node.duplicate_move")
+ layout.operator("node.delete")
+ layout.operator_context = 'EXEC_DEFAULT'
+
+ layout.operator("node.delete_reconnect")
+
+ layout.separator()
+
+ layout.operator("node.link_make").replace = False
+ layout.operator("node.link_make", text="Make and Replace Links").replace = True
+ layout.operator("node.links_detach")
+
+ layout.separator()
+
+ layout.operator("node.group_make", text="Group")
+ layout.operator("node.group_ungroup", text="Ungroup")
+ layout.operator("node.group_edit").exit = False
+
+ layout.separator()
+
+ layout.operator("node.hide_toggle")
+ layout.operator("node.mute_toggle")
+ layout.operator("node.preview_toggle")
+ layout.operator("node.hide_socket_toggle")
+ layout.operator("node.options_toggle")
+ layout.operator("node.collapse_hide_unused_toggle")
+
+
class NODE_PT_active_node_generic(Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
@@ -507,11 +542,15 @@ class NODE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
bl_region_type = 'TOOLS'
# Grease Pencil drawing brushes
+
+
class NODE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'TOOLS'
# Grease Pencil drawing curves
+
+
class NODE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'TOOLS'
@@ -522,6 +561,7 @@ class NODE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Pane
def node_draw_tree_view(layout, context):
pass
+
classes = (
NODE_HT_header,
NODE_MT_editor_menus,
@@ -531,6 +571,7 @@ classes = (
NODE_MT_node,
NODE_MT_node_color_presets,
NODE_MT_node_color_specials,
+ NODE_MT_specials,
NODE_PT_active_node_generic,
NODE_PT_active_node_color,
NODE_PT_active_node_properties,
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 8b8526cf9f2..12cff72b61a 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -179,7 +179,7 @@ class OUTLINER_MT_collection(Menu):
layout.operator("outliner.collection_instance", text="Instance to Scene")
if space.display_mode != 'VIEW_LAYER':
layout.operator("outliner.collection_link", text="Link to Scene")
- layout.operator("outliner.id_operation", text="Unlink").type='UNLINK'
+ layout.operator("outliner.id_operation", text="Unlink").type = 'UNLINK'
if space.display_mode == 'VIEW_LAYER':
layout.separator()
@@ -206,20 +206,20 @@ class OUTLINER_MT_object(Menu):
space = context.space_data
- layout.operator("outliner.object_operation", text="Delete").type='DELETE'
+ layout.operator("outliner.object_operation", text="Delete").type = 'DELETE'
if space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection:
- layout.operator("outliner.object_operation", text="Delete Hierarchy").type='DELETE_HIERARCHY'
+ layout.operator("outliner.object_operation", text="Delete Hierarchy").type = 'DELETE_HIERARCHY'
layout.separator()
- layout.operator("outliner.object_operation", text="Select").type='SELECT'
- layout.operator("outliner.object_operation", text="Select Hierarchy").type='SELECT_HIERARCHY'
- layout.operator("outliner.object_operation", text="Deselect").type='DESELECT'
+ layout.operator("outliner.object_operation", text="Select").type = 'SELECT'
+ layout.operator("outliner.object_operation", text="Select Hierarchy").type = 'SELECT_HIERARCHY'
+ layout.operator("outliner.object_operation", text="Deselect").type = 'DESELECT'
layout.separator()
if not (space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection):
- layout.operator("outliner.id_operation", text="Unlink").type='UNLINK'
+ layout.operator("outliner.id_operation", text="Unlink").type = 'UNLINK'
layout.separator()
layout.operator_menu_enum("outliner.id_operation", 'type', text="ID Data")
diff --git a/release/scripts/startup/bl_ui/space_properties.py b/release/scripts/startup/bl_ui/space_properties.py
index cd7137e0254..2d1725b2087 100644
--- a/release/scripts/startup/bl_ui/space_properties.py
+++ b/release/scripts/startup/bl_ui/space_properties.py
@@ -32,8 +32,7 @@ class PROPERTIES_HT_header(Header):
row = layout.row()
row.template_header()
- if view.mode == 'DATA_PROPERTIES':
- row.prop(view, "context", expand=True, icon_only=True)
+ row.prop(view, "context", expand=True, icon_only=True)
classes = (
diff --git a/release/scripts/startup/bl_ui/space_statusbar.py b/release/scripts/startup/bl_ui/space_statusbar.py
index 983b474d18b..3a6fc4925d8 100644
--- a/release/scripts/startup/bl_ui/space_statusbar.py
+++ b/release/scripts/startup/bl_ui/space_statusbar.py
@@ -73,7 +73,6 @@ class STATUSBAR_HT_header(Header):
return
-
classes = (
STATUSBAR_HT_header,
)
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index 48ac85f0d0e..7c584b3177b 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -117,6 +117,7 @@ class TIME_MT_editor_menus(Menu):
panel_type="TIME_PT_keyframing_settings",
text="Keying")
+
class TIME_MT_marker(Menu):
bl_label = "Marker"
@@ -217,6 +218,7 @@ def marker_menu_generic(layout):
###################################
+
class TimelinePanelButtons:
bl_space_type = 'DOPESHEET_EDITOR'
bl_region_type = 'UI'
@@ -292,7 +294,7 @@ class TIME_PT_keyframing_settings(TimelinePanelButtons, Panel):
col = layout.column(align=True)
col.label("New Keyframe Type:")
col.prop(toolsettings, "keyframe_type", text="")
-
+
col = layout.column(align=True)
col.label("Auto Keyframing:")
row = col.row()
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index cb6d3851d02..2b9d4207272 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -339,9 +339,7 @@ class ToolSelectPanelHelper:
# - None: Signal to finish (complete any final operations, e.g. add padding).
@staticmethod
- def _layout_generator_single_column(layout):
- scale_y = 2.0
-
+ def _layout_generator_single_column(layout, scale_y):
col = layout.column(align=True)
col.scale_y = scale_y
is_sep = False
@@ -355,9 +353,8 @@ class ToolSelectPanelHelper:
is_sep = yield col
@staticmethod
- def _layout_generator_multi_columns(layout, column_count):
- scale_y = 2.0
- scale_x = 2.2
+ def _layout_generator_multi_columns(layout, column_count, scale_y):
+ scale_x = scale_y * 1.1
column_last = column_count - 1
col = layout.column(align=True)
@@ -394,7 +391,7 @@ class ToolSelectPanelHelper:
column_index += 1
@staticmethod
- def _layout_generator_detect_from_region(layout, region):
+ def _layout_generator_detect_from_region(layout, region, scale_y):
"""
Choose an appropriate layout for the toolbar.
"""
@@ -421,15 +418,14 @@ class ToolSelectPanelHelper:
column_count = 1
if column_count == 1:
- ui_gen = ToolSelectPanelHelper._layout_generator_single_column(layout)
+ ui_gen = ToolSelectPanelHelper._layout_generator_single_column(layout, scale_y=scale_y)
else:
- ui_gen = ToolSelectPanelHelper._layout_generator_multi_columns(layout, column_count=column_count)
+ ui_gen = ToolSelectPanelHelper._layout_generator_multi_columns(layout, column_count=column_count, scale_y=scale_y)
return ui_gen, show_text
-
@classmethod
- def draw_cls(cls, layout, context, detect_layout=True):
+ def draw_cls(cls, layout, context, detect_layout=True, scale_y=2.0):
# Use a classmethod so it can be called outside of a panel context.
# XXX, this UI isn't very nice.
@@ -445,9 +441,9 @@ class ToolSelectPanelHelper:
)
if detect_layout:
- ui_gen, show_text = cls._layout_generator_detect_from_region(layout, context.region)
+ ui_gen, show_text = cls._layout_generator_detect_from_region(layout, context.region, scale_y)
else:
- ui_gen = ToolSelectPanelHelper._layout_generator_single_column(layout)
+ ui_gen = ToolSelectPanelHelper._layout_generator_single_column(layout, scale_y)
show_text = True
# Start iteration
@@ -676,6 +672,7 @@ def keymap_from_context(context, space_type):
wm.keyconfigs.update()
return keymap
+
classes = (
WM_MT_toolsystem_submenu,
)
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 42fac9e03a4..da86c1c03bc 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -91,7 +91,7 @@ class _defs_view3d_generic:
("transform.translate",
dict(release_confirm=True, cursor_transform=True),
dict(type='EVT_TWEAK_A', value='ANY'),
- ),
+ ),
),
)
@@ -292,7 +292,6 @@ class _defs_edit_armature:
class _defs_edit_mesh:
-
@ToolDef.from_fn
def cube_add():
return dict(
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py
index 243b36bdeb7..c231d05ecdb 100644
--- a/release/scripts/startup/bl_ui/space_topbar.py
+++ b/release/scripts/startup/bl_ui/space_topbar.py
@@ -141,7 +141,7 @@ class TOPBAR_HT_lower_bar(Header):
elif mode == 'POSE':
pass
elif mode == 'PARTICLE':
- pass
+ layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="")
def draw_right(self, context):
layout = self.layout
@@ -610,6 +610,11 @@ class INFO_MT_edit(Menu):
layout.separator()
+ layout.operator("screen.repeat_last")
+ layout.operator("screen.repeat_history")
+
+ layout.separator()
+
layout.operator("screen.userpref_show", text="User Preferences...", icon='PREFERENCES')
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 1e090884fd1..a480fa433e1 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -22,6 +22,7 @@ from bpy.types import (
Header,
Menu,
Panel,
+ Operator,
)
from bpy.app.translations import pgettext_iface as iface_
from bpy.app.translations import contexts as i18n_contexts
@@ -71,6 +72,10 @@ class USERPREF_HT_header(Header):
layout.operator("wm.addon_install", icon='FILESEL')
layout.operator("wm.addon_refresh", icon='FILE_REFRESH')
layout.menu("USERPREF_MT_addons_online_resources")
+ elif userpref.active_section == 'LIGHTS':
+ layout.operator('wm.studiolight_install', text="Install MatCap").orientation='MATCAP'
+ layout.operator('wm.studiolight_install', text="Install World HDRI").orientation='WORLD'
+ layout.operator('wm.studiolight_install', text="Install Camera HDRI").orientation='CAMERA'
elif userpref.active_section == 'THEMES':
layout.operator("ui.reset_default_theme")
layout.operator("wm.theme_install")
@@ -141,7 +146,6 @@ class USERPREF_MT_app_templates(Menu):
layout.operator_context = 'INVOKE_DEFAULT'
props = layout.operator("wm.app_template_install")
-
def draw(self, context):
self.draw_ex(context, use_splash=False, use_default=True, use_install=True)
@@ -282,14 +286,14 @@ class USERPREF_PT_interface(Panel):
row.separator()
col = row.column()
- #Toolbox doesn't exist yet
- #col.label(text="Toolbox:")
+ # Toolbox doesn't exist yet
+ # col.label(text="Toolbox:")
#col.prop(view, "show_column_layout")
#col.label(text="Open Toolbox Delay:")
#col.prop(view, "open_left_mouse_delay", text="Hold LMB")
#col.prop(view, "open_right_mouse_delay", text="Hold RMB")
col.prop(view, "show_manipulator")
- ## Currently not working
+ # Currently not working
# col.prop(view, "show_manipulator_shaded")
sub = col.column()
sub.active = view.show_manipulator
@@ -328,7 +332,6 @@ class USERPREF_PT_interface(Panel):
col.prop(view, "show_view3d_cursor")
-
class USERPREF_PT_edit(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Edit"
@@ -412,7 +415,7 @@ class USERPREF_PT_edit(Panel):
sub = col.column()
- #~ sub.active = edit.use_keyframe_insert_auto # incorrect, time-line can enable
+ # ~ sub.active = edit.use_keyframe_insert_auto # incorrect, time-line can enable
sub.prop(edit, "use_keyframe_insert_available", text="Only Insert Available")
col.separator()
@@ -1217,7 +1220,7 @@ class USERPREF_PT_input(Panel):
#sub.prop(inputs, "use_mouse_mmb_paste")
- #col.separator()
+ # col.separator()
sub = col.column()
sub.prop(inputs, "invert_zoom_wheel", text="Invert Wheel Zoom Direction")
@@ -1332,7 +1335,7 @@ class USERPREF_PT_addons(Panel):
'OFFICIAL': 'FILE_BLEND',
'COMMUNITY': 'POSE_DATA',
'TESTING': 'MOD_EXPLODE',
- }
+ }
@classmethod
def poll(cls, context):
@@ -1410,7 +1413,6 @@ class USERPREF_PT_addons(Panel):
sub_col.label(" " + addon_file)
sub_col.label(" " + addon_path)
-
if addon_utils.error_encoding:
self.draw_error(
col,
@@ -1435,11 +1437,11 @@ class USERPREF_PT_addons(Panel):
# check if addon should be visible with current filters
if ((filter == "All") or
- (filter == info["category"]) or
- (filter == "Enabled" and is_enabled) or
- (filter == "Disabled" and not is_enabled) or
- (filter == "User" and (mod.__file__.startswith((scripts_addons_folder, userpref_addons_folder))))
- ):
+ (filter == info["category"]) or
+ (filter == "Enabled" and is_enabled) or
+ (filter == "Disabled" and not is_enabled) or
+ (filter == "User" and (mod.__file__.startswith((scripts_addons_folder, userpref_addons_folder))))
+ ):
if search and search not in info["name"].lower():
if info["author"]:
if search not in info["author"].lower():
@@ -1573,6 +1575,60 @@ class USERPREF_PT_addons(Panel):
row.label(text=module_name, translate=False)
+class StudioLightPanelMixin():
+ bl_space_type = 'USER_PREFERENCES'
+ bl_region_type = 'WINDOW'
+
+ @classmethod
+ def poll(cls, context):
+ userpref = context.user_preferences
+ return (userpref.active_section == 'LIGHTS')
+
+ def _get_lights(self, userpref):
+ return [light for light in userpref.studio_lights if light.is_user_defined and light.orientation == self.sl_orientation]
+
+ def draw_header(self, context):
+ layout = self.layout
+ row = layout.row()
+ userpref = context.user_preferences
+ lights = self._get_lights(userpref)
+ row.label("({})".format(len(lights)))
+
+ def draw(self, context):
+ layout = self.layout
+ userpref = context.user_preferences
+ lights = self._get_lights(userpref)
+ if lights:
+ flow = layout.column_flow(4)
+ for studio_light in lights:
+ self.draw_studio_light(flow, studio_light)
+ else:
+ layout.label("No custom {} configured".format(self.bl_label))
+
+ def draw_studio_light(self, layout, studio_light):
+ box = layout.box()
+ row = box.row()
+
+ row.template_icon_view(studio_light, "icon_id")
+ op = row.operator('wm.studiolight_uninstall', text="", icon='ZOOMOUT')
+ op.index = studio_light.index
+
+
+class USERPREF_PT_studiolight_matcaps(Panel, StudioLightPanelMixin):
+ bl_label = "MatCaps"
+ sl_orientation = 'MATCAP'
+
+
+class USERPREF_PT_studiolight_world(Panel, StudioLightPanelMixin):
+ bl_label = "World HDRI"
+ sl_orientation = 'WORLD'
+
+
+class USERPREF_PT_studiolight_camera(Panel, StudioLightPanelMixin):
+ bl_label = "Camera HDRI"
+ sl_orientation = 'CAMERA'
+
+
classes = (
USERPREF_HT_header,
USERPREF_PT_tabs,
@@ -1593,6 +1649,9 @@ classes = (
USERPREF_PT_input,
USERPREF_MT_addons_online_resources,
USERPREF_PT_addons,
+ USERPREF_PT_studiolight_matcaps,
+ USERPREF_PT_studiolight_world,
+ USERPREF_PT_studiolight_camera,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 4f3396c9ed8..3a8fb3ce2f0 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1483,7 +1483,7 @@ class VIEW3D_MT_object_clear(Menu):
class VIEW3D_MT_object_specials(Menu):
- bl_label = "Context Menu"
+ bl_label = "Object Context Menu"
@classmethod
def poll(cls, context):
@@ -2113,7 +2113,7 @@ class VIEW3D_MT_particle(Menu):
class VIEW3D_MT_particle_specials(Menu):
- bl_label = "Context Menu"
+ bl_label = "Particle Context Menu"
def draw(self, context):
layout = self.layout
@@ -2363,7 +2363,7 @@ class VIEW3D_MT_pose_apply(Menu):
class VIEW3D_MT_pose_specials(Menu):
- bl_label = "Context Menu"
+ bl_label = "Pose Context Menu"
def draw(self, context):
layout = self.layout
@@ -2496,7 +2496,7 @@ class VIEW3D_MT_edit_mesh(Menu):
class VIEW3D_MT_edit_mesh_specials(Menu):
- bl_label = "Context Menu"
+ bl_label = "Mesh Context Menu"
def draw(self, context):
layout = self.layout
@@ -3030,7 +3030,7 @@ class VIEW3D_MT_edit_curve_clean(Menu):
class VIEW3D_MT_edit_curve_specials(Menu):
- bl_label = "Context Menu"
+ bl_label = "Curve Context Menu"
def draw(self, context):
layout = self.layout
@@ -3244,7 +3244,7 @@ class VIEW3D_MT_edit_armature(Menu):
class VIEW3D_MT_armature_specials(Menu):
- bl_label = "Context Menu"
+ bl_label = "Armature Context Menu"
def draw(self, context):
layout = self.layout
@@ -3394,6 +3394,28 @@ class VIEW3D_MT_edit_gpencil_interpolate(Menu):
layout.operator("gpencil.interpolate_sequence", text="Sequence")
+class VIEW3D_PIE_object_mode(Menu):
+ bl_label = "Mode"
+
+ def draw(self, context):
+ layout = self.layout
+
+ pie = layout.menu_pie()
+ pie.operator_enum("OBJECT_OT_mode_set", "mode")
+
+
+class VIEW3D_PIE_view(Menu):
+ bl_label = "View"
+ bl_idname = "VIEW3D_PIE_view"
+
+ def draw(self, context):
+ layout = self.layout
+
+ pie = layout.menu_pie()
+ pie.operator_enum("VIEW3D_OT_viewnumpad", "type")
+ pie.operator("view3d.view_selected", text="View Selected", icon='ZOOM_SELECTED')
+
+
# ********** Panel **********
@@ -3476,31 +3498,6 @@ class VIEW3D_PT_view3d_cursor(Panel):
layout.column().prop(view, "cursor_location", text="Location")
-class VIEW3D_PT_view3d_name(Panel):
- bl_space_type = 'VIEW_3D'
- bl_region_type = 'UI'
- bl_label = "Item"
-
- @classmethod
- def poll(cls, context):
- return (context.space_data and context.active_object)
-
- def draw(self, context):
- layout = self.layout
-
- ob = context.active_object
- row = layout.row()
- row.label(text="", icon='OBJECT_DATA')
- row.prop(ob, "name", text="")
-
- if ob.type == 'ARMATURE' and ob.mode in {'EDIT', 'POSE'}:
- bone = context.active_bone
- if bone:
- row = layout.row()
- row.label(text="", icon='BONE_DATA')
- row.prop(bone, "name", text="")
-
-
class VIEW3D_PT_shading(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
@@ -3517,48 +3514,72 @@ class VIEW3D_PT_shading(Panel):
shading = view.shading
col = layout.column()
-
- if shading.type == 'SOLID':
- col.row().prop(shading, "color_type", expand=True)
-
- if shading.color_type == 'SINGLE':
- col.row().prop(shading, "single_color", text="")
-
+ col.row().label("Lighting")
if shading.type in ('SOLID', 'TEXTURED'):
col.row().prop(shading, "light", expand=True)
if shading.light == 'STUDIO':
- col.row().template_icon_view(shading, "studio_light")
+ row = col.row()
+ row.template_icon_view(shading, "studio_light")
+ row.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='ZOOMIN')
if shading.studio_light_orientation == 'WORLD':
col.row().prop(shading, "studiolight_rot_z")
- row = col.row()
- row.prop(shading, "show_specular_highlight")
+ elif shading.light == 'MATCAP':
+ row = col.row()
+ row.template_icon_view(shading, "matcap")
+ sub = row.column()
+ sub.operator('VIEW3D_OT_toggle_matcap_flip', emboss=False, text="", icon='ARROW_LEFTRIGHT')
+ sub.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='ZOOMIN')
+ if shading.type == 'SOLID':
col.separator()
+ col.row().label("Color")
+ col.row().prop(shading, "color_type", expand=True)
- row = col.row()
- row.prop(shading, "show_xray")
- sub = row.row()
- sub.active = shading.show_xray
- sub.prop(shading, "xray_alpha", text="")
-
- row = col.row()
- row.active = not shading.show_xray
- row.prop(shading, "show_shadows")
- sub = row.row()
- sub.active = shading.show_shadows and not shading.show_xray
- sub.prop(shading, "shadow_intensity", text="")
+ if shading.color_type == 'SINGLE':
+ col.row().prop(shading, "single_color", text="")
- row = col.row()
- row.prop(shading, "show_object_outline")
- sub = row.row()
- sub.active = shading.show_object_outline
- sub.prop(shading, "object_outline_color", text="")
+ if shading.type in ('SOLID', 'TEXTURED'):
+ col.separator()
- col.prop(view, "show_world")
+ if not shading.light == 'MATCAP':
+ row = col.row()
+ row.prop(shading, "show_specular_highlight")
+
+ if shading.type in ('SOLID', 'TEXTURED'):
+ row = col.split(0.4)
+ row.prop(shading, "show_xray")
+ sub = row.row()
+ sub.active = shading.show_xray
+ sub.prop(shading, "xray_alpha", text="")
+
+ row = col.split(0.4)
+ row.active = not shading.show_xray
+ row.prop(shading, "show_shadows")
+ sub = row.row()
+ sub.active = shading.show_shadows and not shading.show_xray
+ sub.prop(shading, "shadow_intensity", text="")
+
+ row = col.split(0.4)
+ row.active = not shading.show_xray
+ row.prop(shading, "show_cavity")
+ sub = row.column(align=True)
+ sub.active = not shading.show_xray and shading.show_cavity
+ sub.prop(shading, "cavity_ridge_factor")
+ sub.prop(shading, "cavity_valley_factor")
+
+ row = col.split(0.4)
+ row.prop(shading, "show_object_outline")
+ sub = row.row()
+ sub.active = shading.show_object_outline
+ sub.prop(shading, "object_outline_color", text="")
+
+ col.prop(view, "show_world")
elif shading.type in ('MATERIAL'):
- col.row().template_icon_view(shading, "studio_light")
+ row = col.row()
+ row.template_icon_view(shading, "studio_light")
+ op = row.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='ZOOMIN')
if shading.studio_light_orientation == 'WORLD':
col.row().prop(shading, "studiolight_rot_z")
col.row().prop(shading, "studiolight_background")
@@ -3580,7 +3601,6 @@ class VIEW3D_PT_overlay(Panel):
view = context.space_data
shading = view.shading
overlay = view.overlay
- scene = context.scene
toolsettings = context.tool_settings
display_all = overlay.show_overlays
@@ -3596,7 +3616,13 @@ class VIEW3D_PT_overlay(Panel):
col.prop(overlay, "show_relationship_lines")
col.prop(overlay, "show_motion_paths")
col.prop(overlay, "show_face_orientation")
- col.prop(overlay, "show_wireframes")
+
+ row = col.row()
+ row.prop(overlay, "show_wireframes")
+ sub = row.row()
+ sub.active = overlay.show_wireframes
+ sub.prop(overlay, "wireframe_threshold", text="")
+
col.prop(overlay, "show_backface_culling")
if shading.type == "MATERIAL":
@@ -3616,12 +3642,27 @@ class VIEW3D_PT_overlay(Panel):
sub.active = bool(overlay.show_floor or view.region_quadviews or not view.region_3d.is_perspective)
subsub = sub.column(align=True)
subsub.active = overlay.show_floor
- sub.prop(overlay, "grid_scale", text="Scale")
- sub.prop(overlay, "grid_subdivisions", text="Subdivisions")
+ subsub.prop(overlay, "grid_scale", text="Scale")
+ subsub.prop(overlay, "grid_subdivisions", text="Subdivisions")
+
+ col.prop(view, "show_reconstruction", text="Motion Tracking")
+ sub = col.column(align=True)
+
+ sub.active = view.show_reconstruction
+ sub.prop(view, "show_camera_path", text="Camera Path")
+ sub.prop(view, "show_bundle_names", text="3D Marker Names")
+ sub.label(text="Track Type and Size:")
+ row = sub.row(align=True)
+ row.prop(view, "tracks_draw_type", text="")
+ row.prop(view, "tracks_draw_size", text="")
+ col.separator()
if context.mode == 'EDIT_MESH':
+ data = context.active_object.data
+ statvis = context.tool_settings.statvis
+ with_freestyle = bpy.app.build_options.freestyle
col.separator()
- col.label(text="Edit Mode:")
+ col.label(text="Edit Mesh:")
col.prop(overlay, "show_occlude_wire")
@@ -3640,6 +3681,72 @@ class VIEW3D_PT_overlay(Panel):
sub.active = overlay.show_vertex_normals or overlay.show_face_normals or overlay.show_split_normals
sub.prop(overlay, "normals_length", text="Size")
+ split = col.split()
+
+ sub = split.column()
+ sub.prop(data, "show_faces", text="Faces")
+ sub.prop(data, "show_edges", text="Edges")
+ sub.prop(data, "show_edge_crease", text="Creases")
+
+ if with_freestyle:
+ sub.prop(data, "show_edge_seams", text="Seams")
+
+ sub = split.column()
+ if not with_freestyle:
+ sub.prop(data, "show_edge_seams", text="Seams")
+ sub.prop(data, "show_edge_sharp", text="Sharp", text_ctxt=i18n_contexts.plural)
+ col.prop(data, "show_edge_bevel_weight", text="Bevel")
+ if with_freestyle:
+ sub.prop(data, "show_freestyle_edge_marks", text="Edge Marks")
+ sub.prop(data, "show_freestyle_face_marks", text="Face Marks")
+
+ col.separator()
+ split = col.split()
+ sub = split.column()
+ sub.label(text="Edge Info:")
+ sub.prop(data, "show_extra_edge_length", text="Length")
+ sub.prop(data, "show_extra_edge_angle", text="Angle")
+ sub = split.column()
+ sub.label(text="Face Info:")
+ sub.prop(data, "show_extra_face_area", text="Area")
+ sub.prop(data, "show_extra_face_angle", text="Angle")
+ if bpy.app.debug:
+ sub.prop(data, "show_extra_indices", text="Indices")
+
+ col.prop(data, "show_statvis", text="Mesh Analysis")
+ sub = col.column()
+ sub.active = data.show_statvis
+ sub.prop(statvis, "type")
+ statvis_type = statvis.type
+ if statvis_type == 'OVERHANG':
+ row = sub.row(align=True)
+ row.prop(statvis, "overhang_min", text="")
+ row.prop(statvis, "overhang_max", text="")
+ layout.row().prop(statvis, "overhang_axis", expand=True)
+ elif statvis_type == 'THICKNESS':
+ row = sub.row(align=True)
+ row.prop(statvis, "thickness_min", text="")
+ row.prop(statvis, "thickness_max", text="")
+ layout.prop(statvis, "thickness_samples")
+ elif statvis_type == 'INTERSECT':
+ pass
+ elif statvis_type == 'DISTORT':
+ row = sub.row(align=True)
+ row.prop(statvis, "distort_min", text="")
+ row.prop(statvis, "distort_max", text="")
+ elif statvis_type == 'SHARP':
+ row = sub.row(align=True)
+ row.prop(statvis, "sharp_min", text="")
+ row.prop(statvis, "sharp_max", text="")
+
+ elif context.mode == 'EDIT_CURVE':
+ data = context.active_object.data
+ col.separator()
+ col.label(text="Edit Curve:")
+ row = col.row()
+ row.prop(data, "show_handles", text="Handles")
+ row.prop(data, "show_normal_face", text="Normals")
+
elif context.mode == 'POSE':
col.separator()
col.label(text="Pose Mode:")
@@ -3647,7 +3754,11 @@ class VIEW3D_PT_overlay(Panel):
col = layout.column()
col.active = display_all
col.prop(overlay, "show_transparent_bones")
- col.prop(overlay, "show_bone_selection")
+ row = col.split(0.65)
+ row.prop(overlay, "show_bone_selection")
+ sub = row.column()
+ sub.active = display_all and overlay.show_bone_selection
+ sub.prop(overlay, "bone_selection_alpha", text="")
elif context.mode == 'EDIT_ARMATURE':
col.separator()
@@ -3734,157 +3845,6 @@ class VIEW3D_PT_view3d_stereo(Panel):
split.prop(view, "stereo_3d_volume_alpha", text="Alpha")
-class VIEW3D_PT_view3d_motion_tracking(Panel):
- bl_space_type = 'VIEW_3D'
- bl_region_type = 'UI'
- bl_label = "Motion Tracking"
- bl_options = {'DEFAULT_CLOSED'}
-
- @classmethod
- def poll(cls, context):
- view = context.space_data
- return (view)
-
- def draw_header(self, context):
- view = context.space_data
-
- self.layout.prop(view, "show_reconstruction", text="")
-
- def draw(self, context):
- layout = self.layout
-
- view = context.space_data
-
- col = layout.column()
- col.active = view.show_reconstruction
- col.prop(view, "show_camera_path", text="Camera Path")
- col.prop(view, "show_bundle_names", text="3D Marker Names")
- col.label(text="Track Type and Size:")
- row = col.row(align=True)
- row.prop(view, "tracks_draw_type", text="")
- row.prop(view, "tracks_draw_size", text="")
-
-
-class VIEW3D_PT_view3d_meshdisplay(Panel):
- bl_space_type = 'VIEW_3D'
- bl_region_type = 'UI'
- bl_label = "Mesh Display"
-
- @classmethod
- def poll(cls, context):
- # The active object check is needed because of local-mode
- return (context.active_object and (context.mode == 'EDIT_MESH'))
-
- def draw(self, context):
- layout = self.layout
- with_freestyle = bpy.app.build_options.freestyle
-
- mesh = context.active_object.data
- scene = context.scene
-
- split = layout.split()
-
- col = split.column()
- col.label(text="Overlays:")
- col.prop(mesh, "show_faces", text="Faces")
- col.prop(mesh, "show_edges", text="Edges")
- col.prop(mesh, "show_edge_crease", text="Creases")
- if with_freestyle:
- col.prop(mesh, "show_edge_seams", text="Seams")
-
- col = split.column()
- col.label()
- if not with_freestyle:
- col.prop(mesh, "show_edge_seams", text="Seams")
- col.prop(mesh, "show_edge_sharp", text="Sharp", text_ctxt=i18n_contexts.plural)
- col.prop(mesh, "show_edge_bevel_weight", text="Bevel")
- if with_freestyle:
- col.prop(mesh, "show_freestyle_edge_marks", text="Edge Marks")
- col.prop(mesh, "show_freestyle_face_marks", text="Face Marks")
-
- col = layout.column()
-
- col.separator()
- split = layout.split()
- col = split.column()
- col.label(text="Edge Info:")
- col.prop(mesh, "show_extra_edge_length", text="Length")
- col.prop(mesh, "show_extra_edge_angle", text="Angle")
- col = split.column()
- col.label(text="Face Info:")
- col.prop(mesh, "show_extra_face_area", text="Area")
- col.prop(mesh, "show_extra_face_angle", text="Angle")
- if bpy.app.debug:
- layout.prop(mesh, "show_extra_indices", text="Indices")
-
-
-class VIEW3D_PT_view3d_meshstatvis(Panel):
- bl_space_type = 'VIEW_3D'
- bl_region_type = 'UI'
- bl_label = "Mesh Analysis"
-
- @classmethod
- def poll(cls, context):
- # The active object check is needed because of local-mode
- return (context.active_object and (context.mode == 'EDIT_MESH'))
-
- def draw_header(self, context):
- mesh = context.active_object.data
-
- self.layout.prop(mesh, "show_statvis", text="")
-
- def draw(self, context):
- layout = self.layout
-
- mesh = context.active_object.data
- statvis = context.tool_settings.statvis
- layout.active = mesh.show_statvis
-
- layout.prop(statvis, "type")
- statvis_type = statvis.type
- if statvis_type == 'OVERHANG':
- row = layout.row(align=True)
- row.prop(statvis, "overhang_min", text="")
- row.prop(statvis, "overhang_max", text="")
- layout.row().prop(statvis, "overhang_axis", expand=True)
- elif statvis_type == 'THICKNESS':
- row = layout.row(align=True)
- row.prop(statvis, "thickness_min", text="")
- row.prop(statvis, "thickness_max", text="")
- layout.prop(statvis, "thickness_samples")
- elif statvis_type == 'INTERSECT':
- pass
- elif statvis_type == 'DISTORT':
- row = layout.row(align=True)
- row.prop(statvis, "distort_min", text="")
- row.prop(statvis, "distort_max", text="")
- elif statvis_type == 'SHARP':
- row = layout.row(align=True)
- row.prop(statvis, "sharp_min", text="")
- row.prop(statvis, "sharp_max", text="")
-
-
-class VIEW3D_PT_view3d_curvedisplay(Panel):
- bl_space_type = 'VIEW_3D'
- bl_region_type = 'UI'
- bl_label = "Curve Display"
-
- @classmethod
- def poll(cls, context):
- editmesh = context.mode == 'EDIT_CURVE'
- return (editmesh)
-
- def draw(self, context):
- layout = self.layout
-
- curve = context.active_object.data
-
- col = layout.column()
- row = col.row()
- row.prop(curve, "show_handles", text="Handles")
- row.prop(curve, "show_normal_face", text="Normals")
-
-
class VIEW3D_PT_transform_orientations(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@@ -4079,17 +4039,14 @@ classes = (
VIEW3D_MT_edit_armature_delete,
VIEW3D_MT_edit_gpencil_transform,
VIEW3D_MT_edit_gpencil_interpolate,
+ VIEW3D_PIE_object_mode,
+ VIEW3D_PIE_view,
VIEW3D_PT_grease_pencil,
VIEW3D_PT_grease_pencil_palettecolor,
VIEW3D_PT_view3d_properties,
VIEW3D_PT_view3d_cursor,
- VIEW3D_PT_view3d_name,
VIEW3D_PT_quad_view,
VIEW3D_PT_view3d_stereo,
- VIEW3D_PT_view3d_motion_tracking,
- VIEW3D_PT_view3d_meshdisplay,
- VIEW3D_PT_view3d_meshstatvis,
- VIEW3D_PT_view3d_curvedisplay,
VIEW3D_PT_shading,
VIEW3D_PT_overlay,
VIEW3D_PT_transform_orientations,
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index f6dc64c7df7..cb9ddd470ce 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -70,7 +70,7 @@ def draw_vpaint_symmetry(layout, vpaint):
class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
bl_category = "Options"
- bl_context = ".mesh_edit" # dot on purpose (access from topbar)
+ bl_context = ".mesh_edit" # dot on purpose (access from topbar)
bl_label = "Mesh Options"
@classmethod
@@ -101,9 +101,10 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
# ********** default tools for editmode_curve ****************
+
class VIEW3D_PT_tools_curveedit_options_stroke(View3DPanel, Panel):
bl_category = "Options"
- bl_context = ".curve_edit" # dot on purpose (access from topbar)
+ bl_context = ".curve_edit" # dot on purpose (access from topbar)
bl_label = "Curve Stroke"
def draw(self, context):
@@ -155,8 +156,6 @@ class VIEW3D_PT_tools_curveedit_options_stroke(View3DPanel, Panel):
colsub.prop(cps, "surface_plane", expand=True)
-
-
# ********** default tools for editmode_armature ****************
@@ -175,7 +174,7 @@ class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
bl_category = "Options"
- bl_context = ".posemode" # dot on purpose (access from topbar)
+ bl_context = ".posemode" # dot on purpose (access from topbar)
bl_label = "Pose Options"
def draw(self, context):
@@ -194,7 +193,7 @@ class View3DPaintPanel(UnifiedPaintPanel):
class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
bl_category = "Tools"
- bl_context = ".imagepaint" # dot on purpose (access from topbar)
+ bl_context = ".imagepaint" # dot on purpose (access from topbar)
bl_label = "Missing Data"
@classmethod
@@ -528,7 +527,7 @@ class VIEW3D_MT_tools_projectpaint_uvlayer(Menu):
class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
- bl_context = ".imagepaint" # dot on purpose (access from topbar)
+ bl_context = ".imagepaint" # dot on purpose (access from topbar)
bl_label = "Slots"
bl_category = "Slots"
@@ -589,7 +588,7 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
- bl_context = ".imagepaint" # dot on purpose (access from topbar)
+ bl_context = ".imagepaint" # dot on purpose (access from topbar)
bl_label = "Mask"
bl_category = "Slots"
@@ -723,7 +722,7 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
class VIEW3D_PT_tools_mask_texture(Panel, View3DPaintPanel):
bl_category = "Tools"
- bl_context = ".imagepaint" # dot on purpose (access from topbar)
+ bl_context = ".imagepaint" # dot on purpose (access from topbar)
bl_label = "Texture Mask"
bl_options = {'DEFAULT_CLOSED'}
@@ -886,11 +885,11 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
def draw_header(self, context):
layout = self.layout
layout.operator(
- "sculpt.dynamic_topology_toggle",
- icon='CHECKBOX_HLT' if context.sculpt_object.use_dynamic_topology_sculpting else 'CHECKBOX_DEHLT',
- text="",
- emboss=False,
- )
+ "sculpt.dynamic_topology_toggle",
+ icon='CHECKBOX_HLT' if context.sculpt_object.use_dynamic_topology_sculpting else 'CHECKBOX_DEHLT',
+ text="",
+ emboss=False,
+ )
def draw(self, context):
layout = self.layout
@@ -1124,7 +1123,7 @@ class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel):
bl_category = "Tools"
- bl_context = ".imagepaint" # dot on purpose (access from topbar)
+ bl_context = ".imagepaint" # dot on purpose (access from topbar)
bl_label = "External"
bl_options = {'DEFAULT_CLOSED'}
@@ -1146,7 +1145,7 @@ class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel):
class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel):
bl_category = "Tools"
- bl_context = ".imagepaint" # dot on purpose (access from topbar)
+ bl_context = ".imagepaint" # dot on purpose (access from topbar)
bl_label = "Symmetry"
bl_options = {'DEFAULT_CLOSED'}
@@ -1165,7 +1164,7 @@ class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel):
class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel):
bl_category = "Options"
- bl_context = ".imagepaint" # dot on purpose (access from topbar)
+ bl_context = ".imagepaint" # dot on purpose (access from topbar)
bl_label = "Project Paint"
@classmethod
@@ -1323,6 +1322,8 @@ class VIEW3D_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
bl_space_type = 'VIEW_3D'
# Grease Pencil drawingcurves
+
+
class VIEW3D_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
bl_space_type = 'VIEW_3D'
diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h
index 70250310213..08136fc2f49 100644
--- a/source/blender/alembic/ABC_alembic.h
+++ b/source/blender/alembic/ABC_alembic.h
@@ -29,8 +29,8 @@ extern "C" {
struct bContext;
struct CacheReader;
-struct DerivedMesh;
struct ListBase;
+struct Mesh;
struct Object;
struct Scene;
@@ -114,12 +114,13 @@ void ABC_get_transform(struct CacheReader *reader,
float time,
float scale);
-struct DerivedMesh *ABC_read_mesh(struct CacheReader *reader,
- struct Object *ob,
- struct DerivedMesh *dm,
- const float time,
- const char **err_str,
- int flags);
+/* Either modifies current_mesh in-place or constructs a new mesh. */
+struct Mesh *ABC_read_mesh(struct CacheReader *reader,
+ struct Object *ob,
+ struct Mesh *current_mesh,
+ const float time,
+ const char **err_str,
+ int flags);
void CacheReader_incref(struct CacheReader *reader);
void CacheReader_free(struct CacheReader *reader);
diff --git a/source/blender/alembic/intern/abc_camera.cc b/source/blender/alembic/intern/abc_camera.cc
index 4c91b9a6252..457bbd2b3af 100644
--- a/source/blender/alembic/intern/abc_camera.cc
+++ b/source/blender/alembic/intern/abc_camera.cc
@@ -49,13 +49,11 @@ using Alembic::AbcGeom::kWrapExisting;
/* ************************************************************************** */
-AbcCameraWriter::AbcCameraWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+AbcCameraWriter::AbcCameraWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings)
- : AbcObjectWriter(depsgraph, scene, ob, time_sampling, settings, parent)
+ : AbcObjectWriter(ob, time_sampling, settings, parent)
{
OCamera camera(parent->alembicXform(), m_name, m_time_sampling);
m_camera_schema = camera.getSchema();
diff --git a/source/blender/alembic/intern/abc_camera.h b/source/blender/alembic/intern/abc_camera.h
index a839ca947ca..dd5dc28d598 100644
--- a/source/blender/alembic/intern/abc_camera.h
+++ b/source/blender/alembic/intern/abc_camera.h
@@ -35,9 +35,7 @@ class AbcCameraWriter : public AbcObjectWriter {
Alembic::AbcGeom::OFloatProperty m_eye_separation;
public:
- AbcCameraWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+ AbcCameraWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings);
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index 41c1dacabc0..e27403305da 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -37,8 +37,8 @@ extern "C" {
#include "BLI_listbase.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_curve.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "ED_curve.h"
@@ -71,13 +71,11 @@ using Alembic::AbcGeom::OV2fGeomParam;
/* ************************************************************************** */
-AbcCurveWriter::AbcCurveWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+AbcCurveWriter::AbcCurveWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings)
- : AbcObjectWriter(depsgraph, scene, ob, time_sampling, settings, parent)
+ : AbcObjectWriter(ob, time_sampling, settings, parent)
{
OCurves curves(parent->alembicXform(), m_name, m_time_sampling);
m_schema = curves.getSchema();
@@ -258,9 +256,21 @@ void AbcCurveReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSele
/* ************************************************************************** */
-void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const ISampleSelector &sample_sel)
+void AbcCurveReader::read_curve_sample(Curve *cu, const ICurvesSchema &schema, const ISampleSelector &sample_sel)
{
- ICurvesSchema::Sample smp = schema.getValue(sample_sel);
+ ICurvesSchema::Sample smp;
+ try {
+ smp = schema.getValue(sample_sel);
+ }
+ catch(Alembic::Util::Exception &ex) {
+ printf("Alembic: error reading curve sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return;
+ }
+
const Int32ArraySamplePtr num_vertices = smp.getCurvesNumVertices();
const P3fArraySamplePtr positions = smp.getPositions();
const FloatArraySamplePtr weights = smp.getPositionWeights();
@@ -400,18 +410,31 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const ISampleSele
}
}
-/* NOTE: Alembic only stores data about control points, but the DerivedMesh
+/* NOTE: Alembic only stores data about control points, but the Mesh
* passed from the cache modifier contains the displist, which has more data
* than the control points, so to avoid corrupting the displist we modify the
- * object directly and create a new DerivedMesh from that. Also we might need to
+ * object directly and create a new Mesh from that. Also we might need to
* create new or delete existing NURBS in the curve.
*/
-DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/,
- const ISampleSelector &sample_sel,
- int /*read_flag*/,
- const char ** /*err_str*/)
+Mesh *AbcCurveReader::read_mesh(Mesh *existing_mesh,
+ const ISampleSelector &sample_sel,
+ int /*read_flag*/,
+ const char **err_str)
{
- const ICurvesSchema::Sample sample = m_curves_schema.getValue(sample_sel);
+ ICurvesSchema::Sample sample;
+
+ try {
+ sample = m_curves_schema.getValue(sample_sel);
+ }
+ catch(Alembic::Util::Exception &ex) {
+ *err_str = "Error reading curve sample; more detail on the console";
+ printf("Alembic: error reading curve sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_curves_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return existing_mesh;
+ }
const P3fArraySamplePtr &positions = sample.getPositions();
const Int32ArraySamplePtr num_vertices = sample.getCurvesNumVertices();
@@ -450,5 +473,5 @@ DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/,
}
}
- return CDDM_from_curve(m_object);
+ return BKE_mesh_new_nomain_from_curve(m_object);
}
diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h
index 1e7180bbb1f..eb80553620d 100644
--- a/source/blender/alembic/intern/abc_curves.h
+++ b/source/blender/alembic/intern/abc_curves.h
@@ -36,9 +36,7 @@ class AbcCurveWriter : public AbcObjectWriter {
Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
public:
- AbcCurveWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+ AbcCurveWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings);
@@ -60,16 +58,17 @@ public:
const char **err_str) const;
void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
+ struct Mesh *read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
+
+ void read_curve_sample(Curve *cu,
+ const Alembic::AbcGeom::ICurvesSchema &schema,
+ const Alembic::Abc::ISampleSelector &sample_selector);
+
};
/* ************************************************************************** */
-void read_curve_sample(Curve *cu,
- const Alembic::AbcGeom::ICurvesSchema &schema,
- const Alembic::Abc::ISampleSelector &sample_selector);
-
#endif /* __ABC_CURVES_H__ */
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index 093c4de085e..c766720d6cd 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -60,6 +60,8 @@ extern "C" {
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
+
+#include "DEG_depsgraph_query.h"
}
using Alembic::Abc::TimeSamplingPtr;
@@ -69,6 +71,8 @@ using Alembic::Abc::OBox3dProperty;
ExportSettings::ExportSettings()
: scene(NULL)
+ , view_layer(NULL)
+ , depsgraph(NULL)
, logger()
, selected_only(false)
, visible_layers_only(false)
@@ -168,16 +172,12 @@ static bool export_object(const ExportSettings * const settings, const Base * co
/* ************************************************************************** */
-AbcExporter::AbcExporter(Main *bmain, Scene *scene,
- Depsgraph *depsgraph,
- const char *filename, ExportSettings &settings)
+AbcExporter::AbcExporter(Main *bmain, const char *filename, ExportSettings &settings)
: m_bmain(bmain)
, m_settings(settings)
, m_filename(filename)
, m_trans_sampling_index(0)
, m_shape_sampling_index(0)
- , m_scene(scene)
- , m_depsgraph(depsgraph)
, m_writer(NULL)
{}
@@ -201,7 +201,7 @@ void AbcExporter::getShutterSamples(unsigned int nr_of_samples,
bool time_relative,
std::vector<double> &samples)
{
- Scene *scene = m_scene; /* for use in the FPS macro */
+ Scene *scene = m_settings.scene; /* for use in the FPS macro */
samples.clear();
unsigned int frame_offset = time_relative ? m_settings.frame_start : 0;
@@ -231,7 +231,7 @@ Alembic::Abc::TimeSamplingPtr AbcExporter::createTimeSampling(double step)
Alembic::Abc::TimeSamplingType ts(
static_cast<uint32_t>(samples.size()),
- 1.0 / m_scene->r.frs_sec);
+ 1.0 / m_settings.scene->r.frs_sec); /* TODO(Sybren): shouldn't we use the FPS macro here? */
return TimeSamplingPtr(new Alembic::Abc::TimeSampling(ts, samples));
}
@@ -265,7 +265,7 @@ void AbcExporter::operator()(float &progress, bool &was_canceled)
scene_name = "untitled";
}
- Scene *scene = m_scene;
+ Scene *scene = m_settings.scene;
const double fps = FPS;
char buf[16];
snprintf(buf, 15, "%f", fps);
@@ -297,8 +297,8 @@ void AbcExporter::operator()(float &progress, bool &was_canceled)
OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(m_writer->archive(), m_trans_sampling_index);
- createTransformWritersHierarchy(m_depsgraph);
- createShapeWriters(m_depsgraph);
+ createTransformWritersHierarchy();
+ createShapeWriters();
/* Make a list of frames to export. */
@@ -360,7 +360,7 @@ void AbcExporter::operator()(float &progress, bool &was_canceled)
}
}
-void AbcExporter::createTransformWritersHierarchy(Depsgraph *depsgraph)
+void AbcExporter::createTransformWritersHierarchy()
{
for (Base *base = static_cast<Base *>(m_settings.view_layer->object_bases.first); base; base = base->next) {
Object *ob = base->object;
@@ -373,27 +373,26 @@ void AbcExporter::createTransformWritersHierarchy(Depsgraph *depsgraph)
/* We do not export transforms for objects of these classes. */
break;
default:
- exploreTransform(depsgraph, base, ob->parent, NULL);
+ exploreTransform(base, ob->parent, NULL);
}
}
}
}
-void AbcExporter::exploreTransform(Depsgraph *depsgraph, Base *ob_base, Object *parent, Object *dupliObParent)
+void AbcExporter::exploreTransform(Base *ob_base, Object *parent, Object *dupliObParent)
{
- Object *ob = ob_base->object;
-
/* If an object isn't exported itself, its duplilist shouldn't be
* exported either. */
if (!export_object(&m_settings, ob_base, dupliObParent != NULL)) {
return;
}
- if (object_type_is_exportable(m_scene, ob)) {
- createTransformWriter(depsgraph, ob, parent, dupliObParent);
+ Object *ob = DEG_get_evaluated_object(m_settings.depsgraph, ob_base->object);
+ if (object_type_is_exportable(m_settings.scene, ob)) {
+ createTransformWriter(ob, parent, dupliObParent);
}
- ListBase *lb = object_duplilist(depsgraph, m_scene, ob);
+ ListBase *lb = object_duplilist(m_settings.depsgraph, m_settings.scene, ob);
if (lb) {
Base fake_base = *ob_base; // copy flags (like selection state) from the real object.
@@ -414,15 +413,15 @@ void AbcExporter::exploreTransform(Depsgraph *depsgraph, Base *ob_base, Object *
dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob;
fake_base.object = dupli_ob;
- exploreTransform(depsgraph, &fake_base, dupli_parent, ob);
+ exploreTransform(&fake_base, dupli_parent, ob);
}
}
- }
- free_object_duplilist(lb);
+ free_object_duplilist(lb);
+ }
}
-AbcTransformWriter * AbcExporter::createTransformWriter(Depsgraph *depsgraph, Object *ob, Object *parent, Object *dupliObParent)
+AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupliObParent)
{
/* An object should not be its own parent, or we'll get infinite loops. */
BLI_assert(ob != parent);
@@ -457,29 +456,29 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Depsgraph *depsgraph, Ob
* return the parent's AbcTransformWriter pointer. */
if (parent->parent) {
if (parent == dupliObParent) {
- parent_writer = createTransformWriter(depsgraph, parent, parent->parent, NULL);
+ parent_writer = createTransformWriter(parent, parent->parent, NULL);
}
else {
- parent_writer = createTransformWriter(depsgraph, parent, parent->parent, dupliObParent);
+ parent_writer = createTransformWriter(parent, parent->parent, dupliObParent);
}
}
else if (parent == dupliObParent) {
if (dupliObParent->parent == NULL) {
- parent_writer = createTransformWriter(depsgraph, parent, NULL, NULL);
+ parent_writer = createTransformWriter(parent, NULL, NULL);
}
else {
- parent_writer = createTransformWriter(depsgraph, parent, dupliObParent->parent, dupliObParent->parent);
+ parent_writer = createTransformWriter(parent, dupliObParent->parent, dupliObParent->parent);
}
}
else {
- parent_writer = createTransformWriter(depsgraph, parent, dupliObParent, dupliObParent);
+ parent_writer = createTransformWriter(parent, dupliObParent, dupliObParent);
}
BLI_assert(parent_writer);
alembic_parent = parent_writer->alembicXform();
}
- my_writer = new AbcTransformWriter(depsgraph, ob, alembic_parent, parent_writer,
+ my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer,
m_trans_sampling_index, m_settings);
/* When flattening, the matrix of the dupliobject has to be added. */
@@ -491,14 +490,14 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Depsgraph *depsgraph, Ob
return my_writer;
}
-void AbcExporter::createShapeWriters(Depsgraph *depsgraph)
+void AbcExporter::createShapeWriters()
{
for (Base *base = static_cast<Base *>(m_settings.view_layer->object_bases.first); base; base = base->next) {
- exploreObject(depsgraph, base, NULL);
+ exploreObject(base, NULL);
}
}
-void AbcExporter::exploreObject(Depsgraph *depsgraph, Base *ob_base, Object *dupliObParent)
+void AbcExporter::exploreObject(Base *ob_base, Object *dupliObParent)
{
/* If an object isn't exported itself, its duplilist shouldn't be
* exported either. */
@@ -506,10 +505,10 @@ void AbcExporter::exploreObject(Depsgraph *depsgraph, Base *ob_base, Object *dup
return;
}
- createShapeWriter(ob_base, dupliObParent);
-
- Object *ob = ob_base->object;
- ListBase *lb = object_duplilist(depsgraph, m_scene, ob);
+ Object *ob = DEG_get_evaluated_object(m_settings.depsgraph, ob_base->object);
+ createShapeWriter(ob, dupliObParent);
+
+ ListBase *lb = object_duplilist(m_settings.depsgraph, m_settings.scene, ob);
if (lb) {
Base fake_base = *ob_base; // copy flags (like selection state) from the real object.
@@ -524,12 +523,12 @@ void AbcExporter::exploreObject(Depsgraph *depsgraph, Base *ob_base, Object *dup
}
if (link->type == OB_DUPLICOLLECTION) {
fake_base.object = link->ob;
- exploreObject(depsgraph, &fake_base, ob);
+ exploreObject(&fake_base, ob);
}
}
- }
- free_object_duplilist(lb);
+ free_object_duplilist(lb);
+ }
}
void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform)
@@ -547,19 +546,17 @@ void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *x
if (m_settings.export_hair && psys->part->type == PART_HAIR) {
m_settings.export_child_hairs = true;
- m_shapes.push_back(new AbcHairWriter(m_depsgraph, m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
+ m_shapes.push_back(new AbcHairWriter(ob, xform, m_shape_sampling_index, m_settings, psys));
}
else if (m_settings.export_particles && psys->part->type == PART_EMITTER) {
- m_shapes.push_back(new AbcPointsWriter(m_depsgraph, m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
+ m_shapes.push_back(new AbcPointsWriter(ob, xform, m_shape_sampling_index, m_settings, psys));
}
}
}
-void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent)
+void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
{
- Object *ob = ob_base->object;
-
- if (!object_type_is_exportable(m_scene, ob)) {
+ if (!object_type_is_exportable(m_settings.scene, ob)) {
return;
}
@@ -590,7 +587,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent)
return;
}
- m_shapes.push_back(new AbcMeshWriter(m_depsgraph, m_scene, ob, xform, m_shape_sampling_index, m_settings));
+ m_shapes.push_back(new AbcMeshWriter(ob, xform, m_shape_sampling_index, m_settings));
break;
}
case OB_SURF:
@@ -601,7 +598,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent)
return;
}
- m_shapes.push_back(new AbcNurbsWriter(m_depsgraph, m_scene, ob, xform, m_shape_sampling_index, m_settings));
+ m_shapes.push_back(new AbcNurbsWriter(ob, xform, m_shape_sampling_index, m_settings));
break;
}
case OB_CURVE:
@@ -612,7 +609,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent)
return;
}
- m_shapes.push_back(new AbcCurveWriter(m_depsgraph, m_scene, ob, xform, m_shape_sampling_index, m_settings));
+ m_shapes.push_back(new AbcCurveWriter(ob, xform, m_shape_sampling_index, m_settings));
break;
}
case OB_CAMERA:
@@ -620,7 +617,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent)
Camera *cam = static_cast<Camera *>(ob->data);
if (cam->type == CAM_PERSP) {
- m_shapes.push_back(new AbcCameraWriter(m_depsgraph, m_scene, ob, xform, m_shape_sampling_index, m_settings));
+ m_shapes.push_back(new AbcCameraWriter(ob, xform, m_shape_sampling_index, m_settings));
}
break;
@@ -633,7 +630,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent)
}
m_shapes.push_back(new AbcMBallWriter(
- m_bmain, m_depsgraph, m_scene, ob, xform,
+ m_bmain, ob, xform,
m_shape_sampling_index, m_settings));
break;
}
@@ -653,7 +650,7 @@ AbcTransformWriter *AbcExporter::getXForm(const std::string &name)
void AbcExporter::setCurrentFrame(Main *bmain, double t)
{
- m_scene->r.cfra = static_cast<int>(t);
- m_scene->r.subframe = static_cast<float>(t) - m_scene->r.cfra;
- BKE_scene_graph_update_for_newframe(m_depsgraph, bmain);
+ m_settings.scene->r.cfra = static_cast<int>(t);
+ m_settings.scene->r.subframe = static_cast<float>(t) - m_settings.scene->r.cfra;
+ BKE_scene_graph_update_for_newframe(m_settings.depsgraph, bmain);
}
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index c891824a114..a92e426292c 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -92,9 +92,6 @@ class AbcExporter {
unsigned int m_trans_sampling_index, m_shape_sampling_index;
- Scene *m_scene;
- Depsgraph *m_depsgraph;
-
ArchiveWriter *m_writer;
/* mapping from name to transform writer */
@@ -104,8 +101,7 @@ class AbcExporter {
std::vector<AbcObjectWriter *> m_shapes;
public:
- AbcExporter(Main *bmain, Scene *scene, Depsgraph *depsgraph,
- const char *filename, ExportSettings &settings);
+ AbcExporter(Main *bmain, const char *filename, ExportSettings &settings);
~AbcExporter();
void operator()(float &progress, bool &was_canceled);
@@ -119,12 +115,12 @@ protected:
private:
Alembic::Abc::TimeSamplingPtr createTimeSampling(double step);
- void createTransformWritersHierarchy(Depsgraph *depsgraph);
- AbcTransformWriter * createTransformWriter(Depsgraph *depsgraph, Object *ob, Object *parent, Object *dupliObParent);
- void exploreTransform(Depsgraph *depsgraph, Base *ob_base, Object *parent, Object *dupliObParent);
- void exploreObject(Depsgraph *depsgraph, Base *ob_base, Object *dupliObParent);
- void createShapeWriters(Depsgraph *depsgraph);
- void createShapeWriter(Base *ob_base, Object *dupliObParent);
+ void createTransformWritersHierarchy();
+ AbcTransformWriter * createTransformWriter(Object *ob, Object *parent, Object *dupliObParent);
+ void exploreTransform(Base *ob_base, Object *parent, Object *dupliObParent);
+ void exploreObject(Base *ob_base, Object *dupliObParent);
+ void createShapeWriters();
+ void createShapeWriter(Object *ob, Object *dupliObParent);
void createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform);
AbcTransformWriter *getXForm(const std::string &name);
diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc
index e7cc474e2e8..83a46a330fd 100644
--- a/source/blender/alembic/intern/abc_hair.cc
+++ b/source/blender/alembic/intern/abc_hair.cc
@@ -30,12 +30,16 @@
extern "C" {
#include "MEM_guardedalloc.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_library.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_object.h"
#include "BKE_particle.h"
}
@@ -49,14 +53,12 @@ using Alembic::AbcGeom::OV2fGeomParam;
/* ************************************************************************** */
-AbcHairWriter::AbcHairWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+AbcHairWriter::AbcHairWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings,
ParticleSystem *psys)
- : AbcObjectWriter(depsgraph, scene, ob, time_sampling, settings, parent)
+ : AbcObjectWriter(ob, time_sampling, settings, parent)
, m_uv_warning_shown(false)
{
m_psys = psys;
@@ -70,15 +72,8 @@ void AbcHairWriter::do_write()
if (!m_psys) {
return;
}
-
- ParticleSystemModifierData *psmd = psys_get_modifier(m_object, m_psys);
-
- if (!psmd->mesh_final) {
- return;
- }
-
- DerivedMesh *dm = mesh_create_derived_render(m_depsgraph, m_scene, m_object, CD_MASK_MESH);
- DM_ensure_tessface(dm);
+ Mesh *mesh = mesh_get_eval_final(m_settings.depsgraph, m_settings.scene, m_object, CD_MASK_MESH);
+ BKE_mesh_tessface_ensure(mesh);
std::vector<Imath::V3f> verts;
std::vector<int32_t> hvertices;
@@ -88,15 +83,13 @@ void AbcHairWriter::do_write()
if (m_psys->pathcache) {
ParticleSettings *part = m_psys->part;
- write_hair_sample(dm, part, verts, norm_values, uv_values, hvertices);
+ write_hair_sample(mesh, part, verts, norm_values, uv_values, hvertices);
if (m_settings.export_child_hairs && m_psys->childcache) {
- write_hair_child_sample(dm, part, verts, norm_values, uv_values, hvertices);
+ write_hair_child_sample(mesh, part, verts, norm_values, uv_values, hvertices);
}
}
- dm->release(dm);
-
Alembic::Abc::P3fArraySample iPos(verts);
m_sample = OCurvesSchema::Sample(iPos, hvertices);
m_sample.setBasis(Alembic::AbcGeom::kNoBasis);
@@ -119,7 +112,7 @@ void AbcHairWriter::do_write()
m_schema.set(m_sample);
}
-void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
+void AbcHairWriter::write_hair_sample(Mesh *mesh,
ParticleSettings *part,
std::vector<Imath::V3f> &verts,
std::vector<Imath::V3f> &norm_values,
@@ -130,9 +123,9 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
float inv_mat[4][4];
invert_m4_m4_safe(inv_mat, m_object->obmat);
- MTFace *mtface = static_cast<MTFace *>(CustomData_get_layer(&dm->faceData, CD_MTFACE));
- MFace *mface = dm->getTessFaceArray(dm);
- MVert *mverts = dm->getVertArray(dm);
+ MTFace *mtface = mesh->mtface;
+ MFace *mface = mesh->mface;
+ MVert *mverts = mesh->mvert;
if ((!mtface || !mface) && !m_uv_warning_shown) {
std::fprintf(stderr, "Warning, no UV set found for underlying geometry of %s.\n",
@@ -152,11 +145,13 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
/* underlying info for faces-only emission */
path = cache[p];
+ /* Write UV and normal vectors */
if (part->from == PART_FROM_FACE && mtface) {
const int num = pa->num_dmcache >= 0 ? pa->num_dmcache : pa->num;
- if (num < dm->getNumTessFaces(dm)) {
- MFace *face = static_cast<MFace *>(dm->getTessFaceData(dm, num, CD_MFACE));
+ if (num < mesh->totface) {
+ /* TODO(Sybren): check whether the NULL check here and if(mface) are actually required */
+ MFace *face = mface == NULL ? NULL : &mface[num];
MTFace *tface = mtface + num;
if (mface) {
@@ -172,7 +167,7 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
}
}
else {
- std::fprintf(stderr, "Particle to faces overflow (%d/%d)\n", num, dm->getNumTessFaces(dm));
+ std::fprintf(stderr, "Particle to faces overflow (%d/%d)\n", num, mesh->totface);
}
}
else if (part->from == PART_FROM_VERT && mtface) {
@@ -180,8 +175,8 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
const int num = (pa->num_dmcache >= 0) ? pa->num_dmcache : pa->num;
/* iterate over all faces to find a corresponding underlying UV */
- for (int n = 0; n < dm->getNumTessFaces(dm); ++n) {
- MFace *face = static_cast<MFace *>(dm->getTessFaceData(dm, n, CD_MFACE));
+ for (int n = 0; n < mesh->totface; ++n) {
+ MFace *face = &mface[n];
MTFace *tface = mtface + n;
unsigned int vtx[4];
vtx[0] = face->v1;
@@ -217,7 +212,7 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
int steps = path->segments + 1;
hvertices.push_back(steps);
- for (k = 0; k < steps; ++k) {
+ for (k = 0; k < steps; ++k, ++path) {
float vert[3];
copy_v3_v3(vert, path->co);
mul_m4_v3(inv_mat, vert);
@@ -225,12 +220,11 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
/* Convert Z-up to Y-up. */
verts.push_back(Imath::V3f(vert[0], vert[2], -vert[1]));
- ++path;
}
}
}
-void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
+void AbcHairWriter::write_hair_child_sample(Mesh *mesh,
ParticleSettings *part,
std::vector<Imath::V3f> &verts,
std::vector<Imath::V3f> &norm_values,
@@ -241,8 +235,8 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
float inv_mat[4][4];
invert_m4_m4_safe(inv_mat, m_object->obmat);
- MTFace *mtface = static_cast<MTFace *>(CustomData_get_layer(&dm->faceData, CD_MTFACE));
- MVert *mverts = dm->getVertArray(dm);
+ MTFace *mtface = mesh->mtface;
+ MVert *mverts = mesh->mvert;
ParticleCacheKey **cache = m_psys->childcache;
ParticleCacheKey *path;
@@ -265,7 +259,7 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
continue;
}
- MFace *face = static_cast<MFace *>(dm->getTessFaceData(dm, num, CD_MFACE));
+ MFace *face = &mesh->mface[num];
MTFace *tface = mtface + num;
float r_uv[2], tmpnor[3], mapfw[4], vec[3];
diff --git a/source/blender/alembic/intern/abc_hair.h b/source/blender/alembic/intern/abc_hair.h
index 5627f7726e6..e2dffd4edaf 100644
--- a/source/blender/alembic/intern/abc_hair.h
+++ b/source/blender/alembic/intern/abc_hair.h
@@ -25,7 +25,6 @@
#include "abc_object.h"
-struct DerivedMesh;
struct ParticleSettings;
struct ParticleSystem;
@@ -40,9 +39,7 @@ class AbcHairWriter : public AbcObjectWriter {
bool m_uv_warning_shown;
public:
- AbcHairWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+ AbcHairWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings,
@@ -51,14 +48,14 @@ public:
private:
virtual void do_write();
- void write_hair_sample(DerivedMesh *dm,
+ void write_hair_sample(struct Mesh *mesh,
ParticleSettings *part,
std::vector<Imath::V3f> &verts,
std::vector<Imath::V3f> &norm_values,
std::vector<Imath::V2f> &uv_values,
std::vector<int32_t> &hvertices);
- void write_hair_child_sample(DerivedMesh *dm,
+ void write_hair_child_sample(struct Mesh *mesh,
ParticleSettings *part,
std::vector<Imath::V3f> &verts,
std::vector<Imath::V3f> &norm_values,
diff --git a/source/blender/alembic/intern/abc_mball.cc b/source/blender/alembic/intern/abc_mball.cc
index 1df55712abe..d6e54407922 100644
--- a/source/blender/alembic/intern/abc_mball.cc
+++ b/source/blender/alembic/intern/abc_mball.cc
@@ -42,13 +42,11 @@ extern "C" {
AbcMBallWriter::AbcMBallWriter(
Main *bmain,
- Depsgraph *depsgraph,
- Scene *scene,
Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings)
- : AbcObjectWriter(depsgraph, scene, ob, time_sampling, settings, parent)
+ : AbcObjectWriter(ob, time_sampling, settings, parent)
, m_bmain(bmain)
{
m_is_animated = isAnimated();
@@ -58,8 +56,7 @@ AbcMBallWriter::AbcMBallWriter(
sizeof(CurveCache),
"CurveCache for AbcMBallWriter");
- m_mesh_writer = new AbcMeshWriter(depsgraph, scene, m_mesh_ob, parent,
- time_sampling, settings);
+ m_mesh_writer = new AbcMeshWriter(m_mesh_ob, parent, time_sampling, settings);
m_mesh_writer->setIsAnimated(m_is_animated);
}
@@ -101,7 +98,7 @@ void AbcMBallWriter::do_write()
* only contains for_render flag. As soon as CoW is
* implemented, this is to be rethinked.
*/
- BKE_displist_make_mball_forRender(m_depsgraph, m_scene, m_object, &disp);
+ BKE_displist_make_mball_forRender(m_settings.depsgraph, m_settings.scene, m_object, &disp);
BKE_mesh_from_metaball(&disp, tmpmesh);
BKE_displist_free(&disp);
diff --git a/source/blender/alembic/intern/abc_mball.h b/source/blender/alembic/intern/abc_mball.h
index bae4b6bcb76..07cb1908e95 100644
--- a/source/blender/alembic/intern/abc_mball.h
+++ b/source/blender/alembic/intern/abc_mball.h
@@ -43,8 +43,6 @@ class AbcMBallWriter : public AbcObjectWriter {
public:
AbcMBallWriter(
Main *bmain,
- Depsgraph *depsgraph,
- Scene *scene,
Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index d52d7f06048..2b739837239 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -30,6 +30,7 @@
extern "C" {
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_fluidsim_types.h"
#include "DNA_object_types.h"
@@ -37,10 +38,10 @@ extern "C" {
#include "BLI_math_geom.h"
#include "BLI_string.h"
-#include "BKE_cdderivedmesh.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -51,6 +52,8 @@ extern "C" {
#include "bmesh.h"
#include "bmesh_tools.h"
+
+#include "DEG_depsgraph_query.h"
}
using Alembic::Abc::FloatArraySample;
@@ -103,27 +106,27 @@ using Alembic::AbcGeom::IN3fGeomParam;
/* NOTE: Alembic's polygon winding order is clockwise, to match with Renderman. */
-static void get_vertices(DerivedMesh *dm, std::vector<Imath::V3f> &points)
+static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points)
{
points.clear();
- points.resize(dm->getNumVerts(dm));
+ points.resize(mesh->totvert);
- MVert *verts = dm->getVertArray(dm);
+ MVert *verts = mesh->mvert;
- for (int i = 0, e = dm->getNumVerts(dm); i < e; ++i) {
+ for (int i = 0, e = mesh->totvert; i < e; ++i) {
copy_yup_from_zup(points[i].getValue(), verts[i].co);
}
}
-static void get_topology(DerivedMesh *dm,
+static void get_topology(struct Mesh *mesh,
std::vector<int32_t> &poly_verts,
std::vector<int32_t> &loop_counts,
bool &smooth_normal)
{
- const int num_poly = dm->getNumPolys(dm);
- const int num_loops = dm->getNumLoops(dm);
- MLoop *mloop = dm->getLoopArray(dm);
- MPoly *mpoly = dm->getPolyArray(dm);
+ const int num_poly = mesh->totpoly;
+ const int num_loops = mesh->totloop;
+ MLoop *mloop = mesh->mloop;
+ MPoly *mpoly = mesh->mpoly;
poly_verts.clear();
loop_counts.clear();
@@ -145,7 +148,7 @@ static void get_topology(DerivedMesh *dm,
}
}
-static void get_creases(DerivedMesh *dm,
+static void get_creases(struct Mesh *mesh,
std::vector<int32_t> &indices,
std::vector<int32_t> &lengths,
std::vector<float> &sharpnesses)
@@ -156,9 +159,9 @@ static void get_creases(DerivedMesh *dm,
lengths.clear();
sharpnesses.clear();
- MEdge *edge = dm->getEdgeArray(dm);
+ MEdge *edge = mesh->medge;
- for (int i = 0, e = dm->getNumEdges(dm); i < e; ++i) {
+ for (int i = 0, e = mesh->totedge; i < e; ++i) {
const float sharpness = static_cast<float>(edge[i].crease) * factor;
if (sharpness != 0.0f) {
@@ -171,41 +174,40 @@ static void get_creases(DerivedMesh *dm,
lengths.resize(sharpnesses.size(), 2);
}
-static void get_vertex_normals(DerivedMesh *dm, std::vector<Imath::V3f> &normals)
+static void get_vertex_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals)
{
normals.clear();
- normals.resize(dm->getNumVerts(dm));
+ normals.resize(mesh->totvert);
- MVert *verts = dm->getVertArray(dm);
+ MVert *verts = mesh->mvert;
float no[3];
- for (int i = 0, e = dm->getNumVerts(dm); i < e; ++i) {
+ for (int i = 0, e = mesh->totvert; i < e; ++i) {
normal_short_to_float_v3(no, verts[i].no);
copy_yup_from_zup(normals[i].getValue(), no);
}
}
-static void get_loop_normals(DerivedMesh *dm, std::vector<Imath::V3f> &normals)
+static void get_loop_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals)
{
- MPoly *mpoly = dm->getPolyArray(dm);
- MPoly *mp = mpoly;
+ MPoly *mp = mesh->mpoly;
- MLoop *mloop = dm->getLoopArray(dm);
+ MLoop *mloop = mesh->mloop;
MLoop *ml = mloop;
- MVert *verts = dm->getVertArray(dm);
+ MVert *verts = mesh->mvert;
- const float (*lnors)[3] = static_cast<float(*)[3]>(dm->getLoopDataArray(dm, CD_NORMAL));
+ const float (*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
normals.clear();
- normals.resize(dm->getNumLoops(dm));
+ normals.resize(mesh->totloop);
unsigned loop_index = 0;
/* NOTE: data needs to be written in the reverse order. */
if (lnors) {
- for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i, ++mp) {
+ for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
ml = mloop + mp->loopstart + (mp->totloop - 1);
for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
@@ -217,7 +219,7 @@ static void get_loop_normals(DerivedMesh *dm, std::vector<Imath::V3f> &normals)
else {
float no[3];
- for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i, ++mp) {
+ for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
ml = mloop + mp->loopstart + (mp->totloop - 1);
/* Flat shaded, use common normal for all verts. */
@@ -286,13 +288,11 @@ static ModifierData *get_liquid_sim_modifier(Scene *scene, Object *ob)
/* ************************************************************************** */
-AbcMeshWriter::AbcMeshWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+AbcMeshWriter::AbcMeshWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings)
- : AbcObjectWriter(depsgraph, scene, ob, time_sampling, settings, parent)
+ : AbcObjectWriter(ob, time_sampling, settings, parent)
{
m_is_animated = isAnimated();
m_subsurf_mod = NULL;
@@ -304,11 +304,11 @@ AbcMeshWriter::AbcMeshWriter(Depsgraph *depsgraph,
}
if (!m_settings.apply_subdiv) {
- m_subsurf_mod = get_subsurf_modifier(m_scene, m_object);
+ m_subsurf_mod = get_subsurf_modifier(m_settings.scene, m_object);
m_is_subd = (m_subsurf_mod != NULL);
}
- m_is_liquid = (get_liquid_sim_modifier(m_scene, m_object) != NULL);
+ m_is_liquid = (get_liquid_sim_modifier(m_settings.scene, m_object) != NULL);
while (parent->alembicXform().getChildHeader(m_name)) {
m_name.append("_");
@@ -369,36 +369,37 @@ void AbcMeshWriter::do_write()
if (!m_first_frame && !m_is_animated)
return;
- DerivedMesh *dm = getFinalMesh();
+ bool needsfree;
+ struct Mesh *mesh = getFinalMesh(needsfree);
try {
if (m_settings.use_subdiv_schema && m_subdiv_schema.valid()) {
- writeSubD(dm);
+ writeSubD(mesh);
}
else {
- writeMesh(dm);
+ writeMesh(mesh);
}
- freeMesh(dm);
+ if (needsfree) BKE_id_free(NULL, mesh);
}
catch (...) {
- freeMesh(dm);
+ if (needsfree) BKE_id_free(NULL, mesh);
throw;
}
}
-void AbcMeshWriter::writeMesh(DerivedMesh *dm)
+void AbcMeshWriter::writeMesh(struct Mesh *mesh)
{
std::vector<Imath::V3f> points, normals;
std::vector<int32_t> poly_verts, loop_counts;
bool smooth_normal = false;
- get_vertices(dm, points);
- get_topology(dm, poly_verts, loop_counts, smooth_normal);
+ get_vertices(mesh, points);
+ get_topology(mesh, poly_verts, loop_counts, smooth_normal);
if (m_first_frame && m_settings.export_face_sets) {
- writeFaceSets(dm, m_mesh_schema);
+ writeFaceSets(mesh, m_mesh_schema);
}
m_mesh_sample = OPolyMeshSchema::Sample(V3fArraySample(points),
@@ -407,7 +408,7 @@ void AbcMeshWriter::writeMesh(DerivedMesh *dm)
UVSample sample;
if (m_first_frame && m_settings.export_uvs) {
- const char *name = get_uv_sample(sample, m_custom_data_config, &dm->loopData);
+ const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
if (!sample.indices.empty() && !sample.uvs.empty()) {
OV2fGeomParam::Sample uv_sample;
@@ -419,15 +420,15 @@ void AbcMeshWriter::writeMesh(DerivedMesh *dm)
m_mesh_sample.setUVs(uv_sample);
}
- write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &dm->loopData, CD_MLOOPUV);
+ write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
}
if (m_settings.export_normals) {
if (smooth_normal) {
- get_loop_normals(dm, normals);
+ get_loop_normals(mesh, normals);
}
else {
- get_vertex_normals(dm, normals);
+ get_vertex_normals(mesh, normals);
}
ON3fGeomParam::Sample normals_sample;
@@ -441,7 +442,7 @@ void AbcMeshWriter::writeMesh(DerivedMesh *dm)
if (m_is_liquid) {
std::vector<Imath::V3f> velocities;
- getVelocities(dm, velocities);
+ getVelocities(mesh, velocities);
m_mesh_sample.setVelocities(V3fArraySample(velocities));
}
@@ -450,10 +451,10 @@ void AbcMeshWriter::writeMesh(DerivedMesh *dm)
m_mesh_schema.set(m_mesh_sample);
- writeArbGeoParams(dm);
+ writeArbGeoParams(mesh);
}
-void AbcMeshWriter::writeSubD(DerivedMesh *dm)
+void AbcMeshWriter::writeSubD(struct Mesh *mesh)
{
std::vector<float> crease_sharpness;
std::vector<Imath::V3f> points;
@@ -462,12 +463,12 @@ void AbcMeshWriter::writeSubD(DerivedMesh *dm)
bool smooth_normal = false;
- get_vertices(dm, points);
- get_topology(dm, poly_verts, loop_counts, smooth_normal);
- get_creases(dm, crease_indices, crease_lengths, crease_sharpness);
+ get_vertices(mesh, points);
+ get_topology(mesh, poly_verts, loop_counts, smooth_normal);
+ get_creases(mesh, crease_indices, crease_lengths, crease_sharpness);
if (m_first_frame && m_settings.export_face_sets) {
- writeFaceSets(dm, m_subdiv_schema);
+ writeFaceSets(mesh, m_subdiv_schema);
}
m_subdiv_sample = OSubDSchema::Sample(V3fArraySample(points),
@@ -476,7 +477,7 @@ void AbcMeshWriter::writeSubD(DerivedMesh *dm)
UVSample sample;
if (m_first_frame && m_settings.export_uvs) {
- const char *name = get_uv_sample(sample, m_custom_data_config, &dm->loopData);
+ const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
if (!sample.indices.empty() && !sample.uvs.empty()) {
OV2fGeomParam::Sample uv_sample;
@@ -488,7 +489,7 @@ void AbcMeshWriter::writeSubD(DerivedMesh *dm)
m_subdiv_sample.setUVs(uv_sample);
}
- write_custom_data(m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &dm->loopData, CD_MLOOPUV);
+ write_custom_data(m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
}
if (!crease_indices.empty()) {
@@ -500,11 +501,11 @@ void AbcMeshWriter::writeSubD(DerivedMesh *dm)
m_subdiv_sample.setSelfBounds(bounds());
m_subdiv_schema.set(m_subdiv_sample);
- writeArbGeoParams(dm);
+ writeArbGeoParams(mesh);
}
template <typename Schema>
-void AbcMeshWriter::writeFaceSets(DerivedMesh *dm, Schema &schema)
+void AbcMeshWriter::writeFaceSets(struct Mesh *dm, Schema &schema)
{
std::map< std::string, std::vector<int32_t> > geo_groups;
getGeoGroups(dm, geo_groups);
@@ -518,14 +519,17 @@ void AbcMeshWriter::writeFaceSets(DerivedMesh *dm, Schema &schema)
}
}
-DerivedMesh *AbcMeshWriter::getFinalMesh()
+Mesh *AbcMeshWriter::getFinalMesh(bool &r_needsfree)
{
/* We don't want subdivided mesh data */
if (m_subsurf_mod) {
m_subsurf_mod->mode |= eModifierMode_DisableTemporary;
}
- DerivedMesh *dm = mesh_create_derived_render(m_depsgraph, m_scene, m_object, CD_MASK_MESH);
+ Scene *scene = DEG_get_evaluated_scene(m_settings.depsgraph);
+ Object *ob_eval = DEG_get_evaluated_object(m_settings.depsgraph, m_object);
+ struct Mesh *mesh = mesh_get_eval_final(m_settings.depsgraph, scene, ob_eval, CD_MASK_MESH);
+ r_needsfree = false;
if (m_subsurf_mod) {
m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary;
@@ -536,34 +540,31 @@ DerivedMesh *AbcMeshWriter::getFinalMesh()
const int quad_method = m_settings.quad_method;
const int ngon_method = m_settings.ngon_method;
- BMesh *bm = DM_to_bmesh(dm, true);
+ struct BMeshCreateParams bmcp = {false};
+ struct BMeshFromMeshParams bmfmp = {true, false, false, 0};
+ BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmcp, &bmfmp);
BM_mesh_triangulate(bm, quad_method, ngon_method, tag_only, NULL, NULL, NULL);
- DerivedMesh *result = CDDM_from_bmesh(bm, false);
+ struct BMeshToMeshParams bmmp = {0};
+ Mesh *result = BKE_bmesh_to_mesh_nomain(bm, &bmmp);
BM_mesh_free(bm);
- freeMesh(dm);
-
- dm = result;
+ mesh = result;
+ r_needsfree = true;
}
m_custom_data_config.pack_uvs = m_settings.pack_uv;
- m_custom_data_config.mpoly = dm->getPolyArray(dm);
- m_custom_data_config.mloop = dm->getLoopArray(dm);
- m_custom_data_config.totpoly = dm->getNumPolys(dm);
- m_custom_data_config.totloop = dm->getNumLoops(dm);
- m_custom_data_config.totvert = dm->getNumVerts(dm);
+ m_custom_data_config.mpoly = mesh->mpoly;
+ m_custom_data_config.mloop = mesh->mloop;
+ m_custom_data_config.totpoly = mesh->totpoly;
+ m_custom_data_config.totloop = mesh->totloop;
+ m_custom_data_config.totvert = mesh->totvert;
- return dm;
-}
-
-void AbcMeshWriter::freeMesh(DerivedMesh *dm)
-{
- dm->release(dm);
+ return mesh;
}
-void AbcMeshWriter::writeArbGeoParams(DerivedMesh *dm)
+void AbcMeshWriter::writeArbGeoParams(struct Mesh *dm)
{
if (m_is_liquid) {
/* We don't need anything more for liquid meshes. */
@@ -572,22 +573,22 @@ void AbcMeshWriter::writeArbGeoParams(DerivedMesh *dm)
if (m_first_frame && m_settings.export_vcols) {
if (m_subdiv_schema.valid()) {
- write_custom_data(m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &dm->loopData, CD_MLOOPCOL);
+ write_custom_data(m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &dm->ldata, CD_MLOOPCOL);
}
else {
- write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &dm->loopData, CD_MLOOPCOL);
+ write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &dm->ldata, CD_MLOOPCOL);
}
}
}
-void AbcMeshWriter::getVelocities(DerivedMesh *dm, std::vector<Imath::V3f> &vels)
+void AbcMeshWriter::getVelocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels)
{
- const int totverts = dm->getNumVerts(dm);
+ const int totverts = mesh->totvert;
vels.clear();
vels.resize(totverts);
- ModifierData *md = get_liquid_sim_modifier(m_scene, m_object);
+ ModifierData *md = get_liquid_sim_modifier(m_settings.scene, m_object);
FluidsimModifierData *fmd = reinterpret_cast<FluidsimModifierData *>(md);
FluidsimSettings *fss = fmd->fss;
@@ -605,11 +606,11 @@ void AbcMeshWriter::getVelocities(DerivedMesh *dm, std::vector<Imath::V3f> &vels
}
void AbcMeshWriter::getGeoGroups(
- DerivedMesh *dm,
+ struct Mesh *mesh,
std::map<std::string, std::vector<int32_t> > &geo_groups)
{
- const int num_poly = dm->getNumPolys(dm);
- MPoly *polygons = dm->getPolyArray(dm);
+ const int num_poly = mesh->totpoly;
+ MPoly *polygons = mesh->mpoly;
for (int i = 0; i < num_poly; ++i) {
MPoly &current_poly = polygons[i];
@@ -638,7 +639,7 @@ void AbcMeshWriter::getGeoGroups(
std::vector<int32_t> faceArray;
- for (int i = 0, e = dm->getNumTessFaces(dm); i < e; ++i) {
+ for (int i = 0, e = mesh->totface; i < e; ++i) {
faceArray.push_back(i);
}
@@ -873,11 +874,11 @@ ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
}
}
-static bool check_smooth_poly_flag(DerivedMesh *dm)
+static bool check_smooth_poly_flag(Mesh *mesh)
{
- MPoly *mpolys = dm->getPolyArray(dm);
+ MPoly *mpolys = mesh->mpoly;
- for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i) {
+ for (int i = 0, e = mesh->totpoly; i < e; ++i) {
MPoly &poly = mpolys[i];
if ((poly.flag & ME_SMOOTH) != 0) {
@@ -888,11 +889,11 @@ static bool check_smooth_poly_flag(DerivedMesh *dm)
return false;
}
-static void set_smooth_poly_flag(DerivedMesh *dm)
+static void set_smooth_poly_flag(Mesh *mesh)
{
- MPoly *mpolys = dm->getPolyArray(dm);
+ MPoly *mpolys = mesh->mpoly;
- for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i) {
+ for (int i = 0, e = mesh->totpoly; i < e; ++i) {
MPoly &poly = mpolys[i];
poly.flag |= ME_SMOOTH;
}
@@ -900,7 +901,7 @@ static void set_smooth_poly_flag(DerivedMesh *dm)
static void *add_customdata_cb(void *user_data, const char *name, int data_type)
{
- DerivedMesh *dm = static_cast<DerivedMesh *>(user_data);
+ Mesh *mesh = static_cast<Mesh *>(user_data);
CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
void *cd_ptr;
CustomData *loopdata;
@@ -911,7 +912,7 @@ static void *add_customdata_cb(void *user_data, const char *name, int data_type)
return NULL;
}
- loopdata = dm->getLoopDataLayout(dm);
+ loopdata = &mesh->ldata;
cd_ptr = CustomData_get_layer_named(loopdata, cd_data_type, name);
if (cd_ptr != NULL) {
/* layer already exists, so just return it. */
@@ -920,7 +921,7 @@ static void *add_customdata_cb(void *user_data, const char *name, int data_type)
/* create a new layer, taking care to construct the hopefully-soon-to-be-removed
* CD_MTEXPOLY layer too, with the same name. */
- numloops = dm->getNumLoops(dm);
+ numloops = mesh->totloop;
cd_ptr = CustomData_add_layer_named(loopdata, cd_data_type, CD_DEFAULT,
NULL, numloops, name);
return cd_ptr;
@@ -986,17 +987,19 @@ static void read_mesh_sample(const std::string & iobject_full_name,
}
}
-CDStreamConfig get_config(DerivedMesh *dm)
+CDStreamConfig get_config(Mesh *mesh)
{
CDStreamConfig config;
- config.user_data = dm;
- config.mvert = dm->getVertArray(dm);
- config.mloop = dm->getLoopArray(dm);
- config.mpoly = dm->getPolyArray(dm);
- config.totloop = dm->getNumLoops(dm);
- config.totpoly = dm->getNumPolys(dm);
- config.loopdata = dm->getLoopDataLayout(dm);
+ BLI_assert(mesh->mvert);
+
+ config.user_data = mesh;
+ config.mvert = mesh->mvert;
+ config.mloop = mesh->mloop;
+ config.mpoly = mesh->mpoly;
+ config.totloop = mesh->totloop;
+ config.totpoly = mesh->totpoly;
+ config.loopdata = &mesh->ldata;
config.add_customdata_cb = add_customdata_cb;
return config;
@@ -1027,14 +1030,8 @@ void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
m_object->data = mesh;
- DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
-
- if (ndm != dm) {
- dm->release(dm);
- }
-
- DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
+ Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, CD_MASK_MESH, true);
if (m_settings->validate_meshes) {
BKE_mesh_validate(mesh, false, false);
@@ -1064,33 +1061,45 @@ bool AbcMeshReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHe
return true;
}
-DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm,
- const ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str)
+Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
+ const ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str)
{
- const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel);
+ IPolyMeshSchema::Sample sample;
+ try {
+ sample = m_schema.getValue(sample_sel);
+ }
+ catch(Alembic::Util::Exception &ex) {
+ *err_str = "Error reading mesh sample; more detail on the console";
+ printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return existing_mesh;
+ }
const P3fArraySamplePtr &positions = sample.getPositions();
const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
- DerivedMesh *new_dm = NULL;
+ Mesh *new_mesh = NULL;
/* Only read point data when streaming meshes, unless we need to create new ones. */
ImportSettings settings;
settings.read_flag |= read_flag;
- bool topology_changed = positions->size() != dm->getNumVerts(dm) ||
- face_counts->size() != dm->getNumPolys(dm) ||
- face_indices->size() != dm->getNumLoops(dm);
+ bool topology_changed = positions->size() != existing_mesh->totvert ||
+ face_counts->size() != existing_mesh->totpoly ||
+ face_indices->size() != existing_mesh->totloop;
if (topology_changed) {
- new_dm = CDDM_from_template(dm,
- positions->size(),
- 0,
- 0,
- face_indices->size(),
- face_counts->size());
+ new_mesh = BKE_mesh_new_nomain_from_template(existing_mesh,
+ positions->size(),
+ 0,
+ 0,
+ face_indices->size(),
+ face_counts->size());
settings.read_flag |= MOD_MESHSEQ_READ_ALL;
}
@@ -1098,8 +1107,8 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm,
/* If the face count changed (e.g. by triangulation), only read points.
* This prevents crash from T49813.
* TODO(kevin): perhaps find a better way to do this? */
- if (face_counts->size() != dm->getNumPolys(dm) ||
- face_indices->size() != dm->getNumLoops(dm))
+ if (face_counts->size() != existing_mesh->totpoly ||
+ face_indices->size() != existing_mesh->totloop)
{
settings.read_flag = MOD_MESHSEQ_READ_VERT;
@@ -1110,40 +1119,39 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm,
}
}
- CDStreamConfig config = get_config(new_dm ? new_dm : dm);
+ CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
config.time = sample_sel.getRequestedTime();
bool do_normals = false;
read_mesh_sample(m_iobject.getFullName(),
&settings, m_schema, sample_sel, config, do_normals);
- if (new_dm) {
+ if (new_mesh) {
/* Check if we had ME_SMOOTH flag set to restore it. */
- if (!do_normals && check_smooth_poly_flag(dm)) {
- set_smooth_poly_flag(new_dm);
+ if (!do_normals && check_smooth_poly_flag(existing_mesh)) {
+ set_smooth_poly_flag(new_mesh);
}
- CDDM_calc_normals(new_dm);
- CDDM_calc_edges(new_dm);
+ BKE_mesh_calc_normals(new_mesh);
+ BKE_mesh_calc_edges(new_mesh, false, false);
/* Here we assume that the number of materials doesn't change, i.e. that
* the material slots that were created when the object was loaded from
* Alembic are still valid now. */
- size_t num_polys = new_dm->getNumPolys(new_dm);
+ size_t num_polys = new_mesh->totpoly;
if (num_polys > 0) {
- MPoly *dmpolies = new_dm->getPolyArray(new_dm);
std::map<std::string, int> mat_map;
- assign_facesets_to_mpoly(sample_sel, 0, dmpolies, num_polys, mat_map);
+ assign_facesets_to_mpoly(sample_sel, 0, new_mesh->mpoly, num_polys, mat_map);
}
- return new_dm;
+ return new_mesh;
}
if (do_normals) {
- CDDM_calc_normals(dm);
+ BKE_mesh_calc_normals(existing_mesh);
}
- return dm;
+ return existing_mesh;
}
void AbcMeshReader::assign_facesets_to_mpoly(
@@ -1305,16 +1313,22 @@ void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
m_object->data = mesh;
- DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
+ Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, CD_MASK_MESH, true);
- if (ndm != dm) {
- dm->release(dm);
+ ISubDSchema::Sample sample;
+ try {
+ sample = m_schema.getValue(sample_sel);
+ }
+ catch(Alembic::Util::Exception &ex) {
+ printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return;
}
- DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
-
- const ISubDSchema::Sample sample = m_schema.getValue(sample_sel);
Int32ArraySamplePtr indices = sample.getCreaseIndices();
Alembic::Abc::FloatArraySamplePtr sharpnesses = sample.getCreaseSharpnesses();
@@ -1344,29 +1358,41 @@ void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
}
}
-DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm,
- const ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str)
+Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh,
+ const ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str)
{
- const ISubDSchema::Sample sample = m_schema.getValue(sample_sel);
+ ISubDSchema::Sample sample;
+ try {
+ sample = m_schema.getValue(sample_sel);
+ }
+ catch(Alembic::Util::Exception &ex) {
+ *err_str = "Error reading mesh sample; more detail on the console";
+ printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return existing_mesh;
+ }
const P3fArraySamplePtr &positions = sample.getPositions();
const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
- DerivedMesh *new_dm = NULL;
+ Mesh *new_mesh = NULL;
ImportSettings settings;
settings.read_flag |= read_flag;
- if (dm->getNumVerts(dm) != positions->size()) {
- new_dm = CDDM_from_template(dm,
- positions->size(),
- 0,
- 0,
- face_indices->size(),
- face_counts->size());
+ if (existing_mesh->totvert != positions->size()) {
+ new_mesh = BKE_mesh_new_nomain_from_template(existing_mesh,
+ positions->size(),
+ 0,
+ 0,
+ face_indices->size(),
+ face_counts->size());
settings.read_flag |= MOD_MESHSEQ_READ_ALL;
}
@@ -1374,8 +1400,8 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm,
/* If the face count changed (e.g. by triangulation), only read points.
* This prevents crash from T49813.
* TODO(kevin): perhaps find a better way to do this? */
- if (face_counts->size() != dm->getNumPolys(dm) ||
- face_indices->size() != dm->getNumLoops(dm))
+ if (face_counts->size() != existing_mesh->totpoly ||
+ face_indices->size() != existing_mesh->totpoly)
{
settings.read_flag = MOD_MESHSEQ_READ_VERT;
@@ -1387,22 +1413,22 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm,
}
/* Only read point data when streaming meshes, unless we need to create new ones. */
- CDStreamConfig config = get_config(new_dm ? new_dm : dm);
+ CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
config.time = sample_sel.getRequestedTime();
read_subd_sample(m_iobject.getFullName(),
&settings, m_schema, sample_sel, config);
- if (new_dm) {
+ if (new_mesh) {
/* Check if we had ME_SMOOTH flag set to restore it. */
- if (check_smooth_poly_flag(dm)) {
- set_smooth_poly_flag(new_dm);
+ if (check_smooth_poly_flag(existing_mesh)) {
+ set_smooth_poly_flag(new_mesh);
}
- CDDM_calc_normals(new_dm);
- CDDM_calc_edges(new_dm);
+ BKE_mesh_calc_normals(new_mesh);
+ BKE_mesh_calc_edges(new_mesh, false, false);
- return new_dm;
+ return new_mesh;
}
- return dm;
+ return existing_mesh;
}
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index c57123cda4c..e1507bedd01 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -26,7 +26,6 @@
#include "abc_customdata.h"
#include "abc_object.h"
-struct DerivedMesh;
struct Mesh;
struct ModifierData;
@@ -50,9 +49,7 @@ class AbcMeshWriter : public AbcObjectWriter {
bool m_is_subd;
public:
- AbcMeshWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+ AbcMeshWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings);
@@ -65,29 +62,28 @@ private:
bool isAnimated() const;
- void writeMesh(DerivedMesh *dm);
- void writeSubD(DerivedMesh *dm);
+ void writeMesh(struct Mesh *mesh);
+ void writeSubD(struct Mesh *mesh);
- void getMeshInfo(DerivedMesh *dm, std::vector<float> &points,
+ void getMeshInfo(struct Mesh *mesh, std::vector<float> &points,
std::vector<int32_t> &facePoints,
std::vector<int32_t> &faceCounts,
std::vector<int32_t> &creaseIndices,
std::vector<int32_t> &creaseLengths,
std::vector<float> &creaseSharpness);
- DerivedMesh *getFinalMesh();
- void freeMesh(DerivedMesh *dm);
+ struct Mesh *getFinalMesh(bool &r_needsfree);
- void getMaterialIndices(DerivedMesh *dm, std::vector<int32_t> &indices);
+ void getMaterialIndices(struct Mesh *mesh, std::vector<int32_t> &indices);
- void writeArbGeoParams(DerivedMesh *dm);
- void getGeoGroups(DerivedMesh *dm, std::map<std::string, std::vector<int32_t> > &geoGroups);
+ void writeArbGeoParams(struct Mesh *mesh);
+ void getGeoGroups(struct Mesh *mesh, std::map<std::string, std::vector<int32_t> > &geoGroups);
/* fluid surfaces support */
- void getVelocities(DerivedMesh *dm, std::vector<Imath::V3f> &vels);
+ void getVelocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels);
template <typename Schema>
- void writeFaceSets(DerivedMesh *dm, Schema &schema);
+ void writeFaceSets(struct Mesh *mesh, Schema &schema);
};
/* ************************************************************************** */
@@ -106,10 +102,10 @@ public:
const char **err_str) const;
void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
+ struct Mesh *read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
private:
void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
@@ -136,10 +132,10 @@ public:
const Object *const ob,
const char **err_str) const;
void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
+ struct Mesh *read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
};
/* ************************************************************************** */
@@ -148,6 +144,6 @@ void read_mverts(MVert *mverts,
const Alembic::AbcGeom::P3fArraySamplePtr &positions,
const Alembic::AbcGeom::N3fArraySamplePtr &normals);
-CDStreamConfig get_config(DerivedMesh *dm);
+CDStreamConfig get_config(struct Mesh *mesh);
#endif /* __ABC_MESH_H__ */
diff --git a/source/blender/alembic/intern/abc_nurbs.cc b/source/blender/alembic/intern/abc_nurbs.cc
index 1f042d0bafc..95d06fc5efe 100644
--- a/source/blender/alembic/intern/abc_nurbs.cc
+++ b/source/blender/alembic/intern/abc_nurbs.cc
@@ -60,13 +60,11 @@ using Alembic::AbcGeom::ONuPatchSchema;
/* ************************************************************************** */
-AbcNurbsWriter::AbcNurbsWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+AbcNurbsWriter::AbcNurbsWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings)
- : AbcObjectWriter(depsgraph, scene, ob, time_sampling, settings, parent)
+ : AbcObjectWriter(ob, time_sampling, settings, parent)
{
m_is_animated = isAnimated();
@@ -255,7 +253,19 @@ void AbcNurbsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSele
nu->resolv = cu->resolv;
const INuPatchSchema &schema = it->first;
- const INuPatchSchema::Sample smp = schema.getValue(sample_sel);
+ INuPatchSchema::Sample smp;
+ try {
+ smp = schema.getValue(sample_sel);
+ }
+ catch(Alembic::Util::Exception &ex) {
+ printf("Alembic: error reading nurbs sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return;
+ }
+
nu->orderu = smp.getUOrder() - 1;
nu->orderv = smp.getVOrder() - 1;
diff --git a/source/blender/alembic/intern/abc_nurbs.h b/source/blender/alembic/intern/abc_nurbs.h
index d2422345c3f..827aa4b365f 100644
--- a/source/blender/alembic/intern/abc_nurbs.h
+++ b/source/blender/alembic/intern/abc_nurbs.h
@@ -32,9 +32,7 @@ class AbcNurbsWriter : public AbcObjectWriter {
bool m_is_animated;
public:
- AbcNurbsWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+ AbcNurbsWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings);
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index 85bda9aa8eb..7e0b1ccfbd4 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -58,16 +58,12 @@ using Alembic::AbcGeom::OStringProperty;
/* ************************************************************************** */
-AbcObjectWriter::AbcObjectWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+AbcObjectWriter::AbcObjectWriter(Object *ob,
uint32_t time_sampling,
ExportSettings &settings,
AbcObjectWriter *parent)
: m_object(ob)
, m_settings(settings)
- , m_depsgraph(depsgraph)
- , m_scene(scene)
, m_time_sampling(time_sampling)
, m_first_frame(true)
{
@@ -248,12 +244,12 @@ Imath::M44d get_matrix(const IXformSchema &schema, const float time)
return s0.getMatrix();
}
-DerivedMesh *AbcObjectReader::read_derivedmesh(DerivedMesh *dm,
- const Alembic::Abc::ISampleSelector &UNUSED(sample_sel),
- int UNUSED(read_flag),
- const char **UNUSED(err_str))
+struct Mesh *AbcObjectReader::read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &UNUSED(sample_sel),
+ int UNUSED(read_flag),
+ const char **UNUSED(err_str))
{
- return dm;
+ return existing_mesh;
}
void AbcObjectReader::setupObjectTransform(const float time)
diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h
index d41088bdcad..8794cb61708 100644
--- a/source/blender/alembic/intern/abc_object.h
+++ b/source/blender/alembic/intern/abc_object.h
@@ -44,8 +44,6 @@ protected:
Object *m_object;
ExportSettings &m_settings;
- Depsgraph *m_depsgraph;
- Scene *m_scene;
uint32_t m_time_sampling;
Imath::Box3d m_bounds;
@@ -57,9 +55,7 @@ protected:
std::string m_name;
public:
- AbcObjectWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+ AbcObjectWriter(Object *ob,
uint32_t time_sampling,
ExportSettings &settings,
AbcObjectWriter *parent = NULL);
@@ -124,7 +120,7 @@ static bool has_animations(Schema &schema, ImportSettings *settings)
/* ************************************************************************** */
-struct DerivedMesh;
+struct Mesh;
using Alembic::AbcCoreAbstract::chrono_t;
@@ -180,10 +176,10 @@ public:
virtual void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) = 0;
- virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
+ virtual struct Mesh *read_mesh(struct Mesh *mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
/** Reads the object matrix and sets up an object transform if animated. */
void setupObjectTransform(const float time);
diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc
index 6f52ccec4a7..9ff995ffcbf 100644
--- a/source/blender/alembic/intern/abc_points.cc
+++ b/source/blender/alembic/intern/abc_points.cc
@@ -40,6 +40,8 @@ extern "C" {
#include "BKE_scene.h"
#include "BLI_math.h"
+
+#include "DEG_depsgraph_query.h"
}
using Alembic::AbcGeom::kVertexScope;
@@ -58,14 +60,12 @@ using Alembic::AbcGeom::OPointsSchema;
/* ************************************************************************** */
-AbcPointsWriter::AbcPointsWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+AbcPointsWriter::AbcPointsWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings,
ParticleSystem *psys)
- : AbcObjectWriter(depsgraph, scene, ob, time_sampling, settings, parent)
+ : AbcObjectWriter(ob, time_sampling, settings, parent)
{
m_psys = psys;
@@ -87,8 +87,8 @@ void AbcPointsWriter::do_write()
ParticleKey state;
ParticleSimulationData sim;
- sim.depsgraph = m_depsgraph;
- sim.scene = m_scene;
+ sim.depsgraph = m_settings.depsgraph;
+ sim.scene = m_settings.scene;
sim.ob = m_object;
sim.psys = m_psys;
@@ -102,7 +102,7 @@ void AbcPointsWriter::do_write()
continue;
}
- state.time = BKE_scene_frame_get(m_scene);
+ state.time = DEG_get_ctime(m_settings.depsgraph);
if (psys_get_particle_state(&sim, p, &state, 0) == 0) {
continue;
@@ -173,15 +173,9 @@ bool AbcPointsReader::accepts_object_type(const Alembic::AbcCoreAbstract::Object
void AbcPointsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
+ Mesh *read_mesh = this->read_mesh(mesh, sample_sel, 0, NULL);
- DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, 0, NULL);
-
- if (ndm != dm) {
- dm->release(dm);
- }
-
- DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, CD_MASK_MESH, true);
if (m_settings->validate_meshes) {
BKE_mesh_validate(mesh, false, false);
@@ -218,23 +212,35 @@ void read_points_sample(const IPointsSchema &schema,
read_mverts(config.mvert, positions, vnormals);
}
-DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm,
- const ISampleSelector &sample_sel,
- int /*read_flag*/,
- const char ** /*err_str*/)
+struct Mesh *AbcPointsReader::read_mesh(struct Mesh *existing_mesh,
+ const ISampleSelector &sample_sel,
+ int /*read_flag*/,
+ const char **err_str)
{
- const IPointsSchema::Sample sample = m_schema.getValue(sample_sel);
+ IPointsSchema::Sample sample;
+ try {
+ sample = m_schema.getValue(sample_sel);
+ }
+ catch(Alembic::Util::Exception &ex) {
+ *err_str = "Error reading points sample; more detail on the console";
+ printf("Alembic: error reading points sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return existing_mesh;
+ }
const P3fArraySamplePtr &positions = sample.getPositions();
- DerivedMesh *new_dm = NULL;
+ Mesh *new_mesh = NULL;
- if (dm->getNumVerts(dm) != positions->size()) {
- new_dm = CDDM_new(positions->size(), 0, 0, 0, 0);
+ if (existing_mesh->totvert != positions->size()) {
+ new_mesh = BKE_mesh_new_nomain(positions->size(), 0, 0, 0, 0);
}
- CDStreamConfig config = get_config(new_dm ? new_dm : dm);
+ CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
read_points_sample(m_schema, sample_sel, config);
- return new_dm ? new_dm : dm;
+ return new_mesh ? new_mesh : existing_mesh;
}
diff --git a/source/blender/alembic/intern/abc_points.h b/source/blender/alembic/intern/abc_points.h
index 1ac8792ede1..e986f9448f4 100644
--- a/source/blender/alembic/intern/abc_points.h
+++ b/source/blender/alembic/intern/abc_points.h
@@ -38,9 +38,7 @@ class AbcPointsWriter : public AbcObjectWriter {
ParticleSystem *m_psys;
public:
- AbcPointsWriter(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
+ AbcPointsWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings,
@@ -65,10 +63,10 @@ public:
void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
+ struct Mesh *read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
};
void read_points_sample(const Alembic::AbcGeom::IPointsSchema &schema,
diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc
index e5da367b9a9..81ebfef3e11 100644
--- a/source/blender/alembic/intern/abc_transform.cc
+++ b/source/blender/alembic/intern/abc_transform.cc
@@ -32,6 +32,8 @@ extern "C" {
#include "BLI_math.h"
#include "BKE_object.h"
+
+#include "DEG_depsgraph_query.h"
}
using Alembic::AbcGeom::OObject;
@@ -57,13 +59,12 @@ static bool has_parent_camera(Object *ob)
/* ************************************************************************** */
-AbcTransformWriter::AbcTransformWriter(Depsgraph *depsgraph,
- Object *ob,
+AbcTransformWriter::AbcTransformWriter(Object *ob,
const OObject &abc_parent,
AbcTransformWriter *parent,
unsigned int time_sampling,
ExportSettings &settings)
- : AbcObjectWriter(depsgraph, NULL, ob, time_sampling, settings, parent)
+ : AbcObjectWriter(ob, time_sampling, settings, parent)
, m_proxy_from(NULL)
{
m_is_animated = hasAnimation(m_object);
@@ -81,29 +82,31 @@ AbcTransformWriter::AbcTransformWriter(Depsgraph *depsgraph,
void AbcTransformWriter::do_write()
{
+ Object *ob_eval = DEG_get_evaluated_object(m_settings.depsgraph, m_object);
+
if (m_first_frame) {
m_visibility = Alembic::AbcGeom::CreateVisibilityProperty(m_xform, m_xform.getSchema().getTimeSampling());
}
- m_visibility.set(!(m_object->restrictflag & OB_RESTRICT_VIEW));
+ m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_VIEW));
if (!m_first_frame && !m_is_animated) {
return;
}
float yup_mat[4][4];
- create_transform_matrix(m_object, yup_mat,
+ create_transform_matrix(ob_eval, yup_mat,
m_inherits_xform ? ABC_MATRIX_LOCAL : ABC_MATRIX_WORLD,
m_proxy_from);
/* Only apply rotation to root camera, parenting will propagate it. */
- if (m_object->type == OB_CAMERA && (!m_inherits_xform || !has_parent_camera(m_object))) {
+ if (ob_eval->type == OB_CAMERA && (!m_inherits_xform || !has_parent_camera(ob_eval))) {
float rot_mat[4][4];
axis_angle_to_mat4_single(rot_mat, 'X', -M_PI_2);
mul_m4_m4m4(yup_mat, yup_mat, rot_mat);
}
- if (!m_object->parent || !m_inherits_xform) {
+ if (!ob_eval->parent || !m_inherits_xform) {
/* Only apply scaling to root objects, parenting will propagate it. */
float scale_mat[4][4];
scale_m4_fl(scale_mat, m_settings.global_scale);
diff --git a/source/blender/alembic/intern/abc_transform.h b/source/blender/alembic/intern/abc_transform.h
index 91420b28f93..12bf9d38007 100644
--- a/source/blender/alembic/intern/abc_transform.h
+++ b/source/blender/alembic/intern/abc_transform.h
@@ -43,8 +43,7 @@ public:
Object *m_proxy_from;
public:
- AbcTransformWriter(Depsgraph *depsgraph,
- Object *ob,
+ AbcTransformWriter(Object *ob,
const Alembic::AbcGeom::OObject &abc_parent,
AbcTransformWriter *parent,
unsigned int time_sampling,
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index 6787d118fa1..53860ab149d 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -181,11 +181,11 @@ void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMod
unit_m3(dst_rot);
unit_m4(dst_scale_mat);
- /* We assume there is no sheer component and no homogeneous scaling component. */
- BLI_assert(fabs(src_mat[0][3]) < 2 * FLT_EPSILON);
- BLI_assert(fabs(src_mat[1][3]) < 2 * FLT_EPSILON);
- BLI_assert(fabs(src_mat[2][3]) < 2 * FLT_EPSILON);
- BLI_assert(fabs(src_mat[3][3] - 1.0f) < 2 * FLT_EPSILON);
+ /* TODO(Sybren): This code assumes there is no sheer component and no
+ * homogeneous scaling component, which is not always true when writing
+ * non-hierarchical (e.g. flat) objects (e.g. when parent has non-uniform
+ * scale and the child rotates). This is currently not taken into account
+ * when axis-swapping. */
/* Extract translation, rotation, and scale form matrix. */
mat4_to_loc_rot_size(src_trans, src_rot, src_scale, src_mat);
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 1a6990a1de8..cc9923189c7 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -230,9 +230,7 @@ static void find_iobject(const IObject &object, IObject &ret,
}
struct ExportJobData {
- Scene *scene;
ViewLayer *view_layer;
- Depsgraph *depsgraph;
Main *bmain;
char filename[1024];
@@ -262,10 +260,16 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo
G.is_break = false;
+ DEG_graph_build_from_view_layer(data->settings.depsgraph,
+ data->bmain,
+ data->settings.scene,
+ data->view_layer);
+ BKE_scene_graph_update_tagged(data->settings.depsgraph, data->bmain);
+
try {
- Scene *scene = data->scene;
- AbcExporter exporter(data->bmain, scene, data->depsgraph, data->filename, data->settings);
+ AbcExporter exporter(data->bmain, data->filename, data->settings);
+ Scene *scene = data->settings.scene; /* for the CFRA macro */
const int orig_frame = CFRA;
data->was_canceled = false;
@@ -274,7 +278,7 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo
if (CFRA != orig_frame) {
CFRA = orig_frame;
- BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain);
+ BKE_scene_graph_update_for_newframe(data->settings.depsgraph, data->bmain);
}
data->export_ok = !data->was_canceled;
@@ -313,9 +317,7 @@ bool ABC_export(
{
ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
- job->scene = scene;
job->view_layer = CTX_data_view_layer(C);
- job->depsgraph = CTX_data_depsgraph(C);
job->bmain = CTX_data_main(C);
job->export_ok = false;
BLI_strncpy(job->filename, filepath, 1024);
@@ -336,14 +338,14 @@ bool ABC_export(
* do bigger refactor and maybe there is a better way which does not involve
* hardcore refactoring. */
new (&job->settings) ExportSettings();
- job->settings.scene = job->scene;
- job->settings.depsgraph = job->depsgraph;
+ job->settings.scene = scene;
+ job->settings.depsgraph = DEG_graph_new(scene, job->view_layer, DAG_EVAL_RENDER);
/* Sybren: for now we only export the active scene layer.
* Later in the 2.8 development process this may be replaced by using
* a specific collection for Alembic I/O, which can then be toggled
* between "real" objects and cached Alembic files. */
- job->settings.view_layer = CTX_data_view_layer(C);
+ job->settings.view_layer = job->view_layer;
job->settings.frame_start = params->frame_start;
job->settings.frame_end = params->frame_end;
@@ -387,7 +389,7 @@ bool ABC_export(
if (as_background_job) {
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
CTX_wm_window(C),
- job->scene,
+ job->settings.scene,
"Alembic Export",
WM_JOB_PROGRESS,
WM_JOB_TYPE_ALEMBIC);
@@ -960,12 +962,12 @@ void ABC_get_transform(CacheReader *reader, float r_mat[4][4], float time, float
/* ************************************************************************** */
-DerivedMesh *ABC_read_mesh(CacheReader *reader,
- Object *ob,
- DerivedMesh *dm,
- const float time,
- const char **err_str,
- int read_flag)
+Mesh *ABC_read_mesh(CacheReader *reader,
+ Object *ob,
+ Mesh *existing_mesh,
+ const float time,
+ const char **err_str,
+ int read_flag)
{
AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
IObject iobject = abc_reader->iobject();
@@ -984,7 +986,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
/* kFloorIndex is used to be compatible with non-interpolating
* properties; they use the floor. */
ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
- return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str);
+ return abc_reader->read_mesh(existing_mesh, sample_sel, read_flag, err_str);
}
/* ************************************************************************** */
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index fafee125264..5dd692d3855 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -172,7 +172,7 @@ static int blf_search_available(void)
for (i = 0; i < BLF_MAX_FONT; i++)
if (!global_font[i])
return i;
-
+
return -1;
}
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index d3349a10834..ff5c1151a82 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -61,7 +61,7 @@ static ListBase global_font_dir = { NULL, NULL };
static DirBLF *blf_dir_find(const char *path)
{
DirBLF *p;
-
+
p = global_font_dir.first;
while (p) {
if (BLI_path_cmp(p->path, path) == 0)
@@ -74,11 +74,11 @@ static DirBLF *blf_dir_find(const char *path)
void BLF_dir_add(const char *path)
{
DirBLF *dir;
-
+
dir = blf_dir_find(path);
if (dir) /* already in the list ? just return. */
return;
-
+
dir = (DirBLF *)MEM_callocN(sizeof(DirBLF), "BLF_dir_add");
dir->path = BLI_strdup(path);
BLI_addhead(&global_font_dir, dir);
@@ -87,7 +87,7 @@ void BLF_dir_add(const char *path)
void BLF_dir_rem(const char *path)
{
DirBLF *dir;
-
+
dir = blf_dir_find(path);
if (dir) {
BLI_remlink(&global_font_dir, dir);
@@ -102,11 +102,11 @@ char **BLF_dir_get(int *ndir)
char **dirs;
char *path;
int i, count;
-
+
count = BLI_listbase_count(&global_font_dir);
if (!count)
return NULL;
-
+
dirs = (char **)MEM_callocN(sizeof(char *) * count, "BLF_dir_get");
p = global_font_dir.first;
i = 0;
@@ -123,7 +123,7 @@ void BLF_dir_free(char **dirs, int count)
{
char *path;
int i;
-
+
for (i = 0; i < count; i++) {
path = dirs[i];
MEM_freeN(path);
@@ -159,7 +159,7 @@ int blf_dir_split(const char *str, char *file, int *size)
{
int i, len;
char *s;
-
+
/* Window, Linux or Mac, this is always / */
s = strrchr(str, '/');
if (s) {
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index c31aacb0a54..1289dc6c5a6 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -553,7 +553,7 @@ static void blf_font_draw_buffer_ex(
width_clip -= chx + width_clip - buf_info->w;
if (height_clip + pen_y > buf_info->h)
height_clip -= pen_y + height_clip - buf_info->h;
-
+
/* drawing below the image? */
if (pen_y < 0) {
yb_start += (g->pitch < 0) ? -pen_y : pen_y;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index f3789bee1fd..5a87c726566 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -292,11 +292,11 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
if (font->flags & BLF_HINTING)
flags &= ~FT_LOAD_NO_HINTING;
-
+
if (is_sharp)
err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO);
else
- err = FT_Load_Glyph(font->face, (FT_UInt)index, flags);
+ err = FT_Load_Glyph(font->face, (FT_UInt)index, flags);
if (err) {
BLI_spin_unlock(font->ft_lib_mutex);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 5b9d3f1eb5b..d7b526735d1 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -204,7 +204,7 @@ typedef struct FontBLF {
/* angle in radians. */
float angle;
-
+
#if 0 /* BLF_BLUR_ENABLE */
/* blur: 3 or 5 large kernel */
int blur;
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index e918f158682..79b0e5eb95f 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -531,18 +531,6 @@ DMCoNo *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob);
void mesh_get_mapped_verts_coords(DerivedMesh *dm, float (*r_cos)[3], const int totcos);
/* */
-DerivedMesh *mesh_get_derived_final(
- struct Depsgraph *depsgraph, struct Scene *scene,
- struct Object *ob, CustomDataMask dataMask);
-struct Mesh *mesh_get_eval_final(
- struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, CustomDataMask dataMask);
-
-DerivedMesh *mesh_get_derived_deform(
- struct Depsgraph *depsgraph, struct Scene *scene,
- struct Object *ob, CustomDataMask dataMask);
-struct Mesh *mesh_get_eval_deform(
- struct Depsgraph *depsgraph, struct Scene *scene,
- struct Object *ob, CustomDataMask dataMask);
DerivedMesh *mesh_create_derived_for_modifier(
struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob,
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 701be9d44cc..2f7d0eaba03 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -32,16 +32,17 @@
* \author nzc
* \since March 2001
*/
-struct Depsgraph;
-struct Path;
-struct Object;
-struct Scene;
-struct ListBase;
struct bAnimVizSettings;
struct bMotionPath;
struct bPoseChannel;
-struct ReportList;
+struct Depsgraph;
+struct ListBase;
struct Main;
+struct Object;
+struct ParticleSystem;
+struct Path;
+struct ReportList;
+struct Scene;
/* ---------------------------------------------------- */
/* Animation Visualization */
@@ -68,7 +69,6 @@ int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], fl
/* ---------------------------------------------------- */
/* Dupli-Geometry */
-struct ListBase *object_duplilist_ex(struct Depsgraph *depsgraph, struct Scene *sce, struct Object *ob, bool update);
struct ListBase *object_duplilist(struct Depsgraph *depsgraph, struct Scene *sce, struct Object *ob);
void free_object_duplilist(struct ListBase *lb);
int count_duplilist(struct Object *ob);
@@ -83,6 +83,26 @@ typedef struct DupliApplyData {
DupliExtraData *extra;
} DupliApplyData;
+typedef struct DupliObject {
+ struct DupliObject *next, *prev;
+ struct Object *ob;
+ float mat[4][4];
+ float orco[3], uv[2];
+
+ short type; /* from Object.transflag */
+ char no_draw;
+
+ /* Persistent identifier for a dupli object, for inter-frame matching of
+ * objects with motion blur, or inter-update matching for syncing. */
+ int persistent_id[16]; /* 2*MAX_DUPLI_RECUR */
+
+ /* Particle this dupli was generated from. */
+ struct ParticleSystem *particle_system;
+
+ /* Random ID for shading */
+ unsigned int random_id;
+} DupliObject;
+
DupliApplyData *duplilist_apply(struct Depsgraph *depsgraph, struct Object *ob, struct Scene *scene, struct ListBase *duplilist);
void duplilist_restore(struct ListBase *duplilist, DupliApplyData *apply_data);
void duplilist_free_apply_data(DupliApplyData *apply_data);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 8befeff498e..a1212322983 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -28,7 +28,7 @@
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 280
-#define BLENDER_SUBVERSION 16
+#define BLENDER_SUBVERSION 17
/* Several breakages with 270, e.g. constraint deg vs rad */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 6
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index edc24d9649e..fc5b19ccb4f 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -91,7 +91,6 @@ bool BKE_collection_is_in_scene(struct Collection *collection);
void BKE_collections_after_lib_link(struct Main *bmain);
bool BKE_collection_object_cyclic_check(struct Main *bmain, struct Object *object, struct Collection *collection);
bool BKE_collection_is_animated(struct Collection *collection, struct Object *parent);
-void BKE_collection_handle_recalc_and_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *parent, struct Collection *collection);
/* Object list cache. */
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 0f05170b47c..28bc254f25a 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -182,6 +182,9 @@ struct BlendThumbnail *BKE_main_thumbnail_from_imbuf(struct Main *bmain, struct
struct ImBuf *BKE_main_thumbnail_to_imbuf(struct Main *bmain, struct BlendThumbnail *data);
void BKE_main_thumbnail_create(struct Main *bmain);
+const char *BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL();
+const char *BKE_main_blendfile_path_from_global(void);
+
void BKE_main_id_tag_idcode(struct Main *mainvar, const short type, const int tag, const bool value);
void BKE_main_id_tag_listbase(struct ListBase *lb, const int tag, const bool value);
void BKE_main_id_tag_all(struct Main *mainvar, const int tag, const bool value);
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 41f04c09e69..74ef9d9dbc0 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -76,8 +76,6 @@ void BKE_mball_select_swap(struct MetaBall *mb);
struct Depsgraph;
-void BKE_mball_eval_geometry(struct Depsgraph *depsgraph,
- struct MetaBall *mball);
/* Draw Cache */
enum {
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index efbc00c456f..cb58deb9511 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -178,9 +178,9 @@ struct Mesh *BKE_mesh_create_derived_for_modifier(
struct ModifierData *md, int build_shapekey_layers);
/* Copies a nomain-Mesh into an existing Mesh. */
-void BKE_nomain_mesh_to_mesh(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct Object *ob,
+void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct Object *ob,
CustomDataMask mask, bool take_ownership);
-void BKE_nomain_mesh_to_meshkey(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct KeyBlock *kb);
+void BKE_mesh_nomain_to_meshkey(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct KeyBlock *kb);
/* vertex level transformations & checks (no derived mesh) */
@@ -206,23 +206,10 @@ void BKE_mesh_mselect_active_set(struct Mesh *me, int index, int type);
void BKE_mesh_apply_vert_coords(struct Mesh *mesh, float (*vertCoords)[3]);
-/* *** mesh_runtime.c *** */
-void BKE_mesh_runtime_reset(struct Mesh *mesh);
-int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
-void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
-const struct MLoopTri *BKE_mesh_runtime_looptri_ensure(struct Mesh *mesh);
-bool BKE_mesh_runtime_ensure_edit_data(struct Mesh *mesh);
-bool BKE_mesh_runtime_clear_edit_data(struct Mesh *mesh);
-void BKE_mesh_runtime_clear_geometry(struct Mesh *mesh);
-void BKE_mesh_runtime_clear_cache(struct Mesh *mesh);
-
-void BKE_mesh_runtime_verttri_from_looptri(
- struct MVertTri *r_verttri,
- const struct MLoop *mloop, const struct MLoopTri *looptri, int looptri_num);
-
/* *** mesh_evaluate.c *** */
+void BKE_mesh_calc_normals_mapping_simple(struct Mesh *me);
void BKE_mesh_calc_normals_mapping(
struct MVert *mverts, int numVerts,
const struct MLoop *mloop, const struct MPoly *mpolys, int numLoops, int numPolys, float (*r_polyNors)[3],
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
new file mode 100644
index 00000000000..6904ad529de
--- /dev/null
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -0,0 +1,85 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_MESH_RUNTIME_H__
+#define __BKE_MESH_RUNTIME_H__
+
+/** \file BKE_mesh_runtime.h
+ * \ingroup bke
+ *
+ * This file contains access functions for the Mesh.runtime struct.
+ */
+
+#include "BKE_customdata.h" /* for CustomDataMask */
+
+struct Depsgraph;
+struct Mesh;
+struct MLoop;
+struct MLoopTri;
+struct MVertTri;
+struct Object;
+struct Scene;
+
+/* Undefine to hide DerivedMesh-based function declarations */
+#define USE_DERIVEDMESH
+
+#ifdef USE_DERIVEDMESH
+struct DerivedMesh;
+#endif
+
+void BKE_mesh_runtime_reset(struct Mesh *mesh);
+int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
+void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
+const struct MLoopTri *BKE_mesh_runtime_looptri_ensure(struct Mesh *mesh);
+bool BKE_mesh_runtime_ensure_edit_data(struct Mesh *mesh);
+bool BKE_mesh_runtime_clear_edit_data(struct Mesh *mesh);
+void BKE_mesh_runtime_clear_geometry(struct Mesh *mesh);
+void BKE_mesh_runtime_clear_cache(struct Mesh *mesh);
+
+void BKE_mesh_runtime_verttri_from_looptri(
+ struct MVertTri *r_verttri,
+ const struct MLoop *mloop, const struct MLoopTri *looptri, int looptri_num);
+
+/* NOTE: the functions below are defined in DerivedMesh.c, and are intended to be moved
+ * to a more suitable location when that file is removed. */
+#ifdef USE_DERIVEDMESH
+struct DerivedMesh *mesh_get_derived_final(
+ struct Depsgraph *depsgraph, struct Scene *scene,
+ struct Object *ob, CustomDataMask dataMask);
+#endif
+struct Mesh *mesh_get_eval_final(
+ struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, CustomDataMask dataMask);
+
+#ifdef USE_DERIVEDMESH
+struct DerivedMesh *mesh_get_derived_deform(
+ struct Depsgraph *depsgraph, struct Scene *scene,
+ struct Object *ob, CustomDataMask dataMask);
+#endif
+struct Mesh *mesh_get_eval_deform(
+ struct Depsgraph *depsgraph, struct Scene *scene,
+ struct Object *ob, CustomDataMask dataMask);
+
+#endif /* __BKE_MESH_RUNTIME_H__ */
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index b5d3e67b970..b40d32203f6 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -468,7 +468,7 @@ void modifier_mdef_compact_influences(struct ModifierData *md);
void modifier_path_init(char *path, int path_maxlen, const char *name);
const char *modifier_path_relbase(struct Main *bmain, struct Object *ob);
-
+const char *modifier_path_relbase_from_global(struct Object *ob);
/* wrappers for modifier callbacks that ensure valid normals */
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 5b5ebbf035c..014ea2b9159 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -49,7 +49,7 @@ void BKE_movieclip_make_local(struct Main *bmain, struct MovieClip *clip, const
struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name);
struct MovieClip *BKE_movieclip_file_add_exists_ex(struct Main *bmain, const char *name, bool *r_exists);
struct MovieClip *BKE_movieclip_file_add_exists(struct Main *bmain, const char *name);
-void BKE_movieclip_reload(struct MovieClip *clip);
+void BKE_movieclip_reload(struct Main *bmain, struct MovieClip *clip);
void BKE_movieclip_clear_cache(struct MovieClip *clip);
void BKE_movieclip_clear_proxy_cache(struct MovieClip *clip);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 915cafd5d3d..cb211b65948 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1056,9 +1056,6 @@ void free_nodesystem(void);
struct Depsgraph;
-void BKE_nodetree_copy_default_values(struct bNodeTree *ntree_dst,
- const struct bNodeTree *ntree_src);
-
void BKE_nodetree_shading_params_eval(struct Depsgraph *depsgraph,
struct bNodeTree *ntree_dst,
const struct bNodeTree *ntree_src);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 3929a97ab65..6172c9998af 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -66,6 +66,7 @@ void BKE_object_free_curve_cache(struct Object *ob);
void BKE_object_free(struct Object *ob);
void BKE_object_free_derived_caches(struct Object *ob);
+void BKE_object_free_derived_mesh_caches(struct Object *ob);
void BKE_object_free_caches(struct Object *object);
void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *hmd);
@@ -274,6 +275,9 @@ void BKE_object_sculpt_modifiers_changed(struct Object *ob);
int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);
struct Mesh *BKE_object_get_evaluated_mesh(const struct Depsgraph *depsgraph, struct Object *ob);
+struct Mesh *BKE_object_get_final_mesh(struct Object *object);
+struct Mesh *BKE_object_get_pre_modified_mesh(struct Object *object);
+struct Mesh *BKE_object_get_original_mesh(struct Object *object);
int BKE_object_insert_ptcache(struct Object *ob);
void BKE_object_delete_ptcache(struct Object *ob, int index);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 9bd73bd7553..412cf45de2b 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -40,6 +40,7 @@ struct CurveMapping;
struct MeshElemMap;
struct GridPaintMask;
struct Main;
+struct Mesh;
struct MLoop;
struct MLoopTri;
struct MFace;
@@ -185,7 +186,8 @@ typedef struct SculptSession {
float *vmask;
/* Mesh connectivity */
- const struct MeshElemMap *pmap;
+ struct MeshElemMap *pmap;
+ int *pmap_mem;
/* BMesh for dynamic topology sculpting */
struct BMesh *bm;
@@ -258,6 +260,8 @@ int BKE_sculpt_mask_layers_ensure(struct Object *ob,
struct MultiresModifierData *mmd);
void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene);
+struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Object *ob, struct Mesh *me_eval_deform);
+
enum {
SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1)
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 4820f0173bf..d87d63454f0 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -303,15 +303,13 @@ void psys_set_current_num(Object *ob, int index);
struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim);
struct ParticleSystem *psys_orig_get(struct ParticleSystem *psys);
-struct ParticleSystem *psys_eval_get(struct Depsgraph *depsgraph,
- struct Object *object,
- struct ParticleSystem *psys);
bool psys_in_edit_mode(struct Depsgraph *depsgraph, struct ParticleSystem *psys);
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, const bool use_render_params);
bool psys_check_edited(struct ParticleSystem *psys);
void psys_check_group_weights(struct ParticleSettings *part);
int psys_uses_gravity(struct ParticleSimulationData *sim);
+void BKE_particlesettings_fluid_default_settings(struct ParticleSettings *part);
/* free */
void BKE_particlesettings_free(struct ParticleSettings *part);
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index c18288de1bc..78c766f6115 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -240,7 +240,7 @@ void BKE_pbvh_node_layer_disp_free(PBVHNode *node);
/* vertex deformer */
float (*BKE_pbvh_get_vertCos(struct PBVH *pbvh))[3];
-void BKE_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
+void BKE_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3], const int totvert);
bool BKE_pbvh_isDeformed(struct PBVH *pbvh);
/* Vertex Iterator */
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 722a36c9f1d..0b95152ad8e 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -64,7 +64,7 @@ struct ScrAreaMap;
#include "RNA_types.h"
-/* spacetype has everything stored to get an editor working, it gets initialized via
+/* spacetype has everything stored to get an editor working, it gets initialized via
* ED_spacetypes_init() in editors/space_api/spacetypes.c */
/* an editor in Blender is a combined ScrArea + SpaceType + SpaceData */
@@ -72,36 +72,36 @@ struct ScrAreaMap;
typedef struct SpaceType {
struct SpaceType *next, *prev;
-
+
char name[BKE_ST_MAXNAME]; /* for menus */
int spaceid; /* unique space identifier */
int iconid; /* icon lookup for menus */
-
+
/* Initial allocation, after this WM will call init() too. Some editors need
* area and scene data (e.g. frame range) to set their initial scrolling. */
- struct SpaceLink *(*new)(const struct ScrArea *, const struct Scene *);
+ struct SpaceLink *(*new)(const struct ScrArea *sa, const struct Scene *scene);
/* not free spacelink itself */
- void (*free)(struct SpaceLink *);
-
+ void (*free)(struct SpaceLink *sl);
+
/* init is to cope with file load, screen (size) changes, check handlers */
- void (*init)(struct wmWindowManager *, struct ScrArea *);
+ void (*init)(struct wmWindowManager *wm, struct ScrArea *sa);
/* exit is called when the area is hidden or removed */
- void (*exit)(struct wmWindowManager *, struct ScrArea *);
+ void (*exit)(struct wmWindowManager *wm, struct ScrArea *sa);
/* Listeners can react to bContext changes */
- void (*listener)(struct bScreen *sc, struct ScrArea *,
- struct wmNotifier *, struct Scene *scene,
+ void (*listener)(struct bScreen *sc, struct ScrArea *sa,
+ struct wmNotifier *wmn, struct Scene *scene,
struct WorkSpace *workspace);
-
+
/* refresh context, called after filereads, ED_area_tag_refresh() */
- void (*refresh)(const struct bContext *, struct ScrArea *);
-
+ void (*refresh)(const struct bContext *C, struct ScrArea *sa);
+
/* after a spacedata copy, an init should result in exact same situation */
- struct SpaceLink *(*duplicate)(struct SpaceLink *);
+ struct SpaceLink *(*duplicate)(struct SpaceLink *sl);
/* register operator types on startup */
void (*operatortypes)(void);
/* add default items to WM keymap */
- void (*keymap)(struct wmKeyConfig *);
+ void (*keymap)(struct wmKeyConfig *keyconf);
/* on startup, define dropboxes for spacetype+regions */
void (*dropboxes)(void);
@@ -109,10 +109,10 @@ typedef struct SpaceType {
void (*manipulators)(void);
/* return context data */
- int (*context)(const struct bContext *, const char *, struct bContextDataResult *);
+ int (*context)(const struct bContext *C, const char *member, struct bContextDataResult *result);
/* Used when we want to replace an ID by another (or NULL). */
- void (*id_remap)(struct ScrArea *, struct SpaceLink *, struct ID *, struct ID *);
+ void (*id_remap)(struct ScrArea *sa, struct SpaceLink *sl, struct ID *old_id, struct ID *new_id);
int (*space_subtype_get)(struct ScrArea *sa);
void (*space_subtype_set)(struct ScrArea *sa, int value);
@@ -120,37 +120,37 @@ typedef struct SpaceType {
/* region type definitions */
ListBase regiontypes;
-
+
/* tool shelf definitions */
ListBase toolshelf;
-
+
/* read and write... */
-
+
/* default keymaps to add */
int keymapflag;
-
+
} SpaceType;
/* region types are also defined using spacetypes_init, via a callback */
typedef struct ARegionType {
struct ARegionType *next, *prev;
-
+
int regionid; /* unique identifier within this space, defines RGN_TYPE_xxxx */
-
+
/* add handlers, stuff you only do once or on area/region type/size changes */
- void (*init)(struct wmWindowManager *, struct ARegion *);
+ void (*init)(struct wmWindowManager *wm, struct ARegion *ar);
/* exit is called when the region is hidden or removed */
- void (*exit)(struct wmWindowManager *, struct ARegion *);
+ void (*exit)(struct wmWindowManager *wm, struct ARegion *ar);
/* draw entirely, view changes should be handled here */
- void (*draw)(const struct bContext *, struct ARegion *);
+ void (*draw)(const struct bContext *C, struct ARegion *ar);
/* optional, compute button layout before drawing for dynamic size */
- void (*layout)(const struct bContext *, struct ARegion *);
+ void (*layout)(const struct bContext *C, struct ARegion *ar);
/* snap the size of the region (can be NULL for no snapping). */
int (*snap_size)(const struct ARegion *ar, int size, int axis);
/* contextual changes should be handled here */
- void (*listener)(struct bScreen *, struct ScrArea *, struct ARegion *,
- struct wmNotifier *, const struct Scene *scene);
+ void (*listener)(struct bScreen *sc, struct ScrArea *sa, struct ARegion *ar,
+ struct wmNotifier *wmn, const struct Scene *scene);
/* Optional callback to generate subscriptions. */
void (*message_subscribe)(
const struct bContext *C,
@@ -161,18 +161,18 @@ typedef struct ARegionType {
void (*free)(struct ARegion *);
/* split region, copy data optionally */
- void *(*duplicate)(void *);
+ void *(*duplicate)(void *poin);
+
-
/* register operator types on startup */
void (*operatortypes)(void);
/* add own items to keymap */
- void (*keymap)(struct wmKeyConfig *);
+ void (*keymap)(struct wmKeyConfig *keyconf);
/* allows default cursor per region */
- void (*cursor)(struct wmWindow *, struct ScrArea *, struct ARegion *ar);
+ void (*cursor)(struct wmWindow *win, struct ScrArea *sa, struct ARegion *ar);
/* return context data */
- int (*context)(const struct bContext *, const char *, struct bContextDataResult *);
+ int (*context)(const struct bContext *C, const char *member, struct bContextDataResult *result);
/* custom drawing callbacks */
ListBase drawcalls;
@@ -182,7 +182,7 @@ typedef struct ARegionType {
/* header type definitions */
ListBase headertypes;
-
+
/* hardcoded constraints, smaller than these values region is not visible */
int minsizex, minsizey;
/* when new region opens (region prefsizex/y are zero then */
@@ -199,24 +199,29 @@ typedef struct ARegionType {
typedef struct PanelType {
struct PanelType *next, *prev;
-
+
char idname[BKE_ST_MAXNAME]; /* unique name */
char label[BKE_ST_MAXNAME]; /* for panel header */
char translation_context[BKE_ST_MAXNAME];
char context[BKE_ST_MAXNAME]; /* for buttons window */
char category[BKE_ST_MAXNAME]; /* for category tabs */
- char owner_id[BKE_ST_MAXNAME]; /* for work-spaces to selectively show. */
+ char owner_id[BKE_ST_MAXNAME]; /* for work-spaces to selectively show. */
+ char parent_id[BKE_ST_MAXNAME]; /* parent idname for subpanels */
int space_type;
int region_type;
int flag;
/* verify if the panel should draw or not */
- int (*poll)(const struct bContext *, struct PanelType *);
+ int (*poll)(const struct bContext *C, struct PanelType *pt);
/* draw header (optional) */
- void (*draw_header)(const struct bContext *, struct Panel *);
+ void (*draw_header)(const struct bContext *C, struct Panel *pa);
/* draw entirely, view changes should be handled here */
- void (*draw)(const struct bContext *, struct Panel *);
+ void (*draw)(const struct bContext *C, struct Panel *pa);
+
+ /* sub panels */
+ struct PanelType *parent;
+ ListBase children;
/* RNA integration */
ExtensionRNA ext;
@@ -225,14 +230,18 @@ typedef struct PanelType {
/* uilist types */
/* Draw an item in the uiList */
-typedef void (*uiListDrawItemFunc)(struct uiList *, struct bContext *, struct uiLayout *, struct PointerRNA *,
- struct PointerRNA *, int, struct PointerRNA *, const char *, int, int);
+typedef void (*uiListDrawItemFunc)(
+ struct uiList *ui_list, struct bContext *C, struct uiLayout *layout, struct PointerRNA *dataptr,
+ struct PointerRNA *itemptr, int icon, struct PointerRNA *active_dataptr, const char *active_propname,
+ int index, int flt_flag);
/* Draw the filtering part of an uiList */
-typedef void (*uiListDrawFilterFunc)(struct uiList *, struct bContext *, struct uiLayout *);
+typedef void (*uiListDrawFilterFunc)(
+ struct uiList *ui_list, struct bContext *C, struct uiLayout *layout);
/* Filter items of an uiList */
-typedef void (*uiListFilterItemsFunc)(struct uiList *, struct bContext *, struct PointerRNA *, const char *);
+typedef void (*uiListFilterItemsFunc)(
+ struct uiList *ui_list, struct bContext *C, struct PointerRNA *, const char *propname);
typedef struct uiListType {
struct uiListType *next, *prev;
@@ -257,7 +266,7 @@ typedef struct HeaderType {
int region_type;
/* draw entirely, view changes should be handled here */
- void (*draw)(const struct bContext *, struct Header *);
+ void (*draw)(const struct bContext *C, struct Header *header);
/* RNA integration */
ExtensionRNA ext;
@@ -281,9 +290,9 @@ typedef struct MenuType {
const char *description;
/* verify if the menu should draw or not */
- int (*poll)(const struct bContext *, struct MenuType *);
+ int (*poll)(const struct bContext *C, struct MenuType *mt);
/* draw entirely, view changes should be handled here */
- void (*draw)(const struct bContext *, struct Menu *);
+ void (*draw)(const struct bContext *C, struct Menu *menu);
/* RNA integration */
ExtensionRNA ext;
@@ -307,7 +316,8 @@ void BKE_spacedata_freelist(ListBase *lb);
void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2);
void BKE_spacedata_draw_locks(int set);
-void BKE_spacedata_callback_id_remap_set(void (*func)(struct ScrArea *, struct SpaceLink *, struct ID *, struct ID *));
+void BKE_spacedata_callback_id_remap_set(
+ void (*func)(struct ScrArea *sa, struct SpaceLink *sl, struct ID *old_id, struct ID *new_id));
void BKE_spacedata_id_unref(struct ScrArea *sa, struct SpaceLink *sl, struct ID *id);
/* area/regions */
@@ -344,7 +354,7 @@ float BKE_screen_view3d_zoom_to_fac(float camzoom);
float BKE_screen_view3d_zoom_from_fac(float zoomfac);
/* screen */
-void BKE_screen_free(struct bScreen *sc);
+void BKE_screen_free(struct bScreen *sc);
void BKE_screen_area_map_free(struct ScrAreaMap *area_map) ATTR_NONNULL();
unsigned int BKE_screen_visible_layers(struct bScreen *screen, struct Scene *scene);
@@ -356,4 +366,3 @@ void BKE_screen_remove_unused_scredges(struct bScreen *sc);
void BKE_screen_remove_unused_scrverts(struct bScreen *sc);
#endif
-
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h
index 2f2e948ab26..7883f89f33a 100644
--- a/source/blender/blenkernel/BKE_studiolight.h
+++ b/source/blender/blenkernel/BKE_studiolight.h
@@ -59,15 +59,23 @@ struct GPUTexture;
enum StudioLightFlag {
STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED = (1 << 0),
STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED = (1 << 1),
- STUDIOLIGHT_EXTERNAL_FILE = (1 << 2),
- STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 3),
- STUDIOLIGHT_ORIENTATION_WORLD = (1 << 4),
- STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED = (1 << 5),
- STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_IMAGE_CALCULATED = (1 << 6),
- STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE = (1 << 7),
- STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE = (1 << 8),
- STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 9),
+ STUDIOLIGHT_INTERNAL = (1 << 2),
+ STUDIOLIGHT_EXTERNAL_FILE = (1 << 3),
+ STUDIOLIGHT_USER_DEFINED = (1 << 12),
+ STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 4),
+ STUDIOLIGHT_ORIENTATION_WORLD = (1 << 5),
+ STUDIOLIGHT_ORIENTATION_VIEWNORMAL = (1 << 6),
+ STUDIOLIGHT_EXTERNAL_IMAGE_LOADED = (1 << 7),
+ STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_IMAGE_CALCULATED = (1 << 8),
+ STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE = (1 << 9),
+ STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE = (1 << 10),
+ STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 11),
+ STUDIOLIGHT_UI_EXPANDED = (1 << 13),
} StudioLightFlag;
+#define STUDIOLIGHT_FLAG_ALL (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_EXTERNAL_FILE)
+#define STUDIOLIGHT_FLAG_ORIENTATIONS (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_VIEWNORMAL)
+#define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_WORLD)
+#define STUDIOLIGHT_ORIENTATIONS_SOLID (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD)
typedef struct StudioLight {
struct StudioLight *next, *prev;
@@ -89,9 +97,11 @@ typedef struct StudioLight {
void BKE_studiolight_init(void);
void BKE_studiolight_free(void);
struct StudioLight *BKE_studiolight_find(const char *name, int flag);
-struct StudioLight *BKE_studiolight_findindex(int index);
+struct StudioLight *BKE_studiolight_findindex(int index, int flag);
+struct StudioLight *BKE_studiolight_find_first(int flag);
unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type);
-const struct ListBase *BKE_studiolight_listbase(void);
+struct ListBase *BKE_studiolight_listbase(void);
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag);
+void BKE_studiolight_refresh(void);
#endif /* __BKE_STUDIOLIGHT_H__ */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index c554d5e7b6c..c081bb0799f 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -61,6 +61,7 @@
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_mesh_tangent.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
@@ -94,7 +95,6 @@
static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
-static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob);
static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid);
static void mesh_init_origspace(Mesh *mesh);
@@ -1157,6 +1157,8 @@ DerivedMesh *mesh_create_derived(Mesh *me, float (*vertCos)[3])
return dm;
}
+/* XXX2.8(Sybren): can be removed once DerivedMesh port is done */
+#ifdef WITH_DERIVEDMESH_DEPRECATED_FUNCS
DerivedMesh *mesh_create_derived_for_modifier(
struct Depsgraph *depsgraph, Scene *scene, Object *ob,
ModifierData *md, int build_shapekey_layers)
@@ -1207,6 +1209,7 @@ DerivedMesh *mesh_create_derived_for_modifier(
return dm;
}
+#endif
static float (*get_editbmesh_orco_verts(BMEditMesh *em))[3]
{
@@ -1920,7 +1923,7 @@ static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape
}
}
-static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob))
+static void UNUSED_FUNCTION(add_shapekey_layers)(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob))
{
KeyBlock *kb;
Key *key = me->key;
@@ -2790,7 +2793,7 @@ static void editbmesh_calc_modifiers(
}
else {
struct Mesh *mesh = ob->data;
- if (mesh->id.tag & LIB_TAG_COPY_ON_WRITE) {
+ if (mesh->id.tag & LIB_TAG_COPIED_ON_WRITE) {
BKE_mesh_runtime_ensure_edit_data(mesh);
mesh->runtime.edit_data->vertexCos = MEM_dupallocN(deformedVerts);
}
@@ -2832,7 +2835,7 @@ static void editbmesh_calc_modifiers(
else {
/* this is just a copy of the editmesh, no need to calc normals */
struct Mesh *mesh = ob->data;
- if (mesh->id.tag & LIB_TAG_COPY_ON_WRITE) {
+ if (mesh->id.tag & LIB_TAG_COPIED_ON_WRITE) {
BKE_mesh_runtime_ensure_edit_data(mesh);
if (mesh->runtime.edit_data->vertexCos != NULL)
MEM_freeN((void *)mesh->runtime.edit_data->vertexCos);
@@ -2943,18 +2946,14 @@ static void mesh_finalize_eval(Object *object)
if (mesh_eval->mat != NULL) {
MEM_freeN(mesh_eval->mat);
}
+ /* Set flag which makes it easier to see what's going on in a debugger. */
+ mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
mesh_eval->mat = MEM_dupallocN(mesh->mat);
mesh_eval->totcol = mesh->totcol;
/* Make evaluated mesh to share same edit mesh pointer as original
* and copied meshes.
*/
mesh_eval->edit_btmesh = mesh->edit_btmesh;
- /* Special flags to help debugging and also to allow copy-on-write core
- * to understand that on re-evaluation this mesh is to be preserved and
- * to be remapped back to copied original mesh when used as object data.
- */
- mesh_eval->id.tag |= LIB_TAG_COPY_ON_WRITE_EVAL;
- mesh_eval->id.orig_id = &mesh->id;
/* Copy autosmooth settings from original mesh.
* This is not done by BKE_mesh_new_nomain_from_template(), so need to take
* extra care here.
@@ -2970,7 +2969,7 @@ static void mesh_finalize_eval(Object *object)
/* Object is sometimes not evaluated!
* TODO(sergey): BAD TEMPORARY HACK FOR UNTIL WE ARE SMARTER */
- if (object->id.tag & LIB_TAG_COPY_ON_WRITE) {
+ if (object->id.tag & LIB_TAG_COPIED_ON_WRITE) {
object->data = mesh_eval;
}
else {
@@ -3108,6 +3107,7 @@ void makeDerivedMesh(
/***/
+#ifdef USE_DERIVEDMESH
/* Deprecated DM, use: 'mesh_get_eval_final'. */
DerivedMesh *mesh_get_derived_final(
struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask)
@@ -3128,6 +3128,7 @@ DerivedMesh *mesh_get_derived_final(
if (ob->derivedFinal) { BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS)); }
return ob->derivedFinal;
}
+#endif
Mesh *mesh_get_eval_final(
struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask)
{
@@ -3137,7 +3138,7 @@ Mesh *mesh_get_eval_final(
bool need_mapping;
dataMask |= object_get_datamask(depsgraph, ob, &need_mapping);
- if (!ob->derivedFinal ||
+ if (!ob->runtime.mesh_eval ||
((dataMask & ob->lastDataMask) != dataMask) ||
(need_mapping != ob->lastNeedMapping))
{
@@ -3148,6 +3149,7 @@ Mesh *mesh_get_eval_final(
return ob->runtime.mesh_eval;
}
+#ifdef USE_DERIVEDMESH
/* Deprecated DM, use: 'mesh_get_eval_deform' instead. */
DerivedMesh *mesh_get_derived_deform(struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask)
{
@@ -3167,6 +3169,7 @@ DerivedMesh *mesh_get_derived_deform(struct Depsgraph *depsgraph, Scene *scene,
return ob->derivedDeform;
}
+#endif
Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.c
index 98482bcc8b1..857fc72672c 100644
--- a/source/blender/blenkernel/intern/blender_undo.c
+++ b/source/blender/blenkernel/intern/blender_undo.c
@@ -67,10 +67,11 @@
bool BKE_memfile_undo_decode(MemFileUndoData *mfu, bContext *C)
{
- char mainstr[sizeof(G.main->name)];
+ Main *bmain = CTX_data_main(C);
+ char mainstr[sizeof(bmain->name)];
int success = 0, fileflags;
- BLI_strncpy(mainstr, G.main->name, sizeof(mainstr)); /* temporal store */
+ BLI_strncpy(mainstr, BKE_main_blendfile_path(bmain), sizeof(mainstr)); /* temporal store */
fileflags = G.fileflags;
G.fileflags |= G_FILE_NO_UI;
@@ -82,13 +83,14 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu, bContext *C)
success = BKE_blendfile_read_from_memfile(C, &mfu->memfile, NULL, 0);
}
- /* restore */
- BLI_strncpy(G.main->name, mainstr, sizeof(G.main->name)); /* restore */
+ /* Restore, bmain has been re-allocated. */
+ bmain = CTX_data_main(C);
+ BLI_strncpy(bmain->name, mainstr, sizeof(bmain->name));
G.fileflags = fileflags;
if (success) {
/* important not to update time here, else non keyed tranforms are lost */
- DEG_on_visible_update(G.main, false);
+ DEG_on_visible_update(bmain, false);
}
return success;
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index 34079d778f7..597c69408b5 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -116,6 +116,7 @@ static void setup_app_data(
bContext *C, BlendFileData *bfd,
const char *filepath, ReportList *reports)
{
+ Main *bmain = G.main; /* Valid usage */
Scene *curscene = NULL;
const bool is_startup = (bfd->filename[0] == '\0');
const bool recover = (G.fileflags & G_FILE_RECOVER) != 0;
@@ -172,9 +173,9 @@ static void setup_app_data(
bool track_undo_scene;
/* comes from readfile.c */
- SWAP(ListBase, G.main->wm, bfd->main->wm);
- SWAP(ListBase, G.main->workspaces, bfd->main->workspaces);
- SWAP(ListBase, G.main->screen, bfd->main->screen);
+ SWAP(ListBase, bmain->wm, bfd->main->wm);
+ SWAP(ListBase, bmain->workspaces, bfd->main->workspaces);
+ SWAP(ListBase, bmain->screen, bfd->main->screen);
/* we re-use current window and screen */
win = CTX_wm_window(C);
@@ -236,9 +237,9 @@ static void setup_app_data(
/* clear old property update cache, in case some old references are left dangling */
RNA_property_update_cache_free();
- G.main = bfd->main;
+ bmain = G.main = bfd->main;
- CTX_data_main_set(C, G.main);
+ CTX_data_main_set(C, bmain);
if (bfd->user) {
@@ -266,7 +267,7 @@ static void setup_app_data(
/* Keep state from preferences. */
const int fileflags_skip = G_FILE_FLAGS_RUNTIME;
G.fileflags = (G.fileflags & fileflags_skip) | (bfd->fileflags & ~fileflags_skip);
- CTX_wm_manager_set(C, G.main->wm.first);
+ CTX_wm_manager_set(C, bmain->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
CTX_data_scene_set(C, bfd->curscene);
CTX_wm_area_set(C, NULL);
@@ -280,10 +281,10 @@ static void setup_app_data(
wmWindow *win = CTX_wm_window(C);
/* in case we don't even have a local scene, add one */
- if (!G.main->scene.first)
- BKE_scene_add(G.main, "Empty");
+ if (!bmain->scene.first)
+ BKE_scene_add(bmain, "Empty");
- CTX_data_scene_set(C, G.main->scene.first);
+ CTX_data_scene_set(C, bmain->scene.first);
win->scene = CTX_data_scene(C);
curscene = CTX_data_scene(C);
}
@@ -307,35 +308,35 @@ static void setup_app_data(
/* FIXME: this version patching should really be part of the file-reading code,
* but we still get too many unrelated data-corruption crashes otherwise... */
- if (G.main->versionfile < 250)
- do_versions_ipos_to_animato(G.main);
+ if (bmain->versionfile < 250)
+ do_versions_ipos_to_animato(bmain);
- G.main->recovered = 0;
+ bmain->recovered = 0;
/* startup.blend or recovered startup */
if (bfd->filename[0] == 0) {
- G.main->name[0] = 0;
+ bmain->name[0] = '\0';
}
else if (recover && G.relbase_valid) {
/* in case of autosave or quit.blend, use original filename instead
* use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */
filepath = bfd->filename;
- G.main->recovered = 1;
+ bmain->recovered = 1;
/* these are the same at times, should never copy to the same location */
- if (G.main->name != filepath)
- BLI_strncpy(G.main->name, filepath, FILE_MAX);
+ if (bmain->name != filepath)
+ BLI_strncpy(bmain->name, filepath, FILE_MAX);
}
/* baseflags, groups, make depsgraph, etc */
/* first handle case if other windows have different scenes visible */
if (mode == LOAD_UI) {
- wmWindowManager *wm = G.main->wm.first;
+ wmWindowManager *wm = bmain->wm.first;
if (wm) {
for (wmWindow *win = wm->windows.first; win; win = win->next) {
if (win->scene && win->scene != curscene) {
- BKE_scene_set_background(G.main, win->scene);
+ BKE_scene_set_background(bmain, win->scene);
}
}
}
@@ -346,10 +347,10 @@ static void setup_app_data(
* constructing dependency graph.
*/
if (mode != LOAD_UNDO) {
- IMB_colormanagement_check_file_config(G.main);
+ IMB_colormanagement_check_file_config(bmain);
}
- BKE_scene_set_background(G.main, curscene);
+ BKE_scene_set_background(bmain, curscene);
if (mode != LOAD_UNDO) {
/* TODO(sergey): Can this be also move above? */
@@ -431,9 +432,10 @@ bool BKE_blendfile_read_from_memfile(
bContext *C, struct MemFile *memfile,
ReportList *reports, int skip_flags)
{
+ Main *bmain = CTX_data_main(C);
BlendFileData *bfd;
- bfd = BLO_read_from_memfile(CTX_data_main(C), G.main->name, memfile, reports, skip_flags);
+ bfd = BLO_read_from_memfile(bmain, BKE_main_blendfile_path(bmain), memfile, reports, skip_flags);
if (bfd) {
/* remove the unused screens and wm */
while (bfd->main->wm.first)
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 1fd2797d2f8..82d9f9f8f69 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -325,7 +325,7 @@ void BKE_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportLis
struct BPathFind_Data data = {NULL};
const int flag = BKE_BPATH_TRAVERSE_ABS | BKE_BPATH_TRAVERSE_RELOAD_EDITED;
- data.basedir = bmain->name;
+ data.basedir = BKE_main_blendfile_path(bmain);
data.reports = reports;
data.searchdir = searchpath;
data.find_all = find_all;
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index b3ea3de6ea9..e8328139d64 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -45,6 +45,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 274f7b78529..74c0dca6279 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -89,13 +89,22 @@ void BKE_cachefile_free(CacheFile *cache_file)
{
BKE_animdata_free((ID *)cache_file, false);
+ if (cache_file->id.tag & LIB_TAG_NO_MAIN) {
+ /* CoW/no-main copies reuse the existing ArchiveReader and mutex */
+ return;
+ }
+
+ if (cache_file->handle) {
#ifdef WITH_ALEMBIC
- ABC_free_handle(cache_file->handle);
+ ABC_free_handle(cache_file->handle);
#endif
-
+ cache_file->handle = NULL;
+ }
if (cache_file->handle_mutex) {
BLI_mutex_free(cache_file->handle_mutex);
+ cache_file->handle_mutex = NULL;
}
+
BLI_freelistN(&cache_file->object_paths);
}
@@ -110,8 +119,14 @@ void BKE_cachefile_free(CacheFile *cache_file)
void BKE_cachefile_copy_data(
Main *UNUSED(bmain), CacheFile *cache_file_dst, const CacheFile *UNUSED(cache_file_src), const int UNUSED(flag))
{
+ if (cache_file_dst->id.tag & LIB_TAG_NO_MAIN) {
+ /* CoW/no-main copies reuse the existing ArchiveReader and mutex */
+ return;
+ }
+
cache_file_dst->handle = NULL;
- BLI_listbase_clear(&cache_file_dst->object_paths);
+ cache_file_dst->handle_mutex = NULL;
+ BLI_duplicatelist(&cache_file_dst->object_paths, &cache_file_dst->object_paths);
}
CacheFile *BKE_cachefile_copy(Main *bmain, const CacheFile *cache_file)
@@ -153,6 +168,8 @@ void BKE_cachefile_ensure_handle(const Main *bmain, CacheFile *cache_file)
BLI_mutex_lock(cache_file->handle_mutex);
if (cache_file->handle == NULL) {
+ /* Assigning to a CoW copy is a bad idea; assign to the original instead. */
+ BLI_assert((cache_file->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0);
BKE_cachefile_reload(bmain, cache_file);
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 773ef90aac8..7bcc05b0e37 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -46,6 +46,7 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_editmesh.h"
#include "BKE_curve.h"
@@ -289,7 +290,7 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
* this derivedmesh is just original mesh. it's the multires subsurf dm
* that this is actually for, to support a pbvh on a modified mesh */
if (!cddm->pbvh && ob->type == OB_MESH) {
- Mesh *me = ob->data;
+ Mesh *me = BKE_object_get_original_mesh(ob);
const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
MLoopTri *looptri;
bool deformed;
@@ -324,7 +325,7 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
totvert = deformdm->getNumVerts(deformdm);
vertCos = MEM_malloc_arrayN(totvert, sizeof(float[3]), "cdDM_getPBVH vertCos");
deformdm->getVertCos(deformdm, vertCos);
- BKE_pbvh_apply_vertCos(cddm->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(cddm->pbvh, vertCos, totvert);
MEM_freeN(vertCos);
}
}
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index a39de284064..cc1c7260cbc 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -48,7 +48,7 @@
#include "BKE_cloth.h"
#include "BKE_effect.h"
#include "BKE_global.h"
-#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index c4709a32f78..ab0ec8b0491 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -59,7 +59,7 @@
static bool collection_child_add(Collection *parent, Collection *collection, int flag, const bool add_us);
static bool collection_child_remove(Collection *parent, Collection *collection);
-static bool collection_object_add(Collection *collection, Object *ob, int flag, const bool add_us);
+static bool collection_object_add(Main *bmain, Collection *collection, Object *ob, int flag, const bool add_us);
static bool collection_object_remove(Main *bmain, Collection *collection, Object *ob, const bool free_us);
static CollectionChild *collection_find_child(Collection *parent, Collection *collection);
@@ -163,7 +163,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
/* Link child object into parent collections. */
for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) {
Collection *parent = cparent->collection;
- collection_object_add(parent, cob->ob, 0, true);
+ collection_object_add(bmain, parent, cob->ob, 0, true);
}
/* Remove child object. */
@@ -190,7 +190,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
* \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
void BKE_collection_copy_data(
- Main *UNUSED(bmain), Collection *collection_dst, const Collection *collection_src, const int flag)
+ Main *bmain, Collection *collection_dst, const Collection *collection_src, const int flag)
{
/* Do not copy collection's preview (same behavior as for objects). */
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) { /* XXX TODO temp hack */
@@ -211,7 +211,7 @@ void BKE_collection_copy_data(
collection_child_add(collection_dst, child->collection, flag, false);
}
for (CollectionObject *cob = collection_src->gobject.first; cob; cob = cob->next) {
- collection_object_add(collection_dst, cob->ob, flag, false);
+ collection_object_add(bmain, collection_dst, cob->ob, flag, false);
}
}
@@ -311,23 +311,6 @@ bool BKE_collection_is_animated(Collection *collection, Object *UNUSED(parent))
return false;
}
-/* puts all collection members in local timing system, after this call
- * you can draw everything, leaves tags in objects to signal it needs further updating */
-
-/* note: does not work for derivedmesh and render... it recreates all again in convertblender.c */
-void BKE_collection_handle_recalc_and_update(
- struct Depsgraph *depsgraph, Scene *scene, Object *UNUSED(parent), Collection *collection)
-{
- /* only do existing tags, as set by regular depsgraph */
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(collection, object)
- {
- if (object->id.recalc & ID_RECALC_ALL) {
- BKE_object_handle_update(depsgraph, scene, object);
- }
- }
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
-}
-
/* **************** Object List Cache *******************/
static void collection_object_cache_fill(ListBase *lb, Collection *collection, int parent_restrict)
@@ -367,12 +350,12 @@ ListBase BKE_collection_object_cache_get(Collection *collection)
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) {
static ThreadMutex cache_lock = BLI_MUTEX_INITIALIZER;
+ BLI_mutex_lock(&cache_lock);
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) {
- BLI_mutex_lock(&cache_lock);
collection_object_cache_fill(&collection->object_cache, collection, 0);
collection->flag |= COLLECTION_HAS_OBJECT_CACHE;
- BLI_mutex_unlock(&cache_lock);
}
+ BLI_mutex_unlock(&cache_lock);
}
return collection->object_cache;
@@ -522,7 +505,7 @@ Collection *BKE_collection_object_find(Main *bmain, Collection *collection, Obje
/********************** Collection Objects *********************/
-static bool collection_object_add(Collection *collection, Object *ob, int flag, const bool add_us)
+static bool collection_object_add(Main *bmain, Collection *collection, Object *ob, int flag, const bool add_us)
{
if (ob->dup_group) {
/* Cyclic dependency check. */
@@ -545,6 +528,10 @@ static bool collection_object_add(Collection *collection, Object *ob, int flag,
id_us_plus(&ob->id);
}
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ DEG_id_tag_update_ex(bmain, &collection->id, DEG_TAG_COPY_ON_WRITE);
+ }
+
return true;
}
@@ -565,6 +552,8 @@ static bool collection_object_remove(Main *bmain, Collection *collection, Object
id_us_min(&ob->id);
}
+ DEG_id_tag_update_ex(bmain, &collection->id, DEG_TAG_COPY_ON_WRITE);
+
return true;
}
@@ -577,7 +566,7 @@ bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
return false;
}
- if (!collection_object_add(collection, ob, 0, true)) {
+ if (!collection_object_add(bmain, collection, ob, 0, true)) {
return false;
}
@@ -597,7 +586,7 @@ void BKE_collection_object_add_from(Main *bmain, Scene *scene, Object *ob_src, O
FOREACH_SCENE_COLLECTION_BEGIN(scene, collection)
{
if (BKE_collection_has_object(collection, ob_src)) {
- collection_object_add(collection, ob_dst, 0, true);
+ collection_object_add(bmain, collection, ob_dst, 0, true);
}
}
FOREACH_SCENE_COLLECTION_END;
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 0451031c5b8..3639649eab5 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -50,6 +50,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_mesh_remap.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index fa996b8f73e..a591ab354f6 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -37,6 +37,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_curve_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_vfont_types.h"
@@ -51,8 +52,10 @@
#include "BKE_displist.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_object.h"
+#include "BKE_library.h"
#include "BKE_mball.h"
#include "BKE_mball_tessellate.h"
+#include "BKE_mesh.h"
#include "BKE_curve.h"
#include "BKE_key.h"
#include "BKE_anim.h"
@@ -925,7 +928,7 @@ static void curve_calc_modifiers_post(
Curve *cu = ob->data;
int required_mode = 0, totvert = 0;
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
- DerivedMesh *dm = NULL, *ndm;
+ Mesh *modified = NULL, *mesh_applied;
float (*vertCos)[3] = NULL;
int useCache = !for_render;
ModifierApplyFlag app_flag = 0;
@@ -963,23 +966,21 @@ static void curve_calc_modifiers_post(
continue;
if (mti->type == eModifierTypeType_OnlyDeform ||
- (mti->type == eModifierTypeType_DeformOrConstruct && !dm))
+ (mti->type == eModifierTypeType_DeformOrConstruct && !modified))
{
- if (dm) {
+ if (modified) {
if (!vertCos) {
- totvert = dm->getNumVerts(dm);
- vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv");
- dm->getVertCos(dm, vertCos);
+ vertCos = BKE_mesh_vertexCos_get(modified, &totvert);
}
- modifier_deformVerts_DM_deprecated(md, &mectx_deform, dm, vertCos, totvert);
+ modifier_deformVerts(md, &mectx_deform, modified, vertCos, totvert);
}
else {
if (!vertCos) {
vertCos = displist_get_allverts(dispbase, &totvert);
}
- modifier_deformVerts_DM_deprecated(md, &mectx_deform, NULL, vertCos, totvert);
+ modifier_deformVerts(md, &mectx_deform, NULL, vertCos, totvert);
}
}
else {
@@ -991,13 +992,17 @@ static void curve_calc_modifiers_post(
break;
}
- if (dm) {
+ if (modified) {
if (vertCos) {
- DerivedMesh *tdm = CDDM_copy(dm);
- dm->release(dm);
- dm = tdm;
-
- CDDM_apply_vert_coords(dm, vertCos);
+ Mesh *temp_mesh;
+ BKE_id_copy_ex(NULL, &modified->id, (ID **)&temp_mesh,
+ LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG | LIB_ID_COPY_NO_PREVIEW,
+ false);
+ BKE_id_free(NULL, modified);
+ modified = temp_mesh;
+
+ BKE_mesh_apply_vert_coords(modified, vertCos);
}
}
else {
@@ -1009,7 +1014,7 @@ static void curve_calc_modifiers_post(
curve_to_filledpoly(cu, nurb, dispbase);
}
- dm = CDDM_from_curve_displist(ob, dispbase);
+ modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
}
if (vertCos) {
@@ -1018,26 +1023,31 @@ static void curve_calc_modifiers_post(
vertCos = NULL;
}
- ndm = modwrap_applyModifier(md, &mectx_apply, dm);
+ mesh_applied = modifier_applyModifier(md, &mectx_apply, modified);
- if (ndm) {
+ if (mesh_applied) {
/* Modifier returned a new derived mesh */
- if (dm && dm != ndm) /* Modifier */
- dm->release(dm);
- dm = ndm;
+ if (modified && modified != mesh_applied) /* Modifier */
+ BKE_id_free(NULL, modified);
+ modified = mesh_applied;
}
}
}
if (vertCos) {
- if (dm) {
- DerivedMesh *tdm = CDDM_copy(dm);
- dm->release(dm);
- dm = tdm;
+ if (modified) {
+ Mesh *temp_mesh;
+ BKE_id_copy_ex(NULL, &modified->id, (ID **)&temp_mesh,
+ LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG | LIB_ID_COPY_NO_PREVIEW,
+ false);
+ BKE_id_free(NULL, modified);
+ modified = temp_mesh;
+
+ BKE_mesh_apply_vert_coords(modified, vertCos);
+ BKE_mesh_calc_normals_mapping_simple(modified);
- CDDM_apply_vert_coords(dm, vertCos);
- CDDM_calc_normals_mapping(dm);
MEM_freeN(vertCos);
}
else {
@@ -1048,22 +1058,27 @@ static void curve_calc_modifiers_post(
}
if (r_dm_final) {
- if (dm) {
+ if (modified) {
/* see: mesh_calc_modifiers */
- if (dm->getNumTessFaces(dm) == 0) {
- dm->recalcTessellation(dm);
+ if (modified->totface == 0) {
+ BKE_mesh_tessface_calc(modified);
}
/* Even if tessellation is not needed, some modifiers might have modified CD layers
* (like mloopcol or mloopuv), hence we have to update those. */
- else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) {
- DM_update_tessface_data(dm);
+ else if (modified->runtime.cd_dirty_vert & CD_MASK_TESSLOOPNORMAL) {
+ BKE_mesh_tessface_calc(modified);
}
- if (dm->type == DM_TYPE_CDDM) {
- CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
- }
+ /* XXX2.8(Sybren): make sure the face normals are recalculated as well */
+ BKE_mesh_ensure_normals(modified);
+
+ (*r_dm_final) = CDDM_from_mesh_ex(modified, CD_DUPLICATE, CD_MASK_MESH);
+ BKE_id_free(NULL, modified);
+ }
+ else {
+ (*r_dm_final) = NULL;
}
- (*r_dm_final) = dm;
+
}
}
@@ -1095,6 +1110,8 @@ static void displist_surf_indices(DispList *dl)
}
}
+/* XXX2.8(Sybren): unused function; impossible to test after porting to Mesh */
+#ifdef WITH_DERIVEDMESH_DEPRECATED_FUNCS
static DerivedMesh *create_orco_dm(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
DerivedMesh *dm;
@@ -1138,7 +1155,10 @@ static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
else
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
}
+#endif
+/* XXX2.8(Sybren): unused function; impossible to test after porting to Mesh */
+#ifdef WITH_DERIVEDMESH_DEPRECATED_FUNCS
static void curve_calc_orcodm(
Depsgraph *depsgraph, Scene *scene, Object *ob, DerivedMesh *dm_final,
const bool for_render, const bool use_render_resolution)
@@ -1208,6 +1228,7 @@ static void curve_calc_orcodm(
orcodm->release(orcodm);
}
+#endif
void BKE_displist_make_surf(
Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase,
@@ -1816,6 +1837,8 @@ void BKE_displist_make_curveTypes_forOrco(
}
/* add Orco layer to the displist object which has got derived mesh and return orco */
+/* XXX2.8(Sybren): can be removed once DerivedMesh port is done */
+#ifdef WITH_DERIVEDMESH_DEPRECATED_FUNCS
float *BKE_displist_make_orco(
Depsgraph *depsgraph, Scene *scene, Object *ob, DerivedMesh *dm_final,
const bool for_render,
@@ -1838,6 +1861,7 @@ float *BKE_displist_make_orco(
return orco;
}
+#endif
void BKE_displist_minmax(ListBase *dispbase, float min[3], float max[3])
{
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 89f5f8facda..36452e1d2cf 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -3216,7 +3216,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam
BKE_image_path_ensure_ext_from_imtype(output_file, format);
/* Validate output file path */
- BLI_path_abs(output_file, G.main->name);
+ BLI_path_abs(output_file, BKE_main_blendfile_path_from_global());
BLI_make_existing_file(output_file);
/* Init image buffer */
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 34b185417e3..f7ab5415d1c 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -255,8 +255,8 @@ VFont *BKE_vfont_load(Main *bmain, const char *filepath)
}
else {
BLI_split_file_part(filepath, filename, sizeof(filename));
- pf = newPackedFile(NULL, filepath, bmain->name);
- temp_pf = newPackedFile(NULL, filepath, bmain->name);
+ pf = newPackedFile(NULL, filepath, BKE_main_blendfile_path(bmain));
+ temp_pf = newPackedFile(NULL, filepath, BKE_main_blendfile_path(bmain));
is_builtin = false;
}
@@ -301,7 +301,7 @@ VFont *BKE_vfont_load_exists_ex(struct Main *bmain, const char *filepath, bool *
char str[FILE_MAX], strtest[FILE_MAX];
BLI_strncpy(str, filepath, sizeof(str));
- BLI_path_abs(str, bmain->name);
+ BLI_path_abs(str, BKE_main_blendfile_path(bmain));
/* first search an identical filepath */
for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) {
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index e5c192b3e1e..9a29a8a898b 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -592,7 +592,7 @@ Image *BKE_image_load(Main *bmain, const char *filepath)
char str[FILE_MAX];
STRNCPY(str, filepath);
- BLI_path_abs(str, bmain->name);
+ BLI_path_abs(str, BKE_main_blendfile_path(bmain));
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
@@ -621,7 +621,7 @@ Image *BKE_image_load_exists_ex(const char *filepath, bool *r_exists)
char str[FILE_MAX], strtest[FILE_MAX];
STRNCPY(str, filepath);
- BLI_path_abs(str, G.main->name);
+ BLI_path_abs(str, BKE_main_blendfile_path_from_global());
/* first search an identical filepath */
for (ima = G.main->image.first; ima; ima = ima->id.next) {
@@ -1648,7 +1648,8 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
time_t t;
if (scene->r.stamp & R_STAMP_FILENAME) {
- SNPRINTF(stamp_data->file, do_prefix ? "File %s" : "%s", G.relbase_valid ? G.main->name : "<untitled>");
+ SNPRINTF(stamp_data->file, do_prefix ? "File %s" : "%s",
+ G.relbase_valid ? BKE_main_blendfile_path_from_global() : "<untitled>");
}
else {
stamp_data->file[0] = '\0';
@@ -4698,7 +4699,7 @@ static void image_update_views_format(Image *ima, ImageUser *iuser)
char str[FILE_MAX];
STRNCPY(str, iv->filepath);
- BLI_path_abs(str, G.main->name);
+ BLI_path_abs(str, BKE_main_blendfile_path_from_global());
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 0fa20f00823..b5b62de57ec 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -1057,7 +1057,7 @@ void BKE_lattice_modifiers_calc(struct Depsgraph *depsgraph, Scene *scene, Objec
modifier_deformVerts_DM_deprecated(md, &mectx, NULL, vertexCos, numVerts);
}
- if (ob->id.tag & LIB_TAG_COPY_ON_WRITE) {
+ if (ob->id.tag & LIB_TAG_COPIED_ON_WRITE) {
if (vertexCos) {
BKE_lattice_vertexcos_apply(ob, vertexCos);
MEM_freeN(vertexCos);
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 16e349465f6..c7bb24cdcee 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1264,6 +1264,16 @@ void BKE_layer_eval_view_layer(
/* Store base in the array. */
view_layer->object_bases_array[base_index++] = base;
}
+ if (view_layer == DEG_get_evaluated_view_layer(depsgraph)) {
+ ViewLayer *view_layer_orig = DEG_get_input_view_layer(depsgraph);
+ Base *base_orig = view_layer_orig->object_bases.first;
+ const Base *base_eval = view_layer->object_bases.first;
+ while (base_orig != NULL) {
+ base_orig->flag = base_eval->flag;
+ base_orig = base_orig->next;
+ base_eval = base_eval->next;
+ }
+ }
}
void BKE_layer_eval_view_layer_indexed(
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 917b318899c..8dac716ab02 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -155,7 +155,7 @@
* also note that the id _must_ have a library - campbell */
void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id)
{
- const char *bpath_user_data[2] = {bmain->name, lib->filepath};
+ const char *bpath_user_data[2] = {BKE_main_blendfile_path(bmain), lib->filepath};
BKE_bpath_traverse_id(bmain, id,
BKE_bpath_relocate_visitor,
@@ -1737,6 +1737,24 @@ void BKE_main_thumbnail_create(struct Main *bmain)
bmain->blen_thumb->height = BLEN_THUMB_SIZE;
}
+/**
+ * Return filepath of given \a main.
+ */
+const char *BKE_main_blendfile_path(const Main *bmain)
+{
+ return bmain->name;
+}
+
+/**
+ * Return filepath of global main (G.main).
+ *
+ * \warning Usage is not recommended, you should always try to get a velid Main pointer from context...
+ */
+const char *BKE_main_blendfile_path_from_global(void)
+{
+ return BKE_main_blendfile_path(G.main);
+}
+
/* ***************** ID ************************ */
ID *BKE_libblock_find_name(struct Main *bmain, const short type, const char *name)
{
@@ -2525,7 +2543,7 @@ void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath)
*/
/* Never make paths relative to parent lib - reading code (blenloader) always set *all* lib->name relative to
* current main, not to their parent for indirectly linked ones. */
- const char *basepath = bmain->name;
+ const char *basepath = BKE_main_blendfile_path(bmain);
BLI_path_abs(lib->filepath, basepath);
}
}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 109b436292e..1ea2f170922 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -1315,7 +1315,5 @@ void paste_matcopybuf(Main *bmain, Material *ma)
void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
{
DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
- if ((BLI_listbase_is_empty(&material->gpumaterial) == false)) {
- GPU_material_uniform_buffer_tag_dirty(&material->gpumaterial);
- }
+ GPU_material_free(&material->gpumaterial);
}
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 339e79f2757..3afaf2d569e 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -563,11 +563,6 @@ void BKE_mball_select_swap(struct MetaBall *mb)
/* **** Depsgraph evaluation **** */
-void BKE_mball_eval_geometry(struct Depsgraph *UNUSED(depsgraph),
- MetaBall *UNUSED(mball))
-{
-}
-
/* Draw Engine */
void (*BKE_mball_batch_cache_dirty_cb)(MetaBall *mb, int mode) = NULL;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index d27809586c2..b325d8d02d9 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -46,6 +46,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_library.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
@@ -581,6 +582,34 @@ void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int
}
}
+/* Custom data layer functions; those assume that totXXX are set correctly. */
+static void mesh_ensure_cdlayers_primary(Mesh *mesh, bool do_tessface)
+{
+ if (!CustomData_get_layer(&mesh->vdata, CD_MVERT))
+ CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
+ if (!CustomData_get_layer(&mesh->edata, CD_MEDGE))
+ CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
+ if (!CustomData_get_layer(&mesh->ldata, CD_MLOOP))
+ CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
+ if (!CustomData_get_layer(&mesh->pdata, CD_MPOLY))
+ CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
+
+ if (do_tessface && !CustomData_get_layer(&mesh->fdata, CD_MFACE))
+ CustomData_add_layer(&mesh->fdata, CD_MFACE, CD_CALLOC, NULL, mesh->totface);
+}
+static void mesh_ensure_cdlayers_origindex(Mesh *mesh, bool do_tessface)
+{
+ if (!CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))
+ CustomData_add_layer(&mesh->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert);
+ if (!CustomData_get_layer(&mesh->edata, CD_ORIGINDEX))
+ CustomData_add_layer(&mesh->edata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge);
+ if (!CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX))
+ CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totpoly);
+
+ if (do_tessface && !CustomData_get_layer(&mesh->fdata, CD_ORIGINDEX))
+ CustomData_add_layer(&mesh->fdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
+}
+
Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
{
Mesh *mesh = BKE_libblock_alloc(
@@ -598,28 +627,16 @@ Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int lo
copy_vn_i(mesh->ldata.typemap, CD_NUMTYPES, -1);
copy_vn_i(mesh->pdata.typemap, CD_NUMTYPES, -1);
- CustomData_add_layer(&mesh->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, verts_len);
- CustomData_add_layer(&mesh->edata, CD_ORIGINDEX, CD_CALLOC, NULL, edges_len);
- CustomData_add_layer(&mesh->fdata, CD_ORIGINDEX, CD_CALLOC, NULL, tessface_len);
- CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, polys_len);
-
- CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, verts_len);
- CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, edges_len);
- CustomData_add_layer(&mesh->fdata, CD_MFACE, CD_CALLOC, NULL, tessface_len);
- CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, loops_len);
- CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, polys_len);
-
- mesh->mvert = CustomData_get_layer(&mesh->vdata, CD_MVERT);
- mesh->medge = CustomData_get_layer(&mesh->edata, CD_MEDGE);
- mesh->mface = CustomData_get_layer(&mesh->fdata, CD_MFACE);
- mesh->mloop = CustomData_get_layer(&mesh->ldata, CD_MLOOP);
- mesh->mpoly = CustomData_get_layer(&mesh->pdata, CD_MPOLY);
-
mesh->totvert = verts_len;
mesh->totedge = edges_len;
+ mesh->totface = tessface_len;
mesh->totloop = loops_len;
mesh->totpoly = polys_len;
+ mesh_ensure_cdlayers_primary(mesh, true);
+ mesh_ensure_cdlayers_origindex(mesh, true);
+ BKE_mesh_update_customdata_pointers(mesh, false);
+
return mesh;
}
@@ -638,6 +655,7 @@ static Mesh *mesh_new_nomain_from_template_ex(
me_dst->totvert = verts_len;
me_dst->totedge = edges_len;
+ me_dst->totface = tessface_len;
me_dst->totloop = loops_len;
me_dst->totpoly = polys_len;
@@ -652,15 +670,12 @@ static Mesh *mesh_new_nomain_from_template_ex(
mesh_tessface_clear_intern(me_dst, false);
}
+ /* The destination mesh should at least have valid primary CD layers,
+ * even in cases where the source mesh does not. */
+ mesh_ensure_cdlayers_primary(me_dst, do_tessface);
+ mesh_ensure_cdlayers_origindex(me_dst, false);
BKE_mesh_update_customdata_pointers(me_dst, false);
- if (!CustomData_get_layer(&me_dst->vdata, CD_ORIGINDEX))
- CustomData_add_layer(&me_dst->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, verts_len);
- if (!CustomData_get_layer(&me_dst->edata, CD_ORIGINDEX))
- CustomData_add_layer(&me_dst->edata, CD_ORIGINDEX, CD_CALLOC, NULL, edges_len);
- if (!CustomData_get_layer(&me_dst->pdata, CD_ORIGINDEX))
- CustomData_add_layer(&me_dst->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, polys_len);
-
return me_dst;
}
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index a3eef7b17b2..acd0cf32b13 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -43,6 +43,7 @@
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_displist.h"
#include "BKE_library.h"
@@ -1263,7 +1264,7 @@ static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int act
/* This is a Mesh-based copy of DM_to_mesh() */
-void BKE_nomain_mesh_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob, CustomDataMask mask, bool take_ownership)
+void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob, CustomDataMask mask, bool take_ownership)
{
/* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */
/* TODO(Sybren): the above claim came from DM_to_mesh(); check whether it is still true with Mesh */
@@ -1414,7 +1415,7 @@ void BKE_nomain_mesh_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob, CustomD
}
/* This is a Mesh-based copy of DM_to_meshkey() */
-void BKE_nomain_mesh_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
+void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
{
int a, totvert = mesh_src->totvert;
float *fp;
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 068be0ef304..2d8476d6f02 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -88,6 +88,20 @@ static void mesh_calc_normals_vert_fallback(MVert *mverts, int numVerts)
}
}
+/* TODO(Sybren): we can probably rename this to BKE_mesh_calc_normals_mapping(),
+ * and remove the function of the same name below, as that one doesn't seem to be
+ * called anywhere. */
+void BKE_mesh_calc_normals_mapping_simple(struct Mesh *mesh)
+{
+ const bool only_face_normals = CustomData_is_referenced_layer(&mesh->vdata, CD_MVERT);
+
+ BKE_mesh_calc_normals_mapping_ex(
+ mesh->mvert, mesh->totvert,
+ mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, NULL,
+ mesh->mface, mesh->totface, NULL, NULL,
+ only_face_normals);
+}
+
/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-NULL
* and vertex normals are stored in actual mverts.
*/
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
index c8416811694..cd9db408d19 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.c
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -35,13 +35,22 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
#include "BLI_math_geom.h"
#include "BLI_threads.h"
#include "BKE_bvhutils.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
+#ifdef USE_DERIVEDMESH
+#include "BKE_DerivedMesh.h"
+#endif
+
+/* -------------------------------------------------------------------- */
+/** \name Mesh Runtime Struct Utils
+ * \{ */
static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
@@ -145,8 +154,9 @@ const MLoopTri *BKE_mesh_runtime_looptri_ensure(Mesh *mesh)
}
/* This is a copy of DM_verttri_from_looptri(). */
-void BKE_mesh_runtime_verttri_from_looptri(MVertTri *r_verttri, const MLoop *mloop,
- const MLoopTri *looptri, int looptri_num)
+void BKE_mesh_runtime_verttri_from_looptri(
+ MVertTri *r_verttri, const MLoop *mloop,
+ const MLoopTri *looptri, int looptri_num)
{
int i;
for (i = 0; i < looptri_num; i++) {
@@ -192,6 +202,12 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
MEM_SAFE_FREE(mesh->runtime.looptris.array);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Mesh Batch Cache Callbacks
+ * \{ */
+
/* Draw Engine */
void (*BKE_mesh_batch_cache_dirty_cb)(Mesh *me, int mode) = NULL;
void (*BKE_mesh_batch_cache_free_cb)(Mesh *me) = NULL;
@@ -208,3 +224,5 @@ void BKE_mesh_batch_cache_free(Mesh *me)
BKE_mesh_batch_cache_free_cb(me);
}
}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index bd9cd684548..0b904caf375 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -809,6 +809,18 @@ const char *modifier_path_relbase(Main *bmain, Object *ob)
}
}
+const char *modifier_path_relbase_from_global(Object *ob)
+{
+ if (G.relbase_valid || ID_IS_LINKED(ob)) {
+ return ID_BLEND_PATH_FROM_GLOBAL(&ob->id);
+ }
+ else {
+ /* last resort, better then using "" which resolves to the current
+ * working directory */
+ return BKE_tempdir_session();
+ }
+}
+
/* initializes the path with either */
void modifier_path_init(char *path, int path_maxlen, const char *name)
{
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index d742bcea69d..fc236cc2ad0 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -199,7 +199,7 @@ static void get_proxy_fname(const MovieClip *clip,
else
BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, proxynr);
- BLI_path_abs(name, G.main->name);
+ BLI_path_abs(name, BKE_main_blendfile_path_from_global());
BLI_path_frame(name, 1, 0);
strcat(name, ".jpg");
@@ -270,7 +270,7 @@ static void movieclip_open_anim_file(MovieClip *clip)
if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) {
char dir[FILE_MAX];
BLI_strncpy(dir, clip->proxy.dir, sizeof(dir));
- BLI_path_abs(dir, G.main->name);
+ BLI_path_abs(dir, BKE_main_blendfile_path_from_global());
IMB_anim_set_index_dir(clip->anim, dir);
}
}
@@ -627,13 +627,13 @@ static void movieclip_load_get_size(MovieClip *clip)
}
}
-static void detect_clip_source(MovieClip *clip)
+static void detect_clip_source(Main *bmain, MovieClip *clip)
{
ImBuf *ibuf;
char name[FILE_MAX];
BLI_strncpy(name, clip->name, sizeof(name));
- BLI_path_abs(name, G.main->name);
+ BLI_path_abs(name, BKE_main_blendfile_path(bmain));
ibuf = IMB_testiffname(name, IB_rect | IB_multilayer);
if (ibuf) {
@@ -656,7 +656,7 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
char str[FILE_MAX];
BLI_strncpy(str, name, sizeof(str));
- BLI_path_abs(str, bmain->name);
+ BLI_path_abs(str, BKE_main_blendfile_path(bmain));
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
@@ -670,7 +670,7 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
clip = movieclip_alloc(bmain, BLI_path_basename(name));
BLI_strncpy(clip->name, name, sizeof(clip->name));
- detect_clip_source(clip);
+ detect_clip_source(bmain, clip);
movieclip_load_get_size(clip);
if (clip->lastsize[0]) {
@@ -690,7 +690,7 @@ MovieClip *BKE_movieclip_file_add_exists_ex(Main *bmain, const char *filepath, b
char str[FILE_MAX], strtest[FILE_MAX];
BLI_strncpy(str, filepath, sizeof(str));
- BLI_path_abs(str, bmain->name);
+ BLI_path_abs(str, BKE_main_blendfile_path(bmain));
/* first search an identical filepath */
for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
@@ -1282,13 +1282,13 @@ void BKE_movieclip_clear_proxy_cache(MovieClip *clip)
}
}
-void BKE_movieclip_reload(MovieClip *clip)
+void BKE_movieclip_reload(Main *bmain, MovieClip *clip)
{
/* clear cache */
free_buffers(clip);
/* update clip source */
- detect_clip_source(clip);
+ detect_clip_source(bmain, clip);
clip->lastsize[0] = clip->lastsize[1] = 0;
movieclip_load_get_size(clip);
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index ee32c2398b2..39a472241bc 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -51,6 +51,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_paint.h"
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 7a1f6c5d2b6..bf25306028f 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3739,43 +3739,9 @@ void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer
}
}
-static void node_copy_default_values_list(ListBase *sockets_dst,
- const ListBase *sockets_src)
-{
- bNodeSocket *sock_dst = sockets_dst->first;
- const bNodeSocket *sock_src = sockets_src->first;
- while (sock_dst != NULL) {
- node_socket_copy_default_value(sock_dst, sock_src);
- sock_dst = sock_dst->next;
- sock_src = sock_src->next;
- }
-}
-
-static void node_copy_default_values(bNode *node_dst, const bNode *node_src)
-{
- node_copy_default_values_list(&node_dst->inputs, &node_src->inputs);
- node_copy_default_values_list(&node_dst->outputs, &node_src->outputs);
-}
-
-void BKE_nodetree_copy_default_values(bNodeTree *ntree_dst,
- const bNodeTree *ntree_src)
-{
- if (ntree_dst == ntree_src) {
- return;
- }
- bNode *node_dst = ntree_dst->nodes.first;
- const bNode *node_src = ntree_src->nodes.first;
- while (node_dst != NULL) {
- node_copy_default_values(node_dst, node_src);
- node_dst = node_dst->next;
- node_src = node_src->next;
- }
-}
-
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);
- BKE_nodetree_copy_default_values(ntree_dst, ntree_src);
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 2eb35908d63..f55925f64f5 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -330,21 +330,14 @@ void BKE_object_free_derived_caches(Object *ob)
ob->bb = NULL;
}
- if (ob->derivedFinal) {
- ob->derivedFinal->needsFree = 1;
- ob->derivedFinal->release(ob->derivedFinal);
- ob->derivedFinal = NULL;
- }
- if (ob->derivedDeform) {
- ob->derivedDeform->needsFree = 1;
- ob->derivedDeform->release(ob->derivedDeform);
- ob->derivedDeform = NULL;
- }
+ BKE_object_free_derived_mesh_caches(ob);
if (ob->runtime.mesh_eval != NULL) {
Mesh *mesh_eval = ob->runtime.mesh_eval;
/* Restore initial pointer. */
- ob->data = mesh_eval->id.orig_id;
+ if (ob->data == mesh_eval) {
+ ob->data = ob->runtime.mesh_orig;
+ }
/* Evaluated mesh points to edit mesh, but does not own it. */
mesh_eval->edit_btmesh = NULL;
BKE_mesh_free(mesh_eval);
@@ -363,6 +356,20 @@ void BKE_object_free_derived_caches(Object *ob)
BKE_object_free_curve_cache(ob);
}
+void BKE_object_free_derived_mesh_caches(struct Object *ob)
+{
+ if (ob->derivedFinal) {
+ ob->derivedFinal->needsFree = 1;
+ ob->derivedFinal->release(ob->derivedFinal);
+ ob->derivedFinal = NULL;
+ }
+ if (ob->derivedDeform) {
+ ob->derivedDeform->needsFree = 1;
+ ob->derivedDeform->release(ob->derivedDeform);
+ ob->derivedDeform = NULL;
+ }
+}
+
void BKE_object_free_caches(Object *object)
{
ModifierData *md;
@@ -2849,6 +2856,60 @@ Mesh *BKE_object_get_evaluated_mesh(const Depsgraph *depsgraph, Object *ob)
return ob_eval->runtime.mesh_eval;
}
+/* Get object's mesh with all modifiers applied. */
+Mesh *BKE_object_get_final_mesh(Object *object)
+{
+ if (object->runtime.mesh_eval != NULL) {
+ BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
+ BLI_assert(object->runtime.mesh_eval == object->data);
+ BLI_assert((object->runtime.mesh_eval->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) != 0);
+ return object->runtime.mesh_eval;
+ }
+ /* Wasn't evaluated yet. */
+ return object->data;
+}
+
+/* Get mesh which is not affected by modifiers:
+ * - For original objects it will be same as object->data, and it is a mesh
+ * which is in the corresponding bmain.
+ * - For copied-on-write objects it will give pointer to a copied-on-write
+ * mesh which corresponds to original object's mesh.
+ */
+Mesh *BKE_object_get_pre_modified_mesh(Object *object)
+{
+ if (object->runtime.mesh_orig != NULL) {
+ BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
+ BLI_assert(object->id.orig_id != NULL);
+ BLI_assert(object->runtime.mesh_orig->id.orig_id == ((Object *)object->id.orig_id)->data);
+ Mesh *result = object->runtime.mesh_orig;
+ BLI_assert((result->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
+ BLI_assert((result->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
+ return result;
+ }
+ BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0);
+ return object->data;
+}
+
+/* Get a mesh which corresponds to very very original mesh from bmain.
+ * - For original objects it will be object->data.
+ * - For evaluated objects it will be same mesh as corresponding original
+ * object uses as data.
+ */
+Mesh *BKE_object_get_original_mesh(Object *object)
+{
+ Mesh *result = NULL;
+ if (object->id.orig_id == NULL) {
+ BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0);
+ result = object->data;
+ }
+ else {
+ BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
+ result = ((Object *)object->id.orig_id)->data;
+ }
+ BLI_assert(result != NULL);
+ BLI_assert((result->id.tag & (LIB_TAG_COPIED_ON_WRITE | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT)) == 0);
+ return result;
+}
static int pc_cmp(const void *a, const void *b)
{
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 2c94dc76854..324ad3a31dc 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -56,6 +56,7 @@
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
@@ -72,8 +73,6 @@
typedef struct DupliContext {
Depsgraph *depsgraph;
- bool do_update;
- bool animated;
Collection *collection; /* XXX child objects are selected from this group if set, could be nicer */
Object *obedit; /* Only to check if the object is in edit-mode. */
@@ -99,14 +98,11 @@ typedef struct DupliGenerator {
static const DupliGenerator *get_dupli_generator(const DupliContext *ctx);
/* create initial context for root object */
-static void init_context(DupliContext *r_ctx, Depsgraph *depsgraph, Scene *scene, Object *ob, float space_mat[4][4], bool update)
+static void init_context(DupliContext *r_ctx, Depsgraph *depsgraph, Scene *scene, Object *ob, float space_mat[4][4])
{
r_ctx->depsgraph = depsgraph;
r_ctx->scene = scene;
r_ctx->view_layer = DEG_get_evaluated_view_layer(depsgraph);
- /* don't allow BKE_object_handle_update for viewport during render, can crash */
- r_ctx->do_update = update && !(G.is_rendering && DEG_get_mode(depsgraph) != DAG_EVAL_RENDER);
- r_ctx->animated = false;
r_ctx->collection = NULL;
r_ctx->object = ob;
@@ -123,12 +119,10 @@ static void init_context(DupliContext *r_ctx, Depsgraph *depsgraph, Scene *scene
}
/* create sub-context for recursive duplis */
-static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Object *ob, float mat[4][4], int index, bool animated)
+static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Object *ob, float mat[4][4], int index)
{
*r_ctx = *ctx;
- r_ctx->animated |= animated; /* object animation makes all children animated */
-
/* XXX annoying, previously was done by passing an ID* argument, this at least is more explicit */
if (ctx->gen->type == OB_DUPLICOLLECTION)
r_ctx->collection = ctx->object->dup_group;
@@ -146,8 +140,7 @@ static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Obj
* mat is transform of the object relative to current context (including object obmat)
*/
static DupliObject *make_dupli(const DupliContext *ctx,
- Object *ob, float mat[4][4], int index,
- bool animated, bool hide)
+ Object *ob, float mat[4][4], int index)
{
DupliObject *dob;
int i;
@@ -164,7 +157,6 @@ static DupliObject *make_dupli(const DupliContext *ctx,
dob->ob = ob;
mul_m4_m4m4(dob->mat, (float (*)[4])ctx->space_mat, mat);
dob->type = ctx->gen->type;
- dob->animated = animated || ctx->animated; /* object itself or some parent is animated */
/* set persistent id, which is an array with a persistent index for each level
* (particle number, vertex number, ..). by comparing this we can find the same
@@ -177,8 +169,6 @@ static DupliObject *make_dupli(const DupliContext *ctx,
for (; i < MAX_DUPLI_RECUR; i++)
dob->persistent_id[i] = INT_MAX;
- if (hide)
- dob->no_draw = true;
/* metaballs never draw in duplis, they are instead merged into one by the basis
* mball outside of the group. this does mean that if that mball is not in the
* scene, they will not show up at all, limitation that should be solved once. */
@@ -208,12 +198,12 @@ static DupliObject *make_dupli(const DupliContext *ctx,
/* recursive dupli objects
* space_mat is the local dupli space (excluding dupli object obmat!)
*/
-static void make_recursive_duplis(const DupliContext *ctx, Object *ob, float space_mat[4][4], int index, bool animated)
+static void make_recursive_duplis(const DupliContext *ctx, Object *ob, float space_mat[4][4], int index)
{
/* simple preventing of too deep nested collections with MAX_DUPLI_RECUR */
if (ctx->level < MAX_DUPLI_RECUR) {
DupliContext rctx;
- copy_dupli_context(&rctx, ctx, ob, space_mat, index, animated);
+ copy_dupli_context(&rctx, ctx, ob, space_mat, index);
if (rctx.gen) {
rctx.gen->make_duplis(&rctx);
}
@@ -247,7 +237,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
Object *ob = base->object;
if ((base->flag & BASE_VISIBLED) && ob != ctx->obedit && is_child(ob, parent)) {
DupliContext pctx;
- copy_dupli_context(&pctx, ctx, ctx->object, NULL, collectionid, false);
+ copy_dupli_context(&pctx, ctx, ctx->object, NULL, collectionid);
/* mballs have a different dupli handling */
if (ob->type != OB_MBALL) {
@@ -266,7 +256,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
Object *ob = base->object;
if ((ob != ctx->obedit) && is_child(ob, parent)) {
DupliContext pctx;
- copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid, false);
+ copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid);
/* mballs have a different dupli handling */
if (ob->type != OB_MBALL)
@@ -289,7 +279,6 @@ static void make_duplis_collection(const DupliContext *ctx)
Base *base;
float collection_mat[4][4];
int id;
- bool animated;
if (ob->dup_group == NULL) return;
collection = ob->dup_group;
@@ -300,17 +289,6 @@ static void make_duplis_collection(const DupliContext *ctx)
mul_m4_m4m4(collection_mat, ob->obmat, collection_mat);
/* don't access 'ob->obmat' from now on. */
- /* handles animated collections */
-
- /* we need to check update for objects that are not in scene... */
- if (ctx->do_update) {
- /* note: update is optional because we don't always need object
- * transformations to be correct. Also fixes bug [#29616]. */
- BKE_collection_handle_recalc_and_update(ctx->depsgraph, ctx->scene, ob, collection);
- }
-
- animated = BKE_collection_is_animated(collection, ob);
-
const ListBase dup_collection_objects = BKE_collection_object_cache_get(collection);
for (base = dup_collection_objects.first, id = 0; base; base = base->next, id++) {
if (base->object != ob && (base->flag & BASE_VISIBLED)) {
@@ -319,10 +297,10 @@ static void make_duplis_collection(const DupliContext *ctx)
/* collection dupli offset, should apply after everything else */
mul_m4_m4m4(mat, collection_mat, base->object->obmat);
- make_dupli(ctx, base->object, mat, id, animated, false);
+ make_dupli(ctx, base->object, mat, id);
/* recursion */
- make_recursive_duplis(ctx, base->object, collection_mat, id, animated);
+ make_recursive_duplis(ctx, base->object, collection_mat, id);
}
}
}
@@ -383,7 +361,7 @@ static void make_duplis_frames(const DupliContext *ctx)
BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM);
BKE_object_where_is_calc_time(depsgraph, scene, ob, (float)scene->r.cfra);
- make_dupli(ctx, ob, ob->obmat, scene->r.cfra, false, false);
+ make_dupli(ctx, ob, ob->obmat, scene->r.cfra);
}
}
@@ -469,13 +447,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
*/
mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
- dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index, false, false);
+ dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index);
if (vdd->orco)
copy_v3_v3(dob->orco, vdd->orco[index]);
/* recursion */
- make_recursive_duplis(vdd->ctx, vdd->inst_ob, space_mat, index, false);
+ make_recursive_duplis(vdd->ctx, vdd->inst_ob, space_mat, index);
}
static void make_child_duplis_verts(const DupliContext *ctx, void *userdata, Object *child)
@@ -654,7 +632,7 @@ static void make_duplis_font(const DupliContext *ctx)
copy_v3_v3(obmat[3], vec);
- make_dupli(ctx, ob, obmat, a, false, false);
+ make_dupli(ctx, ob, obmat, a);
}
}
@@ -760,7 +738,7 @@ static void make_child_duplis_faces(const DupliContext *ctx, void *userdata, Obj
*/
mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
- dob = make_dupli(ctx, inst_ob, obmat, a, false, false);
+ dob = make_dupli(ctx, inst_ob, obmat, a);
if (use_texcoords) {
float w = 1.0f / (float)mp->totloop;
@@ -780,7 +758,7 @@ static void make_child_duplis_faces(const DupliContext *ctx, void *userdata, Obj
}
/* recursion */
- make_recursive_duplis(ctx, inst_ob, space_mat, a, false);
+ make_recursive_duplis(ctx, inst_ob, space_mat, a);
}
}
@@ -925,10 +903,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
/* gather list of objects or single object */
if (part->ren_as == PART_DRAW_GR) {
- if (ctx->do_update) {
- BKE_collection_handle_recalc_and_update(ctx->depsgraph, scene, par, part->dup_group);
- }
-
if (part->draw & PART_DRAW_COUNT_GR) {
for (dw = part->dupliweights.first; dw; dw = dw->next)
totcollection += dw->count;
@@ -1075,7 +1049,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
/* individual particle transform */
mul_m4_m4m4(mat, pamat, tmat);
- dob = make_dupli(ctx, object, mat, a, false, false);
+ dob = make_dupli(ctx, object, mat, a);
dob->particle_system = psys;
if (use_texcoords) {
@@ -1129,7 +1103,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
if (part->draw & PART_DRAW_GLOBAL_OB)
add_v3_v3v3(mat[3], mat[3], vec);
- dob = make_dupli(ctx, ob, mat, a, false, false);
+ dob = make_dupli(ctx, ob, mat, a);
dob->particle_system = psys;
if (use_texcoords)
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
@@ -1166,7 +1140,7 @@ static void make_duplis_particles(const DupliContext *ctx)
for (psys = ctx->object->particlesystem.first, psysid = 0; psys; psys = psys->next, psysid++) {
/* particles create one more level for persistent psys index */
DupliContext pctx;
- copy_dupli_context(&pctx, ctx, ctx->object, NULL, psysid, false);
+ copy_dupli_context(&pctx, ctx, ctx->object, NULL, psysid);
make_duplis_particle_system(&pctx, psys);
}
}
@@ -1220,11 +1194,11 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
/* ---- ListBase dupli container implementation ---- */
/* Returns a list of DupliObject */
-ListBase *object_duplilist_ex(Depsgraph *depsgraph, Scene *scene, Object *ob, bool update)
+ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
{
ListBase *duplilist = MEM_callocN(sizeof(ListBase), "duplilist");
DupliContext ctx;
- init_context(&ctx, depsgraph, scene, ob, NULL, update);
+ init_context(&ctx, depsgraph, sce, ob, NULL);
if (ctx.gen) {
ctx.duplilist = duplilist;
ctx.gen->make_duplis(&ctx);
@@ -1233,13 +1207,6 @@ ListBase *object_duplilist_ex(Depsgraph *depsgraph, Scene *scene, Object *ob, bo
return duplilist;
}
-/* note: previously updating was always done, this is why it defaults to be on
- * but there are likely places it can be called without updating */
-ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
-{
- return object_duplilist_ex(depsgraph, sce, ob, true);
-}
-
void free_object_duplilist(ListBase *lb)
{
BLI_freelistN(lb);
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 852d8197a6c..3b684ebfd94 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -145,6 +145,7 @@ void BKE_object_eval_done(Depsgraph *depsgraph, Object *ob)
Object *ob_orig = DEG_get_original_object(ob);
copy_m4_m4(ob_orig->obmat, ob->obmat);
ob_orig->transflag = ob->transflag;
+ ob_orig->flag = ob->flag;
}
}
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index afb155f7646..baa88f00985 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -246,14 +246,14 @@ void packAll(Main *bmain, ReportList *reports, bool verbose)
for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) {
if (vfont->packedfile == NULL && !ID_IS_LINKED(vfont) && BKE_vfont_is_builtin(vfont) == false) {
- vfont->packedfile = newPackedFile(reports, vfont->name, bmain->name);
+ vfont->packedfile = newPackedFile(reports, vfont->name, BKE_main_blendfile_path(bmain));
tot ++;
}
}
for (sound = bmain->sound.first; sound; sound = sound->id.next) {
if (sound->packedfile == NULL && !ID_IS_LINKED(sound)) {
- sound->packedfile = newPackedFile(reports, sound->name, bmain->name);
+ sound->packedfile = newPackedFile(reports, sound->name, BKE_main_blendfile_path(bmain));
tot++;
}
}
@@ -542,7 +542,7 @@ int unpackVFont(Main *bmain, ReportList *reports, VFont *vfont, int how)
if (vfont != NULL) {
unpack_generate_paths(vfont->name, (ID *)vfont, absname, localname, sizeof(absname), sizeof(localname));
- newname = unpackFile(reports, bmain->name, absname, localname, vfont->packedfile, how);
+ newname = unpackFile(reports, BKE_main_blendfile_path(bmain), absname, localname, vfont->packedfile, how);
if (newname != NULL) {
ret_value = RET_OK;
freePackedFile(vfont->packedfile);
@@ -563,7 +563,7 @@ int unpackSound(Main *bmain, ReportList *reports, bSound *sound, int how)
if (sound != NULL) {
unpack_generate_paths(sound->name, (ID *)sound, absname, localname, sizeof(absname), sizeof(localname));
- newname = unpackFile(reports, bmain->name, absname, localname, sound->packedfile, how);
+ newname = unpackFile(reports, BKE_main_blendfile_path(bmain), absname, localname, sound->packedfile, how);
if (newname != NULL) {
BLI_strncpy(sound->name, newname, sizeof(sound->name));
MEM_freeN(newname);
@@ -591,7 +591,7 @@ int unpackImage(Main *bmain, ReportList *reports, Image *ima, int how)
ImagePackedFile *imapf = ima->packedfiles.last;
unpack_generate_paths(imapf->filepath, (ID *)ima, absname, localname, sizeof(absname), sizeof(localname));
- newname = unpackFile(reports, bmain->name, absname, localname, imapf->packedfile, how);
+ newname = unpackFile(reports, BKE_main_blendfile_path(bmain), absname, localname, imapf->packedfile, how);
if (newname != NULL) {
ImageView *iv;
@@ -637,7 +637,7 @@ int unpackLibraries(Main *bmain, ReportList *reports)
for (lib = bmain->library.first; lib; lib = lib->id.next) {
if (lib->packedfile && lib->name[0]) {
- newname = unpackFile(reports, bmain->name, lib->filepath, lib->filepath, lib->packedfile, PF_WRITE_ORIGINAL);
+ newname = unpackFile(reports, BKE_main_blendfile_path(bmain), lib->filepath, lib->filepath, lib->packedfile, PF_WRITE_ORIGINAL);
if (newname != NULL) {
ret_value = RET_OK;
@@ -670,7 +670,7 @@ void packLibraries(Main *bmain, ReportList *reports)
for (lib = bmain->library.first; lib; lib = lib->id.next)
if (lib->packedfile == NULL)
- lib->packedfile = newPackedFile(reports, lib->name, bmain->name);
+ lib->packedfile = newPackedFile(reports, lib->name, BKE_main_blendfile_path(bmain));
}
void unpackAll(Main *bmain, ReportList *reports, int how)
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index f961510984a..f03b46c8a07 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -59,6 +59,8 @@
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -753,7 +755,6 @@ void BKE_sculptsession_free(Object *ob)
{
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
- DerivedMesh *dm = ob->derivedFinal;
if (ss->bm) {
BKE_sculptsession_bm_to_me(ob, true);
@@ -762,12 +763,11 @@ void BKE_sculptsession_free(Object *ob)
if (ss->pbvh)
BKE_pbvh_free(ss->pbvh);
+ MEM_SAFE_FREE(ss->pmap);
+ MEM_SAFE_FREE(ss->pmap_mem);
if (ss->bm_log)
BM_log_free(ss->bm_log);
- if (dm && dm->getPBVH)
- dm->getPBVH(NULL, dm); /* signal to clear */
-
if (ss->texcache)
MEM_freeN(ss->texcache);
@@ -872,9 +872,8 @@ void BKE_sculpt_update_mesh_elements(
return;
}
- DerivedMesh *dm;
SculptSession *ss = ob->sculpt;
- Mesh *me = ob->data;
+ Mesh *me = BKE_object_get_original_mesh(ob);
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob);
@@ -909,13 +908,14 @@ void BKE_sculpt_update_mesh_elements(
ss->kb = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL;
- dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH);
+ Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH);
+ Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, scene, ob, CD_MASK_BAREMESH);
/* VWPaint require mesh info for loop lookup, so require sculpt mode here */
if (mmd && ob->mode & OB_MODE_SCULPT) {
ss->multires = mmd;
- ss->totvert = dm->getNumVerts(dm);
- ss->totpoly = dm->getNumPolys(dm);
+ ss->totvert = me_eval->totvert;
+ ss->totpoly = me_eval->totpoly;
ss->mvert = NULL;
ss->mpoly = NULL;
ss->mloop = NULL;
@@ -930,8 +930,17 @@ void BKE_sculpt_update_mesh_elements(
ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
}
- ss->pbvh = dm->getPBVH(ob, dm);
- ss->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL;
+ PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(ob, me_eval_deform);
+ BLI_assert(pbvh == ss->pbvh);
+ UNUSED_VARS_NDEBUG(pbvh);
+ MEM_SAFE_FREE(ss->pmap);
+ MEM_SAFE_FREE(ss->pmap_mem);
+ if (need_pmap && ob->type == OB_MESH) {
+ BKE_mesh_vert_poly_map_create(
+ &ss->pmap, &ss->pmap_mem,
+ me->mpoly, me->mloop,
+ me->totvert, me->totpoly, me->totloop);
+ }
pbvh_show_diffuse_color_set(ss->pbvh, ss->show_diffuse_color);
pbvh_show_mask_set(ss->pbvh, ss->show_mask);
@@ -945,7 +954,7 @@ void BKE_sculpt_update_mesh_elements(
ss->orig_cos = (ss->kb) ? BKE_keyblock_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
BKE_crazyspace_build_sculpt(depsgraph, scene, ob, &ss->deform_imats, &ss->deform_cos);
- BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos, me->totvert);
for (a = 0; a < me->totvert; ++a) {
invert_m3(ss->deform_imats[a]);
@@ -962,14 +971,14 @@ void BKE_sculpt_update_mesh_elements(
/* if pbvh is deformed, key block is already applied to it */
if (ss->kb) {
- bool pbvh_deformd = BKE_pbvh_isDeformed(ss->pbvh);
- if (!pbvh_deformd || ss->deform_cos == NULL) {
+ bool pbvh_deformed = BKE_pbvh_isDeformed(ss->pbvh);
+ if (!pbvh_deformed || ss->deform_cos == NULL) {
float (*vertCos)[3] = BKE_keyblock_convert_to_vertcos(ob, ss->kb);
if (vertCos) {
- if (!pbvh_deformd) {
+ if (!pbvh_deformed) {
/* apply shape keys coordinates to PBVH */
- BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, vertCos, me->totvert);
}
if (ss->deform_cos == NULL) {
ss->deform_cos = vertCos;
@@ -1091,3 +1100,96 @@ void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene)
sd->paint.tile_offset[2] = 1.0f;
}
}
+
+static bool check_sculpt_object_deformed(Object *object, const bool for_construction)
+{
+ bool deformed = false;
+
+ /* Active modifiers means extra deformation, which can't be handled correct
+ * on birth of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
+ * stuff and show final DerivedMesh so user would see actual object shape.
+ */
+ deformed |= object->sculpt->modifiers_active;
+
+ if (for_construction) {
+ deformed |= object->sculpt->kb != NULL;
+ }
+ else {
+ /* As in case with modifiers, we can't synchronize deformation made against
+ * PBVH and non-locked keyblock, so also use PBVH only for brushes and
+ * final DM to give final result to user.
+ */
+ deformed |= object->sculpt->kb && (object->shapeflag & OB_SHAPE_LOCK) == 0;
+ }
+
+ return deformed;
+}
+
+PBVH *BKE_sculpt_object_pbvh_ensure(Object *ob, Mesh *me_eval_deform)
+{
+ if (!ob) {
+ return NULL;
+ }
+
+ if (!ob->sculpt) {
+ return NULL;
+ }
+
+ PBVH *pbvh = ob->sculpt->pbvh;
+
+ /* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */
+ if (!pbvh && ob->sculpt->bm) {
+ pbvh = BKE_pbvh_new();
+
+ BKE_pbvh_build_bmesh(pbvh, ob->sculpt->bm,
+ ob->sculpt->bm_smooth_shading,
+ ob->sculpt->bm_log, ob->sculpt->cd_vert_node_offset,
+ ob->sculpt->cd_face_node_offset);
+
+ pbvh_show_diffuse_color_set(pbvh, ob->sculpt->show_diffuse_color);
+ pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
+ }
+
+ /* always build pbvh from original mesh, and only use it for drawing if
+ * this derivedmesh is just original mesh. it's the multires subsurf dm
+ * that this is actually for, to support a pbvh on a modified mesh */
+ if (!pbvh && ob->type == OB_MESH) {
+ Mesh *me = BKE_object_get_original_mesh(ob);
+ const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
+ MLoopTri *looptri;
+ bool deformed;
+
+ pbvh = BKE_pbvh_new();
+
+ looptri = MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__);
+
+ BKE_mesh_recalc_looptri(
+ me->mloop, me->mpoly,
+ me->mvert,
+ me->totloop, me->totpoly,
+ looptri);
+
+ BKE_pbvh_build_mesh(
+ pbvh,
+ me->mpoly, me->mloop,
+ me->mvert, me->totvert, &me->vdata,
+ looptri, looptris_num);
+
+ pbvh_show_diffuse_color_set(pbvh, ob->sculpt->show_diffuse_color);
+ pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
+
+ deformed = check_sculpt_object_deformed(ob, true);
+
+ if (deformed && me_eval_deform) {
+ int totvert;
+ float (*v_cos)[3];
+
+ v_cos = BKE_mesh_vertexCos_get(me_eval_deform, &totvert);
+ BKE_pbvh_apply_vertCos(pbvh, v_cos, totvert);
+ MEM_freeN(v_cos);
+ }
+ }
+
+ ob->sculpt->pbvh = pbvh;
+ return pbvh;
+}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 9550cbc6b50..8c322f0c853 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -298,24 +298,6 @@ ParticleSystem *psys_orig_get(ParticleSystem *psys)
return psys->orig_psys;
}
-struct ParticleSystem *psys_eval_get(Depsgraph *depsgraph,
- Object *object,
- ParticleSystem *psys)
-{
- Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
- if (object_eval == object) {
- return psys;
- }
- ParticleSystem *psys_eval = object_eval->particlesystem.first;
- while (psys_eval != NULL) {
- if (psys_eval->orig_psys == psys) {
- return psys_eval;
- }
- psys_eval = psys_eval->next;
- }
- return psys_eval;
-}
-
static PTCacheEdit *psys_orig_edit_get(ParticleSystem *psys)
{
if (psys->orig_psys == NULL) {
@@ -2618,7 +2600,6 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
}
void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params)
{
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
ParticleCacheKey *ca, **cache = edit->pathcache;
ParticleEditSettings *pset = &scene->toolsettings->particle;
@@ -2626,16 +2607,9 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
PTCacheEditKey *ekey = NULL;
ParticleSystem *psys = edit->psys;
- ParticleSystem *psys_eval = NULL;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
- ParticleSystemModifierData *psmd_eval = NULL;
- if (psmd != NULL) {
- psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name);
- psys_eval = psmd_eval->psys;
- }
-
- ParticleData *pa = psys_eval ? psys_eval->particles : NULL;
+ ParticleData *pa = psys ? psys->particles : NULL;
ParticleInterpolationData pind;
ParticleKey result;
@@ -2664,7 +2638,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
/* frs_sec = (psys || edit->pid.flag & PTCACHE_VEL_PER_SEC) ? 25.0f : 1.0f; */ /* UNUSED */
- const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT) && (psys_eval != NULL) && (psys_eval->particles != NULL);
+ const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT) && (psys != NULL) && (psys->particles != NULL);
if (use_weight) {
; /* use weight painting colors now... */
@@ -2709,10 +2683,10 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
cache[i]->segments = segments;
/*--get the first data points--*/
- init_particle_interpolation(ob_eval, psys_eval, pa, &pind);
+ init_particle_interpolation(ob, psys, pa, &pind);
- if (psys_eval) {
- psys_mat_hair_to_global(ob_eval, psmd_eval->mesh_final, psys->part->from, pa, hairmat);
+ if (psys) {
+ psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat);
copy_v3_v3(rotmat[0], hairmat[2]);
copy_v3_v3(rotmat[1], hairmat[1]);
copy_v3_v3(rotmat[2], hairmat[0]);
@@ -2731,7 +2705,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
time = (float)k / (float)segments;
t = birthtime + time * (dietime - birthtime);
result.time = -t;
- do_particle_interpolation(psys_eval, i, pa, t, &pind, &result);
+ do_particle_interpolation(psys, i, pa, t, &pind, &result);
copy_v3_v3(ca->co, result.co);
/* non-hair points are already in global space */
@@ -2828,9 +2802,9 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, Scene *scene, Object *ob, PTCac
ParticleSimulationData sim = {0};
sim.depsgraph = depsgraph;
sim.scene = scene;
- sim.ob = ob_eval;
- sim.psys = psys_eval;
- sim.psmd = psys_get_modifier(ob_eval, psys_eval);
+ sim.ob = ob;
+ sim.psys = psys;
+ sim.psmd = psys_get_modifier(ob, psys);
psys_cache_child_paths(&sim, cfra, true, use_render_params);
}
@@ -3089,6 +3063,9 @@ void object_remove_particle_system(Scene *UNUSED(scene), Object *ob)
DEG_relations_tag_update(G.main);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+
+ /* Flush object mode. */
+ DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
}
static void default_particle_settings(ParticleSettings *part)
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 88fc8c6a440..8d6991ff9f4 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4150,7 +4150,7 @@ void psys_check_boid_data(ParticleSystem *psys)
}
}
-static void fluid_default_settings(ParticleSettings *part)
+void BKE_particlesettings_fluid_default_settings(ParticleSettings *part)
{
SPHFluidSettings *fluid = part->fluid;
@@ -4182,24 +4182,12 @@ static void psys_prepare_physics(ParticleSimulationData *sim)
sim->psys->flag &= ~PSYS_KEYED;
}
- if (part->phystype == PART_PHYS_BOIDS && part->boids == NULL) {
- BoidState *state;
-
- part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings");
- boid_default_settings(part->boids);
-
- state = boid_new_state(part->boids);
- BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Separate));
- BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Flock));
-
- ((BoidRule*)state->rules.first)->flag |= BOIDRULE_CURRENT;
-
- state->flag |= BOIDSTATE_CURRENT;
- BLI_addtail(&part->boids->states, state);
+ /* RNA Update must ensure this is true. */
+ if (part->phystype == PART_PHYS_BOIDS) {
+ BLI_assert(part->boids != NULL);
}
- else if (part->phystype == PART_PHYS_FLUID && part->fluid == NULL) {
- part->fluid = MEM_callocN(sizeof(SPHFluidSettings), "SPH Fluid Settings");
- fluid_default_settings(part);
+ else if (part->phystype == PART_PHYS_FLUID) {
+ BLI_assert(part->fluid != NULL);
}
psys_check_boid_data(sim->psys);
@@ -4229,6 +4217,18 @@ void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *o
if (!psys_check_enabled(ob, psys, use_render_params))
return;
+ if (DEG_is_active(depsgraph)) {
+ if (psys->orig_psys != NULL && psys->orig_psys->edit != NULL) {
+ psys_cache_edit_paths(
+ depsgraph,
+ (Scene *)DEG_get_original_id(&scene->id),
+ DEG_get_original_object(ob),
+ psys->orig_psys->edit,
+ DEG_get_ctime(depsgraph),
+ DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ }
+ }
+
cfra = DEG_get_ctime(depsgraph);
sim.depsgraph = depsgraph;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 7b53c5f8811..8cc8a8510f2 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -2189,8 +2189,13 @@ float (*BKE_pbvh_get_vertCos(PBVH *pbvh))[3]
return vertCos;
}
-void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
+void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3], const int totvert)
{
+ if (totvert != pbvh->totvert) {
+ BLI_assert(!"PBVH: Given deforming vcos number does not natch PBVH vertex number!");
+ return;
+ }
+
if (!pbvh->deformed) {
if (pbvh->verts) {
/* if pbvh is not already deformed, verts/faces points to the */
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index e219e27f851..af13909bf89 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1802,7 +1802,7 @@ static int ptcache_frame_from_filename(const char *filename, const char *ext)
static int ptcache_path(PTCacheID *pid, char *filename)
{
Library *lib = (pid->ob) ? pid->ob->id.lib : NULL;
- const char *blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filepath: G.main->name;
+ const char *blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filepath: BKE_main_blendfile_path_from_global();
size_t i;
if (pid->cache->flag & PTCACHE_EXTERNAL) {
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 75018bbe5bd..e79f86c6520 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -705,7 +705,8 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* --------------------- */
-static void rigidbody_constraint_set_limits(RigidBodyCon *rbc, void (*set_limits)(rbConstraint*,int,float,float))
+static void rigidbody_constraint_set_limits(
+ RigidBodyCon *rbc, void (*set_limits)(rbConstraint *, int, float, float))
{
if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index a488386fed8..2916e5559c4 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -945,11 +945,11 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name)
Scene *sce = (Scene *)BKE_libblock_find_name(bmain, ID_SCE, name);
if (sce) {
BKE_scene_set_background(bmain, sce);
- printf("Scene switch for render: '%s' in file: '%s'\n", name, bmain->name);
+ printf("Scene switch for render: '%s' in file: '%s'\n", name, BKE_main_blendfile_path(bmain));
return sce;
}
- printf("Can't find scene: '%s' in file: '%s'\n", name, bmain->name);
+ printf("Can't find scene: '%s' in file: '%s'\n", name, BKE_main_blendfile_path(bmain));
return NULL;
}
@@ -1029,7 +1029,7 @@ int BKE_scene_base_iter_next(
* this enters eternal loop because of
* makeDispListMBall getting called inside of collection_duplilist */
if ((*base)->object->dup_group == NULL) {
- iter->duplilist = object_duplilist_ex(depsgraph, (*scene), (*base)->object, false);
+ iter->duplilist = object_duplilist(depsgraph, (*scene), (*base)->object);
iter->dupob = iter->duplilist->first;
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index ece68884f5c..8cff10902ef 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -69,13 +69,19 @@ static void spacetype_free(SpaceType *st)
for (art = st->regiontypes.first; art; art = art->next) {
BLI_freelistN(&art->drawcalls);
- for (pt = art->paneltypes.first; pt; pt = pt->next)
- if (pt->ext.free)
+ for (pt = art->paneltypes.first; pt; pt = pt->next) {
+ if (pt->ext.free) {
pt->ext.free(pt->ext.data);
+ }
+
+ BLI_freelistN(&pt->children);
+ }
- for (ht = art->headertypes.first; ht; ht = ht->next)
- if (ht->ext.free)
+ for (ht = art->headertypes.first; ht; ht = ht->next) {
+ if (ht->ext.free) {
ht->ext.free(ht->ext.data);
+ }
+ }
BLI_freelistN(&art->paneltypes);
BLI_freelistN(&art->headertypes);
@@ -169,10 +175,35 @@ void BKE_spacedata_freelist(ListBase *lb)
BLI_freelistN(lb);
}
+static void panel_list_copy(ListBase *newlb, const ListBase *lb)
+{
+ BLI_listbase_clear(newlb);
+ BLI_duplicatelist(newlb, lb);
+
+ /* copy panel pointers */
+ Panel *newpa = newlb->first;
+ Panel *pa = lb->first;
+ for (; newpa; newpa = newpa->next, pa = pa->next) {
+ newpa->activedata = NULL;
+
+ Panel *newpatab = newlb->first;
+ Panel *patab = lb->first;
+ while (newpatab) {
+ if (newpa->paneltab == patab) {
+ newpa->paneltab = newpatab;
+ break;
+ }
+ newpatab = newpatab->next;
+ patab = patab->next;
+ }
+
+ panel_list_copy(&newpa->children, &pa->children);
+ }
+}
+
ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
{
ARegion *newar = MEM_dupallocN(ar);
- Panel *pa, *newpa, *patab;
newar->prev = newar->next = NULL;
BLI_listbase_clear(&newar->handlers);
@@ -199,25 +230,10 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
if (ar->v2d.tab_offset)
newar->v2d.tab_offset = MEM_dupallocN(ar->v2d.tab_offset);
- BLI_listbase_clear(&newar->panels);
- BLI_duplicatelist(&newar->panels, &ar->panels);
+ panel_list_copy(&newar->panels, &ar->panels);
BLI_listbase_clear(&newar->ui_previews);
BLI_duplicatelist(&newar->ui_previews, &ar->ui_previews);
-
- /* copy panel pointers */
- for (newpa = newar->panels.first; newpa; newpa = newpa->next) {
- patab = newar->panels.first;
- pa = ar->panels.first;
- while (patab) {
- if (newpa->paneltab == pa) {
- newpa->paneltab = patab;
- break;
- }
- patab = patab->next;
- pa = pa->next;
- }
- }
return newar;
}
@@ -329,6 +345,19 @@ void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManip
region_free_manipulatormap_callback = callback;
}
+static void panel_list_free(ListBase *lb)
+{
+ Panel *pa, *pa_next;
+ for (pa = lb->first; pa; pa = pa_next) {
+ pa_next = pa->next;
+ if (pa->activedata) {
+ MEM_freeN(pa->activedata);
+ }
+ panel_list_free(&pa->children);
+ MEM_freeN(pa);
+ }
+}
+
/* not region itself */
void BKE_area_region_free(SpaceType *st, ARegion *ar)
{
@@ -351,16 +380,7 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
ar->v2d.tab_offset = NULL;
}
- if (!BLI_listbase_is_empty(&ar->panels)) {
- Panel *pa, *pa_next;
- for (pa = ar->panels.first; pa; pa = pa_next) {
- pa_next = pa->next;
- if (pa->activedata) {
- MEM_freeN(pa->activedata);
- }
- MEM_freeN(pa);
- }
- }
+ panel_list_free(&ar->panels);
for (uilst = ar->ui_lists.first; uilst; uilst = uilst->next) {
if (uilst->dyn_data) {
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 0eca7a00515..00af9721f07 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -1767,13 +1767,13 @@ static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float f
if (output != output) output = 1;
if (wipe->forward) output = 1 - output;
break;
- /* BOX WIPE IS NOT WORKING YET */
+ /* BOX WIPE IS NOT WORKING YET */
/* case DO_CROSS_WIPE: */
/* BOX WIPE IS NOT WORKING YET */
#if 0
- case DO_BOX_WIPE:
- if (!wipe->forward)
- facf0 = 1.0f - facf0; /* Go the other direction */
+ case DO_BOX_WIPE:
+ if (!wipe->forward)
+ facf0 = 1.0f - facf0; /* Go the other direction */
width = (int)(wipe->edgeWidth * ((xo + yo) / 2.0));
hwidth = (float)width / 2.0;
@@ -1806,8 +1806,9 @@ static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float f
output = in_band(hwidth, hyp2, 1, 1) * in_band(hwidth, hyp, 1, 1);
}
- if (!wipe->forward)
- facf0 = 1.0f - facf0; /* Go the other direction */
+ if (!wipe->forward) {
+ facf0 = 1.0f - facf0; /* Go the other direction */
+ }
angle = -1 / angle;
b1 = posy / 2 - (-angle) * posx / 2;
b3 = (yo - posy / 2) - (-angle) * (xo - posx / 2);
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index f5d99e2615a..ecd0335fc4e 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -898,7 +898,7 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, const bool lock_r
BLI_join_dirfile(path, sizeof(path), seq->strip->dir,
seq->strip->stripdata->name);
- BLI_path_abs(path, G.main->name);
+ BLI_path_abs(path, BKE_main_blendfile_path_from_global());
BKE_sequence_free_anim(seq);
@@ -1546,7 +1546,7 @@ static void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile)
BLI_join_dirfile(name, sizeof(name),
seq->strip->dir, seq->strip->stripdata->name);
- BLI_path_abs(name, G.main->name);
+ BLI_path_abs(name, BKE_main_blendfile_path_from_global());
proxy = seq->strip->proxy;
@@ -1563,7 +1563,7 @@ static void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile)
else {
BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
}
- BLI_path_abs(dir, G.main->name);
+ BLI_path_abs(dir, BKE_main_blendfile_path_from_global());
}
if (is_multiview && seq->views_format == R_IMF_VIEWS_INDIVIDUAL) {
@@ -1691,7 +1691,7 @@ static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render
return false;
}
BLI_path_append(dir, sizeof(dir), fname);
- BLI_path_abs(name, G.main->name);
+ BLI_path_abs(name, BKE_main_blendfile_path_from_global());
}
else if ((proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) && (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE)) {
BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir));
@@ -1723,7 +1723,7 @@ static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render
{
char fname[FILE_MAXFILE];
BLI_join_dirfile(fname, PROXY_MAXFILE, dir, proxy->file);
- BLI_path_abs(fname, G.main->name);
+ BLI_path_abs(fname, BKE_main_blendfile_path_from_global());
if (suffix[0] != '\0') {
/* TODO(sergey): This will actually append suffix after extension
* which is weird but how was originally coded in multiview branch.
@@ -1749,7 +1749,7 @@ static bool seq_proxy_get_fname(Editing *ed, Sequence *seq, int cfra, int render
BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####%s", dir, render_size, suffix);
}
- BLI_path_abs(name, G.main->name);
+ BLI_path_abs(name, BKE_main_blendfile_path_from_global());
BLI_path_frame(name, frameno, 0);
strcat(name, ".jpg");
@@ -1894,7 +1894,7 @@ static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, con
char path[FILE_MAX];
BLI_join_dirfile(path, sizeof(path), seq->strip->dir,
seq->strip->stripdata->name);
- BLI_path_abs(path, G.main->name);
+ BLI_path_abs(path, BKE_main_blendfile_path_from_global());
BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext);
}
else {
@@ -2846,7 +2846,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context, Sequence *seq
if (s_elem) {
BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
- BLI_path_abs(name, G.main->name);
+ BLI_path_abs(name, BKE_main_blendfile_path_from_global());
}
flag = IB_rect | IB_metadata;
@@ -5151,7 +5151,7 @@ void BKE_sequence_init_colorspace(Sequence *seq)
ImBuf *ibuf;
BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name);
- BLI_path_abs(name, G.main->name);
+ BLI_path_abs(name, BKE_main_blendfile_path_from_global());
/* initialize input color space */
if (seq->type == SEQ_TYPE_IMAGE) {
@@ -5319,6 +5319,7 @@ static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const int view_
Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C); /* only for sound */
char path[sizeof(seq_load->path)];
@@ -5333,7 +5334,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
int i;
BLI_strncpy(path, seq_load->path, sizeof(path));
- BLI_path_abs(path, G.main->name);
+ BLI_path_abs(path, BKE_main_blendfile_path(bmain));
anim_arr = MEM_callocN(sizeof(struct anim *) * totfiles, "Video files");
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 747ffdafe8b..a7f3fc1df9e 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -77,7 +77,7 @@ bSound *BKE_sound_new_file(struct Main *bmain, const char *filepath)
BLI_strncpy(str, filepath, sizeof(str));
- path = /*bmain ? bmain->name :*/ G.main->name;
+ path = BKE_main_blendfile_path(bmain);
BLI_path_abs(str, path);
@@ -96,7 +96,7 @@ bSound *BKE_sound_new_file_exists_ex(struct Main *bmain, const char *filepath, b
char str[FILE_MAX], strtest[FILE_MAX];
BLI_strncpy(str, filepath, sizeof(str));
- BLI_path_abs(str, bmain->name);
+ BLI_path_abs(str, BKE_main_blendfile_path(bmain));
/* first search an identical filepath */
for (sound = bmain->sound.first; sound; sound = sound->id.next) {
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 4ef7b3d2247..e4b49656907 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -55,13 +55,13 @@
/* Statics */
static ListBase studiolights;
-#define STUDIOLIGHT_EXTENSIONS ".jpg", ".hdr"
#define STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE 8
#define STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT 32
#define STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH (STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT * 2)
static const char *STUDIOLIGHT_CAMERA_FOLDER = "studiolights/camera/";
static const char *STUDIOLIGHT_WORLD_FOLDER = "studiolights/world/";
+static const char *STUDIOLIGHT_MATCAP_FOLDER = "studiolights/matcap/";
/* FUNCTIONS */
static void studiolight_free(struct StudioLight *sl)
@@ -168,16 +168,16 @@ static void studiolight_load_equierectangular_image(StudioLight *sl)
sl->equirectangular_radiance_buffer = ibuf;
}
}
- sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED;
+ sl->flag |= STUDIOLIGHT_EXTERNAL_IMAGE_LOADED;
}
static void studiolight_create_equierectangular_radiance_gputexture(StudioLight *sl)
{
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
char error[256];
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
ImBuf *ibuf = sl->equirectangular_radiance_buffer;
- sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(ibuf->x, ibuf->y, GPU_RGBA16F, ibuf->rect_float, error);
+ sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(ibuf->x, ibuf->y, GPU_RGBA8, ibuf->rect_float, error);
GPUTexture *tex = sl->equirectangular_radiance_gputexture;
GPU_texture_bind(tex, 0);
GPU_texture_filter_mode(tex, true);
@@ -206,7 +206,7 @@ static void studiolight_create_equierectangular_irradiance_gputexture(StudioLigh
static void studiolight_calculate_radiance_cubemap_buffers(StudioLight *sl)
{
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
ImBuf *ibuf = sl->equirectangular_radiance_buffer;
if (ibuf) {
float *colbuf = MEM_mallocN(SQUARE(STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) * sizeof(float[4]), __func__);
@@ -481,7 +481,7 @@ static void studiolight_add_files_from_datafolder(const int folder_id, const cha
if ((dir[i].type & S_IFREG)) {
const char *filename = dir[i].relname;
const char *path = dir[i].path;
- if (BLI_testextensie_n(filename, STUDIOLIGHT_EXTENSIONS, NULL)) {
+ if (BLI_testextensie_array(filename, imb_ext_image)) {
sl = studiolight_create();
sl->flag = STUDIOLIGHT_EXTERNAL_FILE | flag;
BLI_strncpy(sl->name, filename, FILE_MAXFILE);
@@ -527,7 +527,7 @@ static int studiolight_cmp(const void *a, const void *b)
/* icons */
static uint *studiolight_radiance_preview(StudioLight *sl, int icon_size)
{
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
int icon_center = icon_size / 2;
@@ -579,6 +579,29 @@ static uint *studiolight_radiance_preview(StudioLight *sl, int icon_size)
return rect;
}
+static uint *studiolight_matcap_preview(StudioLight *sl, int icon_size)
+{
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
+
+ uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
+ const uint alphamask = 0xff000000;
+ float color[4];
+ float fx, fy;
+ int offset = 0;
+ ImBuf *ibuf = sl->equirectangular_radiance_buffer;
+ for (int y = 0; y < icon_size; y++) {
+ for (int x = 0; x < icon_size; x++) {
+ fx = x * ibuf->x / icon_size;
+ fy = y * ibuf->y / icon_size;
+ nearest_interpolation_color(ibuf, NULL, color, fx, fy);
+ rect[offset++] = rgb_to_cpack(linearrgb_to_srgb(color[0]),
+ linearrgb_to_srgb(color[1]),
+ linearrgb_to_srgb(color[2])) | alphamask;
+ }
+ }
+ return rect;
+}
+
static uint *studiolight_irradiance_preview(StudioLight *sl, int icon_size)
{
if (/*!(sl->flag & STUDIOLIGHT_EXTERNAL_FILE)*/ 1) {
@@ -696,7 +719,7 @@ void BKE_studiolight_init(void)
/* Add default studio light */
sl = studiolight_create();
BLI_strncpy(sl->name, "INTERNAL_01", FILE_MAXFILE);
- sl->flag = STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA;
+ sl->flag = STUDIOLIGHT_INTERNAL | STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA;
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_POS], 0.0f);
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_NEG], 0.0f);
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_POS], 0.8f);
@@ -706,9 +729,11 @@ void BKE_studiolight_init(void)
BLI_addtail(&studiolights, sl);
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA);
- studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA);
+ studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_USER_DEFINED);
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD);
- studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD);
+ studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_USER_DEFINED);
+ studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_MATCAP_FOLDER, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+ studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_MATCAP_FOLDER, STUDIOLIGHT_ORIENTATION_VIEWNORMAL | STUDIOLIGHT_USER_DEFINED);
/* sort studio lights on filename. */
BLI_listbase_sort(&studiolights, studiolight_cmp);
@@ -722,24 +747,34 @@ void BKE_studiolight_free(void)
}
}
+struct StudioLight *BKE_studiolight_find_first(int flag)
+{
+ LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
+ if ((sl->flag & flag)) {
+ return sl;
+ }
+ }
+ return NULL;
+}
+
struct StudioLight *BKE_studiolight_find(const char *name, int flag)
{
LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
if (STREQLEN(sl->name, name, FILE_MAXFILE)) {
- if ((sl->flag & flag) == flag) {
+ if ((sl->flag & flag)) {
return sl;
}
else {
/* flags do not match, so use default */
- return studiolights.first;
+ return BKE_studiolight_find_first(flag);
}
}
}
/* When not found, use the default studio light */
- return studiolights.first;
+ return BKE_studiolight_find_first(flag);
}
-struct StudioLight *BKE_studiolight_findindex(int index)
+struct StudioLight *BKE_studiolight_findindex(int index, int flag)
{
LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
if (sl->index == index) {
@@ -747,10 +782,10 @@ struct StudioLight *BKE_studiolight_findindex(int index)
}
}
/* When not found, use the default studio light */
- return studiolights.first;
+ return BKE_studiolight_find_first(flag);
}
-const struct ListBase *BKE_studiolight_listbase(void)
+struct ListBase *BKE_studiolight_listbase(void)
{
return &studiolights;
}
@@ -758,7 +793,12 @@ const struct ListBase *BKE_studiolight_listbase(void)
uint *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type)
{
if (icon_id_type == STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE) {
- return studiolight_irradiance_preview(sl, icon_size);
+ if (sl->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL) {
+ return studiolight_matcap_preview(sl, icon_size);
+ }
+ else {
+ return studiolight_irradiance_preview(sl, icon_size);
+ }
}
else {
return studiolight_radiance_preview(sl, icon_size);
@@ -771,7 +811,7 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
return;
}
- if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED)) {
+ if ((flag & STUDIOLIGHT_EXTERNAL_IMAGE_LOADED)) {
studiolight_load_equierectangular_image(sl);
}
if ((flag & STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED)) {
@@ -793,3 +833,9 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
studiolight_calculate_irradiance_equirectangular_image(sl);
}
}
+
+void BKE_studiolight_refresh(void)
+{
+ BKE_studiolight_free();
+ BKE_studiolight_init();
+}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index ed23078a9d8..d735944c93d 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -69,6 +69,7 @@
#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
+#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_scene.h"
#include "BKE_subsurf.h"
@@ -2327,7 +2328,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
}
else if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
+ Mesh *me = BKE_object_get_original_mesh(ob);
const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
MLoopTri *looptri;
@@ -2351,7 +2352,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
totvert = deformdm->getNumVerts(deformdm);
vertCos = MEM_malloc_arrayN(totvert, sizeof(float[3]), "ccgDM_getPBVH vertCos");
deformdm->getVertCos(deformdm, vertCos);
- BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos, totvert);
MEM_freeN(vertCos);
}
}
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 3892b2f0546..a24020d7764 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -388,7 +388,7 @@ bool BKE_text_reload(Text *text)
}
BLI_strncpy(filepath_abs, text->name, FILE_MAX);
- BLI_path_abs(filepath_abs, G.main->name);
+ BLI_path_abs(filepath_abs, BKE_main_blendfile_path_from_global());
buffer = BLI_file_read_text_as_mem(filepath_abs, 0, &buffer_len);
if (buffer == NULL) {
@@ -557,7 +557,7 @@ int BKE_text_file_modified_check(Text *text)
return 0;
BLI_strncpy(file, text->name, FILE_MAX);
- BLI_path_abs(file, G.main->name);
+ BLI_path_abs(file, BKE_main_blendfile_path_from_global());
if (!BLI_exists(file))
return 2;
@@ -585,7 +585,7 @@ void BKE_text_file_modified_ignore(Text *text)
if (!text->name) return;
BLI_strncpy(file, text->name, FILE_MAX);
- BLI_path_abs(file, G.main->name);
+ BLI_path_abs(file, BKE_main_blendfile_path_from_global());
if (!BLI_exists(file)) return;
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index f5e4c354a02..a05e79aae1f 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -376,7 +376,7 @@ UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack, bContext *C, c
us->type = ut;
ustack->step_init = us;
ut->step_encode_init(C, us);
- undosys_stack_validate(ustack, true);
+ undosys_stack_validate(ustack, false);
return us;
}
else {
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 15bf01d2049..1b06e7ed851 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -53,6 +53,8 @@
#include "BKE_node.h"
#include "BKE_world.h"
+#include "DEG_depsgraph.h"
+
#include "GPU_material.h"
/** Free (or release) any data used by this world (does not free the world itself). */
@@ -161,13 +163,10 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local)
BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local);
}
-void BKE_world_eval(struct Depsgraph *UNUSED(depsgraph), World *world)
+void BKE_world_eval(struct Depsgraph *depsgraph, World *world)
{
- if (G.debug & G_DEBUG_DEPSGRAPH_EVAL) {
- printf("%s on %s (%p)\n", __func__, world->id.name, world);
- }
+ DEG_debug_print_eval(depsgraph, __func__, world->id.name, world);
if (!BLI_listbase_is_empty(&world->gpumaterial)) {
world->update_flag = 1;
- GPU_material_uniform_buffer_tag_dirty(&world->gpumaterial);
}
}
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index e357f13530d..33ac312425b 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -145,7 +145,7 @@ static void filepath_avi(char *string, RenderData *rd, bool preview, const char
}
strcpy(string, rd->pic);
- BLI_path_abs(string, G.main->name);
+ BLI_path_abs(string, BKE_main_blendfile_path_from_global());
BLI_make_existing_file(string);
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 4a0f697c9ce..17c665f3bcd 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -1127,7 +1127,7 @@ static void ffmpeg_filepath_get(FFMpegContext *context, char *string, RenderData
}
strcpy(string, rd->pic);
- BLI_path_abs(string, G.main->name);
+ BLI_path_abs(string, BKE_main_blendfile_path_from_global());
BLI_make_existing_file(string);
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 6f8e48d83b2..f455436ce63 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -200,24 +200,28 @@ double double_round(double x, int ndigits);
* check the vector is unit length, or zero length (which can't be helped in some cases).
*/
#ifndef NDEBUG
-/* note: 0.0001 is too small becaues normals may be converted from short's: see [#34322] */
+/** \note 0.0001 is too small becaues normals may be converted from short's: see T34322. */
# define BLI_ASSERT_UNIT_EPSILON 0.0002f
+/**
+ * \note Checks are flipped so NAN doesn't assert. This is done because we're making sure the value was normalized
+ * and in the case we don't want NAN to be raising asserts since there is nothing to be done in that case.
+ */
# define BLI_ASSERT_UNIT_V3(v) { \
const float _test_unit = len_squared_v3(v); \
- BLI_assert((fabsf(_test_unit - 1.0f) < BLI_ASSERT_UNIT_EPSILON) || \
- (fabsf(_test_unit) < BLI_ASSERT_UNIT_EPSILON)); \
+ BLI_assert(!(fabsf(_test_unit - 1.0f) >= BLI_ASSERT_UNIT_EPSILON) || \
+ !(fabsf(_test_unit) >= BLI_ASSERT_UNIT_EPSILON)); \
} (void)0
# define BLI_ASSERT_UNIT_V2(v) { \
const float _test_unit = len_squared_v2(v); \
- BLI_assert((fabsf(_test_unit - 1.0f) < BLI_ASSERT_UNIT_EPSILON) || \
- (fabsf(_test_unit) < BLI_ASSERT_UNIT_EPSILON)); \
+ BLI_assert(!(fabsf(_test_unit - 1.0f) >= BLI_ASSERT_UNIT_EPSILON) || \
+ !(fabsf(_test_unit) >= BLI_ASSERT_UNIT_EPSILON)); \
} (void)0
# define BLI_ASSERT_UNIT_QUAT(q) { \
const float _test_unit = dot_qtqt(q, q); \
- BLI_assert((fabsf(_test_unit - 1.0f) < BLI_ASSERT_UNIT_EPSILON * 10) || \
- (fabsf(_test_unit) < BLI_ASSERT_UNIT_EPSILON * 10)); \
+ BLI_assert(!(fabsf(_test_unit - 1.0f) >= BLI_ASSERT_UNIT_EPSILON * 10) || \
+ !(fabsf(_test_unit) >= BLI_ASSERT_UNIT_EPSILON * 10)); \
} (void)0
# define BLI_ASSERT_ZERO_M3(m) { \
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d2542e977e3..a9f93dff9e6 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -140,6 +140,7 @@
#include "BKE_material.h"
#include "BKE_main.h" // for Main
#include "BKE_mesh.h" // for ME_ defines (patching)
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_node.h" // for tree type defines
@@ -6396,19 +6397,24 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
/* *********** READ AREA **************** */
-static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
+static void direct_link_panel_list(FileData *fd, ListBase *lb)
{
- Panel *pa;
- uiList *ui_list;
-
- link_list(fd, &ar->panels);
+ link_list(fd, lb);
- for (pa = ar->panels.first; pa; pa = pa->next) {
+ for (Panel *pa = lb->first; pa; pa = pa->next) {
pa->paneltab = newdataadr(fd, pa->paneltab);
pa->runtime_flag = 0;
pa->activedata = NULL;
pa->type = NULL;
+ direct_link_panel_list(fd, &pa->children);
}
+}
+
+static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
+{
+ uiList *ui_list;
+
+ direct_link_panel_list(fd, &ar->panels);
link_list(fd, &ar->panels_category_active);
@@ -8483,11 +8489,11 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
if (bfd->filename[0] == 0) {
if (fd->fileversion < 265 || (fd->fileversion == 265 && fg->subversion < 1))
if ((G.fileflags & G_FILE_RECOVER)==0)
- BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename));
+ BLI_strncpy(bfd->filename, BKE_main_blendfile_path(bfd->main), sizeof(bfd->filename));
/* early 2.50 version patch - filename not in FileGlobal struct at all */
if (fd->fileversion <= 250)
- BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->filename));
+ BLI_strncpy(bfd->filename, BKE_main_blendfile_path(bfd->main), sizeof(bfd->filename));
}
if (G.fileflags & G_FILE_RECOVER)
@@ -10058,6 +10064,7 @@ static void add_collections_to_scene(
/* Assign the collection. */
ob->dup_group = collection;
+ id_us_plus(&collection->id);
ob->transflag |= OB_DUPLICOLLECTION;
copy_v3_v3(ob->loc, scene->cursor.location);
}
@@ -10313,7 +10320,7 @@ static Main *library_link_begin(Main *mainvar, FileData **fd, const char *filepa
blo_split_main((*fd)->mainlist, mainvar);
/* which one do we need? */
- mainl = blo_find_main(*fd, filepath, G.main->name);
+ mainl = blo_find_main(*fd, filepath, BKE_main_blendfile_path(mainvar));
/* needed for do_version */
mainl->versionfile = (*fd)->fileversion;
@@ -10388,7 +10395,7 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Main
BLI_strncpy(curlib->name, curlib->filepath, sizeof(curlib->name));
/* uses current .blend file as reference */
- BLI_path_rel(curlib->name, G.main->name);
+ BLI_path_rel(curlib->name, BKE_main_blendfile_path_from_global());
}
blo_join_main((*fd)->mainlist);
@@ -10418,7 +10425,7 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Main
BKE_main_id_tag_all(mainvar, LIB_TAG_NEW, false);
lib_verify_nodetree(mainvar, false);
- fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */
+ fix_relpaths_library(BKE_main_blendfile_path(mainvar), mainvar); /* make all relative paths, relative to the open blend file */
/* Give a base to loose objects and collections.
* Only directly linked objects & collections are instantiated by `BLO_library_link_named_part_ex()` & co,
@@ -10539,7 +10546,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
while (fd == NULL) {
char newlib_path[FILE_MAX] = {0};
printf("Missing library...'\n");
- printf(" current file: %s\n", G.main->name);
+ printf(" current file: %s\n", BKE_main_blendfile_path_from_global());
printf(" absolute lib: %s\n", mainptr->curlib->filepath);
printf(" relative lib: %s\n", mainptr->curlib->name);
printf(" enter a new path:\n");
@@ -10547,7 +10554,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
if (scanf("%1023s", newlib_path) > 0) { /* Warning, keep length in sync with FILE_MAX! */
BLI_strncpy(mainptr->curlib->name, newlib_path, sizeof(mainptr->curlib->name));
BLI_strncpy(mainptr->curlib->filepath, newlib_path, sizeof(mainptr->curlib->filepath));
- BLI_cleanup_path(G.main->name, mainptr->curlib->filepath);
+ BLI_cleanup_path(BKE_main_blendfile_path_from_global(), mainptr->curlib->filepath);
fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 299c66f2bbb..7618c023882 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -169,14 +169,14 @@ void blo_do_version_old_trackto_to_constraints(struct Object *ob);
void blo_do_versions_view3d_split_250(struct View3D *v3d, struct ListBase *regions);
void blo_do_versions_key_uidgen(struct Key *key);
-void blo_do_versions_pre250(struct FileData *fd, struct Library *lib, struct Main *main);
-void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main *main);
-void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *main);
-void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *main);
-void blo_do_versions_280(struct FileData *fd, struct Library *lib, struct Main *main);
-
-void do_versions_after_linking_270(struct Main *main);
-void do_versions_after_linking_280(struct Main *main);
+void blo_do_versions_pre250(struct FileData *fd, struct Library *lib, struct Main *bmain);
+void blo_do_versions_250(struct FileData *fd, struct Library *lib, struct Main *bmain);
+void blo_do_versions_260(struct FileData *fd, struct Library *lib, struct Main *bmain);
+void blo_do_versions_270(struct FileData *fd, struct Library *lib, struct Main *bmain);
+void blo_do_versions_280(struct FileData *fd, struct Library *lib, struct Main *bmain);
+
+void do_versions_after_linking_270(struct Main *bmain);
+void do_versions_after_linking_280(struct Main *bmain);
#endif
diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c
index 7133dee0e82..e1ae267ea11 100644
--- a/source/blender/blenloader/intern/undofile.c
+++ b/source/blender/blenloader/intern/undofile.c
@@ -130,7 +130,7 @@ void memfile_chunk_add(
struct Main *BLO_memfile_main_get(struct MemFile *memfile, struct Main *oldmain, struct Scene **r_scene)
{
struct Main *bmain_undo = NULL;
- BlendFileData *bfd = BLO_read_from_memfile(oldmain, oldmain->name, memfile, NULL, BLO_READ_SKIP_NONE);
+ BlendFileData *bfd = BLO_read_from_memfile(oldmain, BKE_main_blendfile_path(oldmain), memfile, NULL, BLO_READ_SKIP_NONE);
if (bfd) {
bmain_undo = bfd->main;
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 3f85011db0b..d51289bee43 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -641,11 +641,11 @@ static void do_versions_socket_default_value_259(bNodeSocket *sock)
}
}
-void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
+void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
- if (main->versionfile < 250) {
+ if (bmain->versionfile < 250) {
bScreen *screen;
Scene *scene;
Base *base;
@@ -663,22 +663,22 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
bSound *sound;
Sequence *seq;
- for (sound = main->sound.first; sound; sound = sound->id.next) {
+ for (sound = bmain->sound.first; sound; sound = sound->id.next) {
if (sound->newpackedfile) {
sound->packedfile = sound->newpackedfile;
sound->newpackedfile = NULL;
}
}
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->ed && scene->ed->seqbasep) {
SEQ_BEGIN (scene->ed, seq)
{
if (seq->type == SEQ_TYPE_SOUND_HD) {
char str[FILE_MAX];
BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name);
- BLI_path_abs(str, main->name);
- seq->sound = BKE_sound_new_file(main, str);
+ BLI_path_abs(str, BKE_main_blendfile_path(bmain));
+ seq->sound = BKE_sound_new_file(bmain, str);
}
#define SEQ_USE_PROXY_CUSTOM_DIR (1 << 19)
#define SEQ_USE_PROXY_CUSTOM_FILE (1 << 21)
@@ -695,21 +695,21 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
do_versions_windowmanager_2_50(screen);
- do_versions_gpencil_2_50(main, screen);
+ do_versions_gpencil_2_50(bmain, screen);
}
/* shader, composite and texture node trees have id.name empty, put something in
* to have them show in RNA viewer and accessible otherwise.
*/
- for (ma = main->mat.first; ma; ma = ma->id.next) {
+ for (ma = bmain->mat.first; ma; ma = ma->id.next) {
if (ma->nodetree && ma->nodetree->id.name[0] == '\0')
strcpy(ma->nodetree->id.name, "NTShader Nodetree");
}
/* and composite trees */
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree && sce->nodetree->id.name[0] == '\0')
strcpy(sce->nodetree->id.name, "NTCompositing Nodetree");
@@ -729,7 +729,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* and texture trees */
- for (tx = main->tex.first; tx; tx = tx->id.next) {
+ for (tx = bmain->tex.first; tx; tx = tx->id.next) {
bNode *node;
if (tx->nodetree) {
@@ -744,12 +744,12 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* copy standard draw flag to meshes(used to be global, is not available here) */
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
me->drawflag = ME_DRAWEDGES|ME_DRAWFACES|ME_DRAWCREASES;
}
/* particle draw and render types */
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
if (part->draw_as) {
if (part->draw_as == PART_DRAW_DOT) {
part->ren_as = PART_DRAW_HALO;
@@ -768,7 +768,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* set old pointcaches to have disk cache flag */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
//BKE_ptcache_ids_from_object(&pidlist, ob);
@@ -779,7 +779,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* type was a mixed flag & enum. move the 2d flag elsewhere */
- for (cu = main->curve.first; cu; cu = cu->id.next) {
+ for (cu = bmain->curve.first; cu; cu = cu->id.next) {
Nurb *nu;
for (nu = cu->nurb.first; nu; nu = nu->next) {
@@ -789,7 +789,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 1)) {
Object *ob;
Tex *tex;
Scene *sce;
@@ -797,7 +797,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
//PTCacheID *pid;
//ListBase pidlist;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
//BKE_ptcache_ids_from_object(&pidlist, ob);
//for (pid = pidlist.first; pid; pid = pid->next) {
@@ -831,12 +831,12 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* texture filter */
- for (tex = main->tex.first; tex; tex = tex->id.next) {
+ for (tex = bmain->tex.first; tex; tex = tex->id.next) {
if (tex->afmax == 0)
tex->afmax = 8;
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
ts = sce->toolsettings;
if (!ts->uv_selectmode || ts->vgroup_weight == 0.0f) {
ts->selectmode = SCE_SELECT_VERTEX;
@@ -854,26 +854,26 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 2)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->flag & 8192) // OB_POSEMODE = 8192
ob->mode |= OB_MODE_POSE;
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 4)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 4)) {
Scene *sce;
Object *ob;
ParticleSettings *part;
bool do_gravity = false;
- for (sce = main->scene.first; sce; sce = sce->id.next)
+ for (sce = bmain->scene.first; sce; sce = sce->id.next)
if (sce->unit.scale_length == 0.0f)
sce->unit.scale_length = 1.0f;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* fluid-sim stuff */
FluidsimModifierData *fluidmd = (FluidsimModifierData *) modifiers_findByType(ob, eModifierType_Fluidsim);
if (fluidmd)
@@ -883,7 +883,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
ob->rotmode = ROT_MODE_EUL;
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->audio.main == 0.0f)
sce->audio.main = 1.0f;
@@ -895,7 +895,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* Add default gravity to scenes */
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if ((sce->physics_settings.flag & PHYS_GLOBAL_GRAVITY) == 0 &&
is_zero_v3(sce->physics_settings.gravity))
{
@@ -908,11 +908,11 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
/* Assign proper global gravity weights for dynamics (only z-coordinate is taken into account) */
if (do_gravity) {
- for (part = main->particle.first; part; part = part->id.next)
+ for (part = bmain->particle.first; part; part = part->id.next)
part->effector_weights->global_gravity = part->acc[2]/-9.81f;
}
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
if (do_gravity) {
@@ -941,11 +941,11 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 6)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 6)) {
Object *ob;
/* New variables for axis-angle rotations and/or quaternion rotations were added, and need proper initialization */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* new variables for all objects */
ob->quat[0] = 1.0f;
ob->rotAxis[1] = 1.0f;
@@ -962,7 +962,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 7)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 7)) {
Mesh *me;
Nurb *nu;
Lattice *lt;
@@ -974,7 +974,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
/* shape keys are no longer applied to the mesh itself, but rather
* to the derivedmesh/displist, so here we ensure that the basis
* shape key is always set in the mesh coordinates. */
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
if ((key = blo_do_versions_newlibadr(fd, lib, me->key)) && key->refkey) {
data = key->refkey->data;
tot = MIN2(me->totvert, key->refkey->totelem);
@@ -984,7 +984,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- for (lt = main->latt.first; lt; lt = lt->id.next) {
+ for (lt = bmain->latt.first; lt; lt = lt->id.next) {
if ((key = blo_do_versions_newlibadr(fd, lib, lt->key)) && key->refkey) {
data = key->refkey->data;
tot = MIN2(lt->pntsu*lt->pntsv*lt->pntsw, key->refkey->totelem);
@@ -994,7 +994,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- for (cu = main->curve.first; cu; cu = cu->id.next) {
+ for (cu = bmain->curve.first; cu; cu = cu->id.next) {
if ((key = blo_do_versions_newlibadr(fd, lib, cu->key)) && key->refkey) {
data = key->refkey->data;
@@ -1022,9 +1022,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 8)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 8)) {
{
- Scene *sce = main->scene.first;
+ Scene *sce = bmain->scene.first;
while (sce) {
if (sce->r.frame_step == 0)
sce->r.frame_step = 1;
@@ -1039,7 +1039,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
{
/* ensure all nodes have unique names */
- bNodeTree *ntree = main->nodetree.first;
+ bNodeTree *ntree = bmain->nodetree.first;
while (ntree) {
bNode *node = ntree->nodes.first;
@@ -1053,7 +1053,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
{
- Object *ob = main->object.first;
+ Object *ob = bmain->object.first;
while (ob) {
/* shaded mode disabled for now */
if (ob->dt == OB_MATERIAL)
@@ -1067,7 +1067,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
ScrArea *sa;
SpaceLink *sl;
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
for (sa = screen->areabase.first; sa; sa = sa->next) {
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
@@ -1081,10 +1081,10 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* only convert old 2.50 files with color management */
- if (main->versionfile == 250) {
- Scene *sce = main->scene.first;
- Material *ma = main->mat.first;
- Tex *tex = main->tex.first;
+ if (bmain->versionfile == 250) {
+ Scene *sce = bmain->scene.first;
+ Material *ma = bmain->mat.first;
+ Tex *tex = bmain->tex.first;
int i, convert = 0;
/* convert to new color management system:
@@ -1120,20 +1120,20 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 9)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 9)) {
Scene *sce;
Mesh *me;
Object *ob;
- for (sce = main->scene.first; sce; sce = sce->id.next)
+ for (sce = bmain->scene.first; sce; sce = sce->id.next)
if (!sce->toolsettings->particle.selectmode)
sce->toolsettings->particle.selectmode = SCE_SELECT_PATH;
- if (main->versionfile == 250 && main->subversionfile > 1) {
- for (me = main->mesh.first; me; me = me->id.next)
+ if (bmain->versionfile == 250 && bmain->subversionfile > 1) {
+ for (me = bmain->mesh.first; me; me = me->id.next)
multires_load_old_250(me);
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
MultiresModifierData *mmd = (MultiresModifierData *) modifiers_findByType(ob, eModifierType_Multires);
if (mmd) {
@@ -1146,11 +1146,11 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 10)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 10)) {
Object *ob;
/* properly initialize hair clothsim data on old files */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Cloth) {
@@ -1163,14 +1163,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* fix bad area setup in subversion 10 */
- if (main->versionfile == 250 && main->subversionfile == 10) {
+ if (bmain->versionfile == 250 && bmain->subversionfile == 10) {
/* fix for new view type in sequencer */
bScreen *screen;
ScrArea *sa;
SpaceLink *sl;
/* remove all preview window in wrong spaces */
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
for (sa = screen->areabase.first; sa; sa = sa->next) {
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype != SPACE_SEQ) {
@@ -1200,14 +1200,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 11)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 11)) {
{
/* fix for new view type in sequencer */
bScreen *screen;
ScrArea *sa;
SpaceLink *sl;
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
for (sa = screen->areabase.first; sa; sa = sa->next) {
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_SEQ) {
@@ -1243,12 +1243,12 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 12)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 12)) {
Object *ob;
Brush *brush;
/* anim viz changes */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* initialize object defaults */
animviz_settings_init(&ob->avs);
@@ -1323,19 +1323,19 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* brush texture changes */
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
BKE_texture_mtex_default(&brush->mtex);
BKE_texture_mtex_default(&brush->mask_mtex);
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 13)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 13)) {
/* NOTE: if you do more conversion, be sure to do it outside of this and
* increase subversion again, otherwise it will not be correct */
Object *ob;
/* convert degrees to radians for internal use */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
bPoseChannel *pchan;
do_version_constraints_radians_degrees_250(&ob->constraints);
@@ -1355,13 +1355,13 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 14)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 14)) {
/* fix for bad View2D extents for Animation Editors */
bScreen *screen;
ScrArea *sa;
SpaceLink *sl;
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
for (sa = screen->areabase.first; sa; sa = sa->next) {
for (sl = sa->spacedata.first; sl; sl = sl->next) {
ListBase *regionbase;
@@ -1385,12 +1385,12 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 17)) {
+ if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 17)) {
Scene *sce;
Sequence *seq;
/* initialize to sane default so toggling on border shows something */
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->r.border.xmin == 0.0f && sce->r.border.ymin == 0.0f &&
sce->r.border.xmax == 0.0f && sce->r.border.ymax == 0.0f)
{
@@ -1411,7 +1411,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* particle brush strength factor was changed from int to float */
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
ParticleEditSettings *pset = &sce->toolsettings->particle;
int a;
@@ -1425,7 +1425,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
ScrArea *sa;
SpaceLink *sl;
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
for (sa = screen->areabase.first; sa; sa = sa->next) {
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_SEQ) {
@@ -1454,14 +1454,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
} /* sequencer changes */
}
- if (main->versionfile <= 251) { /* 2.5.1 had no subversions */
+ if (bmain->versionfile <= 251) { /* 2.5.1 had no subversions */
bScreen *sc;
/* Blender 2.5.2 - subversion 0 introduced a new setting: V3D_RENDER_OVERRIDE.
* This bit was used in the past for V3D_TRANSFORM_SNAP, which is now deprecated.
* Here we clear it for old files so they don't come in with V3D_RENDER_OVERRIDE set,
* which would cause cameras, lamps, etc to become invisible */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1475,19 +1475,19 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 252 || (main->versionfile == 252 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 252 || (bmain->versionfile == 252 && bmain->subversionfile < 1)) {
Brush *brush;
Object *ob;
Scene *scene;
bNodeTree *ntree;
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
if (brush->curve)
brush->curve->preset = CURVE_PRESET_SMOOTH;
}
/* properly initialize active flag for fluidsim modifiers */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Fluidsim) {
@@ -1499,7 +1499,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* adjustment to color balance node values */
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->nodetree) {
bNode *node = scene->nodetree->nodes.first;
@@ -1515,7 +1515,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
/* check inside node groups too */
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) {
bNode *node = ntree->nodes.first;
while (node) {
@@ -1532,18 +1532,18 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* old-track -> constraints (this time we're really doing it!) */
- if (main->versionfile < 252 || (main->versionfile == 252 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 252 || (bmain->versionfile == 252 && bmain->subversionfile < 2)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next)
+ for (ob = bmain->object.first; ob; ob = ob->id.next)
blo_do_version_old_trackto_to_constraints(ob);
}
- if (main->versionfile < 252 || (main->versionfile == 252 && main->subversionfile < 5)) {
+ if (bmain->versionfile < 252 || (bmain->versionfile == 252 && bmain->subversionfile < 5)) {
bScreen *sc;
/* Image editor scopes */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -1559,14 +1559,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 253) {
+ if (bmain->versionfile < 253) {
Object *ob;
Scene *scene;
bScreen *sc;
Tex *tex;
Brush *brush;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1600,10 +1600,10 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- do_version_mdef_250(main);
+ do_version_mdef_250(bmain);
/* parent type to modifier */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->parent) {
Object *parent = (Object *) blo_do_versions_newlibadr(fd, lib, ob->parent);
if (parent) { /* parent may not be in group */
@@ -1638,7 +1638,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* initialize scene active layer */
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
int i;
for (i = 0; i < 20; i++) {
if (scene->lay & (1<<i)) {
@@ -1648,7 +1648,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- for (tex = main->tex.first; tex; tex = tex->id.next) {
+ for (tex = bmain->tex.first; tex; tex = tex->id.next) {
/* if youre picky, this isn't correct until we do a version bump
* since you could set saturation to be 0.0*/
if (tex->saturation == 0.0f)
@@ -1657,12 +1657,12 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
{
Curve *cu;
- for (cu = main->curve.first; cu; cu = cu->id.next) {
+ for (cu = bmain->curve.first; cu; cu = cu->id.next) {
cu->smallcaps_scale = 0.75f;
}
}
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene) {
Sequence *seq;
SEQ_BEGIN (scene->ed, seq)
@@ -1677,7 +1677,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
/* GSOC 2010 Sculpt - New settings for Brush */
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
/* Sanity Check */
/* infinite number of dabs */
@@ -1721,7 +1721,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
brush->rate = 0.1f;
/* New Settings */
- if (main->versionfile < 252 || (main->versionfile == 252 && main->subversionfile < 5)) {
+ if (bmain->versionfile < 252 || (bmain->versionfile == 252 && bmain->subversionfile < 5)) {
brush->flag |= BRUSH_SPACE_ATTEN; // explicitly enable adaptive space
/* spacing was originally in pixels, convert it to percentage for new version
@@ -1751,9 +1751,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* GSOC Sculpt 2010 - Sanity check on Sculpt/Paint settings */
- if (main->versionfile < 253) {
+ if (bmain->versionfile < 253) {
Scene *sce;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->toolsettings->sculpt_paint_unified_alpha == 0)
sce->toolsettings->sculpt_paint_unified_alpha = 0.5f;
@@ -1765,10 +1765,10 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 253 || (main->versionfile == 253 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 253 || (bmain->versionfile == 253 && bmain->subversionfile < 1)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
@@ -1788,7 +1788,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
/* for now just add it to all flow objects in the scene */
{
Object *ob2;
- for (ob2 = main->object.first; ob2; ob2 = ob2->id.next) {
+ for (ob2 = bmain->object.first; ob2; ob2 = ob2->id.next) {
ModifierData *md2;
for (md2 = ob2->modifiers.first; md2; md2 = md2->next) {
if (md2->type == eModifierType_Smoke) {
@@ -1811,17 +1811,17 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 255 || (main->versionfile == 255 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 255 || (bmain->versionfile == 255 && bmain->subversionfile < 1)) {
Brush *br;
ParticleSettings *part;
bScreen *sc;
- for (br = main->brush.first; br; br = br->id.next) {
+ for (br = bmain->brush.first; br; br = br->id.next) {
if (br->ob_mode == 0)
br->ob_mode = OB_MODE_ALL_PAINT;
}
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
if (part->boids)
part->boids->pitch = 1.0f;
@@ -1829,7 +1829,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
part->kink_amp_clump = 1.f; /* keep old files looking similar */
}
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1856,11 +1856,11 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 255 || (main->versionfile == 255 && main->subversionfile < 3)) {
+ if (bmain->versionfile < 255 || (bmain->versionfile == 255 && bmain->subversionfile < 3)) {
Object *ob;
/* ocean res is now squared, reset old ones - will be massive */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Ocean) {
@@ -1872,13 +1872,13 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 256) {
+ if (bmain->versionfile < 256) {
bScreen *sc;
ScrArea *sa;
Key *key;
/* Fix for sample line scope initializing with no height */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
sa = sc->areabase.first;
while (sa) {
SpaceLink *sl;
@@ -1897,7 +1897,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
* 2.4x would never reveal this to users as a dummy value always ended up getting used
* instead
*/
- for (key = main->key.first; key; key = key->id.next) {
+ for (key = bmain->key.first; key; key = key->id.next) {
KeyBlock *kb;
for (kb = key->block.first; kb; kb = kb->next) {
@@ -1907,19 +1907,19 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 256 || (bmain->versionfile == 256 && bmain->subversionfile < 1)) {
/* fix for bones that didn't have arm_roll before */
bArmature *arm;
Bone *bone;
Object *ob;
- for (arm = main->armature.first; arm; arm = arm->id.next)
+ for (arm = bmain->armature.first; arm; arm = arm->id.next)
for (bone = arm->bonebase.first; bone; bone = bone->next)
do_version_bone_roll_256(bone);
/* fix for objects which have zero dquat's
* since this is multiplied with the quat rather than added */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (is_zero_v4(ob->dquat)) {
unit_qt(ob->dquat);
}
@@ -1929,7 +1929,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 256 || (bmain->versionfile == 256 && bmain->subversionfile < 2)) {
bNodeTree *ntree;
bNode *node;
bNodeSocket *sock, *gsock;
@@ -1938,7 +1938,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
/* node sockets are not exposed automatically any more,
* this mimics the old behavior by adding all unlinked sockets to groups.
*/
- for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) {
+ for (ntree=bmain->nodetree.first; ntree; ntree=ntree->id.next) {
/* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */
/* first make sure the own_index for new sockets is valid */
@@ -2007,14 +2007,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 3)) {
+ if (bmain->versionfile < 256 || (bmain->versionfile == 256 && bmain->subversionfile < 3)) {
bScreen *sc;
Brush *brush;
Object *ob;
ParticleSettings *part;
/* redraws flag in SpaceTime has been moved to Screen level */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
if (sc->redraws_flag == 0) {
/* just initialize to default? */
/* XXX: we could also have iterated through areas, and taken them from the first timeline available... */
@@ -2022,13 +2022,13 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
if (brush->height == 0)
brush->height = 0.4f;
}
/* replace 'rim material' option for in offset*/
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Solidify) {
@@ -2042,24 +2042,24 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
/* particle draw color from material */
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
if (part->draw & PART_DRAW_MAT_COL)
part->draw_col = PART_DRAW_COL_MAT;
}
}
- if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 6)) {
+ if (bmain->versionfile < 256 || (bmain->versionfile == 256 && bmain->subversionfile < 6)) {
Mesh *me;
- for (me = main->mesh.first; me; me = me->id.next)
+ for (me = bmain->mesh.first; me; me = me->id.next)
BKE_mesh_calc_normals_tessface(me->mvert, me->totvert, me->mface, me->totface, NULL);
}
- if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 256 || (bmain->versionfile == 256 && bmain->subversionfile < 2)) {
/* update blur area sizes from 0..1 range to 0..100 percentage */
Scene *scene;
bNode *node;
- for (scene = main->scene.first; scene; scene = scene->id.next)
+ for (scene = bmain->scene.first; scene; scene = scene->id.next)
if (scene->nodetree)
for (node = scene->nodetree->nodes.first; node; node = node->next)
if (node->type == CMP_NODE_BLUR) {
@@ -2069,13 +2069,13 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 258 || (main->versionfile == 258 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 1)) {
/* screen view2d settings were not properly initialized [#27164]
* v2d->scroll caused the bug but best reset other values too which are in old blend files only.
* need to make less ugly - possibly an iterator? */
bScreen *screen;
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
ScrArea *sa;
/* add regions */
for (sa = screen->areabase.first; sa; sa = sa->next) {
@@ -2106,19 +2106,19 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
{
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
/* Initialize particle billboard scale */
part->bb_size[0] = part->bb_size[1] = 1.0f;
}
}
}
- if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 259 || (bmain->versionfile == 259 && bmain->subversionfile < 1)) {
{
Scene *scene;
Sequence *seq;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->r.ffcodecdata.audio_channels = 2;
scene->audio.volume = 1.0f;
SEQ_BEGIN (scene->ed, seq)
@@ -2131,7 +2131,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
{
bScreen *screen;
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
ScrArea *sa;
/* add regions */
@@ -2172,7 +2172,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
bAction *act;
FCurve *fcu;
- for (act = main->action.first; act; act = act->id.next) {
+ for (act = bmain->action.first; act; act = act->id.next) {
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
BezTriple *bezt;
unsigned int i = 0;
@@ -2197,10 +2197,10 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 259 || (bmain->versionfile == 259 && bmain->subversionfile < 2)) {
{
/* Convert default socket values from bNodeStack */
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
bNode *node;
bNodeSocket *sock;
@@ -2227,17 +2227,17 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
* associate them with specific node types for polling.
*/
bNodeTree *ntree;
- /* all node trees in main->nodetree are considered groups */
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ /* all node trees in bmain->nodetree are considered groups */
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
ntree->nodetype = NODE_GROUP;
}
}
- if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 4)) {
+ if (bmain->versionfile < 259 || (bmain->versionfile == 259 && bmain->subversionfile < 4)) {
{
/* Adaptive time step for particle systems */
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
part->courant_target = 0.2f;
part->time_flag &= ~PART_TIME_AUTOSF;
}
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index 8e0795f7e34..2cded68f7ec 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -608,15 +608,15 @@ static void do_versions_nodetree_customnodes(bNodeTree *ntree, int UNUSED(is_gro
}
}
-void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
+void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
- if (main->versionfile < 260) {
+ if (bmain->versionfile < 260) {
{
/* set default alpha value of Image outputs in image and render layer nodes to 0 */
Scene *sce;
bNodeTree *ntree;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
/* there are files with invalid audio_channels value, the real cause
* is unknown, but we fix it here anyway to avoid crashes */
if (sce->r.ffcodecdata.audio_channels == 0)
@@ -626,7 +626,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
do_versions_nodetree_image_default_alpha_output(sce->nodetree);
}
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
do_versions_nodetree_image_default_alpha_output(ntree);
}
@@ -634,7 +634,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
/* support old particle dupliobject rotation settings */
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
if (ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
part->draw |= PART_DRAW_ROTATE_OB;
@@ -645,16 +645,16 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 260 || (bmain->versionfile == 260 && bmain->subversionfile < 1)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ob->collision_boundtype = ob->boundtype;
}
{
Camera *cam;
- for (cam = main->camera.first; cam; cam = cam->id.next) {
+ for (cam = bmain->camera.first; cam; cam = cam->id.next) {
if (cam->sensor_x < 0.01f)
cam->sensor_x = DEFAULT_SENSOR_WIDTH;
@@ -664,8 +664,8 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 2)) {
- FOREACH_NODETREE(main, ntree, id) {
+ if (bmain->versionfile < 260 || (bmain->versionfile == 260 && bmain->subversionfile < 2)) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -682,24 +682,24 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 4)) {
+ if (bmain->versionfile < 260 || (bmain->versionfile == 260 && bmain->subversionfile < 4)) {
{
/* Convert node angles to radians! */
Scene *sce;
Material *mat;
bNodeTree *ntree;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree)
do_versions_nodetree_convert_angle(sce->nodetree);
}
- for (mat = main->mat.first; mat; mat = mat->id.next) {
+ for (mat = bmain->mat.first; mat; mat = mat->id.next) {
if (mat->nodetree)
do_versions_nodetree_convert_angle(mat->nodetree);
}
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
do_versions_nodetree_convert_angle(ntree);
}
@@ -708,7 +708,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
bScreen *sc;
MovieClip *clip;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -732,7 +732,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTrackingTrack *track;
if (clip->aspx < 1.0f) {
@@ -764,16 +764,16 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 6)) {
+ if (bmain->versionfile < 260 || (bmain->versionfile == 260 && bmain->subversionfile < 6)) {
Scene *sce;
MovieClip *clip;
bScreen *sc;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
do_versions_image_settings_2_60(sce);
}
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTrackingSettings *settings = &clip->tracking.settings;
if (settings->default_pattern_size == 0.0f) {
@@ -784,7 +784,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -799,7 +799,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
{
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* convert delta addition into delta scale */
int i;
for (i = 0; i < 3; i++) {
@@ -819,25 +819,25 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
/* sigh, this dscale vs dsize version patching was not done right, fix for fix,
* this intentionally checks an exact subversion, also note this was never in a release,
* at some point this could be removed. */
- else if (main->versionfile == 260 && main->subversionfile == 6) {
+ else if (bmain->versionfile == 260 && bmain->subversionfile == 6) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (is_zero_v3(ob->dscale)) {
copy_vn_fl(ob->dscale, 3, 1.0f);
}
}
}
- if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 8)) {
+ if (bmain->versionfile < 260 || (bmain->versionfile == 260 && bmain->subversionfile < 8)) {
Brush *brush;
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
if (brush->sculpt_tool == SCULPT_TOOL_ROTATE)
brush->alpha = 1.0f;
}
}
- if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 261 || (bmain->versionfile == 261 && bmain->subversionfile < 1)) {
{
/* update use flags for node sockets (was only temporary before) */
Scene *sce;
@@ -847,32 +847,32 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
World *world;
bNodeTree *ntree;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree)
do_versions_nodetree_socket_use_flags_2_62(sce->nodetree);
}
- for (mat = main->mat.first; mat; mat = mat->id.next) {
+ for (mat = bmain->mat.first; mat; mat = mat->id.next) {
if (mat->nodetree)
do_versions_nodetree_socket_use_flags_2_62(mat->nodetree);
}
- for (tex = main->tex.first; tex; tex = tex->id.next) {
+ for (tex = bmain->tex.first; tex; tex = tex->id.next) {
if (tex->nodetree)
do_versions_nodetree_socket_use_flags_2_62(tex->nodetree);
}
- for (lamp = main->lamp.first; lamp; lamp = lamp->id.next) {
+ for (lamp = bmain->lamp.first; lamp; lamp = lamp->id.next) {
if (lamp->nodetree)
do_versions_nodetree_socket_use_flags_2_62(lamp->nodetree);
}
- for (world = main->world.first; world; world = world->id.next) {
+ for (world = bmain->world.first; world; world = world->id.next) {
if (world->nodetree)
do_versions_nodetree_socket_use_flags_2_62(world->nodetree);
}
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) {
do_versions_nodetree_socket_use_flags_2_62(ntree);
}
}
@@ -880,7 +880,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
MovieClip *clip;
Object *ob;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *tracking_object = tracking->objects.first;
@@ -900,7 +900,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
@@ -914,12 +914,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 261 || (bmain->versionfile == 261 && bmain->subversionfile < 2)) {
{
/* convert deprecated sculpt_paint_unified_* fields to
* UnifiedPaintSettings */
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
ToolSettings *ts = scene->toolsettings;
UnifiedPaintSettings *ups = &ts->unified_paint_settings;
ups->size = ts->sculpt_paint_unified_size;
@@ -930,11 +930,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 3)) {
+ if (bmain->versionfile < 261 || (bmain->versionfile == 261 && bmain->subversionfile < 3)) {
{
/* convert extended ascii to utf-8 for text editor */
Text *text;
- for (text = main->text.first; text; text = text->id.next) {
+ for (text = bmain->text.first; text; text = text->id.next) {
if (!(text->flags & TXT_ISEXT)) {
TextLine *tl;
@@ -952,7 +952,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
{
/* set new dynamic paint values */
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_DynamicPaint) {
@@ -972,9 +972,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 262) {
+ if (bmain->versionfile < 262) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
@@ -987,12 +987,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 263) {
+ if (bmain->versionfile < 263) {
/* set fluidsim rate. the version patch for this in 2.62 was wrong, so
* try to correct it, if rate is 0.0 that's likely not intentional */
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Fluidsim) {
@@ -1004,35 +1004,35 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 262 || (main->versionfile == 262 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 262 || (bmain->versionfile == 262 && bmain->subversionfile < 1)) {
/* update use flags for node sockets (was only temporary before) */
Scene *sce;
bNodeTree *ntree;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree)
do_versions_nodetree_multi_file_output_format_2_62_1(sce, sce->nodetree);
}
/* XXX can't associate with scene for group nodes, image format will stay uninitialized */
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
do_versions_nodetree_multi_file_output_format_2_62_1(NULL, ntree);
}
/* only swap for pre-release bmesh merge which had MLoopCol red/blue swap */
- if (main->versionfile == 262 && main->subversionfile == 1) {
+ if (bmain->versionfile == 262 && bmain->subversionfile == 1) {
{
Mesh *me;
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
do_versions_mesh_mloopcol_swap_2_62_1(me);
}
}
}
- if (main->versionfile < 262 || (main->versionfile == 262 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 262 || (bmain->versionfile == 262 && bmain->subversionfile < 2)) {
/* Set new idname of keyingsets from their now "label-only" name. */
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
KeyingSet *ks;
for (ks = scene->keyingsets.first; ks; ks = ks->next) {
if (!ks->idname[0])
@@ -1041,11 +1041,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 262 || (main->versionfile == 262 && main->subversionfile < 3)) {
+ if (bmain->versionfile < 262 || (bmain->versionfile == 262 && bmain->subversionfile < 3)) {
Object *ob;
ModifierData *md;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Lattice) {
LatticeModifierData *lmd = (LatticeModifierData *)md;
@@ -1055,11 +1055,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 262 || (main->versionfile == 262 && main->subversionfile < 4)) {
+ if (bmain->versionfile < 262 || (bmain->versionfile == 262 && bmain->subversionfile < 4)) {
/* Read Viscosity presets from older files */
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Fluidsim) {
@@ -1079,27 +1079,27 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
- if (main->versionfile < 263) {
+ if (bmain->versionfile < 263) {
/* Default for old files is to save particle rotations to pointcache */
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
part->flag |= PART_ROTATIONS;
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 1)) {
/* file output node paths are now stored in the file info struct instead socket name */
Scene *sce;
bNodeTree *ntree;
- for (sce = main->scene.first; sce; sce = sce->id.next)
+ for (sce = bmain->scene.first; sce; sce = sce->id.next)
if (sce->nodetree)
do_versions_nodetree_multi_file_output_path_2_63_1(sce->nodetree);
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
do_versions_nodetree_multi_file_output_path_2_63_1(ntree);
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 3)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 3)) {
Scene *scene;
Brush *brush;
@@ -1107,7 +1107,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
* unified paint settings also have weight. Update unified
* paint settings and brushes with a default weight value. */
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
ToolSettings *ts = scene->toolsettings;
if (ts) {
ts->unified_paint_settings.weight = ts->vgroup_weight;
@@ -1115,15 +1115,15 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
brush->weight = 0.5;
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 2)) {
bScreen *sc;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1155,18 +1155,18 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 4)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 4)) {
Camera *cam;
Curve *cu;
- for (cam = main->camera.first; cam; cam = cam->id.next) {
+ for (cam = bmain->camera.first; cam; cam = cam->id.next) {
if (cam->flag & CAM_PANORAMA) {
cam->type = CAM_PANO;
cam->flag &= ~CAM_PANORAMA;
}
}
- for (cu = main->curve.first; cu; cu = cu->id.next) {
+ for (cu = bmain->curve.first; cu; cu = cu->id.next) {
if (cu->bevfac2 == 0.0f) {
cu->bevfac1 = 0.0f;
cu->bevfac2 = 1.0f;
@@ -1174,26 +1174,26 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 5)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 5)) {
{
/* file output node paths are now stored in the file info struct instead socket name */
Scene *sce;
bNodeTree *ntree;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree) {
do_versions_nodetree_file_output_layers_2_64_5(sce->nodetree);
do_versions_nodetree_image_layer_2_64_5(sce->nodetree);
}
}
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) {
do_versions_nodetree_file_output_layers_2_64_5(ntree);
do_versions_nodetree_image_layer_2_64_5(ntree);
}
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 6)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 6)) {
/* update use flags for node sockets (was only temporary before) */
Scene *sce;
Material *mat;
@@ -1202,34 +1202,34 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
World *world;
bNodeTree *ntree;
- for (sce = main->scene.first; sce; sce = sce->id.next)
+ for (sce = bmain->scene.first; sce; sce = sce->id.next)
if (sce->nodetree)
do_versions_nodetree_frame_2_64_6(sce->nodetree);
- for (mat = main->mat.first; mat; mat = mat->id.next)
+ for (mat = bmain->mat.first; mat; mat = mat->id.next)
if (mat->nodetree)
do_versions_nodetree_frame_2_64_6(mat->nodetree);
- for (tex = main->tex.first; tex; tex = tex->id.next)
+ for (tex = bmain->tex.first; tex; tex = tex->id.next)
if (tex->nodetree)
do_versions_nodetree_frame_2_64_6(tex->nodetree);
- for (lamp = main->lamp.first; lamp; lamp = lamp->id.next)
+ for (lamp = bmain->lamp.first; lamp; lamp = lamp->id.next)
if (lamp->nodetree)
do_versions_nodetree_frame_2_64_6(lamp->nodetree);
- for (world = main->world.first; world; world = world->id.next)
+ for (world = bmain->world.first; world; world = world->id.next)
if (world->nodetree)
do_versions_nodetree_frame_2_64_6(world->nodetree);
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
do_versions_nodetree_frame_2_64_6(ntree);
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 7)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 7)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Smoke) {
@@ -1244,8 +1244,8 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 9)) {
- FOREACH_NODETREE(main, ntree, id) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 9)) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1262,11 +1262,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 10)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 10)) {
{
Scene *scene;
// composite redesign
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->nodetree) {
if (scene->nodetree->chunksize == 0) {
scene->nodetree->chunksize = 256;
@@ -1274,7 +1274,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1292,7 +1292,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
{
bScreen *sc;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -1314,16 +1314,16 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
{
MovieClip *clip;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
clip->start_frame = 1;
}
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 11)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 11)) {
MovieClip *clip;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTrackingTrack *track;
track = clip->tracking.tracks.first;
@@ -1335,8 +1335,8 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 13)) {
- FOREACH_NODETREE(main, ntree, id) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 13)) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1352,10 +1352,10 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 14)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 14)) {
ParticleSettings *part;
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1371,14 +1371,14 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
/* keep compatibility for dupliobject particle size */
- for (part = main->particle.first; part; part = part->id.next)
+ for (part = bmain->particle.first; part; part = part->id.next)
if (ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR))
if ((part->draw & PART_DRAW_ROTATE_OB) == 0)
part->draw |= PART_DRAW_NO_SCALE_OB;
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 17)) {
- FOREACH_NODETREE(main, ntree, id) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 17)) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1397,10 +1397,10 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 18)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 18)) {
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->ed) {
Sequence *seq;
@@ -1434,7 +1434,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
/* color management pipeline changes compatibility code */
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 19)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 19)) {
Scene *scene;
Image *ima;
bool colormanagement_disabled = false;
@@ -1442,7 +1442,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
/* make scenes which are not using color management have got None as display device,
* so they wouldn't perform linear-to-sRGB conversion on display
*/
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if ((scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) == 0) {
ColorManagedDisplaySettings *display_settings = &scene->display_settings;
@@ -1455,7 +1455,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (ima = main->image.first; ima; ima = ima->id.next) {
+ for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (ima->source == IMA_SRC_VIEWER) {
ima->flag |= IMA_VIEW_AS_RENDER;
}
@@ -1474,17 +1474,17 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 20)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 20)) {
Key *key;
- for (key = main->key.first; key; key = key->id.next) {
+ for (key = bmain->key.first; key; key = key->id.next) {
blo_do_versions_key_uidgen(key);
}
}
- if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 21)) {
+ if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 21)) {
{
Mesh *me;
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
CustomData_update_typemap(&me->vdata);
CustomData_free_layers(&me->vdata, CD_MSTICKY, me->totvert);
}
@@ -1495,10 +1495,10 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
* didn't copy animation visualization, which lead to deadlocks on motion
* path calculation for proxied armatures, see [#32742]
*/
- if (main->versionfile < 264) {
+ if (bmain->versionfile < 264) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->pose) {
if (ob->pose->avs.path_step == 0) {
animviz_settings_init(&ob->pose->avs);
@@ -1507,8 +1507,8 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 1)) {
- FOREACH_NODETREE(main, ntree, id) {
+ if (bmain->versionfile < 264 || (bmain->versionfile == 264 && bmain->subversionfile < 1)) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next)
@@ -1518,10 +1518,10 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 264 || (bmain->versionfile == 264 && bmain->subversionfile < 2)) {
MovieClip *clip;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *tracking_object;
@@ -1537,12 +1537,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 3)) {
+ if (bmain->versionfile < 264 || (bmain->versionfile == 264 && bmain->subversionfile < 3)) {
/* smoke branch */
{
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Smoke) {
@@ -1581,7 +1581,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
{
bScreen *sc;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1601,11 +1601,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 5)) {
+ if (bmain->versionfile < 264 || (bmain->versionfile == 264 && bmain->subversionfile < 5)) {
/* set a unwrapping margin and ABF by default */
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->toolsettings->uvcalc_margin == 0.0f) {
scene->toolsettings->uvcalc_margin = 0.001f;
scene->toolsettings->unwrapper = 0;
@@ -1613,11 +1613,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 6)) {
+ if (bmain->versionfile < 264 || (bmain->versionfile == 264 && bmain->subversionfile < 6)) {
/* Fix for bug #32982, internal_links list could get corrupted from r51630 onward.
* Simply remove bad internal_links lists to avoid NULL pointers.
*/
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
bNode *node;
bNodeLink *link, *nextlink;
@@ -1632,12 +1632,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 7)) {
+ if (bmain->versionfile < 264 || (bmain->versionfile == 264 && bmain->subversionfile < 7)) {
/* convert tiles size from resolution and number of tiles */
{
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->r.tilex == 0 || scene->r.tiley == 1) {
scene->r.tilex = scene->r.tiley = 64;
}
@@ -1647,7 +1647,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
/* collision masks */
{
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->col_group == 0) {
ob->col_group = 0x01;
ob->col_mask = 0xff;
@@ -1656,10 +1656,10 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 7)) {
+ if (bmain->versionfile < 264 || (bmain->versionfile == 264 && bmain->subversionfile < 7)) {
MovieClip *clip;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTrackingTrack *track;
MovieTrackingObject *object;
@@ -1675,9 +1675,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 3)) {
+ if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 3)) {
bScreen *sc;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1719,11 +1719,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 5)) {
+ if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 5)) {
Scene *scene;
Tex *tex;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
Sequence *seq;
SEQ_BEGIN (scene->ed, seq)
@@ -1741,7 +1741,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
scene->r.bake_samples = 256;
}
- for (Image *image = main->image.first; image; image = image->id.next) {
+ for (Image *image = bmain->image.first; image; image = image->id.next) {
if (image->flag & IMA_DO_PREMUL) {
image->alpha_mode = IMA_ALPHA_STRAIGHT;
}
@@ -1750,7 +1750,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (tex = main->tex.first; tex; tex = tex->id.next) {
+ for (tex = bmain->tex.first; tex; tex = tex->id.next) {
if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) {
Image *image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima);
@@ -1759,7 +1759,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1775,20 +1775,20 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
} FOREACH_NODETREE_END
}
- else if (main->versionfile < 266 || (main->versionfile == 266 && main->subversionfile < 1)) {
+ else if (bmain->versionfile < 266 || (bmain->versionfile == 266 && bmain->subversionfile < 1)) {
/* texture use alpha was removed for 2.66 but added back again for 2.66a,
* for compatibility all textures assumed it to be enabled */
Tex *tex;
- for (tex = main->tex.first; tex; tex = tex->id.next)
+ for (tex = bmain->tex.first; tex; tex = tex->id.next)
if (tex->type == TEX_IMAGE)
tex->imaflag |= TEX_USEALPHA;
}
- if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
+ if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 7)) {
Curve *cu;
- for (cu = main->curve.first; cu; cu = cu->id.next) {
+ for (cu = bmain->curve.first; cu; cu = cu->id.next) {
if (cu->flag & (CU_FRONT | CU_BACK)) {
if ( cu->ext1 != 0.0f || cu->ext2 != 0.0f) {
Nurb *nu;
@@ -1820,16 +1820,16 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (MAIN_VERSION_OLDER(main, 265, 9)) {
+ if (MAIN_VERSION_OLDER(bmain, 265, 9)) {
Mesh *me;
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
BKE_mesh_do_versions_cd_flag_init(me);
}
}
- if (MAIN_VERSION_OLDER(main, 265, 10)) {
+ if (MAIN_VERSION_OLDER(bmain, 265, 10)) {
Brush *br;
- for (br = main->brush.first; br; br = br->id.next) {
+ for (br = bmain->brush.first; br; br = br->id.next) {
if (br->ob_mode & OB_MODE_TEXTURE_PAINT) {
br->mtex.brush_map_mode = MTEX_MAP_MODE_TILED;
}
@@ -1837,8 +1837,8 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
// add storage for compositor translate nodes when not existing
- if (MAIN_VERSION_OLDER(main, 265, 11)) {
- FOREACH_NODETREE(main, ntree, id) {
+ if (MAIN_VERSION_OLDER(bmain, 265, 11)) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1850,15 +1850,15 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (MAIN_VERSION_OLDER(main, 266, 2)) {
- FOREACH_NODETREE(main, ntree, id) {
+ if (MAIN_VERSION_OLDER(bmain, 266, 2)) {
+ FOREACH_NODETREE(bmain, ntree, id) {
do_versions_nodetree_customnodes(ntree, ((ID *)ntree == id));
} FOREACH_NODETREE_END
}
- if (MAIN_VERSION_OLDER(main, 266, 2)) {
+ if (MAIN_VERSION_OLDER(bmain, 266, 2)) {
bScreen *sc;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1892,7 +1892,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
/* Set flag for delayed do_versions in lib_verify_nodetree. It needs valid typeinfo pointers ... */
{
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
/* XXX This should be kept without version check for now!
* As long as USE_NODE_COMPAT_CUSTOMNODES is active, files will write links
* to tree interface sockets for forward compatibility. These links need to be removed again
@@ -1904,22 +1904,22 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
/* Only add interface nodes once.
* In old Blender versions they will be removed automatically due to undefined type */
- if (MAIN_VERSION_OLDER(main, 266, 2))
+ if (MAIN_VERSION_OLDER(bmain, 266, 2))
ntree->flag |= NTREE_DO_VERSIONS_CUSTOMNODES_GROUP_CREATE_INTERFACE;
}
FOREACH_NODETREE_END
}
- if (MAIN_VERSION_OLDER(main, 266, 3)) {
+ if (MAIN_VERSION_OLDER(bmain, 266, 3)) {
{
/* Fix for a very old issue:
* Node names were nominally made unique in r24478 (2.50.8), but the do_versions check
- * to update existing node names only applied to main->nodetree (i.e. group nodes).
+ * to update existing node names only applied to bmain->nodetree (i.e. group nodes).
* Uniqueness is now required for proper preview mapping,
* so do this now to ensure old files don't break.
*/
bNode *node;
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (id == &ntree->id)
continue; /* already fixed for node groups */
@@ -1930,9 +1930,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 266, 4)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 266, 4)) {
Brush *brush;
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
BKE_texture_mtex_default(&brush->mask_mtex);
if (brush->ob_mode & OB_MODE_TEXTURE_PAINT) {
@@ -1941,11 +1941,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 266, 6)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 266, 6)) {
Brush *brush;
#define BRUSH_TEXTURE_OVERLAY (1 << 21)
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
brush->overlay_flags = 0;
if (brush->flag & BRUSH_TEXTURE_OVERLAY)
brush->overlay_flags |= (BRUSH_OVERLAY_PRIMARY | BRUSH_OVERLAY_CURSOR);
@@ -1953,11 +1953,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
#undef BRUSH_TEXTURE_OVERLAY
}
- if (main->versionfile < 267) {
+ if (bmain->versionfile < 267) {
//if (!DNA_struct_elem_find(fd->filesdna, "Brush", "int", "stencil_pos")) {
Brush *brush;
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
if (brush->stencil_dimension[0] == 0) {
brush->stencil_dimension[0] = 256;
brush->stencil_dimension[1] = 256;
@@ -1982,12 +1982,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
/* default values in Freestyle settings */
- if (main->versionfile < 267) {
+ if (bmain->versionfile < 267) {
Scene *sce;
SceneRenderLayer *srl;
FreestyleLineStyle *linestyle;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->r.line_thickness_mode == 0) {
sce->r.line_thickness_mode = R_LINE_THICKNESS_ABSOLUTE;
sce->r.unit_line_thickness = 1.0f;
@@ -2023,7 +2023,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
+ for (linestyle = bmain->linestyle.first; linestyle; linestyle = linestyle->id.next) {
#if 1
/* disable the Misc panel for now */
if (linestyle->panel == LS_PANEL_MISC) {
@@ -2041,13 +2041,13 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (main->versionfile < 267) {
+ if (bmain->versionfile < 267) {
/* Initialize the active_viewer_key for compositing */
bScreen *screen;
Scene *scene;
bNodeInstanceKey active_viewer_key = {0};
/* simply pick the first node space and use that for the active viewer key */
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
ScrArea *sa;
for (sa = screen->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -2069,17 +2069,17 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
break;
}
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
/* NB: scene->nodetree is a local ID block, has been direct_link'ed */
if (scene->nodetree)
scene->nodetree->active_viewer_key = active_viewer_key;
}
}
- if (MAIN_VERSION_OLDER(main, 267, 1)) {
+ if (MAIN_VERSION_OLDER(bmain, 267, 1)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Smoke) {
@@ -2097,17 +2097,17 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 268, 1)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 268, 1)) {
Brush *brush;
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
brush->spacing = MAX2(1, brush->spacing);
}
}
- if (!MAIN_VERSION_ATLEAST(main, 268, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 268, 2)) {
Brush *brush;
#define BRUSH_FIXED (1 << 6)
- for (brush = main->brush.first; brush; brush = brush->id.next) {
+ for (brush = bmain->brush.first; brush; brush = brush->id.next) {
brush->flag &= ~BRUSH_FIXED;
if (brush->cursor_overlay_alpha < 2)
@@ -2121,11 +2121,11 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
- if (!MAIN_VERSION_ATLEAST(main, 268, 4)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 268, 4)) {
bScreen *sc;
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
if (con->type == CONSTRAINT_TYPE_SHRINKWRAP) {
@@ -2138,7 +2138,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Smoke) {
@@ -2157,7 +2157,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
*
* We moved this check to the do versions to be sure the value makes any sense.
*/
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -2173,12 +2173,12 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 268, 5)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 268, 5)) {
bScreen *sc;
ScrArea *sa;
/* add missing (+) expander in node editor */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
for (sa = sc->areabase.first; sa; sa = sa->next) {
ARegion *ar, *arnew;
@@ -2207,9 +2207,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 269, 1)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 269, 1)) {
/* Removal of Cycles SSS Compatible falloff */
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -2223,9 +2223,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (!MAIN_VERSION_ATLEAST(main, 269, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 269, 2)) {
/* Initialize CDL settings for Color Balance nodes */
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -2250,14 +2250,14 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
} FOREACH_NODETREE_END
}
- if (!MAIN_VERSION_ATLEAST(main, 269, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 269, 3)) {
bScreen *sc;
ScrArea *sa;
SpaceLink *sl;
Scene *scene;
/* Update files using invalid (outdated) outlinevis Outliner values. */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
for (sa = sc->areabase.first; sa; sa = sa->next) {
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_OUTLINER) {
@@ -2278,7 +2278,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingTrack", "float", "weight")) {
MovieClip *clip;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *tracking_object;
for (tracking_object = tracking->objects.first;
@@ -2299,7 +2299,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "TriangulateModifierData", "int", "quad_method")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Triangulate) {
@@ -2317,7 +2317,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
/* this can now be turned off */
ToolSettings *ts = scene->toolsettings;
if (ts->sculpt)
@@ -2337,17 +2337,17 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 269, 4)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 269, 4)) {
/* Internal degrees to radians conversions... */
{
Scene *scene;
Object *ob;
Lamp *lamp;
- for (lamp = main->lamp.first; lamp; lamp = lamp->id.next)
+ for (lamp = bmain->lamp.first; lamp; lamp = lamp->id.next)
lamp->spotsize = DEG2RADF(lamp->spotsize);
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
@@ -2362,7 +2362,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
Sequence *seq;
SEQ_BEGIN (scene->ed, seq)
{
@@ -2374,7 +2374,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
SEQ_END
}
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -2397,7 +2397,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingPlaneTrack", "float", "image_opacity")) {
MovieClip *clip;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTrackingPlaneTrack *plane_track;
for (plane_track = clip->tracking.plane_tracks.first;
plane_track;
@@ -2409,9 +2409,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 269, 7)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 269, 7)) {
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
Sculpt *sd = scene->toolsettings->sculpt;
if (sd) {
@@ -2429,20 +2429,20 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 269, 8)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 269, 8)) {
Curve *cu;
- for (cu = main->curve.first; cu; cu = cu->id.next) {
+ for (cu = bmain->curve.first; cu; cu = cu->id.next) {
if (cu->str) {
cu->len_wchar = BLI_strlen_utf8(cu->str);
}
}
}
- if (!MAIN_VERSION_ATLEAST(main, 269, 9)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 269, 9)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Build) {
@@ -2455,10 +2455,10 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 269, 11)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 269, 11)) {
bScreen *sc;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *space_link;
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index ee589e511c6..ba714405cc0 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -346,14 +346,14 @@ static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id), FCurve *fcu, void
}
-void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
+void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
- if (!MAIN_VERSION_ATLEAST(main, 270, 0)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 270, 0)) {
if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "float", "profile")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Bevel) {
@@ -366,7 +366,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
/* nodes don't use fixed node->id any more, clean up */
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -380,7 +380,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
{
bScreen *screen;
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
ScrArea *area;
for (area = screen->areabase.first; area; area = area->next) {
SpaceLink *space_link;
@@ -398,17 +398,17 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingSettings", "float", "default_weight")) {
MovieClip *clip;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
clip->tracking.settings.default_weight = 1.0f;
}
}
}
- if (!MAIN_VERSION_ATLEAST(main, 270, 1)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 270, 1)) {
Object *ob;
/* Update Transform constraint (another deg -> rad stuff). */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
do_version_constraints_radians_degrees_270_1(&ob->constraints);
if (ob->pose) {
@@ -421,32 +421,32 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 270, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 270, 2)) {
Mesh *me;
/* Mesh smoothresh deg->rad. */
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
me->smoothresh = DEG2RADF(me->smoothresh);
}
}
- if (!MAIN_VERSION_ATLEAST(main, 270, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 270, 3)) {
FreestyleLineStyle *linestyle;
- for (linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
+ for (linestyle = bmain->linestyle.first; linestyle; linestyle = linestyle->id.next) {
linestyle->flag |= LS_NO_SORTING;
linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
linestyle->integration_type = LS_INTEGRATION_MEAN;
}
}
- if (!MAIN_VERSION_ATLEAST(main, 270, 4)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 270, 4)) {
/* ui_previews were not handled correctly when copying areas, leading to corrupted files (see T39847).
* This will always reset situation to a valid state.
*/
bScreen *sc;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -463,11 +463,11 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 270, 5)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 270, 5)) {
Object *ob;
/* Update Transform constraint (again :|). */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
do_version_constraints_radians_degrees_270_5(&ob->constraints);
if (ob->pose) {
@@ -480,11 +480,11 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 271, 0)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 271, 0)) {
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "BakeData", "bake")) {
Scene *sce;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
sce->r.bake.flag = R_BAKE_CLEAR;
sce->r.bake.width = 512;
sce->r.bake.height = 512;
@@ -506,7 +506,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "FreestyleLineStyle", "float", "texstep")) {
FreestyleLineStyle *linestyle;
- for (linestyle = main->linestyle.first; linestyle; linestyle = linestyle->id.next) {
+ for (linestyle = bmain->linestyle.first; linestyle; linestyle = linestyle->id.next) {
linestyle->flag |= LS_TEXTURE;
linestyle->texstep = 1.0;
}
@@ -514,18 +514,18 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
{
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
int num_layers = BLI_listbase_count(&scene->r.layers);
scene->r.actlay = min_ff(scene->r.actlay, num_layers - 1);
}
}
}
- if (!MAIN_VERSION_ATLEAST(main, 271, 1)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 271, 1)) {
if (!DNA_struct_elem_find(fd->filesdna, "Material", "float", "line_col[4]")) {
Material *mat;
- for (mat = main->mat.first; mat; mat = mat->id.next) {
+ for (mat = bmain->mat.first; mat; mat = mat->id.next) {
mat->line_col[0] = mat->line_col[1] = mat->line_col[2] = 0.0f;
mat->line_col[3] = mat->alpha;
}
@@ -533,22 +533,22 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->r.preview_start_resolution = 64;
}
}
}
- if (!MAIN_VERSION_ATLEAST(main, 271, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 271, 3)) {
Brush *br;
- for (br = main->brush.first; br; br = br->id.next) {
+ for (br = bmain->brush.first; br; br = br->id.next) {
br->fill_threshold = 0.2f;
}
if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "int", "mat")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
@@ -561,9 +561,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 271, 6)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 271, 6)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
@@ -577,27 +577,27 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 272, 0)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 272, 0)) {
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->r.preview_start_resolution = 64;
}
}
}
- if (!MAIN_VERSION_ATLEAST(main, 272, 1)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 272, 1)) {
Brush *br;
- for (br = main->brush.first; br; br = br->id.next) {
+ for (br = bmain->brush.first; br; br = br->id.next) {
if ((br->ob_mode & OB_MODE_SCULPT) && ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK))
br->alpha = 1.0f;
}
}
- if (!MAIN_VERSION_ATLEAST(main, 272, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 272, 2)) {
if (!DNA_struct_elem_find(fd->filesdna, "Image", "float", "gen_color")) {
Image *image;
- for (image = main->image.first; image != NULL; image = image->id.next) {
+ for (image = bmain->image.first; image != NULL; image = image->id.next) {
image->gen_color[3] = 1.0f;
}
}
@@ -606,7 +606,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
Object *ob;
/* Update Transform constraint (again :|). */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
do_version_constraints_stretch_to_limits(&ob->constraints);
if (ob->pose) {
@@ -620,13 +620,13 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 273, 1)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 273, 1)) {
#define BRUSH_RAKE (1 << 7)
#define BRUSH_RANDOM_ROTATION (1 << 25)
Brush *br;
- for (br = main->brush.first; br; br = br->id.next) {
+ for (br = bmain->brush.first; br; br = br->id.next) {
if (br->flag & BRUSH_RAKE) {
br->mtex.brush_angle_mode |= MTEX_ANGLE_RAKE;
br->mask_mtex.brush_angle_mode |= MTEX_ANGLE_RAKE;
@@ -644,11 +644,11 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
#undef BRUSH_RANDOM_ROTATION
/* Customizable Safe Areas */
- if (!MAIN_VERSION_ATLEAST(main, 273, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 273, 2)) {
if (!DNA_struct_elem_find(fd->filesdna, "Scene", "DisplaySafeAreas", "safe_areas")) {
Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
copy_v2_fl2(scene->safe_areas.title, 3.5f / 100.0f, 3.5f / 100.0f);
copy_v2_fl2(scene->safe_areas.action, 10.0f / 100.0f, 5.0f / 100.0f);
copy_v2_fl2(scene->safe_areas.title_center, 17.5f / 100.0f, 5.0f / 100.0f);
@@ -657,9 +657,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 273, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 273, 3)) {
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
if (part->clumpcurve)
part->child_flag |= PART_CHILD_USE_CLUMP_CURVE;
if (part->roughcurve)
@@ -667,11 +667,11 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 273, 6)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 273, 6)) {
if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "float", "bending_damping")) {
Object *ob;
ModifierData *md;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Cloth) {
ClothModifierData *clmd = (ClothModifierData *)md;
@@ -689,21 +689,21 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "ParticleSettings", "float", "clump_noise_size")) {
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
part->clump_noise_size = 1.0f;
}
}
if (!DNA_struct_elem_find(fd->filesdna, "ParticleSettings", "int", "kink_extra_steps")) {
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
part->kink_extra_steps = 4;
}
}
if (!DNA_struct_elem_find(fd->filesdna, "MTex", "float", "kinkampfac")) {
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
int a;
for (a = 0; a < MAX_MTEX; a++) {
MTex *mtex = part->mtex[a];
@@ -717,7 +717,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "HookModifierData", "char", "flag")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Hook) {
@@ -729,7 +729,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "NodePlaneTrackDeformData", "char", "flag")) {
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -747,7 +747,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "Camera", "GPUDOFSettings", "gpu_dof")) {
Camera *ca;
- for (ca = main->camera.first; ca; ca = ca->id.next) {
+ for (ca = bmain->camera.first; ca; ca = ca->id.next) {
ca->gpu_dof.fstop = 128.0f;
ca->gpu_dof.focal_length = 1.0f;
ca->gpu_dof.focus_distance = 1.0f;
@@ -756,9 +756,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 273, 8)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 273, 8)) {
Object *ob;
- for (ob = main->object.first; ob != NULL; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob != NULL; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.last; md != NULL; md = md->prev) {
if (modifier_unique_name(&ob->modifiers, md)) {
@@ -770,14 +770,14 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 273, 9)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 273, 9)) {
bScreen *scr;
ScrArea *sa;
SpaceLink *sl;
ARegion *ar;
/* Make sure sequencer preview area limits zoom */
- for (scr = main->screen.first; scr; scr = scr->id.next) {
+ for (scr = bmain->screen.first; scr; scr = scr->id.next) {
for (sa = scr->areabase.first; sa; sa = sa->next) {
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_SEQ) {
@@ -795,12 +795,12 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 274, 1)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 274, 1)) {
/* particle systems need to be forced to redistribute for jitter mode fix */
{
Object *ob;
ParticleSystem *psys;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
if ((psys->pointcache->flag & PTCACHE_BAKED) == 0) {
psys->recalc |= PSYS_RECALC_RESET;
@@ -812,7 +812,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
/* hysteresis setted to 10% but not actived */
if (!DNA_struct_elem_find(fd->filesdna, "LodLevel", "int", "obhysteresis")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
LodLevel *level;
for (level = ob->lodlevels.first; level; level = level->next) {
level->obhysteresis = 10;
@@ -821,7 +821,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 274, 4)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 274, 4)) {
SceneRenderView *srv;
wmWindowManager *wm;
bScreen *screen;
@@ -830,7 +830,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
Camera *cam;
Image *ima;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
Sequence *seq;
BKE_scene_add_render_view(scene, STEREO_LEFT_NAME);
@@ -860,7 +860,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
SEQ_END
}
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
ScrArea *sa;
for (sa = screen->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -887,12 +887,12 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (cam = main->camera.first; cam; cam = cam->id.next) {
+ for (cam = bmain->camera.first; cam; cam = cam->id.next) {
cam->stereo.interocular_distance = 0.065f;
cam->stereo.convergence_distance = 30.0f * 0.065f;
}
- for (ima = main->image.first; ima; ima = ima->id.next) {
+ for (ima = bmain->image.first; ima; ima = ima->id.next) {
ima->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Image Stereo 3d Format");
if (ima->packedfile) {
@@ -905,18 +905,18 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (wm = main->wm.first; wm; wm = wm->id.next) {
+ for (wm = bmain->wm.first; wm; wm = wm->id.next) {
for (win = wm->windows.first; win; win = win->next) {
win->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format");
}
}
}
- if (!MAIN_VERSION_ATLEAST(main, 274, 6)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 274, 6)) {
bScreen *screen;
if (!DNA_struct_elem_find(fd->filesdna, "FileSelectParams", "int", "thumbnail_size")) {
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
ScrArea *sa;
for (sa = screen->areabase.first; sa; sa = sa->next) {
@@ -937,7 +937,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "short", "simplify_subsurf_render")) {
Scene *scene;
- for (scene = main->scene.first; scene != NULL; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
scene->r.simplify_subsurf_render = scene->r.simplify_subsurf;
scene->r.simplify_particles_render = scene->r.simplify_particles;
}
@@ -946,7 +946,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "DecimateModifierData", "float", "defgrp_factor")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Decimate) {
@@ -958,20 +958,20 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 275, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 275, 3)) {
Brush *br;
#define BRUSH_TORUS (1 << 1)
- for (br = main->brush.first; br; br = br->id.next) {
+ for (br = bmain->brush.first; br; br = br->id.next) {
br->flag &= ~BRUSH_TORUS;
}
#undef BRUSH_TORUS
}
- if (!MAIN_VERSION_ATLEAST(main, 276, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 276, 2)) {
if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "custom_scale")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->pose) {
bPoseChannel *pchan;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -984,7 +984,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
{
bScreen *screen;
#define RV3D_VIEW_PERSPORTHO 7
- for (screen = main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
ScrArea *sa;
for (sa = screen->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1013,7 +1013,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
{
Lamp *lamp;
#define LA_YF_PHOTON 5
- for (lamp = main->lamp.first; lamp; lamp = lamp->id.next) {
+ for (lamp = bmain->lamp.first; lamp; lamp = lamp->id.next) {
if (lamp->type == LA_YF_PHOTON) {
lamp->type = LA_LOCAL;
}
@@ -1022,10 +1022,10 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 276, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 276, 3)) {
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "CurveMapping", "mblur_shutter_curve")) {
Scene *scene;
- for (scene = main->scene.first; scene != NULL; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
CurveMapping *curve_mapping = &scene->r.mblur_shutter_curve;
curvemapping_set_defaults(curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
curvemapping_initialize(curve_mapping);
@@ -1037,8 +1037,8 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 276, 4)) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 276, 4)) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
ToolSettings *ts = scene->toolsettings;
if (ts->gp_sculpt.brush[0].size == 0) {
@@ -1113,7 +1113,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (bGPdata *gpd = main->gpencil.first; gpd; gpd = gpd->id.next) {
+ for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
bool enabled = false;
/* Ensure that the datablock's onionskinning toggle flag
@@ -1131,13 +1131,13 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
gpd->flag &= ~GP_DATA_SHOW_ONIONSKINS;
}
}
- if (!MAIN_VERSION_ATLEAST(main, 276, 5)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 276, 5)) {
ListBase *lbarray[MAX_LIBARRAY];
int a;
/* Important to clear all non-persistent flags from older versions here, otherwise they could collide
* with any new persistent flag we may add in the future. */
- a = set_listbasepointers(main, lbarray);
+ a = set_listbasepointers(bmain, lbarray);
while (a--) {
for (ID *id = lbarray[a]->first; id; id = id->next) {
id->flag &= LIB_FAKEUSER;
@@ -1145,15 +1145,15 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 276, 7)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 276, 7)) {
Scene *scene;
- for (scene = main->scene.first; scene != NULL; scene = scene->id.next) {
+ for (scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
scene->r.bake.pass_filter = R_BAKE_PASS_FILTER_ALL;
}
}
- if (!MAIN_VERSION_ATLEAST(main, 277, 1)) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 277, 1)) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
ParticleEditSettings *pset = &scene->toolsettings->particle;
for (int a = 0; a < ARRAY_SIZE(pset->brush); a++) {
if (pset->brush[a].strength > 1.0f) {
@@ -1162,7 +1162,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
@@ -1195,7 +1195,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
CurvePaintSettings *cps = &scene->toolsettings->curve_paint_settings;
if (cps->error_threshold == 0) {
cps->curve_type = CU_BEZIER;
@@ -1206,7 +1206,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
Sequence *seq;
SEQ_BEGIN (scene->ed, seq)
@@ -1230,7 +1230,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
/* Adding "Properties" region to DopeSheet */
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
/* handle pushed-back space data first */
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
@@ -1248,14 +1248,14 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 277, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 277, 2)) {
if (!DNA_struct_elem_find(fd->filesdna, "Bone", "float", "scaleIn")) {
- for (bArmature *arm = main->armature.first; arm; arm = arm->id.next) {
+ for (bArmature *arm = bmain->armature.first; arm; arm = arm->id.next) {
do_version_bones_super_bbone(&arm->bonebase);
}
}
if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "scaleIn")) {
- for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->pose) {
for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* see do_version_bones_super_bbone()... */
@@ -1275,7 +1275,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (Camera *camera = main->camera.first; camera != NULL; camera = camera->id.next) {
+ for (Camera *camera = bmain->camera.first; camera != NULL; camera = camera->id.next) {
if (camera->stereo.pole_merge_angle_from == 0.0f &&
camera->stereo.pole_merge_angle_to == 0.0f)
{
@@ -1287,7 +1287,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "NormalEditModifierData", "float", "mix_limit")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_NormalEdit) {
@@ -1300,7 +1300,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "BooleanModifierData", "float", "double_threshold")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Boolean) {
@@ -1311,7 +1311,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (Brush *br = main->brush.first; br; br = br->id.next) {
+ for (Brush *br = bmain->brush.first; br; br = br->id.next) {
if (br->sculpt_tool == SCULPT_TOOL_FLATTEN) {
br->flag |= BRUSH_ACCUMULATE;
}
@@ -1320,7 +1320,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "float", "time_scale")) {
Object *ob;
ModifierData *md;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Cloth) {
ClothModifierData *clmd = (ClothModifierData *)md;
@@ -1337,10 +1337,10 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 277, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 277, 3)) {
/* ------- init of grease pencil initialization --------------- */
if (!DNA_struct_elem_find(fd->filesdna, "bGPDstroke", "bGPDpalettecolor", "*palcolor")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
ToolSettings *ts = scene->toolsettings;
/* initialize use position for sculpt brushes */
ts->gp_sculpt.flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION;
@@ -1359,8 +1359,8 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
/* create a default grease pencil drawing brushes set */
- if (!BLI_listbase_is_empty(&main->gpencil)) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ if (!BLI_listbase_is_empty(&bmain->gpencil)) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
ToolSettings *ts = scene->toolsettings;
if (BLI_listbase_is_empty(&ts->gp_brushes)) {
BKE_gpencil_brush_init_presets(ts);
@@ -1370,7 +1370,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
/* Convert Grease Pencil to new palettes/brushes
* Loop all strokes and create the palette and all colors
*/
- for (bGPdata *gpd = main->gpencil.first; gpd; gpd = gpd->id.next) {
+ for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
if (BLI_listbase_is_empty(&gpd->palettes)) {
/* create palette */
bGPDpalette *palette = BKE_gpencil_palette_addnew(gpd, "GP_Palette", true);
@@ -1423,10 +1423,10 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
/* ------- end of grease pencil initialization --------------- */
}
- if (!MAIN_VERSION_ATLEAST(main, 278, 0)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 278, 0)) {
if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingTrack", "float", "weight_stab")) {
MovieClip *clip;
- for (clip = main->movieclip.first; clip; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip; clip = clip->id.next) {
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *tracking_object;
for (tracking_object = tracking->objects.first;
@@ -1447,7 +1447,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "MovieTrackingStabilization", "int", "tot_rot_track")) {
MovieClip *clip;
- for (clip = main->movieclip.first; clip != NULL; clip = clip->id.next) {
+ for (clip = bmain->movieclip.first; clip != NULL; clip = clip->id.next) {
if (clip->tracking.stabilization.rot_track) {
migrate_single_rot_stabilization_track_settings(&clip->tracking.stabilization);
}
@@ -1467,15 +1467,15 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
- if (!MAIN_VERSION_ATLEAST(main, 278, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 278, 2)) {
if (!DNA_struct_elem_find(fd->filesdna, "FFMpegCodecData", "int", "ffmpeg_preset")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
/* "medium" is the preset FFmpeg uses when no presets are given. */
scene->r.ffcodecdata.ffmpeg_preset = FFM_PRESET_MEDIUM;
}
}
if (!DNA_struct_elem_find(fd->filesdna, "FFMpegCodecData", "int", "constant_rate_factor")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
/* fall back to behaviour from before we introduced CRF for old files */
scene->r.ffcodecdata.constant_rate_factor = FFM_CRF_NONE;
}
@@ -1485,7 +1485,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
Object *ob;
ModifierData *md;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
@@ -1500,8 +1500,8 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 278, 3)) {
- for (Scene *scene = main->scene.first; scene != NULL; scene = scene->id.next) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 278, 3)) {
+ for (Scene *scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
if (scene->toolsettings != NULL) {
ToolSettings *ts = scene->toolsettings;
ParticleEditSettings *pset = &ts->particle;
@@ -1515,7 +1515,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
if (!DNA_struct_elem_find(fd->filesdna, "RigidBodyCon", "float", "spring_stiffness_ang_x")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
RigidBodyCon *rbc = ob->rigidbody_constraint;
if (rbc) {
rbc->spring_stiffness_ang_x = 10.0;
@@ -1530,7 +1530,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
/* constant detail for sculpting is now a resolution value instead of
* a percentage, we reuse old DNA struct member but convert it */
- for (Scene *scene = main->scene.first; scene != NULL; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
if (scene->toolsettings != NULL) {
ToolSettings *ts = scene->toolsettings;
if (ts->sculpt && ts->sculpt->constant_detail != 0.0f) {
@@ -1540,16 +1540,16 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 278, 4)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 278, 4)) {
const float sqrt_3 = (float)M_SQRT3;
- for (Brush *br = main->brush.first; br; br = br->id.next) {
+ for (Brush *br = bmain->brush.first; br; br = br->id.next) {
br->fill_threshold /= sqrt_3;
}
/* Custom motion paths */
if (!DNA_struct_elem_find(fd->filesdna, "bMotionPath", "int", "line_thickness")) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
bMotionPath *mpath;
bPoseChannel *pchan;
mpath = ob->mpath;
@@ -1577,9 +1577,9 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 278, 5)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 278, 5)) {
/* Mask primitive adding code was not initializing correctly id_type of its points' parent. */
- for (Mask *mask = main->mask.first; mask; mask = mask->id.next) {
+ for (Mask *mask = bmain->mask.first; mask; mask = mask->id.next) {
for (MaskLayer *mlayer = mask->masklayers.first; mlayer; mlayer = mlayer->next) {
for (MaskSpline *mspline = mlayer->splines.first; mspline; mspline = mspline->next) {
int i = 0;
@@ -1594,7 +1594,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
/* Fix for T50736, Glare comp node using same var for two different things. */
if (!DNA_struct_elem_find(fd->filesdna, "NodeGlare", "char", "star_45")) {
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
ntreeSetTypes(NULL, ntree);
for (bNode *node = ntree->nodes.first; node; node = node->next) {
@@ -1617,7 +1617,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "mat[4][4]")) {
- for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_SurfaceDeform) {
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
@@ -1627,32 +1627,32 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
do_versions_compositor_render_passes(ntree);
}
} FOREACH_NODETREE_END
}
- if (!MAIN_VERSION_ATLEAST(main, 279, 0)) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 279, 0)) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->r.im_format.exr_codec == R_IMF_EXR_CODEC_DWAB) {
scene->r.im_format.exr_codec = R_IMF_EXR_CODEC_DWAA;
}
}
/* Fix related to VGroup modifiers creating named defgroup CD layers! See T51520. */
- for (Mesh *me = main->mesh.first; me; me = me->id.next) {
+ for (Mesh *me = bmain->mesh.first; me; me = me->id.next) {
CustomData_set_layer_name(&me->vdata, CD_MDEFORMVERT, 0, "");
}
}
- if (!MAIN_VERSION_ATLEAST(main, 279, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 279, 3)) {
if (!DNA_struct_elem_find(fd->filesdna, "SmokeDomainSettings", "float", "clipping")) {
Object *ob;
ModifierData *md;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
@@ -1667,7 +1667,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
{
/* Fix for invalid state of screen due to bug in older versions. */
- for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) {
+ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) {
for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
if (sa->full && sc->state == SCREENNORMAL) {
sa->full = NULL;
@@ -1676,7 +1676,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "falloff_angle")) {
- for (Brush *br = main->brush.first; br; br = br->id.next) {
+ for (Brush *br = bmain->brush.first; br; br = br->id.next) {
br->falloff_angle = DEG2RADF(80);
br->flag &= ~(
BRUSH_FLAG_DEPRECATED_1 | BRUSH_FLAG_DEPRECATED_2 |
@@ -1684,7 +1684,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
BRUSH_FRONTFACE_FALLOFF);
}
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
ToolSettings *ts = scene->toolsettings;
for (int i = 0; i < 2; i++) {
VPaint *vp = i ? ts->vpaint : ts->wpaint;
@@ -1699,7 +1699,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
/* Simple deform modifier no longer assumes Z axis (X for bend type).
* Must set previous defaults. */
if (!DNA_struct_elem_find(fd->filesdna, "SimpleDeformModifierData", "char", "deform_axis")) {
- for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_SimpleDeform) {
SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
@@ -1709,7 +1709,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
int preset = scene->r.ffcodecdata.ffmpeg_preset;
if (preset == FFM_PRESET_NONE || preset >= FFM_PRESET_GOOD) {
continue;
@@ -1727,7 +1727,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "ParticleInstanceModifierData", "float", "particle_amount")) {
- for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_ParticleInstance) {
ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
@@ -1740,11 +1740,11 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
-void do_versions_after_linking_270(Main *main)
+void do_versions_after_linking_270(Main *bmain)
{
/* To be added to next subversion bump! */
- if (!MAIN_VERSION_ATLEAST(main, 279, 0)) {
- FOREACH_NODETREE(main, ntree, id) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 279, 0)) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
ntreeSetTypes(NULL, ntree);
for (bNode *node = ntree->nodes.first; node; node = node->next) {
@@ -1756,9 +1756,9 @@ void do_versions_after_linking_270(Main *main)
} FOREACH_NODETREE_END
}
- if (!MAIN_VERSION_ATLEAST(main, 279, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 279, 2)) {
/* B-Bones (bbone_in/out -> bbone_easein/out) + Stepped FMod Frame Start/End fix */
/* if (!DNA_struct_elem_find(fd->filesdna, "Bone", "float", "bbone_easein")) */
- BKE_fcurves_main_cb(main, do_version_bbone_easing_fcurve_fix, NULL);
+ BKE_fcurves_main_cb(bmain, do_version_bbone_easing_fcurve_fix, NULL);
}
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 144b3889d30..eb165efb4f9 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -67,6 +67,7 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "BKE_studiolight.h"
#include "BKE_workspace.h"
#include "BLO_readfile.h"
@@ -96,6 +97,9 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
Scene *scene = screen->scene;
WorkSpace *workspace;
ViewLayer *layer = BLI_findlink(&scene->view_layers, scene->r.actlay);
+ if (screen->temp) {
+ continue;
+ }
if (!layer) {
layer = BKE_view_layer_default_view(scene);
}
@@ -671,15 +675,15 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
scene->basact = NULL;
}
-void do_versions_after_linking_280(Main *main)
+void do_versions_after_linking_280(Main *bmain)
{
bool use_collection_compat_28 = true;
- if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 0)) {
use_collection_compat_28 = false;
/* Convert group layer visibility flags to hidden nested collection. */
- for (Collection *collection = main->collection.first; collection; collection = collection->id.next) {
+ for (Collection *collection = bmain->collection.first; collection; collection = collection->id.next) {
/* Add fake user for all existing groups. */
id_fake_user_set(&collection->id);
@@ -694,25 +698,25 @@ void do_versions_after_linking_280(Main *main)
if (!(ob->lay & collection->layer)) {
if (collection_hidden == NULL) {
- collection_hidden = BKE_collection_add(main, collection, "Hidden");
+ collection_hidden = BKE_collection_add(bmain, collection, "Hidden");
collection_hidden->id.lib = collection->id.lib;
collection_hidden->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
}
- BKE_collection_object_add(main, collection_hidden, ob);
- BKE_collection_object_remove(main, collection, ob, true);
+ BKE_collection_object_add(bmain, collection_hidden, ob);
+ BKE_collection_object_remove(bmain, collection, ob, true);
}
}
}
/* Convert layers to collections. */
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
- do_version_layers_to_collections(main, scene);
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+ do_version_layers_to_collections(bmain, scene);
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 0)) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
/* same render-layer as do_version_workspaces_after_lib_link will activate,
* so same layer as BKE_view_layer_from_workspace_get would return */
ViewLayer *layer = screen->scene->view_layers.first;
@@ -746,14 +750,14 @@ void do_versions_after_linking_280(Main *main)
}
/* New workspace design */
- if (!MAIN_VERSION_ATLEAST(main, 280, 1)) {
- do_version_workspaces_after_lib_link(main);
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 1)) {
+ do_version_workspaces_after_lib_link(bmain);
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 2)) {
/* Cleanup any remaining SceneRenderLayer data for files that were created
* with Blender 2.8 before the SceneRenderLayer > RenderLayer refactor. */
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
for (SceneRenderLayer *srl = scene->r.layers.first; srl; srl = srl->next) {
if (srl->prop) {
IDP_FreeProperty(srl->prop);
@@ -765,10 +769,10 @@ void do_versions_after_linking_280(Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 3)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 3)) {
/* Due to several changes to particle RNA and draw code particles from older files may no longer
* be visible. Here we correct this by setting a default draw size for those files. */
- for (Object *object = main->object.first; object; object = object->id.next) {
+ for (Object *object = bmain->object.first; object; object = object->id.next) {
for (ParticleSystem *psys = object->particlesystem.first; psys; psys = psys->next) {
if (psys->part->draw_size == 0.0f) {
psys->part->draw_size = 0.1f;
@@ -777,8 +781,8 @@ void do_versions_after_linking_280(Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 4)) {
- for (Object *object = main->object.first; object; object = object->id.next) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 4)) {
+ for (Object *object = bmain->object.first; object; object = object->id.next) {
#ifndef VERSION_280_SUBVERSION_4
/* If any object already has an initialized value for
* duplicator_visibility_flag it means we've already doversioned it.
@@ -810,9 +814,9 @@ void do_versions_after_linking_280(Main *main)
}
/* SpaceTime & SpaceLogic removal/replacing */
- if (!MAIN_VERSION_ATLEAST(main, 280, 9)) {
- const wmWindowManager *wm = main->wm.first;
- const Scene *scene = main->scene.first;
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 9)) {
+ const wmWindowManager *wm = bmain->wm.first;
+ const Scene *scene = bmain->scene.first;
if (wm != NULL) {
/* Action editors need a scene for creation. First, update active
@@ -832,7 +836,7 @@ void do_versions_after_linking_280(Main *main)
}
}
if (scene != NULL) {
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *area = screen->areabase.first; area; area = area->next) {
if (ELEM(area->butspacetype, SPACE_TIME, SPACE_LOGIC)) {
/* Areas that were already handled won't be handled again */
@@ -847,39 +851,39 @@ void do_versions_after_linking_280(Main *main)
}
#ifdef USE_COLLECTION_COMPAT_28
- if (use_collection_compat_28 && !MAIN_VERSION_ATLEAST(main, 280, 14)) {
- for (Collection *group = main->collection.first; group; group = group->id.next) {
- do_version_group_collection_to_collection(main, group);
+ if (use_collection_compat_28 && !MAIN_VERSION_ATLEAST(bmain, 280, 14)) {
+ for (Collection *group = bmain->collection.first; group; group = group->id.next) {
+ do_version_group_collection_to_collection(bmain, group);
}
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
- do_version_scene_collection_to_collection(main, scene);
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
+ do_version_scene_collection_to_collection(bmain, scene);
}
}
#endif
}
-void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
+void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
bool use_collection_compat_28 = true;
- if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 0)) {
use_collection_compat_28 = false;
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->r.gauss = 1.5f;
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 1)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 1)) {
if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "bleedexp")) {
- for (Lamp *la = main->lamp.first; la; la = la->id.next) {
+ for (Lamp *la = bmain->lamp.first; la; la = la->id.next) {
la->bleedexp = 2.5f;
}
}
if (!DNA_struct_elem_find(fd->filesdna, "GPUDOFSettings", "float", "ratio")) {
- for (Camera *ca = main->camera.first; ca; ca = ca->id.next) {
+ for (Camera *ca = bmain->camera.first; ca; ca = ca->id.next) {
ca->gpu_dof.ratio = 1.0f;
}
}
@@ -887,7 +891,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
/* MTexPoly now removed. */
if (DNA_struct_find(fd->filesdna, "MTexPoly")) {
const int cd_mtexpoly = 15; /* CD_MTEXPOLY, deprecated */
- for (Mesh *me = main->mesh.first; me; me = me->id.next) {
+ for (Mesh *me = bmain->mesh.first; me; me = me->id.next) {
/* If we have UV's, so this file will have MTexPoly layers too! */
if (me->mloopuv != NULL) {
CustomData_update_typemap(&me->pdata);
@@ -898,9 +902,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 2)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 2)) {
if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "cascade_max_dist")) {
- for (Lamp *la = main->lamp.first; la; la = la->id.next) {
+ for (Lamp *la = bmain->lamp.first; la; la = la->id.next) {
la->cascade_max_dist = 1000.0f;
la->cascade_count = 4;
la->cascade_exponent = 0.8f;
@@ -909,7 +913,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "contact_dist")) {
- for (Lamp *la = main->lamp.first; la; la = la->id.next) {
+ for (Lamp *la = bmain->lamp.first; la; la = la->id.next) {
la->contact_dist = 1.0f;
la->contact_bias = 0.03f;
la->contact_spread = 0.2f;
@@ -918,7 +922,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "LightProbe", "float", "vis_bias")) {
- for (LightProbe *probe = main->lightprobe.first; probe; probe = probe->id.next) {
+ for (LightProbe *probe = bmain->lightprobe.first; probe; probe = probe->id.next) {
probe->vis_bias = 1.0f;
probe->vis_blur = 0.2f;
}
@@ -937,7 +941,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
* Also, metallic node is now unified into the principled node. */
eNTreeDoVersionErrors error = NTREE_DOVERSION_NO_ERROR;
- FOREACH_NODETREE(main, ntree, id) {
+ FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
for (bNode *node = ntree->nodes.first; node; node = node->next) {
if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ &&
@@ -986,7 +990,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
(DNA_struct_elem_find(fd->filesdna, "ViewLayer", "FreestyleConfig", "freestyle_config") == false) &&
DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "view_layers"))
{
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
ViewLayer *view_layer;
for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
view_layer->flag |= VIEW_LAYER_FREESTYLE;
@@ -1001,15 +1005,15 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
#ifdef USE_COLLECTION_COMPAT_28
- if (use_collection_compat_28 && !MAIN_VERSION_ATLEAST(main, 280, 3)) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ if (use_collection_compat_28 && !MAIN_VERSION_ATLEAST(bmain, 280, 3)) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
ViewLayer *view_layer;
for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
do_version_view_layer_visibility(view_layer);
}
}
- for (Collection *group = main->collection.first; group; group = group->id.next) {
+ for (Collection *group = bmain->collection.first; group; group = group->id.next) {
if (group->view_layer != NULL) {
do_version_view_layer_visibility(group->view_layer);
}
@@ -1017,14 +1021,14 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
#endif
- if (!MAIN_VERSION_ATLEAST(main, 280, 6)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 6)) {
if (DNA_struct_elem_find(fd->filesdna, "SpaceOops", "int", "filter") == false) {
bScreen *sc;
ScrArea *sa;
SpaceLink *sl;
/* Update files using invalid (outdated) outlinevis Outliner values. */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
for (sa = sc->areabase.first; sa; sa = sa->next) {
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_OUTLINER) {
@@ -1046,12 +1050,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "LightProbe", "float", "intensity")) {
- for (LightProbe *probe = main->lightprobe.first; probe; probe = probe->id.next) {
+ for (LightProbe *probe = bmain->lightprobe.first; probe; probe = probe->id.next) {
probe->intensity = 1.0f;
}
}
- for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
bConstraint *con, *con_next;
con = ob->constraints.first;
while (con) {
@@ -1066,12 +1070,12 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "Scene", "int", "orientation_index_custom")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->orientation_index_custom = -1;
}
}
- for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) {
+ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) {
for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
@@ -1081,7 +1085,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
/* Assume (demo) files written with 2.8 want to show
* Eevee renders in the viewport. */
- if (MAIN_VERSION_ATLEAST(main, 280, 0)) {
+ if (MAIN_VERSION_ATLEAST(bmain, 280, 0)) {
v3d->drawtype = OB_MATERIAL;
}
}
@@ -1090,20 +1094,20 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 7)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 7)) {
/* Render engine storage moved elsewhere and back during 2.8
* development, we assume any files saved in 2.8 had Eevee set
* as scene render engine. */
- if (MAIN_VERSION_ATLEAST(main, 280, 0)) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ if (MAIN_VERSION_ATLEAST(bmain, 280, 0)) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine));
}
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 8)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 8)) {
/* Blender Internal removal */
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
if (STREQ(scene->r.engine, "BLENDER_RENDER") ||
STREQ(scene->r.engine, "BLENDER_GAME"))
{
@@ -1113,7 +1117,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
scene->r.bake_mode = 0;
}
- for (Tex *tex = main->tex.first; tex; tex = tex->id.next) {
+ for (Tex *tex = bmain->tex.first; tex; tex = tex->id.next) {
/* Removed envmap, pointdensity, voxeldata, ocean textures. */
if (ELEM(tex->type, 10, 14, 15, 16)) {
tex->type = 0;
@@ -1121,10 +1125,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 11)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 11)) {
/* Remove info editor, but only if at the top of the window. */
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
/* Calculate window width/height from screen vertices */
int win_width = 0, win_height = 0;
for (ScrVert *vert = screen->vertbase.first; vert; vert = vert->next) {
@@ -1154,8 +1158,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 11)) {
- for (Lamp *lamp = main->lamp.first; lamp; lamp = lamp->id.next) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 11)) {
+ for (Lamp *lamp = bmain->lamp.first; lamp; lamp = lamp->id.next) {
if (lamp->mode & (1 << 13)) { /* LA_SHAD_RAY */
lamp->mode |= LA_SHADOW;
lamp->mode &= ~(1 << 13);
@@ -1163,9 +1167,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 12)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 12)) {
/* Remove tool property regions. */
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (ELEM(sl->spacetype, SPACE_VIEW3D, SPACE_CLIP)) {
@@ -1185,16 +1189,16 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 13)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 13)) {
/* Initialize specular factor. */
if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "spec_fac")) {
- for (Lamp *la = main->lamp.first; la; la = la->id.next) {
+ for (Lamp *la = bmain->lamp.first; la; la = la->id.next) {
la->spec_fac = 1.0f;
}
}
/* Initialize new view3D options. */
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
@@ -1213,10 +1217,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_find(fd->filesdna, "View3DCursor")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
unit_qt(scene->cursor.rotation);
}
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
@@ -1229,34 +1233,34 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 14)) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 14)) {
if (!DNA_struct_elem_find(fd->filesdna, "Scene", "SceneDisplay", "display")) {
/* Initialize new scene.SceneDisplay */
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
copy_v3_v3(scene->display.light_direction, (float[3]){-M_SQRT1_3, -M_SQRT1_3, M_SQRT1_3});
}
}
if (!DNA_struct_elem_find(fd->filesdna, "SceneDisplay", "float", "shadow_shift")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->display.shadow_shift = 0.1;
}
}
if (!DNA_struct_elem_find(fd->filesdna, "Object", "ObjectDisplay", "display")) {
/* Initialize new object.ObjectDisplay */
- for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
ob->display.flag = OB_SHOW_SHADOW;
}
}
if (!DNA_struct_elem_find(fd->filesdna, "ToolSettings", "char", "transform_pivot_point")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->toolsettings->transform_pivot_point = V3D_AROUND_CENTER_MEAN;
}
}
if (!DNA_struct_find(fd->filesdna, "SceneEEVEE")) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
/* First set the default for all the properties. */
scene->eevee.gi_diffuse_bounces = 3;
@@ -1438,8 +1442,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
- if (!MAIN_VERSION_ATLEAST(main, 280, 15)) {
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 15)) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->display.matcap_icon = 1;
scene->display.matcap_type = CLAY_MATCAP_NONE;
scene->display.matcap_hue = 0.5f;
@@ -1452,7 +1456,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
scene->display.matcap_ssao_samples = 16;
}
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_OUTLINER) {
@@ -1464,7 +1468,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
switch (scene->toolsettings->snap_mode) {
case 0: scene->toolsettings->snap_mode = SCE_SNAP_MODE_INCREMENT; break;
case 1: scene->toolsettings->snap_mode = SCE_SNAP_MODE_VERTEX ; break;
@@ -1485,7 +1489,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
ParticleSettings *part;
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
part->shape_flag = PART_SHAPE_CLOSE_TIP;
part->shape = 0.0f;
part->rad_root = 1.0f;
@@ -1497,9 +1501,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
{
if (!DNA_struct_elem_find(fd->filesdna, "Material", "float", "roughness")) {
- for (Material *mat = main->mat.first; mat; mat = mat->id.next) {
+ for (Material *mat = bmain->mat.first; mat; mat = mat->id.next) {
if (mat->use_nodes) {
- if (MAIN_VERSION_ATLEAST(main, 280, 0)) {
+ if (MAIN_VERSION_ATLEAST(bmain, 280, 0)) {
mat->roughness = mat->gloss_mir;
}
else {
@@ -1512,7 +1516,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
mat->metallic = mat->ray_mirror;
}
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
@@ -1525,7 +1529,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "xray_alpha")) {
- for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_VIEW3D) {
@@ -1536,5 +1540,58 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "char", "matcap[256]")) {
+ StudioLight *default_matcap = BKE_studiolight_find_first(STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+ /* when loading the internal file is loaded before the matcaps */
+ if (default_matcap) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ BLI_strncpy(v3d->shading.matcap, default_matcap->name, FILE_MAXFILE);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "wireframe_threshold")) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->overlay.wireframe_threshold = 0.5f;
+ }
+ }
+ }
+ }
+ }
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "cavity_valley_factor")) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->shading.cavity_valley_factor = 1.0f;
+ v3d->shading.cavity_ridge_factor = 1.0f;
+ }
+ }
+ }
+ }
+ }
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "bone_selection_alpha")) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->overlay.bone_selection_alpha = 0.5f;
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 9e0c3f3ccdc..bc69b1d99fc 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -483,13 +483,13 @@ void blo_do_version_old_trackto_to_constraints(Object *ob)
ob->track = NULL;
}
-void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
+void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
- if (main->versionfile == 100) {
+ if (bmain->versionfile == 100) {
/* tex->extend and tex->imageflag have changed: */
- Tex *tex = main->tex.first;
+ Tex *tex = bmain->tex.first;
while (tex) {
if (tex->id.tag & LIB_TAG_NEED_LINK) {
@@ -508,9 +508,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 101) {
+ if (bmain->versionfile <= 101) {
/* frame mapping */
- Scene *sce = main->scene.first;
+ Scene *sce = bmain->scene.first;
while (sce) {
sce->r.framapto = 100;
sce->r.images = 100;
@@ -519,9 +519,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 103) {
+ if (bmain->versionfile <= 103) {
/* new variable in object: colbits */
- Object *ob = main->object.first;
+ Object *ob = bmain->object.first;
int a;
while (ob) {
ob->colbits = 0;
@@ -535,9 +535,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 104) {
+ if (bmain->versionfile <= 104) {
/* timeoffs moved */
- Object *ob = main->object.first;
+ Object *ob = bmain->object.first;
while (ob) {
if (ob->transflag & 1) {
ob->transflag -= 1;
@@ -546,8 +546,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 105) {
- Object *ob = main->object.first;
+ if (bmain->versionfile <= 105) {
+ Object *ob = bmain->object.first;
while (ob) {
ob->dupon = 1;
ob->dupoff = 0;
@@ -557,9 +557,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 106) {
+ if (bmain->versionfile <= 106) {
/* mcol changed */
- Mesh *me = main->mesh.first;
+ Mesh *me = bmain->mesh.first;
while (me) {
if (me->mcol)
vcol_to_fcol(me);
@@ -568,9 +568,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
- if (main->versionfile <= 107) {
+ if (bmain->versionfile <= 107) {
Object *ob;
- ob = main->object.first;
+ ob = bmain->object.first;
while (ob) {
if (ob->dt == 0)
ob->dt = OB_SOLID;
@@ -579,9 +579,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
- if (main->versionfile <= 109) {
+ if (bmain->versionfile <= 109) {
/* new variable: gridlines */
- bScreen *sc = main->screen.first;
+ bScreen *sc = bmain->screen.first;
while (sc) {
ScrArea *sa = sc->areabase.first;
while (sa) {
@@ -601,8 +601,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 134) {
- Tex *tex = main->tex.first;
+ if (bmain->versionfile <= 134) {
+ Tex *tex = bmain->tex.first;
while (tex) {
if ((tex->rfac == 0.0f) &&
(tex->gfac == 0.0f) &&
@@ -617,9 +617,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 140) {
+ if (bmain->versionfile <= 140) {
/* r-g-b-fac in texture */
- Tex *tex = main->tex.first;
+ Tex *tex = bmain->tex.first;
while (tex) {
if ((tex->rfac == 0.0f) &&
(tex->gfac == 0.0f) &&
@@ -634,8 +634,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 153) {
- Scene *sce = main->scene.first;
+ if (bmain->versionfile <= 153) {
+ Scene *sce = bmain->scene.first;
while (sce) {
if (sce->r.blurfac == 0.0f)
sce->r.blurfac = 1.0f;
@@ -643,8 +643,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 163) {
- Scene *sce = main->scene.first;
+ if (bmain->versionfile <= 163) {
+ Scene *sce = bmain->scene.first;
while (sce) {
if (sce->r.frs_sec == 0)
sce->r.frs_sec = 25;
@@ -652,16 +652,16 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 164) {
- Mesh *me = main->mesh.first;
+ if (bmain->versionfile <= 164) {
+ Mesh *me = bmain->mesh.first;
while (me) {
me->smoothresh = 30;
me = me->id.next;
}
}
- if (main->versionfile <= 165) {
- Mesh *me = main->mesh.first;
+ if (bmain->versionfile <= 165) {
+ Mesh *me = bmain->mesh.first;
TFace *tface;
int nr;
char *cp;
@@ -687,8 +687,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 169) {
- Mesh *me = main->mesh.first;
+ if (bmain->versionfile <= 169) {
+ Mesh *me = bmain->mesh.first;
while (me) {
if (me->subdiv == 0)
me->subdiv = 1;
@@ -696,8 +696,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 169) {
- bScreen *sc = main->screen.first;
+ if (bmain->versionfile <= 169) {
+ bScreen *sc = bmain->screen.first;
while (sc) {
ScrArea *sa = sc->areabase.first;
while (sa) {
@@ -715,8 +715,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 170) {
- Object *ob = main->object.first;
+ if (bmain->versionfile <= 170) {
+ Object *ob = bmain->object.first;
PartEff *paf;
while (ob) {
paf = blo_do_version_give_parteff_245(ob);
@@ -729,8 +729,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 171) {
- bScreen *sc = main->screen.first;
+ if (bmain->versionfile <= 171) {
+ bScreen *sc = bmain->screen.first;
while (sc) {
ScrArea *sa = sc->areabase.first;
while (sa) {
@@ -748,9 +748,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 173) {
+ if (bmain->versionfile <= 173) {
int a, b;
- Mesh *me = main->mesh.first;
+ Mesh *me = bmain->mesh.first;
while (me) {
if (me->tface) {
TFace *tface = me->tface;
@@ -765,10 +765,10 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 204) {
+ if (bmain->versionfile <= 204) {
bSound *sound;
- sound = main->sound.first;
+ sound = bmain->sound.first;
while (sound) {
if (sound->volume < 0.01f) {
sound->volume = 1.0f;
@@ -777,11 +777,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 212) {
+ if (bmain->versionfile <= 212) {
bSound *sound;
Mesh *me;
- sound = main->sound.first;
+ sound = bmain->sound.first;
while (sound) {
sound->max_gain = 1.0;
sound->min_gain = 0.0;
@@ -800,7 +800,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
* it a subsurf, and reset the subdiv level because subsurf
* takes a lot more work to calculate.
*/
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
if (me->flag & ME_SMESH) {
me->flag &= ~ME_SMESH;
me->flag |= ME_SUBSURF;
@@ -816,14 +816,14 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 220) {
+ if (bmain->versionfile <= 220) {
Mesh *me;
/* Began using alpha component of vertex colors, but
* old file vertex colors are undefined, reset them
* to be fully opaque. -zr
*/
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
if (me->mcol) {
int i;
@@ -848,22 +848,22 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 223) {
+ if (bmain->versionfile <= 223) {
VFont *vf;
- for (vf = main->vfont.first; vf; vf = vf->id.next) {
+ for (vf = bmain->vfont.first; vf; vf = vf->id.next) {
if (STREQ(vf->name + strlen(vf->name) - 6, ".Bfont")) {
strcpy(vf->name, FO_BUILTIN_NAME);
}
}
}
- if (main->versionfile <= 224) {
+ if (bmain->versionfile <= 224) {
bSound *sound;
Scene *sce;
Mesh *me;
bScreen *sc;
- for (sound = main->sound.first; sound; sound = sound->id.next) {
+ for (sound = bmain->sound.first; sound; sound = sound->id.next) {
if (sound->packedfile) {
if (sound->newpackedfile == NULL) {
sound->newpackedfile = sound->packedfile;
@@ -872,17 +872,17 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
/* Make sure that old subsurf meshes don't have zero subdivision level for rendering */
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
if ((me->flag & ME_SUBSURF) && (me->subdivr == 0))
me->subdivr = me->subdiv;
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
sce->r.stereomode = 1; // no stereo
}
/* some oldfile patch, moved from set_func_space */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -898,7 +898,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 227) {
+ if (bmain->versionfile <= 227) {
Scene *sce;
bScreen *sc;
Object *ob;
@@ -906,7 +906,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
/* As of now, this insures that the transition from the old Track system
* to the new full constraint Track is painless for everyone. - theeth
*/
- ob = main->object.first;
+ ob = bmain->object.first;
while (ob) {
ListBase *list;
@@ -949,13 +949,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
ob = ob->id.next;
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
sce->audio.mixrate = 48000;
sce->audio.flag |= AUDIO_SCRUB;
}
/* patch for old wrong max view2d settings, allows zooming out more */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -975,14 +975,14 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 228) {
+ if (bmain->versionfile <= 228) {
bScreen *sc;
Object *ob;
/* As of now, this insures that the transition from the old Track system
* to the new full constraint Track is painless for everyone.
*/
- ob = main->object.first;
+ ob = bmain->object.first;
while (ob) {
ListBase *list;
@@ -1022,7 +1022,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
/* convert old mainb values for new button panels */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -1089,19 +1089,17 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
* check apart from the do_versions()
*/
- if (main->versionfile <= 230) {
+ if (bmain->versionfile <= 230) {
bScreen *sc;
/* new variable blockscale, for panels in any area */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
for (sl = sa->spacedata.first; sl; sl = sl->next) {
- if (sl->blockscale == 0.0f)
- sl->blockscale = 0.7f;
/* added: 5x better zoom in for action */
if (sl->spacetype == SPACE_ACTION) {
SpaceAction *sac = (SpaceAction *)sl;
@@ -1112,9 +1110,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 231) {
+ if (bmain->versionfile <= 231) {
/* new bit flags for showing/hiding grid floor and axes */
- bScreen *sc = main->screen.first;
+ bScreen *sc = bmain->screen.first;
while (sc) {
ScrArea *sa = sc->areabase.first;
@@ -1139,8 +1137,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 231) {
- bScreen *sc = main->screen.first;
+ if (bmain->versionfile <= 231) {
+ bScreen *sc = bmain->screen.first;
/* new bit flags for showing/hiding grid floor and axes */
@@ -1167,9 +1165,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 232) {
- Tex *tex = main->tex.first;
- World *wrld = main->world.first;
+ if (bmain->versionfile <= 232) {
+ Tex *tex = bmain->tex.first;
+ World *wrld = bmain->world.first;
bScreen *sc;
while (tex) {
@@ -1206,14 +1204,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
/* new variable blockscale, for panels in any area, do again because new
* areas didnt initialize it to 0.7 yet
*/
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
for (sl = sa->spacedata.first; sl; sl = sl->next) {
- if (sl->blockscale == 0.0f)
- sl->blockscale = 0.7f;
-
/* added: 5x better zoom in for nla */
if (sl->spacetype == SPACE_NLA) {
SpaceNla *snla = (SpaceNla *) sl;
@@ -1224,10 +1219,10 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 233) {
+ if (bmain->versionfile <= 233) {
bScreen *sc;
- Material *ma = main->mat.first;
- /* Object *ob = main->object.first; */
+ Material *ma = bmain->mat.first;
+ /* Object *ob = bmain->object.first; */
while (ma) {
if (ma->pr_lamp == 0)
@@ -1235,7 +1230,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
ma = ma->id.next;
}
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1249,10 +1244,10 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 234) {
+ if (bmain->versionfile <= 234) {
bScreen *sc;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1271,9 +1266,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 235) {
- Tex *tex = main->tex.first;
- Scene *sce = main->scene.first;
+ if (bmain->versionfile <= 235) {
+ Tex *tex = bmain->tex.first;
+ Scene *sce = bmain->scene.first;
Sequence *seq;
Editing *ed;
@@ -1297,9 +1292,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 236) {
+ if (bmain->versionfile <= 236) {
Object *ob;
- Camera *cam = main->camera.first;
+ Camera *cam = bmain->camera.first;
while (cam) {
if (cam->ortho_scale == 0.0f) {
@@ -1313,7 +1308,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
/* set time line var */
/* softbody init new vars */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->soft) {
if (ob->soft->defgoal == 0.0f)
ob->soft->defgoal = 0.7f;
@@ -1336,20 +1331,20 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 237) {
+ if (bmain->versionfile <= 237) {
bArmature *arm;
bConstraint *con;
Object *ob;
Bone *bone;
/* armature recode checks */
- for (arm = main->armature.first; arm; arm = arm->id.next) {
+ for (arm = bmain->armature.first; arm; arm = arm->id.next) {
BKE_armature_where_is(arm);
for (bone = arm->bonebase.first; bone; bone = bone->next)
do_version_bone_head_tail_237(bone);
}
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->parent) {
Object *parent = blo_do_versions_newlibadr(fd, lib, ob->parent);
if (parent && parent->type == OB_LATTICE)
@@ -1359,7 +1354,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
/* btw. armature_rebuild_pose is further only called on leave editmode */
if (ob->type == OB_ARMATURE) {
if (ob->pose)
- BKE_pose_tag_recalc(main, ob->pose);
+ BKE_pose_tag_recalc(bmain, ob->pose);
/* cannot call stuff now (pointers!), done in setup_app_data */
ob->id.recalc |= ID_RECALC_ALL;
@@ -1410,13 +1405,13 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 238) {
+ if (bmain->versionfile <= 238) {
Lattice *lt;
Object *ob;
bArmature *arm;
Mesh *me;
Key *key;
- Scene *sce = main->scene.first;
+ Scene *sce = bmain->scene.first;
while (sce) {
if (sce->toolsettings == NULL) {
@@ -1426,7 +1421,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
sce = sce->id.next;
}
- for (lt = main->latt.first; lt; lt = lt->id.next) {
+ for (lt = bmain->latt.first; lt; lt = lt->id.next) {
if (lt->fu == 0.0f && lt->fv == 0.0f && lt->fw == 0.0f) {
calc_lat_fudu(lt->flag, lt->pntsu, &lt->fu, &lt->du);
calc_lat_fudu(lt->flag, lt->pntsv, &lt->fv, &lt->dv);
@@ -1434,7 +1429,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
PartEff *paf;
@@ -1483,7 +1478,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
data->rootbone = -1;
/* update_pose_etc handles rootbone == -1 */
- BKE_pose_tag_recalc(main, ob->pose);
+ BKE_pose_tag_recalc(bmain, ob->pose);
}
}
}
@@ -1501,12 +1496,12 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (arm = main->armature.first; arm; arm = arm->id.next) {
+ for (arm = bmain->armature.first; arm; arm = arm->id.next) {
bone_version_238(&arm->bonebase);
arm->deformflag |= ARM_DEF_VGROUP;
}
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
if (!me->medge) {
BKE_mesh_calc_edges_legacy(me, true); /* true = use mface->edcode */
}
@@ -1515,7 +1510,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (key = main->key.first; key; key = key->id.next) {
+ for (key = bmain->key.first; key; key = key->id.next) {
KeyBlock *kb;
int index = 1;
@@ -1534,15 +1529,15 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 239) {
+ if (bmain->versionfile <= 239) {
bArmature *arm;
Object *ob;
- Scene *sce = main->scene.first;
- Camera *cam = main->camera.first;
+ Scene *sce = bmain->scene.first;
+ Camera *cam = bmain->camera.first;
int set_passepartout = 0;
/* deformflag is local in modifier now */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
for (md = ob->modifiers.first; md; md = md->next) {
@@ -1558,7 +1553,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
/* updating stepsize for ghost drawing */
- for (arm = main->armature.first; arm; arm = arm->id.next) {
+ for (arm = bmain->armature.first; arm; arm = arm->id.next) {
if (arm->ghostsize == 0)
arm->ghostsize = 1;
bone_version_239(&arm->bonebase);
@@ -1587,7 +1582,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 241) {
+ if (bmain->versionfile <= 241) {
Object *ob;
Scene *sce;
Lamp *la;
@@ -1595,12 +1590,12 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
bNodeTree *ntree;
/* updating layers still */
- for (arm = main->armature.first; arm; arm = arm->id.next) {
+ for (arm = bmain->armature.first; arm; arm = arm->id.next) {
bone_version_239(&arm->bonebase);
if (arm->layer == 0)
arm->layer = 1;
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->audio.mixrate == 0)
sce->audio.mixrate = 48000;
@@ -1627,15 +1622,15 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
ntree_version_241(ntree);
- for (la = main->lamp.first; la; la = la->id.next)
+ for (la = bmain->lamp.first; la; la = la->id.next)
if (la->buffers == 0)
la->buffers = 1;
/* for empty drawsize and drawtype */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->empty_drawsize == 0.0f) {
ob->empty_drawtype = OB_ARROWS;
ob->empty_drawsize = 1.0;
@@ -1643,9 +1638,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
/* during 2.41 images with this name were used for viewer node output, lets fix that */
- if (main->versionfile == 241) {
+ if (bmain->versionfile == 241) {
Image *ima;
- for (ima = main->image.first; ima; ima = ima->id.next) {
+ for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (STREQ(ima->name, "Compositor")) {
strcpy(ima->id.name + 2, "Viewer Node");
strcpy(ima->name, "Viewer Node");
@@ -1654,7 +1649,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 242) {
+ if (bmain->versionfile <= 242) {
Scene *sce;
bScreen *sc;
Object *ob;
@@ -1668,7 +1663,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
bNodeTree *ntree;
int a;
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
sa = sc->areabase.first;
while (sa) {
@@ -1685,7 +1680,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->toolsettings->select_thresh == 0.0f)
sce->toolsettings->select_thresh = 0.01f;
@@ -1699,11 +1694,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
ntree_version_242(sce->nodetree);
}
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
ntree_version_242(ntree);
/* add default radius values to old curve points */
- for (cu = main->curve.first; cu; cu = cu->id.next) {
+ for (cu = bmain->curve.first; cu; cu = cu->id.next) {
for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu) {
if (nu->bezt) {
@@ -1722,7 +1717,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
ListBase *list;
list = &ob->constraints;
@@ -1810,25 +1805,25 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
- for (ma = main->mat.first; ma; ma = ma->id.next) {
+ for (ma = bmain->mat.first; ma; ma = ma->id.next) {
if (ma->nodetree)
ntree_version_242(ma->nodetree);
}
- for (me = main->mesh.first; me; me = me->id.next)
+ for (me = bmain->mesh.first; me; me = me->id.next)
customdata_version_242(me);
- for (collection = main->collection.first; collection; collection = collection->id.next)
+ for (collection = bmain->collection.first; collection; collection = collection->id.next)
if (collection->layer == 0)
collection->layer = (1 << 20) - 1;
/* now, subversion control! */
- if (main->subversionfile < 3) {
+ if (bmain->subversionfile < 3) {
Image *ima;
Tex *tex;
/* Image refactor initialize */
- for (ima = main->image.first; ima; ima = ima->id.next) {
+ for (ima = bmain->image.first; ima; ima = ima->id.next) {
ima->source = IMA_SRC_FILE;
ima->type = IMA_TYPE_IMAGE;
@@ -1845,7 +1840,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (tex = main->tex.first; tex; tex = tex->id.next) {
+ for (tex = bmain->tex.first; tex; tex = tex->id.next) {
if (tex->type == TEX_IMAGE && tex->ima) {
ima = blo_do_versions_newlibadr(fd, lib, tex->ima);
if (tex->imaflag & TEX_ANIM5_)
@@ -1861,17 +1856,17 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
tex->iuser.sfra = tex->sfra;
tex->iuser.cycl = (tex->imaflag & TEX_ANIMCYCLIC_)!=0;
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree)
do_version_ntree_242_2(sce->nodetree);
}
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
do_version_ntree_242_2(ntree);
- for (ma = main->mat.first; ma; ma = ma->id.next)
+ for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->nodetree)
do_version_ntree_242_2(ma->nodetree);
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
@@ -1884,8 +1879,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->subversionfile < 4) {
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ if (bmain->subversionfile < 4) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
sce->r.bake_mode = 1; /* prevent to include render stuff here */
sce->r.bake_filter = 16;
sce->r.bake_flag = R_BAKE_CLEAR;
@@ -1893,8 +1888,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 243) {
- Object *ob = main->object.first;
+ if (bmain->versionfile <= 243) {
+ Object *ob = bmain->object.first;
for (; ob; ob = ob->id.next) {
bDeformGroup *curdef;
@@ -1906,7 +1901,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 243 || main->subversionfile < 1) {
+ if (bmain->versionfile < 243 || bmain->subversionfile < 1) {
ModifierData *md;
/* translate old mirror modifier axis values to new flags */
@@ -1933,20 +1928,20 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
/* render layer added, this is not the active layer */
- if (main->versionfile <= 243 || main->subversionfile < 2) {
+ if (bmain->versionfile <= 243 || bmain->subversionfile < 2) {
Mesh *me;
- for (me = main->mesh.first; me; me = me->id.next)
+ for (me = bmain->mesh.first; me; me = me->id.next)
customdata_version_243(me);
}
}
- if (main->versionfile <= 244) {
+ if (bmain->versionfile <= 244) {
bScreen *sc;
- if (main->versionfile != 244 || main->subversionfile < 2) {
+ if (bmain->versionfile != 244 || bmain->subversionfile < 2) {
/* correct older action editors - incorrect scrolling */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
sa = sc->areabase.first;
while (sa) {
@@ -1969,7 +1964,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile <= 245) {
+ if (bmain->versionfile <= 245) {
Scene *sce;
Object *ob;
Image *ima;
@@ -1983,10 +1978,10 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
ParticleSystem *psys;
/* unless the file was created 2.44.3 but not 2.45, update the constraints */
- if (!(main->versionfile == 244 && main->subversionfile == 3) &&
- ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile == 0)) )
+ if (!(bmain->versionfile == 244 && bmain->subversionfile == 3) &&
+ ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile == 0)) )
{
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ListBase *list;
list = &ob->constraints;
@@ -2053,16 +2048,16 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
/* fix all versions before 2.45 */
- if (main->versionfile != 245) {
+ if (bmain->versionfile != 245) {
/* repair preview from 242 - 244*/
- for (ima = main->image.first; ima; ima = ima->id.next) {
+ for (ima = bmain->image.first; ima; ima = ima->id.next) {
ima->preview = NULL;
}
}
/* add point caches */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->soft && !ob->soft->pointcache)
ob->soft->pointcache = BKE_ptcache_add(&ob->soft->ptcaches);
@@ -2090,7 +2085,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
/* Copy over old per-level multires vertex data
* into a single vertex array in struct Multires */
- for (me = main->mesh.first; me; me = me->id.next) {
+ for (me = bmain->mesh.first; me; me = me->id.next) {
if (me->mr && !me->mr->verts) {
MultiresLevel *lvl = me->mr->levels.last;
if (lvl) {
@@ -2105,8 +2100,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile != 245 || main->subversionfile < 1) {
- for (la = main->lamp.first; la; la = la->id.next) {
+ if (bmain->versionfile != 245 || bmain->subversionfile < 1) {
+ for (la = bmain->lamp.first; la; la = la->id.next) {
la->falloff_type = LA_FALLOFF_INVLINEAR;
if (la->curfalloff == NULL) {
@@ -2116,18 +2111,18 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (ma = main->mat.first; ma; ma = ma->id.next) {
+ for (ma = bmain->mat.first; ma; ma = ma->id.next) {
if (ma->gloss_mir == 0.0f) {
ma->gloss_mir = 1.0f;
}
}
- for (part = main->particle.first; part; part = part->id.next) {
+ for (part = bmain->particle.first; part; part = part->id.next) {
if (part->ren_child_nbr == 0)
part->ren_child_nbr = part->child_nbr;
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree)
ntree_version_245(fd, lib, sce->nodetree);
@@ -2137,18 +2132,18 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next)
ntree_version_245(fd, lib, ntree);
/* fix for temporary flag changes during 245 cycle */
- for (ima = main->image.first; ima; ima = ima->id.next) {
+ for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (ima->flag & IMA_OLD_PREMUL) {
ima->flag &= ~IMA_OLD_PREMUL;
ima->alpha_mode = IMA_ALPHA_STRAIGHT;
}
}
- for (tex = main->tex.first; tex; tex = tex->id.next) {
+ for (tex = bmain->tex.first; tex; tex = tex->id.next) {
if (tex->iuser.flag & IMA_OLD_PREMUL) {
tex->iuser.flag &= ~IMA_OLD_PREMUL;
}
@@ -2161,24 +2156,24 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 2)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 2)) {
Image *ima;
/* initialize 1:1 Aspect */
- for (ima = main->image.first; ima; ima = ima->id.next) {
+ for (ima = bmain->image.first; ima; ima = ima->id.next) {
ima->aspx = ima->aspy = 1.0f;
}
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 4)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 4)) {
bArmature *arm;
ModifierData *md;
Object *ob;
- for (arm = main->armature.first; arm; arm = arm->id.next)
+ for (arm = bmain->armature.first; arm; arm = arm->id.next)
arm->deformflag |= ARM_DEF_B_BONE_REST;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
for (md = ob->modifiers.first; md; md = md->next) {
if (md->type == eModifierType_Armature)
((ArmatureModifierData*) md)->deformflag |= ARM_DEF_B_BONE_REST;
@@ -2186,10 +2181,10 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 5)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 5)) {
/* foreground color needs to be something other then black */
Scene *sce;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
sce->r.fg_stamp[0] = sce->r.fg_stamp[1] = sce->r.fg_stamp[2] = 0.8f;
sce->r.fg_stamp[3] = 1.0f; /* don't use text alpha yet */
sce->r.bg_stamp[3] = 0.25f; /* make sure the background has full alpha */
@@ -2197,21 +2192,21 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 6)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 6)) {
Scene *sce;
/* fix frs_sec_base */
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->r.frs_sec_base == 0) {
sce->r.frs_sec_base = 1;
}
}
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 7)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 7)) {
Object *ob;
bPoseChannel *pchan;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->pose) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
do_version_constraints_245(&pchan->constraints);
@@ -2236,12 +2231,12 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 8)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 8)) {
Scene *sce;
Object *ob;
PartEff *paf = NULL;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->soft && ob->soft->keys) {
SoftBody *sb = ob->soft;
int k;
@@ -2268,7 +2263,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
psys->pointcache = BKE_ptcache_add(&psys->ptcaches);
- part = psys->part = BKE_particlesettings_add(main, "ParticleSettings");
+ part = psys->part = BKE_particlesettings_add(bmain, "ParticleSettings");
/* needed for proper libdata lookup */
blo_do_versions_oldnewmap_insert(fd->libmap, psys->part, psys->part, 0);
@@ -2348,7 +2343,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
/* dupliobjects */
if (ob->transflag & OB_DUPLIVERTS) {
- Object *dup = main->object.first;
+ Object *dup = bmain->object.first;
for (; dup; dup = dup->id.next) {
if (ob == blo_do_versions_newlibadr(fd, lib, dup->parent)) {
@@ -2376,7 +2371,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
ParticleEditSettings *pset = &sce->toolsettings->particle;
int a;
@@ -2398,20 +2393,20 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 10)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 10)) {
Object *ob;
/* dupliface scale */
- for (ob = main->object.first; ob; ob = ob->id.next)
+ for (ob = bmain->object.first; ob; ob = ob->id.next)
ob->dupfacesca = 1.0f;
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 11)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 11)) {
Object *ob;
bActionStrip *strip;
/* nla-strips - scale */
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
for (strip = ob->nlastrips.first; strip; strip = strip->next) {
float length, actlength, repeat;
@@ -2436,11 +2431,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 14)) {
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 14)) {
Scene *sce;
Sequence *seq;
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
SEQ_BEGIN (sce->ed, seq)
{
if (seq->blend_mode == 0)
@@ -2451,39 +2446,39 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
/* fix broken group lengths in id properties */
- if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 15)) {
- idproperties_fix_group_lengths(main->scene);
- idproperties_fix_group_lengths(main->library);
- idproperties_fix_group_lengths(main->object);
- idproperties_fix_group_lengths(main->mesh);
- idproperties_fix_group_lengths(main->curve);
- idproperties_fix_group_lengths(main->mball);
- idproperties_fix_group_lengths(main->mat);
- idproperties_fix_group_lengths(main->tex);
- idproperties_fix_group_lengths(main->image);
- idproperties_fix_group_lengths(main->latt);
- idproperties_fix_group_lengths(main->lamp);
- idproperties_fix_group_lengths(main->camera);
- idproperties_fix_group_lengths(main->ipo);
- idproperties_fix_group_lengths(main->key);
- idproperties_fix_group_lengths(main->world);
- idproperties_fix_group_lengths(main->screen);
- idproperties_fix_group_lengths(main->vfont);
- idproperties_fix_group_lengths(main->text);
- idproperties_fix_group_lengths(main->sound);
- idproperties_fix_group_lengths(main->collection);
- idproperties_fix_group_lengths(main->armature);
- idproperties_fix_group_lengths(main->action);
- idproperties_fix_group_lengths(main->nodetree);
- idproperties_fix_group_lengths(main->brush);
- idproperties_fix_group_lengths(main->particle);
+ if ((bmain->versionfile < 245) || (bmain->versionfile == 245 && bmain->subversionfile < 15)) {
+ idproperties_fix_group_lengths(bmain->scene);
+ idproperties_fix_group_lengths(bmain->library);
+ idproperties_fix_group_lengths(bmain->object);
+ idproperties_fix_group_lengths(bmain->mesh);
+ idproperties_fix_group_lengths(bmain->curve);
+ idproperties_fix_group_lengths(bmain->mball);
+ idproperties_fix_group_lengths(bmain->mat);
+ idproperties_fix_group_lengths(bmain->tex);
+ idproperties_fix_group_lengths(bmain->image);
+ idproperties_fix_group_lengths(bmain->latt);
+ idproperties_fix_group_lengths(bmain->lamp);
+ idproperties_fix_group_lengths(bmain->camera);
+ idproperties_fix_group_lengths(bmain->ipo);
+ idproperties_fix_group_lengths(bmain->key);
+ idproperties_fix_group_lengths(bmain->world);
+ idproperties_fix_group_lengths(bmain->screen);
+ idproperties_fix_group_lengths(bmain->vfont);
+ idproperties_fix_group_lengths(bmain->text);
+ idproperties_fix_group_lengths(bmain->sound);
+ idproperties_fix_group_lengths(bmain->collection);
+ idproperties_fix_group_lengths(bmain->armature);
+ idproperties_fix_group_lengths(bmain->action);
+ idproperties_fix_group_lengths(bmain->nodetree);
+ idproperties_fix_group_lengths(bmain->brush);
+ idproperties_fix_group_lengths(bmain->particle);
}
/* convert fluids to modifier */
- if (main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 246 || (bmain->versionfile == 246 && bmain->subversionfile < 1)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->fluidsimSettings) {
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifier_new(eModifierType_Fluidsim);
BLI_addhead(&ob->modifiers, (ModifierData *)fluidmd);
@@ -2500,20 +2495,20 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 246 || (main->versionfile == 246 && main->subversionfile < 1)) {
+ if (bmain->versionfile < 246 || (bmain->versionfile == 246 && bmain->subversionfile < 1)) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->pd && (ob->pd->forcefield == PFIELD_WIND))
ob->pd->f_noise = 0.0f;
}
}
/* set the curve radius interpolation to 2.47 default - easy */
- if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 6)) {
+ if (bmain->versionfile < 247 || (bmain->versionfile == 247 && bmain->subversionfile < 6)) {
Curve *cu;
Nurb *nu;
- for (cu = main->curve.first; cu; cu = cu->id.next) {
+ for (cu = bmain->curve.first; cu; cu = cu->id.next) {
for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu) {
nu->radius_interp = 3;
@@ -2531,21 +2526,21 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
}
- if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 2)) {
+ if (bmain->versionfile < 248 || (bmain->versionfile == 248 && bmain->subversionfile < 2)) {
Scene *sce;
/* Note, these will need to be added for painting */
- for (sce = main->scene.first; sce; sce = sce->id.next) {
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
sce->toolsettings->imapaint.seam_bleed = 2;
sce->toolsettings->imapaint.normal_angle = 80;
}
}
- if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 3)) {
+ if (bmain->versionfile < 248 || (bmain->versionfile == 248 && bmain->subversionfile < 3)) {
bScreen *sc;
/* adjust default settings for Animation Editors */
- for (sc = main->screen.first; sc; sc = sc->id.next) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -2580,17 +2575,17 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
}
/* correct introduce of seed for wind force */
- if (main->versionfile < 249 && main->subversionfile < 1) {
+ if (bmain->versionfile < 249 && bmain->subversionfile < 1) {
Object *ob;
- for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->pd)
ob->pd->seed = ((unsigned int)(ceil(PIL_check_seconds_timer())) + 1) % 128;
}
}
- if (main->versionfile < 249 && main->subversionfile < 2) {
- Scene *sce = main->scene.first;
+ if (bmain->versionfile < 249 && bmain->subversionfile < 2) {
+ Scene *sce = bmain->scene.first;
Sequence *seq;
Editing *ed;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index de1699e24b7..6abcf6cfa02 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2762,14 +2762,19 @@ static void write_soops(WriteData *wd, SpaceOops *so)
}
}
+static void write_panel_list(WriteData *wd, ListBase *lb)
+{
+ for (Panel *pa = lb->first; pa; pa = pa->next) {
+ writestruct(wd, DATA, Panel, 1, pa);
+ write_panel_list(wd, &pa->children);
+ }
+}
+
static void write_area_regions(WriteData *wd, ScrArea *area)
{
for (ARegion *region = area->regionbase.first; region; region = region->next) {
write_region(wd, region, area->spacetype);
-
- for (Panel *pa = region->panels.first; pa; pa = pa->next) {
- writestruct(wd, DATA, Panel, 1, pa);
- }
+ write_panel_list(wd, &region->panels);
for (PanelCategoryStack *pc_act = region->panels_category_active.first; pc_act; pc_act = pc_act->next) {
writestruct(wd, DATA, PanelCategoryStack, 1, pc_act);
@@ -4088,7 +4093,7 @@ bool BLO_write_file(
* we should not have any relative paths, but if there
* is somehow, an invalid or empty G.main->name it will
* print an error, don't try make the absolute in this case. */
- BKE_bpath_absolute_convert(mainvar, G.main->name, NULL);
+ BKE_bpath_absolute_convert(mainvar, BKE_main_blendfile_path_from_global(), NULL);
}
}
}
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index bec2c7a1f45..10e2892c5a5 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -119,7 +119,7 @@ typedef struct BMEdge {
/* the list of loops around the edge (use l->radial_prev/next)
* to access the other loops using the edge */
struct BMLoop *l;
-
+
/* disk cycle pointers
* relative data: d1 indicates indicates the next/prev edge around vertex v1 and d2 does the same for v2 */
BMDiskLink v1_disk_link, v2_disk_link;
@@ -229,7 +229,7 @@ typedef struct BMesh {
int toolflag_index;
struct BMOperator *currentop;
-
+
CustomData vdata, edata, ldata, pdata;
#ifdef USE_BMESH_HOLES
@@ -241,10 +241,10 @@ typedef struct BMesh {
* make sure they're in sync!
* Only use when the edit mesh cant be accessed - campbell */
short selectmode;
-
+
/* ID of the shape key this bmesh came from */
int shapenr;
-
+
int totflags;
ListBase selected;
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index f8ecbe1756b..1b300b24808 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -712,7 +712,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
/* safety check */
BLI_assert(i == bm_old->totvert);
-
+
BM_ITER_MESH_INDEX (e, &iter, bm_old, BM_EDGES_OF_MESH, i) {
e_new = BM_edge_create(bm_new,
vtable[BM_elem_index_get(e->v1)],
@@ -730,7 +730,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
/* safety check */
BLI_assert(i == bm_old->totedge);
-
+
BM_ITER_MESH_INDEX (f, &iter, bm_old, BM_FACES_OF_MESH, i) {
BM_elem_index_set(f, i); /* set_inline */
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 7e35866887d..c6836187eee 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -158,7 +158,7 @@ BMEdge *BM_edge_create(
if ((create_flag & BM_CREATE_NO_DOUBLE) && (e = BM_edge_exists(v1, v2)))
return e;
-
+
e = BLI_mempool_alloc(bm->epool);
@@ -286,7 +286,7 @@ static BMLoop *bm_face_boundary_add(
BMLoopList *lst = BLI_mempool_calloc(bm->looplistpool);
#endif
BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL /* starte->l */, create_flag);
-
+
bmesh_radial_loop_append(starte, l);
#ifdef USE_BMESH_HOLES
@@ -295,7 +295,7 @@ static BMLoop *bm_face_boundary_add(
#else
f->l_first = l;
#endif
-
+
return l;
}
@@ -330,7 +330,7 @@ BMFace *BM_face_copy(
do {
if (copy_edges) {
BMVert *v1, *v2;
-
+
if (l_iter->e->v1 == verts[i]) {
v1 = verts[i];
v2 = verts[(i + 1) % f->len];
@@ -339,7 +339,7 @@ BMFace *BM_face_copy(
v2 = verts[i];
v1 = verts[(i + 1) % f->len];
}
-
+
edges[i] = BM_edge_create(bm_dst, v1, v2, l_iter->e, BM_CREATE_NOP);
}
else {
@@ -347,11 +347,11 @@ BMFace *BM_face_copy(
}
i++;
} while ((l_iter = l_iter->next) != l_first);
-
+
f_copy = BM_face_create(bm_dst, verts, edges, f->len, NULL, BM_CREATE_SKIP_CD);
-
+
BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy);
-
+
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
l_copy = BM_FACE_FIRST_LOOP(f_copy);
do {
@@ -463,12 +463,12 @@ BMFace *BM_face_create(
lastl->next = l;
lastl = l;
}
-
+
startl->prev = lastl;
lastl->next = startl;
-
+
f->len = len;
-
+
if (!(create_flag & BM_CREATE_SKIP_CD)) {
if (f_example) {
BM_elem_attrs_copy(bm, bm, f_example, f);
@@ -563,7 +563,7 @@ int bmesh_elem_check(void *element, const char htype)
if (head->htype != htype)
return IS_WRONG_TYPE;
-
+
switch (htype) {
case BM_VERT:
{
@@ -830,12 +830,12 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
BMLoop *l_iter;
BMLoop *l_first;
int i = 0;
-
+
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
edges[i++] = l_iter->e;
} while ((l_iter = l_iter->next) != l_first);
-
+
for (i = 0; i < f->len; i++) {
BM_edge_kill(bm, edges[i]);
}
@@ -851,12 +851,12 @@ void BM_face_verts_kill(BMesh *bm, BMFace *f)
BMLoop *l_iter;
BMLoop *l_first;
int i = 0;
-
+
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
verts[i++] = l_iter->v;
} while ((l_iter = l_iter->next) != l_first);
-
+
for (i = 0; i < f->len; i++) {
BM_vert_kill(bm, verts[i]);
}
@@ -979,7 +979,7 @@ void BM_edge_kill(BMesh *bm, BMEdge *e)
bmesh_disk_edge_remove(e, e->v1);
bmesh_disk_edge_remove(e, e->v2);
-
+
bm_kill_only_edge(bm, e);
}
@@ -1159,11 +1159,11 @@ static bool bm_vert_is_manifold_flagged(BMVert *v, const char api_flag)
if (!l) {
return false;
}
-
+
if (BM_edge_is_boundary(l->e)) {
return false;
}
-
+
do {
if (!BM_ELEM_API_FLAG_TEST(l->f, api_flag))
return false;
@@ -1361,7 +1361,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
BM_face_kill(bm, faces[i]);
}
}
-
+
BLI_array_free(edges);
BLI_array_free(deledges);
BLI_array_free(delverts);
@@ -1562,7 +1562,7 @@ BMFace *bmesh_kernel_split_face_make_edge(
BM_CHECK_ELEMENT(e);
BM_CHECK_ELEMENT(f);
BM_CHECK_ELEMENT(f2);
-
+
return f2;
}
@@ -1664,7 +1664,7 @@ BMVert *bmesh_kernel_split_edge_make_vert(BMesh *bm, BMVert *tv, BMEdge *e, BMEd
is_first = false;
l->radial_next = l->radial_prev = NULL;
}
-
+
bmesh_radial_loop_append(l_new->e, l_new);
bmesh_radial_loop_append(l->e, l);
}
@@ -1784,7 +1784,7 @@ BMEdge *bmesh_kernel_join_edge_kill_vert(
if (BM_vert_in_edge(e_kill, v_kill) == 0) {
return NULL;
}
-
+
if (bmesh_disk_count_at_most(v_kill, 3) == 2) {
#ifndef NDEBUG
int valence1, valence2;
@@ -2122,10 +2122,10 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
/* join the two loop */
l_f1->prev->next = l_f2->next;
l_f2->next->prev = l_f1->prev;
-
+
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 (BM_FACE_FIRST_LOOP(f1) == l_f1)
BM_FACE_FIRST_LOOP(f1) = l_f1->next;
@@ -2137,11 +2137,11 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
newlen = f1->len;
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < newlen; i++, l_iter = l_iter->next)
l_iter->f = f1;
-
+
/* remove edge from the disk cycle of its two vertices */
bmesh_disk_edge_remove(l_f1->e, l_f1->e->v1);
bmesh_disk_edge_remove(l_f1->e, l_f1->e->v2);
-
+
/* deallocate edge and its two loops as well as f2 */
if (bm->etoolflagpool) {
BLI_mempool_free(bm->etoolflagpool, ((BMEdge_OFlag *)l_f1->e)->oflags);
@@ -2165,7 +2165,7 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
/* validate the new loop cycle */
edok = bmesh_loop_validate(f1);
BMESH_ASSERT(edok != false);
-
+
return f1;
}
@@ -2600,7 +2600,7 @@ void bmesh_kernel_edge_separate(
BLI_assert(l_sep->e == e);
BLI_assert(e->l);
-
+
if (BM_edge_is_boundary(e)) {
BLI_assert(0); /* no cut required */
return;
diff --git a/source/blender/bmesh/intern/bmesh_delete.c b/source/blender/bmesh/intern/bmesh_delete.c
index 1449a6ef9d7..1869bc49da0 100644
--- a/source/blender/bmesh/intern/bmesh_delete.c
+++ b/source/blender/bmesh/intern/bmesh_delete.c
@@ -105,7 +105,7 @@ void BMO_mesh_delete_oflag_tagged(BMesh *bm, const short oflag, const char htype
bmo_remove_tagged_edges(bm, oflag);
}
if (htype & BM_VERT) {
- bmo_remove_tagged_verts(bm, oflag);
+ bmo_remove_tagged_verts(bm, oflag);
}
}
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c
index 54fe2801d0c..9e107c822ac 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.c
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.c
@@ -160,7 +160,7 @@ int BM_mesh_edgeloops_find(
BMEdge **edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack));
BLI_stack_free(edge_stack);
-
+
for (uint i = 0; i < edges_len; i += 1) {
e = edges[i];
if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 8a1090891f2..e3b779ddbcd 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -152,7 +152,7 @@ void BM_data_interp_face_vert_edge(
l_v = l_iter;
l_v2 = l_iter->prev;
}
-
+
if (!l_v1 || !l_v2) {
return;
}
@@ -260,15 +260,15 @@ static int compute_mdisp_quad(
mid_v3_v3v3(p, l->prev->v->co, l->v->co);
mid_v3_v3v3(n, l->next->v->co, l->v->co);
-
+
copy_v3_v3(v1, l_f_center);
copy_v3_v3(v2, p);
copy_v3_v3(v3, l->v->co);
copy_v3_v3(v4, n);
-
+
sub_v3_v3v3(e1, v2, v1);
sub_v3_v3v3(e2, v3, v4);
-
+
return 1;
}
@@ -331,7 +331,7 @@ static bool mdisp_in_mdispquad(
{
float v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3];
float eps = FLT_EPSILON * 4000;
-
+
if (is_zero_v3(l_src->v->no))
BM_vert_normal_update_all(l_src->v);
if (is_zero_v3(l_dst->v->no))
@@ -341,17 +341,17 @@ static bool mdisp_in_mdispquad(
/* expand quad a bit */
mid_v3_v3v3v3v3(c, v1, v2, v3, v4);
-
+
sub_v3_v3(v1, c); sub_v3_v3(v2, c);
sub_v3_v3(v3, c); sub_v3_v3(v4, c);
mul_v3_fl(v1, 1.0f + eps); mul_v3_fl(v2, 1.0f + eps);
mul_v3_fl(v3, 1.0f + eps); mul_v3_fl(v4, 1.0f + eps);
add_v3_v3(v1, c); add_v3_v3(v2, c);
add_v3_v3(v3, c); add_v3_v3(v4, c);
-
+
if (!quad_co(v1, v2, v3, v4, p, l_src->v->no, r_uv))
return 0;
-
+
mul_v2_fl(r_uv, (float)(res - 1));
mdisp_axis_from_quad(v1, v2, v3, v4, r_axis_x, r_axis_y);
@@ -478,14 +478,14 @@ void BM_loop_interp_multires_ex(
MDisps *md_dst;
float v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3];
float axis_x[3], axis_y[3];
-
+
/* ignore 2-edged faces */
if (UNLIKELY(l_dst->f->len < 3))
return;
md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset);
compute_mdisp_quad(l_dst, f_dst_center, v1, v2, v3, v4, e1, e2);
-
+
/* if no disps data allocate a new grid, the size of the first grid in f_src. */
if (!md_dst->totdisp) {
const MDisps *md_src = BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset);
@@ -499,7 +499,7 @@ void BM_loop_interp_multires_ex(
return;
}
}
-
+
mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
const int res = (int)sqrt(md_dst->totdisp);
@@ -571,10 +571,10 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
BMLoop *l;
BMIter liter;
-
+
if (cd_loop_mdisp_offset == -1)
return;
-
+
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset);
MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
@@ -582,7 +582,7 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
float co1[3];
int sides;
int y;
-
+
/*
* mdisps is a grid of displacements, ordered thus:
*
@@ -605,14 +605,14 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
copy_v3_v3(mdl->disps[y], co1);
}
}
-
+
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
MDisps *mdl2;
float co1[3], co2[3], co[3];
int sides;
int y;
-
+
/*
* mdisps is a grid of displacements, ordered thus:
*
@@ -638,11 +638,11 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
sides = (int)sqrt(mdl1->totdisp);
for (y = 0; y < sides; y++) {
int a1, a2, o1, o2;
-
+
if (l->v != l->radial_next->v) {
a1 = sides * y + sides - 2;
a2 = (sides - 2) * sides + y;
-
+
o1 = sides * y + sides - 1;
o2 = (sides - 1) * sides + y;
}
@@ -652,16 +652,16 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
o1 = sides * y + sides - 1;
o2 = sides * y + sides - 1;
}
-
+
/* magic blending numbers, hardcoded! */
add_v3_v3v3(co1, mdl1->disps[a1], mdl2->disps[a2]);
mul_v3_fl(co1, 0.18);
-
+
add_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2]);
mul_v3_fl(co2, 0.32);
-
+
add_v3_v3v3(co, co1, co2);
-
+
copy_v3_v3(mdl1->disps[o1], co);
copy_v3_v3(mdl2->disps[o2], co);
}
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 9fe28561b93..c9b7b80b658 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -508,7 +508,7 @@ void *bmiter__face_of_vert_step(struct BMIter__face_of_vert *iter)
iter->l_next = iter->l_first;
}
}
-
+
if (!((BMIter *)iter)->count) {
iter->l_next = NULL;
}
@@ -549,7 +549,7 @@ void *bmiter__loop_of_vert_step(struct BMIter__loop_of_vert *iter)
iter->l_next = iter->l_first;
}
}
-
+
if (!((BMIter *)iter)->count) {
iter->l_next = NULL;
}
@@ -590,7 +590,7 @@ void bmiter__loop_of_loop_begin(struct BMIter__loop_of_loop *iter)
{
iter->l_first = iter->ldata;
iter->l_next = iter->l_first->radial_next;
-
+
if (iter->l_next == iter->l_first)
iter->l_next = NULL;
}
@@ -598,7 +598,7 @@ void bmiter__loop_of_loop_begin(struct BMIter__loop_of_loop *iter)
void *bmiter__loop_of_loop_step(struct BMIter__loop_of_loop *iter)
{
BMLoop *l_curr = iter->l_next;
-
+
if (iter->l_next) {
iter->l_next = iter->l_next->radial_next;
if (iter->l_next == iter->l_first) {
@@ -696,7 +696,7 @@ void *bmiter__edge_of_face_step(struct BMIter__edge_of_face *iter)
iter->l_next = NULL;
}
}
-
+
return l_curr ? l_curr->e : NULL;
}
diff --git a/source/blender/bmesh/intern/bmesh_iterators_inline.h b/source/blender/bmesh/intern/bmesh_iterators_inline.h
index 88985d639cf..e7bd6164c27 100644
--- a/source/blender/bmesh/intern/bmesh_iterators_inline.h
+++ b/source/blender/bmesh/intern/bmesh_iterators_inline.h
@@ -156,7 +156,7 @@ BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *da
return false;
break;
}
-
+
iter->begin(iter);
return true;
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 28827a5ddaa..30ab0dd9459 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -141,7 +141,7 @@ static uint bm_log_vert_id_get(BMLog *log, BMVert *v)
static void bm_log_vert_id_set(BMLog *log, BMVert *v, uint id)
{
void *vid = SET_UINT_IN_POINTER(id);
-
+
BLI_ghash_reinsert(log->id_to_elem, vid, v, NULL, NULL);
BLI_ghash_reinsert(log->elem_to_id, v, vid, NULL, NULL);
}
@@ -654,17 +654,21 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
*/
BMLogEntry *BM_log_entry_add(BMLog *log)
{
- BMLogEntry *entry, *next;
-
+ /* WARNING: this is now handled by the UndoSystem: BKE_UNDOSYS_TYPE_SCULPT
+ * freeing here causes unnecesssary complications. */
+ BMLogEntry *entry;
+#if 0
/* Delete any entries after the current one */
entry = log->current_entry;
if (entry) {
+ BMLogEntry *next;
for (entry = entry->next; entry; entry = next) {
next = entry->next;
bm_log_entry_free(entry);
BLI_freelinkN(&log->entries, entry);
}
}
+#endif
/* Create and append the new entry */
entry = bm_log_entry_create();
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 1b96237e262..10a03050d4b 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -609,7 +609,7 @@ void BM_mesh_select_mode_set(BMesh *bm, int selectmode)
{
BMIter iter;
BMElem *ele;
-
+
bm->selectmode = selectmode;
if (bm->selectmode & SCE_SELECT_VERTEX) {
@@ -737,13 +737,13 @@ BMFace *BM_mesh_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_s
BMIter iter;
BMFace *f = NULL;
BMEditSelection *ese;
-
+
/* Find the latest non-hidden face from the BMEditSelection */
ese = bm->selected.last;
for ( ; ese; ese = ese->prev) {
if (ese->htype == BM_FACE) {
f = (BMFace *)ese->ele;
-
+
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
f = NULL;
}
@@ -842,10 +842,10 @@ void BM_editselection_normal(BMEditSelection *ese, float r_normal[3])
BMEdge *eed = (BMEdge *)ese->ele;
float plane[3]; /* need a plane to correct the normal */
float vec[3]; /* temp vec storage */
-
+
add_v3_v3v3(r_normal, eed->v1->no, eed->v2->no);
sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
-
+
/* the 2 vertex normals will be close but not at rightangles to the edge
* for rotate about edge we want them to be at right angles, so we need to
* do some extra calculation to correct the vert normals,
@@ -853,7 +853,7 @@ void BM_editselection_normal(BMEditSelection *ese, float r_normal[3])
cross_v3_v3v3(vec, r_normal, plane);
cross_v3_v3v3(r_normal, plane, vec);
normalize_v3(r_normal);
-
+
}
else if (ese->htype == BM_FACE) {
BMFace *efa = (BMFace *)ese->ele;
@@ -869,7 +869,7 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3])
if (ese->htype == BM_VERT) {
BMVert *eve = (BMVert *)ese->ele;
float vec[3] = {0.0f, 0.0f, 0.0f};
-
+
if (ese->prev) { /* use previously selected data to make a useful vertex plane */
BM_editselection_center(ese->prev, vec);
sub_v3_v3v3(r_plane, vec, eve->co);
@@ -1261,7 +1261,7 @@ void BM_edge_hide_set(BMEdge *e, const bool hide)
BM_elem_flag_set(l_iter->f, BM_ELEM_HIDDEN, hide);
} while ((l_iter = l_iter->radial_next) != l_first);
}
-
+
BM_elem_flag_set(e, BM_ELEM_HIDDEN, hide);
/* hide vertices if necessary */
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 8071637d95e..5a04fcaa490 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -168,7 +168,7 @@ BMesh *BM_mesh_create(
{
/* allocate the structure */
BMesh *bm = MEM_callocN(sizeof(BMesh), __func__);
-
+
/* allocate the memory pools for the mesh elements */
bm_mempool_init(bm, allocsize, params->use_toolflags);
@@ -1052,41 +1052,41 @@ static void UNUSED_FUNCTION(bm_mdisps_space_set)(
BMFace *f;
BMIter iter;
// int i = 0; // UNUSED
-
+
multires_set_space(dm, ob, from, to);
-
+
mdisps = CustomData_get_layer(&dm->loopData, CD_MDISPS);
-
+
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
MDisps *lmd = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MDISPS);
-
+
if (!lmd->disps) {
printf("%s: warning - 'lmd->disps' == NULL\n", __func__);
}
-
+
if (lmd->disps && lmd->totdisp == mdisps->totdisp) {
memcpy(lmd->disps, mdisps->disps, sizeof(float) * 3 * lmd->totdisp);
}
else if (mdisps->disps) {
if (lmd->disps)
MEM_freeN(lmd->disps);
-
+
lmd->disps = MEM_dupallocN(mdisps->disps);
lmd->totdisp = mdisps->totdisp;
lmd->level = mdisps->level;
}
-
+
mdisps++;
// i += 1;
}
}
-
+
dm->needsFree = 1;
dm->release(dm);
-
+
/* setting this to NULL prevents BKE_editmesh_free from freeing it */
em->bm = NULL;
BKE_editmesh_free(em);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index cf6bc0e0bac..5ba3f149689 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -88,6 +88,7 @@
#include "BLI_math_vector.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_customdata.h"
#include "BKE_multires.h"
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 4290f94bba1..a10f2e2bb3f 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -66,7 +66,7 @@ bool BM_vert_dissolve(BMesh *bm, BMVert *v)
{
/* logic for 3 or more is identical */
const int len = BM_vert_edge_count_at_most(v, 3);
-
+
if (len == 1) {
BM_vert_kill(bm, v); /* will kill edges too */
return true;
@@ -110,7 +110,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
if (!BM_vert_is_manifold(v)) {
return false;
}
-
+
if (v->e) {
/* v->e we keep, what else */
e = v->e;
@@ -124,7 +124,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
len++;
} while (e != v->e);
}
-
+
/* this code for handling 2 and 3-valence verts
* may be totally bad */
if (keepedge == NULL && len == 3) {
@@ -200,7 +200,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
if (!e) {
return false;
}
-
+
if (e->l) {
/* get remaining two faces */
if (e->l != e->l->radial_next) {
@@ -286,13 +286,13 @@ BMFace *BM_face_split(
if (cd_loop_mdisp_offset != -1) {
f_tmp = BM_face_copy(bm, bm, f, false, false);
}
-
+
#ifdef USE_BMESH_HOLES
f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, r_l, NULL, example, no_double);
#else
f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, r_l, example, no_double);
#endif
-
+
if (f_new) {
/* handle multires update */
if (cd_loop_mdisp_offset != -1) {
@@ -368,7 +368,7 @@ BMFace *BM_face_split_n(
}
f_tmp = BM_face_copy(bm, bm, f, true, true);
-
+
#ifdef USE_BMESH_HOLES
f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, &l_new, NULL, example, false);
#else
@@ -600,13 +600,13 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
if (cd_loop_mdisp_offset != -1) {
BMLoop *l;
int i;
-
+
l = e->l;
do {
BLI_array_append(oldfaces, l->f);
l = l->radial_next;
} while (l != e->l);
-
+
/* flag existing faces so we can differentiate oldfaces from new faces */
for (i = 0; i < BLI_array_len(oldfaces); i++) {
BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP);
@@ -647,7 +647,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
for (j = 0; j < 2; j++) {
BMEdge *e1 = j ? e_new : e;
BMLoop *l;
-
+
l = e1->l;
if (UNLIKELY(!l)) {
@@ -669,31 +669,31 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
} while (l != e1->l);
}
}
-
+
/* destroy the old faces */
for (i = 0; i < BLI_array_len(oldfaces); i++) {
BM_face_verts_kill(bm, oldfaces[i]);
}
-
+
/* fix boundaries a bit, doesn't work too well quite yet */
#if 0
for (j = 0; j < 2; j++) {
BMEdge *e1 = j ? e_new : e;
BMLoop *l, *l2;
-
+
l = e1->l;
if (UNLIKELY(!l)) {
BMESH_ASSERT(0);
break;
}
-
+
do {
BM_face_multires_bounds_smooth(bm, l->f);
l = l->radial_next;
} while (l != e1->l);
}
#endif
-
+
BLI_array_free(oldfaces);
}
@@ -710,7 +710,7 @@ BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts, BMVert **r_varr)
int i;
float percent;
BMVert *v_new = NULL;
-
+
for (i = 0; i < numcuts; i++) {
percent = 1.0f / (float)(numcuts + 1 - i);
v_new = BM_edge_split(bm, e, e->v2, NULL, percent);
@@ -734,7 +734,7 @@ bool BM_face_validate(BMFace *face, FILE *err)
BMLoop *l;
int i, j;
bool ret = true;
-
+
if (face->len == 2) {
fprintf(err, "warning: found two-edged face. face ptr: %p\n", face);
fflush(err);
@@ -765,7 +765,7 @@ bool BM_face_validate(BMFace *face, FILE *err)
}
}
}
-
+
BLI_array_free(verts);
return ret;
}
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index f814767a200..62d892712fd 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -65,10 +65,10 @@ BLI_STATIC_ASSERT(ARRAY_SIZE(bmo_error_messages) + 1 == BMERR_TOTAL, "message mi
/* operator slot type information - size of one element of the type given. */
const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES] = {
0, /* 0: BMO_OP_SLOT_SENTINEL */
- sizeof(int), /* 1: BMO_OP_SLOT_BOOL */
- sizeof(int), /* 2: BMO_OP_SLOT_INT */
- sizeof(float), /* 3: BMO_OP_SLOT_FLT */
- sizeof(void *), /* 4: BMO_OP_SLOT_PNT */
+ sizeof(int), /* 1: BMO_OP_SLOT_BOOL */
+ sizeof(int), /* 2: BMO_OP_SLOT_INT */
+ sizeof(float), /* 3: BMO_OP_SLOT_FLT */
+ sizeof(void *), /* 4: BMO_OP_SLOT_PNT */
sizeof(void *), /* 5: BMO_OP_SLOT_PNT */
0, /* 6: unused */
0, /* 7: unused */
@@ -185,7 +185,7 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
op->type = opcode;
op->type_flag = bmo_opdefines[opcode]->type_flag;
op->flag = flag;
-
+
/* initialize the operator slot types */
bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_in, op->slots_in);
bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_out, op->slots_out);
@@ -217,10 +217,10 @@ void BMO_op_exec(BMesh *bm, BMOperator *op)
if (bm->toolflag_index == 1)
bmesh_edit_begin(bm, op->type_flag);
op->exec(bm, op);
-
+
if (bm->toolflag_index == 1)
bmesh_edit_end(bm, op->type_flag);
-
+
BMO_pop(bm);
}
@@ -406,7 +406,7 @@ void BMO_slot_mat_set(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], cons
slot->len = 4;
slot->data.p = BLI_memarena_alloc(op->arena, sizeof(float) * 4 * 4);
-
+
if (size == 4) {
copy_m4_m4(slot->data.p, (float (*)[4])mat);
}
@@ -661,7 +661,7 @@ int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
-
+
/* check if its actually a buffer */
if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF)
return 0;
@@ -697,7 +697,7 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd)
BMOpSlot *slot = &op->slots[slot_code];
void *tmp;
ssize_t allocsize;
-
+
BLI_assert(slot->slottype == BMO_OP_SLOT_ELEMENT_BUF);
/* check if its actually a buffer */
@@ -760,7 +760,7 @@ void *BMO_slot_buffer_alloc(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS]
/* check if its actually a buffer */
if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF)
return NULL;
-
+
slot->len = len;
if (len) {
slot->data.buf = BLI_memarena_alloc(op->arena, BMO_OPSLOT_TYPEINFO[slot->slot_type] * len);
@@ -783,7 +783,7 @@ void BMO_slot_buffer_from_all(
{
BMOpSlot *output = BMO_slot_get(slot_args, slot_name);
int totelement = 0, i = 0;
-
+
BLI_assert(output->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
BLI_assert(((output->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
@@ -1365,7 +1365,7 @@ static void bmo_flag_layer_clear(BMesh *bm)
void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
-
+
if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF)
return NULL;
@@ -1505,14 +1505,14 @@ void BMO_error_clear(BMesh *bm)
void BMO_error_raise(BMesh *bm, BMOperator *owner, int errcode, const char *msg)
{
BMOpError *err = MEM_callocN(sizeof(BMOpError), "bmop_error");
-
+
err->errorcode = errcode;
if (!msg) {
msg = bmo_error_messages[errcode];
}
err->msg = msg;
err->op = owner;
-
+
BLI_addhead(&bm->errorstack, err);
}
@@ -1531,17 +1531,17 @@ int BMO_error_get(BMesh *bm, const char **msg, BMOperator **op)
if (msg) *msg = err->msg;
if (op) *op = err->op;
-
+
return err->errorcode;
}
int BMO_error_pop(BMesh *bm, const char **msg, BMOperator **op)
{
int errorcode = BMO_error_get(bm, msg, op);
-
+
if (errorcode) {
BMOpError *err = bm->errorstack.first;
-
+
BLI_remlink(&bm->errorstack, bm->errorstack.first);
MEM_freeN(err);
}
@@ -1680,7 +1680,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
/* we muck around in here, so dup it */
fmt = ofmt = BLI_strdup(_fmt);
-
+
/* find operator name */
i = strcspn(fmt, " ");
@@ -1689,7 +1689,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
opname[i] = '\0';
fmt += i + (noslot ? 0 : 1);
-
+
i = BMO_opcode_from_opname_check(opname);
if (i == -1) {
@@ -1700,7 +1700,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
BMO_op_init(bm, op, flag, opname);
// def = bmo_opdefines[i];
-
+
i = 0;
state = true; /* false: not inside slot_code name, true: inside slot_code name */
@@ -1709,7 +1709,7 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
/* jump past leading whitespace */
i = strspn(fmt, " ");
fmt += i;
-
+
/* ignore trailing whitespace */
if (!fmt[i])
break;
@@ -1725,9 +1725,9 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
if (bmo_name_to_slotcode_check(op->slots_in, fmt) < 0) {
GOTO_ERROR("name to slot code check failed");
}
-
+
BLI_strncpy(slot_name, fmt, sizeof(slot_name));
-
+
state = false;
fmt += i;
}
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index bcb940f8b96..7cbc6461667 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -611,7 +611,7 @@ void BM_edge_normals_update(BMEdge *e)
{
BMIter iter;
BMFace *f;
-
+
BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
BM_face_normal_update(f);
}
@@ -886,7 +886,7 @@ bool BM_face_point_inside_test(const BMFace *f, const float co[3])
float co_2d[2];
BMLoop *l_iter;
int i;
-
+
BLI_assert(BM_face_is_normal_valid(f));
axis_dominant_v3_to_m3(axis_mat, f->no);
@@ -1199,7 +1199,7 @@ void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int l
out[1] = max_ff(out[1], projverts[i][1]);
}
bm->elem_index_dirty |= BM_LOOP;
-
+
/* ensure we are well outside the face bounds (value is arbitrary) */
add_v2_fl(out, 1.0f);
@@ -1212,7 +1212,7 @@ void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int l
for (i = 0; i < len; i++) {
float mid[2];
mid_v2_v2v2(mid, edgeverts[i][0], edgeverts[i][1]);
-
+
int isect = 0;
int j_prev;
for (j = 0, j_prev = f->len - 1; j < f->len; j_prev = j++) {
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index ab2f017d103..5ce4b236d03 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -424,7 +424,7 @@ int BM_verts_in_face_count(BMVert **varr, int len, BMFace *f)
#endif
int i, count = 0;
-
+
for (i = 0; i < len; i++) {
BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
}
@@ -1213,7 +1213,7 @@ int BM_face_share_edge_count(BMFace *f_a, BMFace *f_b)
BMLoop *l_iter;
BMLoop *l_first;
int count = 0;
-
+
l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
do {
if (BM_edge_in_face(l_iter->e, f_b)) {
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index 8aa9502c0f7..ff744ae1a42 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -217,7 +217,7 @@ void bmesh_disk_edge_remove(BMEdge *e, BMVert *v)
BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2)
{
BMEdge *e_iter, *e_first;
-
+
if (v1->e) {
e_first = e_iter = v1->e;
@@ -227,7 +227,7 @@ BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2)
}
} while ((e_iter = bmesh_disk_edge_next(e_iter, v1)) != e_first);
}
-
+
return NULL;
}
@@ -380,7 +380,7 @@ bool bmesh_radial_validate(int radlen, BMLoop *l)
{
BMLoop *l_iter = l;
int i = 0;
-
+
if (bmesh_radial_length(l) != radlen)
return false;
@@ -389,17 +389,17 @@ bool bmesh_radial_validate(int radlen, BMLoop *l)
BMESH_ASSERT(0);
return false;
}
-
+
if (l_iter->e != l->e)
return false;
if (l_iter->v != l->e->v1 && l_iter->v != l->e->v2)
return false;
-
+
if (UNLIKELY(i > BM_LOOP_RADIAL_MAX)) {
BMESH_ASSERT(0);
return false;
}
-
+
i++;
} while ((l_iter = l_iter->radial_next) != l);
@@ -529,7 +529,7 @@ int bmesh_radial_length(const BMLoop *l)
BMESH_ASSERT(0);
return 0;
}
-
+
i++;
if (UNLIKELY(i >= BM_LOOP_RADIAL_MAX)) {
BMESH_ASSERT(0);
diff --git a/source/blender/bmesh/intern/bmesh_walkers.c b/source/blender/bmesh/intern/bmesh_walkers.c
index d39fb382b96..77e9d441bbb 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.c
+++ b/source/blender/bmesh/intern/bmesh_walkers.c
@@ -63,7 +63,7 @@ void *BMW_begin(BMWalker *walker, void *start)
BLI_assert(((BMHeader *)start)->htype & walker->begin_htype);
walker->begin(walker, start);
-
+
return BMW_current_state(walker) ? walker->step(walker) : NULL;
}
@@ -101,7 +101,7 @@ void BMW_init(
BLI_assert(0);
return;
}
-
+
if (type != BMW_CUSTOM) {
walker->begin_htype = bm_walker_types[type]->begin_htype;
walker->begin = bm_walker_types[type]->begin;
@@ -118,7 +118,7 @@ void BMW_init(
BLI_assert(mask_edge == 0 || (walker->valid_mask & BM_EDGE));
BLI_assert(mask_face == 0 || (walker->valid_mask & BM_FACE));
}
-
+
walker->worklist = BLI_mempool_create(walker->structsize, 0, 128, BLI_MEMPOOL_NOP);
BLI_listbase_clear(&walker->states);
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index 279440984bb..81487b70edc 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -210,7 +210,7 @@ static void *bmw_VertShellWalker_step(BMWalker *walker)
BMVert *v_old = NULL;
bool restrictpass = true;
BMwShellWalker shellWalk = *((BMwShellWalker *)BMW_current_state(walker));
-
+
if (!BLI_gset_haskey(walker->visit_set, shellWalk.base)) {
BLI_gset_insert(walker->visit_set, shellWalk.base);
}
@@ -228,11 +228,11 @@ static void *bmw_VertShellWalker_step(BMWalker *walker)
BMwShellWalker *newstate;
v_old = BM_edge_other_vert(curedge, shellWalk.base);
-
+
/* push a new state onto the stac */
newState = BMW_state_add(walker);
BLI_gset_insert(walker->visit_set, curedge);
-
+
/* populate the new stat */
newState->base = v_old;
@@ -240,7 +240,7 @@ static void *bmw_VertShellWalker_step(BMWalker *walker)
}
}
} while ((curedge = bmesh_disk_edge_next(curedge, shellWalk.base)) != shellWalk.curedge);
-
+
return shellWalk.curedge;
}
#endif
@@ -711,12 +711,12 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
e = l->e;
v = BM_edge_other_vert(e, iwalk->lastv);
-
+
/* pop off current state */
BMW_state_remove(walker);
-
+
f = l->f;
-
+
while (1) {
l = BM_loop_other_edge_loop(l, v);
if (BM_loop_is_manifold(l)) {
@@ -736,7 +736,7 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
break;
}
}
-
+
if (l == owalk.curloop) {
return NULL;
}
@@ -789,7 +789,7 @@ static void *bmw_IslandWalker_step_ex(BMWalker *walker, bool only_manifold)
{
BMwIslandWalker *iwalk, owalk;
BMLoop *l_iter, *l_first;
-
+
BMW_state_remove_r(walker, &owalk);
iwalk = &owalk;
@@ -1154,7 +1154,7 @@ static bool bmw_FaceLoopWalker_edge_begins_loop(BMWalker *walker, BMEdge *e)
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 */
if (BM_edge_is_boundary(e)) {
@@ -1162,7 +1162,7 @@ static bool bmw_FaceLoopWalker_edge_begins_loop(BMWalker *walker, BMEdge *e)
return false;
}
}
-
+
/* Don't start a face loop from non-manifold edges */
if (!BM_edge_is_manifold(e)) {
return false;
@@ -1206,7 +1206,7 @@ static void bmw_FaceLoopWalker_begin(BMWalker *walker, void *data)
static void *bmw_FaceLoopWalker_yield(BMWalker *walker)
{
BMwFaceLoopWalker *lwalk = BMW_current_state(walker);
-
+
if (!lwalk) {
return NULL;
}
@@ -1225,7 +1225,7 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker)
f = lwalk->l->f;
l = lwalk->l->radial_next;
-
+
if (lwalk->no_calc) {
return f;
}
@@ -1314,7 +1314,7 @@ static void bmw_EdgeringWalker_begin(BMWalker *walker, void *data)
static void *bmw_EdgeringWalker_yield(BMWalker *walker)
{
BMwEdgeringWalker *lwalk = BMW_current_state(walker);
-
+
if (!lwalk) {
return NULL;
}
@@ -1381,7 +1381,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
l = l->radial_next;
l = l->next->next;
-
+
if ((l->f->len != 4) || !EDGE_CHECK(l->e) || !bmw_mask_check_face(walker, l->f)) {
l = owalk.l->next->next;
}
@@ -1502,7 +1502,7 @@ static void bmw_UVEdgeWalker_begin(BMWalker *walker, void *data)
static void *bmw_UVEdgeWalker_yield(BMWalker *walker)
{
BMwUVEdgeWalker *lwalk = BMW_current_state(walker);
-
+
if (!lwalk) {
return NULL;
}
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index c70e8b675c7..aeaedf6417c 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -66,7 +66,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
break;
}
}
-
+
/* --- Support Edge Creation ---
* simple case when we only have 2 verts selected.
*/
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 816d2e8d009..0ad800cbddd 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -158,7 +158,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
}
BMO_slot_buffer_flag_enable(bm, op->slots_in, "faces", BM_FACE, FACE_MARK | FACE_TAG);
-
+
/* collect region */
BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
BMFace *f_iter;
@@ -178,7 +178,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
BLI_array_append(faces, f_iter);
}
BMW_end(&regwalker);
-
+
for (i = 0; i < BLI_array_len(faces); i++) {
f_iter = faces[i];
BMO_face_flag_disable(bm, f_iter, FACE_TAG);
@@ -190,7 +190,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED, NULL);
goto cleanup;
}
-
+
BLI_array_append(faces, NULL);
BLI_array_append(regions, faces);
}
@@ -201,17 +201,17 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
for (i = 0; i < BLI_array_len(regions); i++) {
BMFace *f_new;
int tot = 0;
-
+
faces = regions[i];
if (!faces[0]) {
BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED,
"Could not find boundary of dissolve region");
goto cleanup;
}
-
+
while (faces[tot])
tot++;
-
+
f_new = BM_faces_join(bm, faces, tot, true);
if (f_new) {
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index 394faabbd25..eed87ed20af 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -64,7 +64,7 @@ static BMVert *bmo_vert_copy(
/* Mark the vert for output */
BMO_vert_flag_enable(bm_dst, v_dst, DUPE_NEW);
-
+
return v_dst;
}
@@ -103,7 +103,7 @@ static BMEdge *bmo_edge_copy(
/* Lookup v1 and v2 */
e_dst_v1 = BLI_ghash_lookup(vhash, e_src->v1);
e_dst_v2 = BLI_ghash_lookup(vhash, e_src->v2);
-
+
/* Create a new edge */
e_dst = BM_edge_create(bm_dst, e_dst_v1, e_dst_v2, NULL, BM_CREATE_SKIP_CD);
BMO_slot_map_elem_insert(op, slot_edgemap_out, e_src, e_dst);
@@ -124,7 +124,7 @@ static BMEdge *bmo_edge_copy(
/* Mark the edge for output */
BMO_edge_flag_enable(bm_dst, e_dst, DUPE_NEW);
-
+
return e_dst;
}
@@ -164,7 +164,7 @@ static BMFace *bmo_face_copy(
/* Copy attributes */
BM_elem_attrs_copy(bm_src, bm_dst, f_src, f_dst);
-
+
/* copy per-loop custom data */
l_iter_src = l_first_src;
l_iter_dst = BM_FACE_FIRST_LOOP(f_dst);
@@ -192,7 +192,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_dst, BMesh *bm_src)
BMVert *v = NULL, *v2;
BMEdge *e = NULL;
BMFace *f = NULL;
-
+
BMIter viter, eiter, fiter;
GHash *vhash, *ehash;
@@ -286,7 +286,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_dst, BMesh *bm_src)
BMO_face_flag_enable(bm_src, f, DUPE_DONE);
}
}
-
+
/* free pointer hashes */
BLI_ghash_free(vhash, NULL, NULL);
BLI_ghash_free(ehash, NULL, NULL);
@@ -326,7 +326,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
{
BMOperator *dupeop = op;
BMesh *bm_dst = BMO_slot_ptr_get(op->slots_in, "dest");
-
+
if (!bm_dst)
bm_dst = bm;
@@ -335,7 +335,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
/* use the internal copy function */
bmo_mesh_copy(dupeop, bm_dst, bm);
-
+
/* Output */
/* First copy the input buffers to output buffers - original data */
BMO_slot_copy(dupeop, slots_in, "geom",
@@ -393,11 +393,11 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
/* initialize our sub-operator */
BMO_op_init(bm, &dupeop, op->flag, "duplicate");
-
+
BMO_slot_copy(splitop, slots_in, "geom",
&dupeop, slots_in, "geom");
BMO_op_exec(bm, &dupeop);
-
+
BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
if (use_only_faces) {
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 87369472df7..3a6fbd419c1 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -175,7 +175,7 @@ static void bm_extrude_copy_face_loop_attributes(BMesh *bm, BMFace *f)
static void bm_extrude_disable_skin_root(BMesh *bm, BMVert *v)
{
MVertSkin *vs;
-
+
vs = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_MVERT_SKIN);
vs->flag &= ~MVERT_SKIN_ROOT;
}
@@ -186,7 +186,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
BMOperator dupeop;
BMFace *f;
BMEdge *e, *e_new;
-
+
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
BMO_edge_flag_enable(bm, e, EXT_INPUT);
BMO_vert_flag_enable(bm, e->v1, EXT_INPUT);
@@ -227,16 +227,16 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
/* not sure what to do about example face, pass NULL for now */
f = BM_face_create_verts(bm, f_verts, 4, NULL, BM_CREATE_NOP, true);
bm_extrude_copy_face_loop_attributes(bm, f);
-
+
if (BMO_edge_flag_test(bm, e, EXT_INPUT)) {
e = e_new;
}
-
+
BMO_face_flag_enable(bm, f, EXT_KEEP);
BMO_edge_flag_enable(bm, e, EXT_KEEP);
BMO_vert_flag_enable(bm, e->v1, EXT_KEEP);
BMO_vert_flag_enable(bm, e->v2, EXT_KEEP);
-
+
}
BMO_op_finish(bm, &dupeop);
@@ -343,7 +343,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMO_slot_bool_get(op->slots_in, "use_select_history"));
BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_EDGE | BM_FACE, EXT_INPUT);
-
+
/* if one flagged face is bordered by an un-flagged face, then we delete
* original geometry unless caller explicitly asked to keep it. */
if (!BMO_slot_bool_get(op->slots_in, "use_keep_orig")) {
@@ -404,7 +404,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
}
}
-
+
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if (BMO_face_flag_test(bm, f, EXT_INPUT)) {
BMO_face_flag_enable(bm, f, EXT_DEL);
@@ -436,7 +436,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
if (delorig) {
BMO_op_exec(bm, &delop);
}
-
+
/* if not delorig, reverse loops of original face */
if (!delorig) {
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
@@ -445,7 +445,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
}
}
-
+
BMO_slot_copy(&dupeop, slots_out, "geom.out",
op, slots_out, "geom.out");
@@ -493,7 +493,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
else
fwd = (e_new->l->v == e_new->v1);
-
+
if (fwd) {
f_verts[0] = e->v1;
f_verts[1] = e->v2;
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index d52cb00e172..ca727de5756 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -46,10 +46,10 @@
/* Internal operator flags */
typedef enum {
HULL_FLAG_INPUT = (1 << 0),
-
+
HULL_FLAG_INTERIOR_ELE = (1 << 1),
HULL_FLAG_OUTPUT_GEOM = (1 << 2),
-
+
HULL_FLAG_DEL = (1 << 3),
HULL_FLAG_HOLE = (1 << 4)
} HullFlags;
@@ -106,7 +106,7 @@ static BMFace *hull_find_example_face(BMesh *bm, BMEdge *e)
static void hull_output_triangles(BMesh *bm, GSet *hull_triangles)
{
GSetIterator iter;
-
+
GSET_ITER (iter, hull_triangles) {
HullTriangle *t = BLI_gsetIterator_getKey(&iter);
int i;
@@ -213,7 +213,7 @@ static HullFinalEdges *hull_final_edges(GSet *hull_triangles)
{
HullFinalEdges *final_edges;
GSetIterator iter;
-
+
final_edges = MEM_callocN(sizeof(HullFinalEdges), "HullFinalEdges");
final_edges->edges = BLI_ghash_ptr_new("final edges ghash");
final_edges->base_pool = BLI_mempool_create(sizeof(ListBase), 0, 128, BLI_MEMPOOL_NOP);
@@ -286,7 +286,7 @@ static void hull_remove_overlapping(
break;
}
}
-
+
/* Note: can't change ghash while iterating, so mark
* with 'skip' flag rather than deleting triangles */
if (BM_vert_in_face(t->v[1], f) &&
@@ -336,7 +336,7 @@ static void hull_tag_unused(BMesh *bm, BMOperator *op)
BMO_ITER (v, &oiter, op->slots_in, "input", BM_VERT) {
if (BMO_vert_flag_test(bm, v, HULL_FLAG_INTERIOR_ELE)) {
bool del = true;
-
+
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
if (!BMO_edge_flag_test(bm, e, HULL_FLAG_INPUT)) {
del = false;
@@ -406,7 +406,7 @@ static void hull_tag_holes(BMesh *bm, BMOperator *op)
BMO_ITER (e, &oiter, op->slots_in, "input", BM_EDGE) {
bool hole = true;
bool any_faces = false;
-
+
BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
any_faces = true;
if (!BMO_face_flag_test(bm, f, HULL_FLAG_HOLE)) {
@@ -511,7 +511,7 @@ static void hull_from_bullet(
hull = plConvexHullCompute(coords, num_input_verts);
hull_verts = hull_verts_from_bullet(hull, input_verts, num_input_verts);
-
+
count = plConvexHullNumFaces(hull);
for (i = 0; i < count; i++) {
const int len = plConvexHullGetFaceSize(hull, i);
@@ -601,7 +601,7 @@ void bmo_convex_hull_exec(BMesh *bm, BMOperator *op)
hull_from_bullet(bm, op, hull_triangles, hull_pool);
final_edges = hull_final_edges(hull_triangles);
-
+
hull_mark_interior_elements(bm, op, final_edges);
/* Remove hull triangles covered by an existing face */
diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c
index f1bf3179cd6..64f9773714b 100644
--- a/source/blender/bmesh/operators/bmo_mirror.c
+++ b/source/blender/bmesh/operators/bmo_mirror.c
@@ -57,13 +57,13 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
BMOpSlot *slot_targetmap;
ototvert = bm->totvert;
-
+
BMO_slot_mat4_get(op->slots_in, "matrix", mtx);
invert_m4_m4(imtx, mtx);
-
+
BMO_op_initf(bm, &dupeop, op->flag, "duplicate geom=%s", op, "geom");
BMO_op_exec(bm, &dupeop);
-
+
BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW);
/* create old -> new mappin */
@@ -74,7 +74,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
BMO_op_callf(bm, op->flag, "transform verts=%fv matrix=%m4", ELE_NEW, mtx);
BMO_op_callf(bm, op->flag, "scale verts=%fv vec=%v", ELE_NEW, scale);
BMO_op_callf(bm, op->flag, "transform verts=%fv matrix=%m4", ELE_NEW, imtx);
-
+
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
@@ -87,7 +87,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
}
v = BM_iter_step(&iter);
}
-
+
if (mirror_u || mirror_v) {
BMFace *f;
BMLoop *l;
@@ -109,7 +109,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
}
BMO_op_exec(bm, &weldop);
-
+
BMO_op_finish(bm, &weldop);
BMO_op_finish(bm, &dupeop);
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index 95d61763902..fd9b88ca4d3 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -940,7 +940,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_VERT, VERT_MARK);
BMO_op_callf(bm, op->flag, "rotate cent=%v matrix=%m3 verts=%S", vec, cmat, &bmop, "geom.out");
-
+
prevop = bmop;
}
@@ -1041,7 +1041,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
v3 = eva[icoface[a][2]];
f = BM_face_create_quad_tri(bm, v1, v2, v3, NULL, NULL, BM_CREATE_NOP);
-
+
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BMO_edge_flag_enable(bm, l->e, EDGE_MARK);
}
@@ -1296,10 +1296,10 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL;
float vec[3], mat[4][4], phi, phid;
int a;
-
+
if (!segs)
return;
-
+
BMO_slot_mat4_get(op->slots_in, "matrix", mat);
phid = 2.0f * (float)M_PI / segs;
@@ -1308,7 +1308,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
if (cap_ends) {
zero_v3(vec);
mul_m4_v3(mat, vec);
-
+
cent1 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
BMO_vert_flag_enable(bm, cent1, VERT_MARK);
}
@@ -1322,17 +1322,17 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
v1 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
BMO_vert_flag_enable(bm, v1, VERT_MARK);
-
+
if (lastv1)
BM_edge_create(bm, v1, lastv1, NULL, BM_CREATE_NOP);
-
+
if (a && cap_ends) {
BMFace *f;
-
+
f = BM_face_create_quad_tri(bm, cent1, lastv1, v1, NULL, NULL, BM_CREATE_NOP);
BMO_face_flag_enable(bm, f, FACE_NEW);
}
-
+
if (!firstv1)
firstv1 = v1;
@@ -1346,7 +1346,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
if (cap_ends) {
BMFace *f;
-
+
f = BM_face_create_quad_tri(bm, cent1, v1, firstv1, NULL, NULL, BM_CREATE_NOP);
BMO_face_flag_enable(bm, f, FACE_NEW);
@@ -1354,11 +1354,11 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
BM_mesh_calc_uvs_circle(bm, mat, radius, FACE_NEW, cd_loop_uv_offset);
}
}
-
+
if (!cap_tris) {
BMO_op_callf(bm, op->flag, "dissolve_faces faces=%ff", FACE_NEW);
}
-
+
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
@@ -1421,10 +1421,10 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
int a;
-
+
if (!segs)
return;
-
+
BMO_slot_mat4_get(op->slots_in, "matrix", mat);
phid = 2.0f * (float)M_PI / segs;
@@ -1435,13 +1435,13 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
vec[0] = vec[1] = 0.0f;
vec[2] = -depth;
mul_m4_v3(mat, vec);
-
+
cent1 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
vec[0] = vec[1] = 0.0f;
vec[2] = depth;
mul_m4_v3(mat, vec);
-
+
cent2 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
BMO_vert_flag_enable(bm, cent1, VERT_MARK);
@@ -1522,7 +1522,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
if (!cap_tris) {
BMO_op_callf(bm, op->flag, "dissolve_faces faces=%ff", FACE_NEW);
}
-
+
BMO_op_callf(bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, 0.000001);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index e85751531ae..8468227d17e 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -303,7 +303,7 @@ void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op)
if (l_first == NULL) {
l_first = l;
}
-
+
for (i = 0; i < bm->ldata.totlayer; i++) {
if (CustomData_layer_has_math(&bm->ldata, i)) {
const int type = bm->ldata.layers[i].type;
@@ -312,7 +312,7 @@ void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op)
e1 = BM_ELEM_CD_GET_VOID_P(l_first, offset);
e2 = BM_ELEM_CD_GET_VOID_P(l, offset);
-
+
CustomData_data_multiply(type, e2, fac);
if (l != l_first) {
@@ -348,7 +348,7 @@ void bmo_average_vert_facedata_exec(BMesh *bm, BMOperator *op)
if (!CustomData_layer_has_math(&bm->ldata, i))
continue;
-
+
CustomData_data_initminmax(type, &min, &max);
BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
@@ -378,7 +378,7 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
BMVert *v, *vert_snap = NULL;
float vec[3];
BMOpSlot *slot_targetmap;
-
+
BMO_slot_vec_get(op->slots_in, "merge_co", vec);
//BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 8f998797a16..90cbe9a5d76 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -156,7 +156,7 @@ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace
BLI_assert(!BM_loop_is_adjacent(l_a, l_b));
f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false);
-
+
if (r_f_new) *r_f_new = f_new;
return l_new ? l_new->e : NULL;
}
@@ -380,7 +380,7 @@ static BMVert *bm_subdivide_edge_addvert(
BMEdge **r_edge)
{
BMVert *v_new;
-
+
v_new = BM_edge_split(bm, edge, edge->v1, r_edge, factor_edge_split);
BMO_vert_flag_enable(bm, v_new, ELE_INNER);
@@ -402,7 +402,7 @@ static BMVert *bm_subdivide_edge_addvert(
}
}
#endif
-
+
interp_v3_v3v3(v_new->no, v_a->no, v_b->no, factor_subd);
normalize_v3(v_new->no);
@@ -426,7 +426,7 @@ static BMVert *subdivide_edge_num(
factor_edge_split = 1.0f / (float)(totpoint + 1 - curpoint);
factor_subd = (float)(curpoint + 1) / (float)(totpoint + 1);
}
-
+
v_new = bm_subdivide_edge_addvert(
bm, edge, e_orig, params,
factor_edge_split, factor_subd,
@@ -444,7 +444,7 @@ static void bm_subdivide_multicut(
e_tmp.v1 = &v1_tmp;
e_tmp.v2 = &v2_tmp;
-
+
for (i = 0; i < numcuts; i++) {
v = subdivide_edge_num(bm, eed, &e_tmp, i, params->numcuts, params, v_a, v_b, &e_new);
@@ -456,7 +456,7 @@ static void bm_subdivide_multicut(
if (v->e) BM_CHECK_ELEMENT(v->e);
if (v->e && v->e->l) BM_CHECK_ELEMENT(v->e->l->f);
}
-
+
alter_co(v1, &e_tmp, params, 0, &v1_tmp, &v2_tmp);
alter_co(v2, &e_tmp, params, 1.0, &v1_tmp, &v2_tmp);
}
@@ -526,7 +526,7 @@ static void quad_2edge_split_path(BMesh *bm, BMFace *UNUSED(face), BMVert **vert
{
BMFace *f_new;
int i, numcuts = params->numcuts;
-
+
for (i = 0; i < numcuts; i++) {
connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new);
}
@@ -556,7 +556,7 @@ static void quad_2edge_split_innervert(BMesh *bm, BMFace *UNUSED(face), BMVert *
BMVert *v, *v_last;
BMEdge *e, *e_new, e_tmp;
int i, numcuts = params->numcuts;
-
+
v_last = verts[numcuts];
for (i = numcuts - 1; i >= 0; i--) {
@@ -629,7 +629,7 @@ static void quad_3edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
{
BMFace *f_new;
int i, add = 0, numcuts = params->numcuts;
-
+
for (i = 0; i < numcuts; i++) {
if (i == numcuts / 2) {
if (numcuts % 2 != 0) {
@@ -687,12 +687,12 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
for (i = 0; i < numcuts + 2; i++) {
lines[(s - 1) * s + i] = verts[numcuts + i];
}
-
+
/* first and last members of middle lines */
for (i = 0; i < numcuts; i++) {
a = i;
b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
-
+
e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
if (!e)
continue;
@@ -700,10 +700,10 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
BMO_edge_flag_enable(bm, e, ELE_INNER);
BMO_face_flag_enable(bm, f_new, ELE_INNER);
-
+
v1 = lines[(i + 1) * s] = verts[a];
v2 = lines[(i + 1) * s + s - 1] = verts[b];
-
+
e_tmp = *e;
for (a = 0; a < numcuts; a++) {
v = subdivide_edge_num(bm, e, &e_tmp, a, numcuts, params, v1, v2, &e_new);
@@ -748,7 +748,7 @@ static void tri_1edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
{
BMFace *f_new;
int i, numcuts = params->numcuts;
-
+
for (i = 0; i < numcuts; i++) {
connect_smallest_face(bm, verts[i], verts[numcuts + 1], &f_new);
}
@@ -780,13 +780,13 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
BMVert ***lines, *v, v1_tmp, v2_tmp;
void *stackarr[1];
int i, j, a, b, numcuts = params->numcuts;
-
+
/* number of verts in each lin */
lines = MEM_callocN(sizeof(void *) * (numcuts + 2), "triangle vert table");
-
+
lines[0] = (BMVert **) stackarr;
lines[0][0] = verts[numcuts * 2 + 1];
-
+
lines[numcuts + 1] = MEM_callocN(sizeof(void *) * (numcuts + 2), "triangle vert table 2");
for (i = 0; i < numcuts; i++) {
lines[numcuts + 1][i + 1] = verts[i];
@@ -806,7 +806,7 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
lines[i + 1][0] = verts[a];
lines[i + 1][i + 1] = verts[b];
-
+
e_tmp = *e;
v1_tmp = *verts[a];
v2_tmp = *verts[b];
@@ -819,7 +819,7 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
BMO_edge_flag_enable(bm, e_new, ELE_INNER);
}
}
-
+
/**
* <pre>
* v5
@@ -906,9 +906,9 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
float smooth, fractal, along_normal;
bool use_sphere, use_single_edge, use_grid_fill, use_only_quads;
int cornertype, seed, i, j, a, b, numcuts, totesel, smooth_falloff;
-
+
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT);
-
+
numcuts = BMO_slot_int_get(op->slots_in, "cuts");
seed = BMO_slot_int_get(op->slots_in, "seed");
smooth = BMO_slot_float_get(op->slots_in, "smooth");
@@ -935,7 +935,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
patterns[1] = &quad_2edge_fan;
break;
}
-
+
if (use_single_edge) {
patterns[0] = &quad_1edge;
patterns[2] = &tri_1edge;
@@ -953,12 +953,12 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
patterns[3] = NULL;
patterns[5] = NULL;
}
-
+
/* add a temporary shapekey layer to store displacements on current geometry */
BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
bmo_subd_init_shape_info(bm, &params);
-
+
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp);
copy_v3_v3(co, v->co);
@@ -990,7 +990,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_rng_free(rng);
}
-
+
BMO_slot_map_to_flag(bm, op->slots_in, "custom_patterns",
BM_FACE, FACE_CUSTOMFILL);
@@ -1105,10 +1105,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
}
-
+
if (!matched && totesel) {
SubDFaceData *fd;
-
+
BMO_face_flag_enable(bm, face, SUBD_SPLIT);
/* must initialize all members here */
@@ -1146,7 +1146,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
if (!pat && fd->totedgesel == 2) {
int vlen;
-
+
/* ok, no pattern. we still may be able to do something */
BLI_array_clear(loops);
BLI_array_clear(loops_split);
@@ -1156,7 +1156,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BM_ITER_ELEM_INDEX (l, &liter, face, BM_LOOPS_OF_FACE, a) {
loops[a] = l;
}
-
+
vlen = BLI_array_len(loops);
/* find the boundary of one of the split edges */
@@ -1167,7 +1167,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
break;
}
}
-
+
if (BMO_vert_flag_test(bm, loops[(a + numcuts + 1) % vlen]->v, ELE_INNER)) {
b = (a + numcuts + 1) % vlen;
}
@@ -1182,7 +1182,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
}
}
-
+
b += numcuts - 1;
BLI_array_grow_items(loops_split, numcuts);
@@ -1230,7 +1230,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
b = (b - 1) % vlen;
a = (a + 1) % vlen;
}
-
+
/* Since these are newly created vertices, we don't need to worry about them being legal,
* ... though there are some cases we _should_ check for
* - concave corner of an ngon.
@@ -1281,7 +1281,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, params.shape_info.tmpkey);
-
+
BLI_stack_free(facedata);
if (edges) BLI_array_free(edges);
if (verts) BLI_array_free(verts);
@@ -1290,7 +1290,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL_NOLOOP, ELE_INNER);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
-
+
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
}
@@ -1306,7 +1306,7 @@ void BM_mesh_esubdivide(
const int seed)
{
BMOperator op;
-
+
/* use_sphere isnt exposed here since its only used for new primitives */
BMO_op_initf(bm, &op, BMO_FLAG_DEFAULTS,
"subdivide_edges edges=%he "
@@ -1325,9 +1325,9 @@ void BM_mesh_esubdivide(
use_single_edge, use_grid_fill,
use_only_quads,
seed);
-
+
BMO_op_exec(bm, &op);
-
+
switch (seltype) {
case SUBDIV_SELECT_NONE:
break;
@@ -1354,11 +1354,11 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMEdge *e;
SubDParams params = {0};
-
+
params.numcuts = BMO_slot_int_get(op->slots_in, "cuts");
params.op = op;
params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents");
-
+
BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
bmo_subd_init_shape_info(bm, &params);
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index 163a9ef599c..e686ef0429a 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -83,9 +83,9 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
sf_vert_map = BLI_ghash_ptr_new_ex(__func__, BMO_slot_buffer_count(op->slots_in, "edges"));
BMO_slot_vec_get(op->slots_in, "normal", normal);
-
+
BLI_scanfill_begin(&sf_ctx);
-
+
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
ScanFillVert *sf_verts[2];
BMVert **e_verts = &e->v1;
@@ -108,7 +108,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
}
nors_tot = BLI_ghash_len(sf_vert_map);
BLI_ghash_free(sf_vert_map, NULL, NULL);
-
+
if (is_zero_v3(normal)) {
/* calculate the normal from the cross product of vert-edge pairs.
@@ -225,7 +225,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
f = BM_face_create_quad_tri(bm,
sf_tri->v1->tmp.p, sf_tri->v2->tmp.p, sf_tri->v3->tmp.p, NULL,
NULL, BM_CREATE_NO_DOUBLE);
-
+
BMO_face_flag_enable(bm, f, ELE_NEW);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
if (!BMO_edge_flag_test(bm, l->e, EDGE_MARK)) {
@@ -233,9 +233,9 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
}
}
}
-
+
BLI_scanfill_end(&sf_ctx);
-
+
if (use_beauty) {
BMOperator bmop;
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index ca96e5b4b78..33380cee18e 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -151,7 +151,7 @@ typedef struct BoundVert {
bool any_seam; /* are any of the edges attached here seams? */
bool visited; /* used during delta adjust pass */
// int _pad;
-} BoundVert;
+} BoundVert;
/* Mesh structure replacing a vertex */
typedef struct VMesh {
@@ -511,7 +511,7 @@ static BMFace *bev_create_ngon(
static BMFace *bev_create_quad(
BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
- BMFace *f1, BMFace *f2, BMFace *f3, BMFace *f4,
+ BMFace *f1, BMFace *f2, BMFace *f3, BMFace *f4,
int mat_nr)
{
BMVert *varr[4] = {v1, v2, v3, v4};
@@ -521,7 +521,7 @@ static BMFace *bev_create_quad(
static BMFace *bev_create_quad_ex(
BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
- BMFace *f1, BMFace *f2, BMFace *f3, BMFace *f4,
+ BMFace *f1, BMFace *f2, BMFace *f3, BMFace *f4,
BMEdge *e1, BMEdge *e2, BMEdge *e3, BMEdge *e4,
int mat_nr)
{
@@ -1355,7 +1355,7 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int n,
else
copy_v3_v3(r_co, pro->cob);
}
-
+
else {
if (n == bp->seg) {
BLI_assert(pro->prof_co != NULL);
@@ -2119,7 +2119,7 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
#ifdef DEBUG_ADJUST
printf("b[%d]=%f * %f, for e%d->offset_r\n", row, weight, eright->offset_r, BM_elem_index_get(eright->e));
#endif
-
+
/* residue np + 2*i + 1 (if cycle) else np - 1 + 2*i + 1:
* left offset for parm i matches its spec; weighted */
row = row + 1;
@@ -2607,7 +2607,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm0)
float beta, gamma;
VMesh *vm1;
BoundVert *bndv;
-
+
n = vm0->count;
ns0 = vm0->seg;
ns20 = ns0 / 2;
@@ -2627,7 +2627,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm0)
add_v3_v3v3(acc, co1, co2);
madd_v3_v3fl(acc, co, -2.0f);
madd_v3_v3fl(co, acc, -1.0f / 6.0f);
-
+
copy_v3_v3(mesh_vert_canon(vm1, i, 0, 2 * k)->co, co);
}
}
@@ -2642,7 +2642,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm0)
add_v3_v3v3(acc, co1, co2);
madd_v3_v3fl(acc, co, -2.0f);
madd_v3_v3fl(co, acc, -1.0f / 6.0f);
-
+
copy_v3_v3(mesh_vert_canon(vm1, i, 0, k)->co, co);
}
bndv = bndv->next;
@@ -2661,7 +2661,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm0)
/* Now we do the internal vertices, using standard Catmull-Clark
* and assuming all boundary vertices have valence 4 */
-
+
/* The new face vertices */
for (i = 0; i < n; i++) {
for (j = 0; j < ns20; j++) {
@@ -2882,7 +2882,7 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp)
copy_v3_v3(bndv->profile.proj_dir, bndv->profile.plane_no);
calculate_profile(bp, bndv);
get_profile_point(bp, &bndv->profile, 1, 2, mesh_vert(vm0, i, 0, 1)->co);
-
+
bndv = bndv->next;
}
/* center vertex */
@@ -4618,7 +4618,7 @@ static void bevel_reattach_wires(BMesh *bm, BevelParams *bp, BMVert *v)
vclosest = bndv->nv.v;
votherclosest = bndvother->nv.v;
dclosest = d;
-
+
}
} while ((bndvother = bndvother->next) != bvother->vmesh->boundstart);
}
@@ -5215,7 +5215,7 @@ static float geometry_collide_offset(BevelParams *bp, EdgeHalf *eb)
kc = kc / bp->offset;
th1 = angle_v3v3v3(va->co, vb->co, vc->co);
th2 = angle_v3v3v3(vb->co, vc->co, vd->co);
-
+
/* First calculate offset at which edge B collapses, which happens
* when advancing clones of A, B, C all meet at a point.
* This only happens if at least two of those three edges have non-zero k's */
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index fc4bbea108b..95298986f5a 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -270,7 +270,7 @@ void AnimationExporter::export_sampled_transrotloc_animation(Object *ob, std::ve
create_sampled_animation(3, ctimes, baked_curves[SCALE], ob_name, "scale", "", false);
create_sampled_animation(3, ctimes, baked_curves[LOC], ob_name, "location", "", false);
- /* Not sure how to export rotation as a 3channel animation,
+ /* Not sure how to export rotation as a 3channel animation,
* so separate into 3 single animations for now:
*/
@@ -314,7 +314,7 @@ void AnimationExporter::operator()(Object *ob)
//This needs to be handled by extra profiles, so postponed for now
//export_morph_animation(ob);
-
+
//Export Lamp parameter animations
if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action) {
FCurve *fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first);
@@ -338,7 +338,7 @@ void AnimationExporter::operator()(Object *ob)
if ((STREQ(transformName, "lens")) ||
(STREQ(transformName, "ortho_scale")) ||
- (STREQ(transformName, "clip_end")) ||
+ (STREQ(transformName, "clip_end")) ||
(STREQ(transformName, "clip_start")))
{
create_keyframed_animation(ob, fcu, transformName, true);
@@ -380,7 +380,7 @@ void AnimationExporter::export_object_constraint_animation(Object *ob)
}
void AnimationExporter::export_morph_animation(Object *ob)
-{
+{
FCurve *fcu;
char *transformName;
Key *key = BKE_key_from_object(ob);
@@ -388,12 +388,12 @@ void AnimationExporter::export_morph_animation(Object *ob)
if (key->adt && key->adt->action) {
fcu = (FCurve *)key->adt->action->curves.first;
-
+
while (fcu) {
transformName = extract_transform_name(fcu->rna_path);
create_keyframed_animation(ob, fcu, transformName, true);
-
+
fcu = fcu->next;
}
}
@@ -407,17 +407,17 @@ void AnimationExporter::make_anim_frames_from_targets(Object *ob, std::vector<fl
bConstraint *con;
for (con = (bConstraint *)conlist->first; con; con = con->next) {
ListBase targets = {NULL, NULL};
-
+
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
-
+
if (!validateConstraints(con)) continue;
if (cti && cti->get_constraint_targets) {
bConstraintTarget *ct;
Object *obtar;
- /* get targets
+ /* get targets
* - constraints should use ct->matrix, not directly accessing values
- * - ct->matrix members have not yet been calculated here!
+ * - ct->matrix members have not yet been calculated here!
*/
cti->get_constraint_targets(con, &targets);
@@ -438,7 +438,7 @@ void AnimationExporter::make_anim_frames_from_targets(Object *ob, std::vector<fl
float *AnimationExporter::get_eul_source_for_quat(Object *ob)
{
FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
- const int keys = fcu->totvert;
+ const int keys = fcu->totvert;
float *quat = (float *)MEM_callocN(sizeof(float) * fcu->totvert * 4, "quat output source values");
float *eul = (float *)MEM_callocN(sizeof(float) * fcu->totvert * 3, "quat output source values");
float temp_quat[4];
@@ -520,11 +520,11 @@ void AnimationExporter::create_keyframed_animation(Object *ob, FCurve *fcu, char
/*
* Note: Handle transformation animations separately (to apply matrix inverse to fcurves)
- * We will use the object to evaluate the animation on all keyframes and calculate the
+ * We will use the object to evaluate the animation on all keyframes and calculate the
* resulting object matrix. We need this to incorporate the
* effects of the parent inverse matrix (when it contains a rotation component)
*
- * TODO: try to combine exported fcurves into 3 channel animations like done
+ * TODO: try to combine exported fcurves into 3 channel animations like done
* in export_sampled_animation(). For now each channel is exported as separate <Animation>.
*/
@@ -648,7 +648,7 @@ void AnimationExporter::create_keyframed_animation(Object *ob, FCurve *fcu, char
"/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true);
//if shape key animation, this is the main problem, how to define the channel targets.
/*target = get_morph_id(ob) +
- "/value" +*/
+ "/value" +*/
}
addChannel(COLLADABU::URI(empty, sampler_id), target);
@@ -673,7 +673,7 @@ void AnimationExporter::write_bone_animation_matrix(Object *ob_arm, Bone *bone)
}
bool AnimationExporter::is_bone_deform_group(Bone *bone)
-{
+{
bool is_def;
//Check if current bone is deform
if ((bone->flag & BONE_NO_DEFORM) == 0) return true;
@@ -707,7 +707,7 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B
fcu = fcu->next;
}
- if (!(fcu)) return;*/
+ if (!(fcu)) return;*/
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);
if (!pchan)
@@ -728,7 +728,7 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B
dae_baked_animation(fra, ob_arm, bone);
}
- if (flag & ARM_RESTPOS)
+ if (flag & ARM_RESTPOS)
arm->flag = flag;
BKE_pose_where_is(depsgraph, scene, ob_arm);
}
@@ -921,7 +921,7 @@ void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNa
if (axis) {
param.push_back(axis);
}
- else
+ else
if (transform) {
param.push_back("TRANSFORM");
}
@@ -1307,7 +1307,7 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
enable_fcurves(ob->adt->action, bone->name);
}
-
+
std::vector<float>::iterator it;
int j = 0;
for (it = frames.begin(); it != frames.end(); it++) {
@@ -1326,7 +1326,7 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
else {
BKE_pose_where_is_bone(depsgraph, scene, ob, pchan, ctime, 1);
}
-
+
// compute bone local mat
if (bone->parent) {
invert_m4_m4(ipar, parchan->pose_mat);
@@ -1334,7 +1334,7 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
}
else
copy_m4_m4(mat, pchan->pose_mat);
-
+
/* OPEN_SIM_COMPATIBILITY
* AFAIK animation to second life is via BVH, but no
* reason to not have the collada-animation be correct
@@ -1359,7 +1359,7 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
else {
copy_m4_m4(mat, ob->obmat);
}
-
+
UnitConverter converter;
double outmat[4][4];
@@ -1515,7 +1515,7 @@ std::string AnimationExporter::get_light_param_sid(char *rna_path, int tm_type,
if (tm_name.size()) {
if (axis_name[0])
return tm_name + "." + std::string(axis_name);
- else
+ else
return tm_name;
}
@@ -1564,7 +1564,7 @@ std::string AnimationExporter::get_camera_param_sid(char *rna_path, int tm_type,
if (tm_name.size()) {
if (axis_name[0])
return tm_name + "." + std::string(axis_name);
- else
+ else
return tm_name;
}
@@ -1751,7 +1751,7 @@ void AnimationExporter::find_sampleframes(Object *ob, std::vector<float> &fra)
} while (true);
}
-/*
+/*
* find keyframes of all the objects animations
*/
void AnimationExporter::find_keyframes(Object *ob, std::vector<float> &fra)
@@ -1844,7 +1844,7 @@ void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bo
arm->flag &= ~ARM_RESTPOS;
BKE_pose_where_is(depsgraph, scene, ob_arm);
}
- //v array will hold all values which will be exported.
+ //v array will hold all values which will be exported.
if (fra.size()) {
float *values = (float *)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
sample_animation(values, fra, transform_type, bone, ob_arm, pchan);
@@ -1870,7 +1870,7 @@ void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bo
}
// restore restpos
- if (flag & ARM_RESTPOS)
+ if (flag & ARM_RESTPOS)
arm->flag = flag;
BKE_pose_where_is(depsgraph, scene, ob_arm);
}
diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h
index 2ed0a92d89c..a50bcaf0ef4 100644
--- a/source/blender/collada/AnimationExporter.h
+++ b/source/blender/collada/AnimationExporter.h
@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
-extern "C"
+extern "C"
{
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -100,8 +100,8 @@ public:
bool exportAnimations(Scene *sce);
// called for each exported object
- void operator() (Object *ob);
-
+ void operator() (Object *ob);
+
protected:
const ExportSettings *export_settings;
@@ -127,7 +127,7 @@ protected:
// dae_bone_animation -> add_bone_animation
// (blend this into dae_bone_animation)
void dae_bone_animation(std::vector<float> &fra, float *v, int tm_type, int axis, std::string ob_name, std::string bone_name);
-
+
void dae_baked_animation(std::vector<float> &fra, Object *ob_arm, Bone *bone);
void dae_baked_object_animation(std::vector<float> &fra, Object *ob);
@@ -140,9 +140,9 @@ protected:
void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform);
-
+
void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool is_angle, float *values, int *length);
-
+
float* get_eul_source_for_quat(Object *ob );
bool is_flat_line(std::vector<float> &values, int channel_count);
@@ -171,12 +171,12 @@ protected:
std::string create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents);
std::string fake_interpolation_source(int tot, const std::string& anim_id, const char *axis_name);
-
+
// for rotation, axis name is always appended and the value of append_axis is ignored
std::string get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
std::string get_light_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
std::string get_camera_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
-
+
void find_keyframes(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name);
void find_keyframes(Object *ob, std::vector<float> &fra);
void find_sampleframes(Object *ob, std::vector<float> &fra);
@@ -185,13 +185,13 @@ protected:
void make_anim_frames_from_targets(Object *ob, std::vector<float> &frames );
void find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode);
-
+
// enable fcurves driving a specific bone, disable all the rest
// if bone_name = NULL enable all fcurves
void enable_fcurves(bAction *act, char *bone_name);
-
+
bool hasAnimations(Scene *sce);
-
+
char *extract_transform_name(char *rna_path);
std::string getObjectBoneName(Object *ob, const FCurve * fcu);
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index c9b2f6d6d55..e57f8c2f652 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -118,7 +118,7 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
// input, output
- bez.vec[1][0] = bc_get_float_value(input, j) * fps;
+ bez.vec[1][0] = bc_get_float_value(input, j) * fps;
bez.vec[1][1] = bc_get_float_value(output, j * dim + i);
@@ -135,14 +135,14 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
// outtangent
bez.vec[2][0] = bc_get_float_value(outtan, (j * 2 * dim) + (2 * i)) * fps;
bez.vec[2][1] = bc_get_float_value(outtan, (j * 2 * dim) + (2 * i) + 1);
- if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER)
+ if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER)
bez.ipo = BEZT_IPO_BEZ;
- else
+ else
bez.ipo = BEZT_IPO_CONST;
//bez.h1 = bez.h2 = HD_AUTO;
}
else {
- bez.h1 = bez.h2 = HD_AUTO;
+ bez.h1 = bez.h2 = HD_AUTO;
bez.ipo = BEZT_IPO_LIN;
}
// bez.ipo = U.ipo_new; /* use default interpolation mode here... */
@@ -180,13 +180,13 @@ void AnimationImporter::fcurve_is_used(FCurve *fcu)
}
-void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector<FCurve *>& curves, char *rna_path, int array_index, Animation *animated)
+void AnimationImporter::add_fcurves_to_object(Main *bmain, Object *ob, std::vector<FCurve *>& curves, char *rna_path, int array_index, Animation *animated)
{
bAction *act;
-
- if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID *)&ob->id, 1);
+
+ if (!ob->adt || !ob->adt->action) act = verify_adt_action(bmain, (ID *)&ob->id, 1);
else act = ob->adt->action;
-
+
std::vector<FCurve *>::iterator it;
int i;
@@ -198,39 +198,39 @@ void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector<FCurve *>&
if (is_rotation)
fcurve_deg_to_rad(fcu);
#endif
-
+
for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) {
FCurve *fcu = *it;
fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
-
+
if (array_index == -1) fcu->array_index = i;
else fcu->array_index = array_index;
-
+
if (ob->type == OB_ARMATURE) {
bActionGroup *grp = NULL;
const char *bone_name = bc_get_joint_name(animated->node);
-
+
if (bone_name) {
/* try to find group */
grp = BKE_action_group_find_name(act, bone_name);
-
+
/* no matching groups, so add one */
if (grp == NULL) {
/* Add a new group, and make it active */
grp = (bActionGroup *)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
-
+
grp->flag = AGRP_SELECTED;
BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
-
+
BLI_addtail(&act->groups, grp);
BLI_uniquename(&act->groups, grp, CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "Group"), '.',
offsetof(bActionGroup, name), 64);
}
-
+
/* add F-Curve to group */
action_groups_add_channel(act, grp, fcu);
fcurve_is_used(fcu);
-
+
}
#if 0
if (is_rotation) {
@@ -263,7 +263,7 @@ bool AnimationImporter::write_animation(const COLLADAFW::Animation *anim)
{
if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) {
COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve *)anim;
-
+
// XXX Don't know if it's necessary
// Should we check outPhysicalDimension?
if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) {
@@ -296,10 +296,10 @@ bool AnimationImporter::write_animation(const COLLADAFW::Animation *anim)
else {
fprintf(stderr, "FORMULA animation type is not supported yet.\n");
}
-
+
return true;
}
-
+
// called on post-process stage after writeVisualScenes
bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList *animlist)
{
@@ -340,16 +340,16 @@ virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act)
{
bActionGroup *grp;
int i;
-
+
for (grp = (bActionGroup *)act->groups.first; grp; grp = grp->next) {
FCurve *eulcu[3] = {NULL, NULL, NULL};
-
+
if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end())
continue;
std::vector<FCurve *> &rot_fcurves = fcurves_actionGroup_map[grp];
-
+
if (rot_fcurves.size() > 3) continue;
for (i = 0; i < rot_fcurves.size(); i++)
@@ -437,7 +437,7 @@ void AnimationImporter::modify_fcurve(std::vector<FCurve *> *curves, const char
for (it = curves->begin(), i = 0; it != curves->end(); it++, i++) {
FCurve *fcu = *it;
fcu->rna_path = BLI_strdup(rna_path);
-
+
if (array_index == -1) fcu->array_index = i;
else fcu->array_index = array_index;
@@ -674,7 +674,7 @@ void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& list
}
}
}
-
+
}
float AnimationImporter::convert_to_focal_length(float in_xfov, int fov_type, float aspect, float sensorx)
@@ -711,7 +711,7 @@ void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId& listid
//Add the curves of the current animation to the object
for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
FCurve *fcu = *iter;
-
+
for (unsigned int i = 0; i < fcu->totvert; i++) {
fcu->bezt[i].vec[0][1] = convert_to_focal_length(fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x);
fcu->bezt[i].vec[1][1] = convert_to_focal_length(fcu->bezt[i].vec[1][1], fov_type, aspect, cam->sensor_x);
@@ -725,7 +725,7 @@ void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId& listid
}
}
-void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node,
+void AnimationImporter::apply_matrix_curves(Main *bmain, Object *ob, std::vector<FCurve *>& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node,
COLLADAFW::Transformation *tm)
{
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
@@ -840,7 +840,7 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a
add_bezt(newcu[i], fra, scale[i - 7]);
}
}
- verify_adt_action((ID *)&ob->id, 1);
+ verify_adt_action(bmain, (ID *)&ob->id, 1);
ListBase *curves = &ob->adt->action->curves;
@@ -897,18 +897,18 @@ static const double get_aspect_ratio(const COLLADAFW::Camera *camera)
return aspect;
}
-static ListBase &get_animation_curves(Material *ma)
+static ListBase &get_animation_curves(Main *bmain, Material *ma)
{
bAction *act;
if (!ma->adt || !ma->adt->action)
- act = verify_adt_action((ID *)&ma->id, 1);
+ act = verify_adt_action(bmain, (ID *)&ma->id, 1);
else
act = ma->adt->action;
return act->curves;
}
-void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
+void AnimationImporter::translate_Animations(Main *bmain, COLLADAFW::Node *node,
std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>& root_map,
std::multimap<COLLADAFW::UniqueId, Object *>& object_map,
std::map<COLLADAFW::UniqueId, const COLLADAFW::Object *> FW_object_map,
@@ -941,7 +941,7 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
- if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID *)&ob->id, 1);
+ if (!ob->adt || !ob->adt->action) act = verify_adt_action(bmain, (ID *)&ob->id, 1);
else act = ob->adt->action;
//Get the list of animation curves of the object
@@ -949,7 +949,7 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
- //for each transformation in node
+ //for each transformation in node
for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
@@ -972,12 +972,11 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
for (unsigned int j = 0; j < bindings.getCount(); j++) {
animcurves = curve_map[bindings[j].animation];
if (is_matrix) {
- apply_matrix_curves(ob, animcurves, root, node, transform);
+ apply_matrix_curves(bmain, ob, animcurves, root, node, transform);
}
- else {
-
+ else {
if (is_joint) {
- add_bone_animation_sampled(ob, animcurves, root, node, transform);
+ add_bone_animation_sampled(bmain, ob, animcurves, root, node, transform);
}
else {
//calculate rnapaths and array index of fcurves according to transformation and animation class
@@ -987,12 +986,12 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
//Add the curves of the current animation to the object
for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
FCurve *fcu = *iter;
-
+
BLI_addtail(AnimCurves, fcu);
fcurve_is_used(fcu);
}
}
-
+
}
}
}
@@ -1005,7 +1004,7 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
if ((animType->light) != 0) {
Lamp *lamp = (Lamp *) ob->data;
- if (!lamp->adt || !lamp->adt->action) act = verify_adt_action((ID *)&lamp->id, 1);
+ if (!lamp->adt || !lamp->adt->action) act = verify_adt_action(bmain, (ID *)&lamp->id, 1);
else act = lamp->adt->action;
ListBase *AnimCurves = &(act->curves);
@@ -1018,7 +1017,7 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
const COLLADAFW::Color *col = &(light->getColor());
const COLLADAFW::UniqueId& listid = col->getAnimationList();
- Assign_color_animations(listid, AnimCurves, "color");
+ Assign_color_animations(listid, AnimCurves, "color");
}
if ((animType->light & LIGHT_FOA) != 0) {
const COLLADAFW::AnimatableFloat *foa = &(light->getFallOffAngle());
@@ -1039,7 +1038,7 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
if (animType->camera != 0) {
Camera *cam = (Camera *) ob->data;
if (!cam->adt || !cam->adt->action)
- act = verify_adt_action((ID *)&cam->id, 1);
+ act = verify_adt_action(bmain, (ID *)&cam->id, 1);
else
act = cam->adt->action;
@@ -1052,14 +1051,14 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
if ((animType->camera & CAMERA_XFOV) != 0) {
const COLLADAFW::AnimatableFloat *xfov = &(camera->getXFov());
const COLLADAFW::UniqueId& listid = xfov->getAnimationList();
- double aspect = get_aspect_ratio(camera);
+ double aspect = get_aspect_ratio(camera);
Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_XFOV);
}
else if ((animType->camera & CAMERA_YFOV) != 0) {
const COLLADAFW::AnimatableFloat *yfov = &(camera->getYFov());
const COLLADAFW::UniqueId& listid = yfov->getAnimationList();
- double aspect = get_aspect_ratio(camera);
+ double aspect = get_aspect_ratio(camera);
Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_YFOV);
}
@@ -1103,7 +1102,7 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
fprintf(stderr, "Collada: Node %s refers to undefined material\n", node->getName().c_str());
continue;
}
- ListBase &AnimCurves = get_animation_curves(ma);
+ ListBase &AnimCurves = get_animation_curves(bmain, ma);
const COLLADAFW::CommonEffectPointerArray& commonEffects = ef->getCommonEffects();
COLLADAFW::EffectCommon *efc = commonEffects[0];
if ((animType->material & MATERIAL_SHININESS) != 0) {
@@ -1137,7 +1136,7 @@ void AnimationImporter::translate_Animations(COLLADAFW::Node *node,
delete animType;
}
-void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector<FCurve *>& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node, COLLADAFW::Transformation *tm)
+void AnimationImporter::add_bone_animation_sampled(Main *bmain, Object *ob, std::vector<FCurve *>& animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node, COLLADAFW::Transformation *tm)
{
const char *bone_name = bc_get_joint_name(node);
char joint_path[200];
@@ -1260,7 +1259,7 @@ void AnimationImporter::add_bone_animation_sampled(Object *ob, std::vector<FCurv
add_bezt(newcu[i], fra, scale[i - 7]);
}
}
- verify_adt_action((ID *)&ob->id, 1);
+ verify_adt_action(bmain, (ID *)&ob->id, 1);
// add curves
for (int i = 0; i < totcu; i++) {
@@ -1282,7 +1281,7 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(const COLLADAF
const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
- //for each transformation in node
+ //for each transformation in node
for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
COLLADAFW::Transformation *transform = nodeTransforms[i];
const COLLADAFW::UniqueId& listid = transform->getAnimationList();
@@ -1370,7 +1369,7 @@ int AnimationImporter::setAnimType(const COLLADAFW::Animatable *prop, int types,
anim_type = types;
return anim_type;
-}
+}
// Is not used anymore.
void AnimationImporter::find_frames_old(std::vector<float> *frames, COLLADAFW::Node *node, COLLADAFW::Transformation::TransformationType tm_type)
@@ -1392,7 +1391,7 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames, COLLADAFW::N
const COLLADAFW::UniqueId& listid = transform->getAnimationList();
//if transform is animated its animlist must exist.
if (animlist_map.find(listid) != animlist_map.end()) {
-
+
const COLLADAFW::AnimationList *animlist = animlist_map[listid];
const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
@@ -1436,17 +1435,17 @@ void AnimationImporter::find_frames_old(std::vector<float> *frames, COLLADAFW::N
// prerequisites:
// animlist_map - map animlist id -> animlist
// curve_map - map anim id -> curve(s)
-Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node,
+Object *AnimationImporter::translate_animation_OLD(Main *bmain, COLLADAFW::Node *node,
std::map<COLLADAFW::UniqueId, Object *>& object_map,
std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>& root_map,
COLLADAFW::Transformation::TransformationType tm_type,
Object *par_job)
{
-
+
bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
-
+
COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
@@ -1457,11 +1456,11 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node,
// frames at which to sample
std::vector<float> frames;
-
+
find_frames_old(&frames, node, tm_type);
-
+
unsigned int i;
-
+
float irest_dae[4][4];
float rest[4][4], irest[4][4];
@@ -1659,7 +1658,7 @@ Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node,
#endif
}
- verify_adt_action((ID *)&ob->id, 1);
+ verify_adt_action(bmain, (ID *)&ob->id, 1);
ListBase *curves = &ob->adt->action->curves;
@@ -1732,9 +1731,9 @@ void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW::
}
}
-static void report_class_type_unsupported(const char *path,
+static void report_class_type_unsupported(const char *path,
const COLLADAFW::AnimationList::AnimationClass animclass,
- const COLLADAFW::Transformation::TransformationType type)
+ const COLLADAFW::Transformation::TransformationType type)
{
if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) {
fprintf(stderr, "%s: UNKNOWN animation class\n", path);
@@ -1829,7 +1828,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float
fprintf(stderr, "%s: expected 1 curve, got %d\n", path, (int)curves.size());
return false;
}
-
+
switch (animclass) {
case COLLADAFW::AnimationList::POSITION_X:
vec[0] = evaluate_fcurve(curves[0], fra);
@@ -2011,7 +2010,7 @@ void AnimationImporter::add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurv
{
const char *bone_name = bc_get_joint_name(node);
bAction *act = ob->adt->action;
-
+
/* try to find group */
bActionGroup *grp = BKE_action_group_find_name(act, bone_name);
diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h
index e25116cac9f..f63329158f0 100644
--- a/source/blender/collada/AnimationImporter.h
+++ b/source/blender/collada/AnimationImporter.h
@@ -19,7 +19,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-
+
/** \file AnimationImporter.h
* \ingroup collada
*/
@@ -75,9 +75,9 @@ private:
std::map<COLLADAFW::UniqueId, const COLLADAFW::AnimationList*> animlist_map;
std::vector<FCurve*> unused_curves;
std::map<COLLADAFW::UniqueId, Object*> joint_objects;
-
+
FCurve *create_fcurve(int array_index, const char *rna_path);
-
+
void add_bezt(FCurve *fcu, float frame, float value, eBezTriple_Interpolation ipo=BEZT_IPO_LIN);
// create one or several fcurves depending on the number of parameters being animated
@@ -87,9 +87,9 @@ private:
void fcurve_is_used(FCurve *fcu);
- void add_fcurves_to_object(Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated);
+ void add_fcurves_to_object(Main *bmain, Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated);
+
-
int typeFlag;
std::string import_from_version;
@@ -121,7 +121,7 @@ private:
MATERIAL_TRANSPARENCY = 1 << 4,
MATERIAL_IOR = 1 << 5
};
-
+
enum AnimationType
{
INANIMATE = 0,
@@ -144,7 +144,7 @@ public:
void set_import_from_version(std::string import_from_version);
bool write_animation(const COLLADAFW::Animation* anim);
-
+
// called on post-process stage after writeVisualScenes
bool write_animation_list(const COLLADAFW::AnimationList* animlist);
@@ -153,7 +153,7 @@ public:
virtual void change_eul_to_quat(Object *ob, bAction *act);
#endif
- void translate_Animations(COLLADAFW::Node * Node,
+ void translate_Animations(Main *bmain, COLLADAFW::Node * Node,
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
std::multimap<COLLADAFW::UniqueId, Object*>& object_map,
std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map,
@@ -161,10 +161,10 @@ public:
AnimMix* get_animation_type( const COLLADAFW::Node * node, std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map );
- void apply_matrix_curves(Object *ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node,
+ void apply_matrix_curves(Main *bmain, Object *ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node,
COLLADAFW::Transformation * tm );
-
- void add_bone_animation_sampled(Object *ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm);
+
+ void add_bone_animation_sampled(Main *bmain, Object *ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm);
void Assign_transform_animations(COLLADAFW::Transformation* transform,
const COLLADAFW::AnimationList::AnimationBinding *binding,
@@ -175,18 +175,18 @@ public:
void Assign_lens_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const double aspect, Camera *cam, const char *anim_type, int fov_type);
int setAnimType ( const COLLADAFW::Animatable * prop, int type, int addition);
-
+
void modify_fcurve(std::vector<FCurve*>* curves, const char *rna_path, int array_index );
void unused_fcurve(std::vector<FCurve*>* curves );
// prerequisites:
// animlist_map - map animlist id -> animlist
// curve_map - map anim id -> curve(s)
- Object * translate_animation_OLD(COLLADAFW::Node *node,
+ Object * translate_animation_OLD(Main *bmain, COLLADAFW::Node *node,
std::map<COLLADAFW::UniqueId, Object*>& object_map,
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
COLLADAFW::Transformation::TransformationType tm_type,
Object *par_job = NULL);
-
+
void find_frames( std::vector<float>* frames, std::vector<FCurve*>* curves );
void find_frames_old( std::vector<float>* frames, COLLADAFW::Node * node, COLLADAFW::Transformation::TransformationType tm_type );
// internal, better make it private
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index 5e349535610..85b9d3297ca 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -62,10 +62,11 @@ ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSett
}
// write bone nodes
-void ArmatureExporter::add_armature_bones(Depsgraph *depsgraph, Object *ob_arm,
+void ArmatureExporter::add_armature_bones(bContext *C, Depsgraph *depsgraph, Object *ob_arm,
Scene *sce, SceneExporter *se,
std::list<Object *>& child_objects)
{
+ Main *bmain = CTX_data_main(C);
// write bone nodes
bArmature * armature = (bArmature *)ob_arm->data;
@@ -77,11 +78,11 @@ void ArmatureExporter::add_armature_bones(Depsgraph *depsgraph, Object *ob_arm,
for (Bone *bone = (Bone *)armature->bonebase.first; bone; bone = bone->next) {
// start from root bones
if (!bone->parent)
- add_bone_node(depsgraph, bone, ob_arm, sce, se, child_objects);
+ add_bone_node(C, depsgraph, bone, ob_arm, sce, se, child_objects);
}
if (!is_edited) {
- ED_armature_from_edit(armature);
+ ED_armature_from_edit(bmain, armature);
ED_armature_edit_free(armature);
}
}
@@ -117,7 +118,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob)
}
InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob, this->export_settings->active_uv_only);
-
+
ins.add();
return true;
}
@@ -146,7 +147,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O
Base *base = (Base *) sce->base.first;
while (base) {
Object *ob = base->object;
-
+
if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) {
objects.push_back(ob);
}
@@ -157,7 +158,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O
#endif
// parent_mat is armature-space
-void ArmatureExporter::add_bone_node(Depsgraph *depsgraph, Bone *bone, Object *ob_arm, Scene *sce,
+void ArmatureExporter::add_bone_node(bContext *C, Depsgraph *depsgraph, Bone *bone, Object *ob_arm, Scene *sce,
SceneExporter *se,
std::list<Object *>& child_objects)
{
@@ -231,7 +232,7 @@ void ArmatureExporter::add_bone_node(Depsgraph *depsgraph, Bone *bone, Object *o
mul_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv);
}
- se->writeNodes(depsgraph, *i, sce);
+ se->writeNodes(C, depsgraph, *i, sce);
copy_m4_m4((*i)->parentinv, backup_parinv);
child_objects.erase(i++);
@@ -240,13 +241,13 @@ void ArmatureExporter::add_bone_node(Depsgraph *depsgraph, Bone *bone, Object *o
}
for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
- add_bone_node(depsgraph, child, ob_arm, sce, se, child_objects);
+ add_bone_node(C, depsgraph, child, ob_arm, sce, se, child_objects);
}
node.end();
}
else {
for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
- add_bone_node(depsgraph, child, ob_arm, sce, se, child_objects);
+ add_bone_node(C, depsgraph, child, ob_arm, sce, se, child_objects);
}
}
}
@@ -264,7 +265,7 @@ void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW:
if (!has_restmat) {
/* Have no restpose matrix stored, try old style <= Blender 2.78 */
-
+
bc_create_restpose_mat(this->export_settings, bone, bone_rest_mat, bone->arm_mat, true);
if (bone->parent) {
diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h
index 17c02d637e8..7efa8b70e43 100644
--- a/source/blender/collada/ArmatureExporter.h
+++ b/source/blender/collada/ArmatureExporter.h
@@ -60,7 +60,7 @@ public:
ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
// write bone nodes
- void add_armature_bones(struct Depsgraph *depsgraph, Object *ob_arm, Scene *sce, SceneExporter *se,
+ void add_armature_bones(bContext *C, struct Depsgraph *depsgraph, Object *ob_arm, Scene *sce, SceneExporter *se,
std::list<Object *>& child_objects);
bool add_instance_controller(Object *ob);
@@ -85,7 +85,7 @@ private:
// Scene, SceneExporter and the list of child_objects
// are required for writing bone parented objects
- void add_bone_node(struct Depsgraph *depsgraph, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se,
+ void add_bone_node(bContext *C, struct Depsgraph *depsgraph, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se,
std::list<Object *>& child_objects);
void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node);
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index f24688479af..19f174d4840 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -61,7 +61,7 @@ ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh,
view_layer(view_layer),
unit_converter(conv),
import_settings(import_settings),
- empty(NULL),
+ empty(NULL),
mesh_importer(mesh) {
}
@@ -103,7 +103,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
std::vector<COLLADAFW::Node *>::iterator it;
it = std::find(finished_joints.begin(), finished_joints.end(), node);
if (it != finished_joints.end()) return chain_length;
-
+
EditBone *bone = ED_armature_ebone_add(arm, bc_get_joint_name(node));
totbone++;
@@ -141,7 +141,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
if (parent) bone->parent = parent;
- float loc[3], size[3], rot[3][3];
+ float loc[3], size[3], rot[3][3];
BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(arm);
BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels, extended_bones);
int layer = be.get_bone_layers();
@@ -386,7 +386,7 @@ void ArmatureImporter::set_euler_rotmode()
COLLADAFW::Node *joint = it->second;
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator sit;
-
+
for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) {
SkinInfo& skin = sit->second;
@@ -410,7 +410,7 @@ void ArmatureImporter::set_euler_rotmode()
Object *ArmatureImporter::get_empty_for_leaves()
{
if (empty) return empty;
-
+
empty = bc_add_object(scene, view_layer, OB_EMPTY, NULL);
empty->empty_drawtype = OB_EMPTY_SPHERE;
@@ -448,7 +448,7 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm)
return armature_joints.back();
}
#endif
-void ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
+void ArmatureImporter::create_armature_bones(Main *bmain, std::vector<Object *> &ob_arms)
{
std::vector<COLLADAFW::Node *>::iterator ri;
std::vector<std::string> layer_labels;
@@ -456,7 +456,7 @@ void ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
//if there is an armature created for root_joint next root_joint
for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
if (get_armature_for_joint(*ri) != NULL) continue;
-
+
Object *ob_arm = joint_parent_map[(*ri)->getUniqueId()];
if (!ob_arm)
continue;
@@ -481,7 +481,7 @@ void ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
}
/* exit armature edit mode to populate the Armature object */
- ED_armature_from_edit(armature);
+ ED_armature_from_edit(bmain, armature);
ED_armature_edit_free(armature);
ED_armature_to_edit(armature);
@@ -489,7 +489,7 @@ void ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
fix_leaf_bone_hierarchy(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation);
unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
- ED_armature_from_edit(armature);
+ ED_armature_from_edit(bmain, armature);
ED_armature_edit_free(armature);
int index = std::find(ob_arms.begin(), ob_arms.end(), ob_arm) - ob_arms.begin();
@@ -501,7 +501,7 @@ void ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
}
}
-Object *ArmatureImporter::create_armature_bones(SkinInfo& skin)
+Object *ArmatureImporter::create_armature_bones(Main *bmain, SkinInfo& skin)
{
// just do like so:
// - get armature
@@ -572,8 +572,8 @@ Object *ArmatureImporter::create_armature_bones(SkinInfo& skin)
}
if (!shared && this->joint_parent_map.size() > 0) {
- // All armatures have been created while creating the Node tree.
- // The Collada exporter currently does not create a
+ // All armatures have been created while creating the Node tree.
+ // The Collada exporter currently does not create a
// strict relationship between geometries and armatures
// So when we reimport a Blender collada file, then we have
// to guess what is meant.
@@ -619,7 +619,7 @@ Object *ArmatureImporter::create_armature_bones(SkinInfo& skin)
}
/* exit armature edit mode to populate the Armature object */
- ED_armature_from_edit(armature);
+ ED_armature_from_edit(bmain, armature);
ED_armature_edit_free(armature);
ED_armature_to_edit(armature);
@@ -627,7 +627,7 @@ Object *ArmatureImporter::create_armature_bones(SkinInfo& skin)
connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
}
fix_leaf_bone_hierarchy(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation);
- ED_armature_from_edit(armature);
+ ED_armature_from_edit(bmain, armature);
ED_armature_edit_free(armature);
DEG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
@@ -657,12 +657,12 @@ void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, con
}
else {
-
+
copy_m4_m4(mat, obmat);
float invObmat[4][4];
invert_m4_m4(invObmat, ob_arm->obmat);
mul_m4_m4m4(pchan->pose_mat, invObmat, mat);
-
+
}
//float angle = 0.0f;
@@ -709,6 +709,7 @@ void ArmatureImporter::add_root_joint(COLLADAFW::Node *node)
// here we add bones to armatures, having armatures previously created in write_controller
void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &objects_to_scale)
{
+ Main *bmain = CTX_data_main(C);
std::vector<Object *> ob_arms;
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
@@ -718,7 +719,7 @@ void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &object
SkinInfo& skin = it->second;
- Object *ob_arm = create_armature_bones(skin);
+ Object *ob_arm = create_armature_bones(bmain, skin);
// link armature with a mesh object
const COLLADAFW::UniqueId &uid = skin.get_controller_uid();
@@ -757,9 +758,9 @@ void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &object
// free memory stolen from SkinControllerData
skin.free();
}
-
+
//for bones without skins
- create_armature_bones(ob_arms);
+ create_armature_bones(bmain, ob_arms);
// Fix bone relations
std::vector<Object *>::iterator ob_arm_it;
@@ -773,7 +774,7 @@ void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &object
fix_parent_connect(armature, (Bone *)armature->bonebase.first);
- ED_armature_from_edit(armature);
+ ED_armature_from_edit(bmain, armature);
ED_armature_edit_free(armature);
}
}
@@ -807,9 +808,9 @@ bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControlle
// don't forget to call defgroup_unique_name before we copy
- // controller data uid -> [armature] -> joint data,
+ // controller data uid -> [armature] -> joint data,
// [mesh object]
- //
+ //
SkinInfo skin(unit_converter);
skin.borrow_skin_controller_data(data);
@@ -867,7 +868,7 @@ void ArmatureImporter::make_shape_keys()
//Prereq: all the geometries must be imported and mesh objects must be made
Object *source_ob = this->mesh_importer->get_object_by_geom_uid((*mc)->getSource());
-
+
if (source_ob) {
Mesh *source_me = (Mesh *)source_ob->data;
@@ -875,7 +876,7 @@ void ArmatureImporter::make_shape_keys()
Key *key = source_me->key = BKE_key_add((ID *)source_me);
key->type = KEY_RELATIVE;
KeyBlock *kb;
-
+
//insert basis key
kb = BKE_keyblock_add_ctime(key, "Basis", false);
BKE_keyblock_convert_from_mesh(source_me, kb);
@@ -886,14 +887,14 @@ void ArmatureImporter::make_shape_keys()
//This'll do for now since only mesh morphing is imported
Mesh *me = this->mesh_importer->get_mesh_by_geom_uid(morphTargetIds[i]);
-
+
if (me) {
me->key = key;
std::string morph_name = *this->mesh_importer->get_geometry_name(me->id.name);
kb = BKE_keyblock_add_ctime(key, morph_name.c_str(), false);
BKE_keyblock_convert_from_mesh(me, kb);
-
+
//apply weights
weight = morphWeights.getFloatValues()->getData()[i];
kb->curval = weight;
@@ -989,14 +990,14 @@ BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Nod
has_connect = et->setData("connect", &connect_type);
bool has_roll = et->setData("roll", &roll);
-
+
layers = et->setData("layer", layers);
if (has_tail && !has_connect)
{
/* got a bone tail definition but no connect info -> bone is not connected */
has_connect = true;
- connect_type = 0;
+ connect_type = 0;
}
be->set_bone_layers(layers, layer_labels);
diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h
index f260bb2307c..b13e40bf855 100644
--- a/source/blender/collada/ArmatureImporter.h
+++ b/source/blender/collada/ArmatureImporter.h
@@ -130,8 +130,8 @@ private:
ArmatureJoints& get_armature_joints(Object *ob_arm);
#endif
- Object *create_armature_bones(SkinInfo& skin);
- void create_armature_bones(std::vector<Object *> &arm_objs);
+ Object *create_armature_bones(Main *bmain, SkinInfo& skin);
+ void create_armature_bones(Main *bmain, std::vector<Object *> &arm_objs);
/** TagsMap typedef for uid_tags_map. */
typedef std::map<std::string, ExtraTags*> TagsMap;
@@ -158,16 +158,16 @@ public:
bool write_controller(const COLLADAFW::Controller* controller);
COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId& controller_uid);
-
+
Object *get_armature_for_joint(COLLADAFW::Node *node);
void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count);
-
+
// gives a world-space mat
bool get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint);
void set_tags_map( TagsMap& tags_map);
-
+
};
#endif
diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp
index 649288c2db4..32bd24f1e0b 100644
--- a/source/blender/collada/CameraExporter.cpp
+++ b/source/blender/collada/CameraExporter.cpp
@@ -56,9 +56,9 @@ void forEachCameraObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set
void CamerasExporter::exportCameras(Scene *sce)
{
openLibrary();
-
+
forEachCameraObjectInExportSet(sce, *this, this->export_settings->export_set);
-
+
closeLibrary();
}
void CamerasExporter::operator()(Object *ob, Scene *sce)
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
index f6dbc965b42..122094e33a6 100644
--- a/source/blender/collada/ControllerExporter.cpp
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -99,7 +99,7 @@ bool ControllerExporter::add_instance_controller(Object *ob)
}
InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob, this->export_settings->active_uv_only);
-
+
ins.add();
return true;
}
@@ -148,7 +148,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O
Base *base = (Base *) sce->base.first;
while (base) {
Object *ob = base->object;
-
+
if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) {
objects.push_back(ob);
}
@@ -203,7 +203,7 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
this->export_settings->export_mesh_type,
this->export_settings->apply_modifiers,
this->export_settings->triangulate);
-
+
if (!me->dvert) return;
std::string controller_name = id_name(ob_arm);
@@ -246,7 +246,7 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
for (j = 0; j < vert->totweight; j++) {
int idx = vert->dw[j].def_nr;
if (idx >= joint_index_by_def_index.size()) {
- // XXX: Maybe better find out where and
+ // XXX: Maybe better find out where and
// why the Out Of Bound indexes get created ?
oob_counter += 1;
}
@@ -314,7 +314,7 @@ void ControllerExporter::export_morph_controller(Object *ob, Key *key)
std::string targets_id = add_morph_targets(key, ob);
std::string morph_weights_id = add_morph_weights(key, ob);
-
+
COLLADASW::TargetsElement targets(mSW);
COLLADASW::InputList &input = targets.getInputList();
@@ -376,7 +376,7 @@ std::string ControllerExporter::add_morph_weights(Key *key, Object *ob)
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("MORPH_WEIGHT");
-
+
source.prepareToAppendValues();
KeyBlock *kb = (KeyBlock *)key->block.first;
@@ -396,7 +396,7 @@ void ControllerExporter::add_weight_extras(Key *key)
{
// can also try the base element and param alternative
COLLADASW::BaseExtraTechnique extra;
-
+
KeyBlock * kb = (KeyBlock *)key->block.first;
//skip the basis
kb = kb->next;
@@ -447,7 +447,7 @@ std::string ControllerExporter::add_joints_source(Object *ob_arm, ListBase *defb
source.setArrayId(source_id + ARRAY_ID_SUFFIX);
source.setAccessorCount(totjoint);
source.setAccessorStride(1);
-
+
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("JOINT");
@@ -480,7 +480,7 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBas
source.setArrayId(source_id + ARRAY_ID_SUFFIX);
source.setAccessorCount(totjoint); //BLI_listbase_count(defbase));
source.setAccessorStride(16);
-
+
source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("TRANSFORM");
@@ -509,7 +509,7 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBas
float bind_mat[4][4]; /* derived from bone->arm_mat */
bool has_bindmat = bc_get_property_matrix(pchan->bone, "bind_mat", bind_mat);
-
+
if (!has_bindmat) {
/* Have no bind matrix stored, try old style <= Blender 2.78 */
@@ -571,7 +571,7 @@ std::string ControllerExporter::add_weights_source(Mesh *me, const std::string&
source.setArrayId(source_id + ARRAY_ID_SUFFIX);
source.setAccessorCount(weights.size());
source.setAccessorStride(1);
-
+
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("WEIGHT");
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index a66c4db7b4d..9e78c164dad 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -62,7 +62,7 @@
#include "COLLADASWInstanceNode.h"
#include "COLLADASWBaseInputElement.h"
-extern "C"
+extern "C"
{
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -180,8 +180,7 @@ static COLLADABU::NativeString make_temp_filepath(const char *name, const char *
// COLLADA allows this through multiple <channel>s in <animation>.
// For this to work, we need to know objects that use a certain action.
-
-int DocumentExporter::exportCurrentScene(Scene *sce)
+int DocumentExporter::exportCurrentScene(bContext *C, Scene *sce)
{
PointerRNA sceneptr, unit_settings;
PropertyRNA *system; /* unused , *scale; */
@@ -258,14 +257,14 @@ int DocumentExporter::exportCurrentScene(Scene *sce)
#endif
asset.getContributor().mAuthoringTool = version_buf;
asset.add();
-
+
LinkNode *export_set = this->export_settings->export_set;
// <library_cameras>
if (bc_has_object_type(export_set, OB_CAMERA)) {
CamerasExporter ce(writer, this->export_settings);
ce.exportCameras(sce);
}
-
+
// <library_lights>
if (bc_has_object_type(export_set, OB_LAMP)) {
LightsExporter le(writer, this->export_settings);
@@ -275,11 +274,11 @@ int DocumentExporter::exportCurrentScene(Scene *sce)
// <library_images>
ImagesExporter ie(writer, this->export_settings);
ie.exportImages(sce);
-
+
// <library_effects>
EffectsExporter ee(writer, this->export_settings);
ee.exportEffects(sce);
-
+
// <library_materials>
MaterialsExporter me(writer, this->export_settings);
me.exportMaterials(sce);
@@ -293,7 +292,7 @@ int DocumentExporter::exportCurrentScene(Scene *sce)
// <library_controllers>
ArmatureExporter arm_exporter(writer, this->export_settings);
ControllerExporter controller_exporter(writer, this->export_settings);
- if (bc_has_object_type(export_set, OB_ARMATURE) || this->export_settings->include_shapekeys)
+ if (bc_has_object_type(export_set, OB_ARMATURE) || this->export_settings->include_shapekeys)
{
controller_exporter.export_controllers(depsgraph, sce);
}
@@ -307,14 +306,14 @@ int DocumentExporter::exportCurrentScene(Scene *sce)
AnimationExporter ae(depsgraph, writer, this->export_settings);
ae.exportAnimations(sce);
}
- se.exportScene(depsgraph, sce);
-
+ se.exportScene(C, depsgraph, sce);
+
// <scene>
std::string scene_name(translate_id(id_name(sce)));
COLLADASW::Scene scene(writer, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING,
scene_name));
scene.add();
-
+
// close <Collada>
writer->endDocument();
delete writer;
diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h
index c98f82e68b4..8a48ca29090 100644
--- a/source/blender/collada/DocumentExporter.h
+++ b/source/blender/collada/DocumentExporter.h
@@ -40,7 +40,7 @@ class DocumentExporter
{
public:
DocumentExporter(Depsgraph *depsgraph, const ExportSettings *export_settings);
- int exportCurrentScene(Scene *sce);
+ int exportCurrentScene(bContext *C, Scene *sce);
void exportScenes(const char *filename);
private:
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 47b720614ea..ae573fec0d8 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -130,7 +130,7 @@ bool DocumentImporter::import()
COLLADASaxFWL::Loader loader(&errorHandler);
COLLADAFW::Root root(&loader, this);
ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer));
-
+
loader.registerExtraDataCallbackHandler(ehandler);
// deselect all to select new objects
@@ -143,19 +143,19 @@ bool DocumentImporter::import()
delete ehandler;
return false;
}
-
+
if (errorHandler.hasError()) {
delete ehandler;
return false;
}
-
+
/** TODO set up scene graph and such here */
-
+
mImportStage = Controller;
-
+
COLLADASaxFWL::Loader loader2;
COLLADAFW::Root root2(&loader2, this);
-
+
if (!root2.loadDocument(encodedFilename)) {
fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n");
delete ehandler;
@@ -198,7 +198,7 @@ void DocumentImporter::finish()
for (sit = vscenes.begin(); sit != vscenes.end(); sit++) {
PointerRNA sceneptr, unit_settings;
PropertyRNA *system, *scale;
-
+
// for scene unit settings: system, scale_length
RNA_id_pointer_create(&sce->id, &sceneptr);
@@ -207,7 +207,7 @@ void DocumentImporter::finish()
scale = RNA_struct_find_property(&unit_settings, "scale_length");
if (this->import_settings->import_units) {
-
+
switch (unit_converter.isMetricSystem()) {
case UnitConverter::Metric:
RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
@@ -272,7 +272,7 @@ void DocumentImporter::finish()
DEG_relations_tag_update(bmain);
}
-
+
bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units);
delete objects_to_scale;
@@ -281,7 +281,7 @@ void DocumentImporter::finish()
void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = NULL, Object *parob = NULL)
{
-
+ Main *bmain = CTX_data_main(mContext);
// The split in #29246, rootmap 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
@@ -316,7 +316,7 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW
translate_anim_recursive(node, node, parob);
}
else {
- anim_importer.translate_Animations(node, root_map, object_map, FW_object_map, uid_material_map);
+ anim_importer.translate_Animations(bmain, node, root_map, object_map, FW_object_map, uid_material_map);
COLLADAFW::NodePointerArray &children = node->getChildNodes();
for (i = 0; i < children.getCount(); i++) {
translate_anim_recursive(children[i], node, NULL);
@@ -473,7 +473,7 @@ void DocumentImporter::create_constraints(ExtraTags *et, Object *ob)
short type = 0;
et->setData("type", &type);
BKE_constraint_add_for_object(ob, "Test_con", type);
-
+
}
}
@@ -634,7 +634,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
root_objects->push_back(ob);
}
}
-
+
// XXX: if there're multiple instances, only one is stored
if (!ob) {
@@ -700,7 +700,7 @@ bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScen
{
if (mImportStage != General)
return true;
-
+
// this method called on post process after writeGeometry, writeMaterial, etc.
// for each <node> in <visual_scene>:
@@ -712,18 +712,18 @@ bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScen
// we link Objects with Meshes here
vscenes.push_back(visualScene);
-
+
return true;
}
-/** When this method is called, the writer must handle all nodes contained in the
+/** When this method is called, the writer must handle all nodes contained in the
* library nodes.
* \return The writer should return true, if writing succeeded, false otherwise.*/
bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes)
{
if (mImportStage != General)
return true;
-
+
Scene *sce = CTX_data_scene(mContext);
const COLLADAFW::NodePointerArray& nodes = libraryNodes->getNodes();
@@ -743,7 +743,7 @@ bool DocumentImporter::writeGeometry(const COLLADAFW::Geometry *geom)
{
if (mImportStage != General)
return true;
-
+
return mesh_importer.write_geometry(geom);
}
@@ -753,13 +753,13 @@ bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat)
{
if (mImportStage != General)
return true;
-
+
const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId();
Material *ma = BKE_material_add(G.main, (char *)str_mat_id.c_str());
-
+
this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
this->uid_material_map[cmat->getUniqueId()] = ma;
-
+
return true;
}
@@ -768,7 +768,7 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
// TODO: add back texture and extended material parameter support
-
+
// blinn
if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
#if 0
@@ -802,9 +802,9 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
#if 0
ma->ang = ef->getIndexOfRefraction().getFloatValue();
#endif
-
+
COLLADAFW::Color col;
-
+
// DIFFUSE
// color
if (ef->getDiffuse().isColor()) {
@@ -816,7 +816,7 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
// texture
else if (ef->getDiffuse().isTexture()) {
#if 0
- COLLADAFW::Texture ctex = ef->getDiffuse().getTexture();
+ COLLADAFW::Texture ctex = ef->getDiffuse().getTexture();
#endif
}
// AMBIENT
@@ -829,7 +829,7 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
// texture
else if (ef->getAmbient().isTexture()) {
#if 0
- COLLADAFW::Texture ctex = ef->getAmbient().getTexture();
+ COLLADAFW::Texture ctex = ef->getAmbient().getTexture();
#endif
}
// SPECULAR
@@ -843,7 +843,7 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
// texture
else if (ef->getSpecular().isTexture()) {
#if 0
- COLLADAFW::Texture ctex = ef->getSpecular().getTexture();
+ COLLADAFW::Texture ctex = ef->getSpecular().getTexture();
#endif
}
// REFLECTIVE
@@ -856,7 +856,7 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
// texture
else if (ef->getReflective().isTexture()) {
#if 0
- COLLADAFW::Texture ctex = ef->getReflective().getTexture();
+ COLLADAFW::Texture ctex = ef->getReflective().getTexture();
#endif
}
@@ -869,7 +869,7 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia
// texture
else if (ef->getEmission().isTexture()) {
#if 0
- COLLADAFW::Texture ctex = ef->getEmission().getTexture();
+ COLLADAFW::Texture ctex = ef->getEmission().getTexture();
#endif
}
@@ -902,14 +902,14 @@ bool DocumentImporter::writeEffect(const COLLADAFW::Effect *effect)
{
if (mImportStage != General)
return true;
-
+
const COLLADAFW::UniqueId& uid = effect->getUniqueId();
-
+
if (uid_effect_map.find(uid) == uid_effect_map.end()) {
fprintf(stderr, "Couldn't find a material by UID.\n");
return true;
}
-
+
Material *ma = uid_effect_map[uid];
std::map<COLLADAFW::UniqueId, Material *>::iterator iter;
for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) {
@@ -928,7 +928,7 @@ bool DocumentImporter::writeEffect(const COLLADAFW::Effect *effect)
COLLADAFW::EffectCommon *ef = common_efs[0];
write_profile_COMMON(ef, ma);
this->FW_object_map[effect->getUniqueId()] = effect;
-
+
return true;
}
@@ -939,16 +939,16 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
{
if (mImportStage != General)
return true;
-
+
Camera *cam = NULL;
std::string cam_id, cam_name;
-
+
ExtraTags *et=getExtraTags(camera->getUniqueId());
cam_id = camera->getOriginalId();
cam_name = camera->getName();
if (cam_name.size()) cam = (Camera *)BKE_camera_add(G.main, (char *)cam_name.c_str());
else cam = (Camera *)BKE_camera_add(G.main, (char *)cam_id.c_str());
-
+
if (!cam) {
fprintf(stderr, "Cannot create camera.\n");
return true;
@@ -961,7 +961,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
}
cam->clipsta = camera->getNearClippingPlane().getValue();
cam->clipend = camera->getFarClippingPlane().getValue();
-
+
COLLADAFW::Camera::CameraType type = camera->getCameraType();
switch (type) {
case COLLADAFW::Camera::ORTHOGRAPHIC:
@@ -981,7 +981,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
}
break;
}
-
+
switch (camera->getDescriptionType()) {
case COLLADAFW::Camera::ASPECTRATIO_AND_Y:
{
@@ -1051,7 +1051,7 @@ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
// read nothing, use blender defaults.
break;
}
-
+
this->uid_camera_map[camera->getUniqueId()] = cam;
this->FW_object_map[camera->getUniqueId()] = camera;
// XXX import camera options
@@ -1064,7 +1064,7 @@ bool DocumentImporter::writeImage(const COLLADAFW::Image *image)
{
if (mImportStage != General)
return true;
-
+
const std::string& imagepath = image->getImageURI().toNativePath();
char dir[FILE_MAX];
@@ -1075,7 +1075,7 @@ bool DocumentImporter::writeImage(const COLLADAFW::Image *image)
BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str());
if (BLI_exists(absolute_path)) {
workpath = absolute_path;
- }
+ }
else {
// Maybe imagepath was already absolute ?
if (!BLI_exists(imagepath.c_str())) {
@@ -1091,7 +1091,7 @@ bool DocumentImporter::writeImage(const COLLADAFW::Image *image)
return true;
}
this->uid_image_map[image->getUniqueId()] = ima;
-
+
return true;
}
@@ -1185,7 +1185,7 @@ bool DocumentImporter::writeLight(const COLLADAFW::Light *light)
// assuming point light (const att = 1.0);
att1 = 1.0f;
}
-
+
d *= (1.0f / unit_converter.getLinearMeter());
lamp->energy = e;
@@ -1247,7 +1247,7 @@ bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim)
{
if (mImportStage != General)
return true;
-
+
// return true;
return anim_importer.write_animation(anim);
}
@@ -1257,7 +1257,7 @@ bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animat
{
if (mImportStage != General)
return true;
-
+
// return true;
return anim_importer.write_animation_list(animationList);
}
@@ -1274,7 +1274,7 @@ bool DocumentImporter::writeController(const COLLADAFW::Controller *controller)
{
if (mImportStage != General)
return true;
-
+
return armature_importer.write_controller(controller);
}
diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h
index 758caef7e60..b31a086d710 100644
--- a/source/blender/collada/DocumentImporter.h
+++ b/source/blender/collada/DocumentImporter.h
@@ -78,7 +78,7 @@ public:
void create_constraints(ExtraTags *et, Object *ob);
std::vector<Object *> *write_node(COLLADAFW::Node*, COLLADAFW::Node*, Scene*, Object*, bool);
void write_profile_COMMON(COLLADAFW::EffectCommon*, Material*);
-
+
void translate_anim_recursive(COLLADAFW::Node*, COLLADAFW::Node*, Object*);
/**
@@ -149,7 +149,7 @@ private:
ArmatureImporter armature_importer;
MeshImporter mesh_importer;
AnimationImporter anim_importer;
-
+
/** TagsMap typedef for uid_tags_map. */
typedef std::map<std::string, ExtraTags*> TagsMap;
/** Tags map of unique id as a string and ExtraTags instance. */
@@ -165,7 +165,7 @@ private:
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> node_map;
std::vector<const COLLADAFW::VisualScene*> vscenes;
std::vector<Object*> libnode_ob;
-
+
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> root_map; // find root joint by child joint uid, for bone tree evaluation during resampling
std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map;
diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp
index dbcdfd01a9c..271dab5deea 100644
--- a/source/blender/collada/EffectExporter.cpp
+++ b/source/blender/collada/EffectExporter.cpp
@@ -57,7 +57,7 @@ static std::string getActiveUVLayerName(Object *ob)
int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
if (num_layers)
return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE));
-
+
return "";
}
@@ -105,12 +105,12 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
// TODO: add back texture and extended material parameter support
openEffect(translate_id(id_name(ma)) + "-effect");
-
+
COLLADASW::EffectProfile ep(mSW);
ep.setProfileType(COLLADASW::EffectProfile::COMMON);
ep.openProfile();
writeLambert(ep, ma);
-
+
COLLADASW::ColorOrTexture cot;
// transparency
@@ -144,7 +144,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
//COLLADASW::Surface surfaces[MAX_MTEX];
//void *samp_surf[MAX_MTEX][2];
void *samp_surf[MAX_MTEX];
-
+
// image to index to samp_surf map
// samp_surf[index] stores 2 pointers, sampler and surface
std::map<std::string, int> im_samp_map;
@@ -153,10 +153,10 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
for (a = 0, b = 0; a < tex_indices.size(); a++) {
MTex *t = ma->mtex[tex_indices[a]];
Image *ima = t->tex->ima;
-
+
// Image not set for texture
if (!ima) continue;
-
+
std::string key(id_name(ima));
key = translate_id(key);
@@ -171,7 +171,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
// COLLADASW::NewParamSurface surface(mSW);
// surface->setParamType(COLLADASW::CSW_SURFACE_TYPE_2D);
-
+
//<newparam> <sampler> <source>
COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
@@ -180,11 +180,11 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
// copy values to arrays since they will live longer
samplers[a] = sampler;
//surfaces[a] = surface;
-
+
// store pointers so they can be used later when we create <texture>s
samp_surf[b] = &samplers[a];
//samp_surf[b][1] = &surfaces[a];
-
+
im_samp_map[key] = b;
b++;
}
@@ -238,12 +238,12 @@ COLLADASW::ColorOrTexture EffectsExporter::createTexture(Image *ima,
COLLADASW::Sampler *sampler
/*COLLADASW::Surface *surface*/)
{
-
+
COLLADASW::Texture texture(translate_id(id_name(ima)));
texture.setTexcoord(uv_layer_name);
//texture.setSurface(*surface);
texture.setSampler(*sampler);
-
+
COLLADASW::ColorOrTexture cot(texture);
return cot;
}
diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h
index eac428ae330..a1395bfde9f 100644
--- a/source/blender/collada/EffectExporter.h
+++ b/source/blender/collada/EffectExporter.h
@@ -50,25 +50,25 @@ public:
void exportEffects(Scene *sce);
void operator()(Material *ma, Object *ob);
-
+
COLLADASW::ColorOrTexture createTexture(Image *ima,
std::string& uv_layer_name,
COLLADASW::Sampler *sampler
/*COLLADASW::Surface *surface*/);
-
+
COLLADASW::ColorOrTexture getcol(float r, float g, float b, float a);
private:
void writeLambert(COLLADASW::EffectProfile &ep, Material *ma);
void writeTextures(COLLADASW::EffectProfile &ep,
std::string &key,
- COLLADASW::Sampler *sampler,
+ COLLADASW::Sampler *sampler,
MTex *t, Image *ima,
std::string &uvname );
bool hasEffects(Scene *sce);
-
+
const ExportSettings *export_settings;
-
+
Scene *scene;
};
diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp
index 7e18328f000..26674445d98 100644
--- a/source/blender/collada/ErrorHandler.cpp
+++ b/source/blender/collada/ErrorHandler.cpp
@@ -53,7 +53,7 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
See https://github.com/KhronosGroup/OpenCOLLADA/issues/442
*/
bool isWarning = false;
-
+
if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) {
COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error;
const GeneratedSaxParser::ParserError& parserError = saxParserError->getError();
diff --git a/source/blender/collada/ExtraHandler.cpp b/source/blender/collada/ExtraHandler.cpp
index bef7accd9f7..5d704bc9abc 100644
--- a/source/blender/collada/ExtraHandler.cpp
+++ b/source/blender/collada/ExtraHandler.cpp
@@ -54,9 +54,9 @@ bool ExtraHandler::elementEnd(const char *elementName)
bool ExtraHandler::textData(const char *text, size_t textLength)
{
char buf[1024];
-
+
if (currentElement.length() == 0 || currentExtraTags == 0) return false;
-
+
BLI_strncpy(buf, text, textLength + 1);
currentExtraTags->addTag(currentElement, std::string(buf));
return true;
diff --git a/source/blender/collada/ExtraHandler.h b/source/blender/collada/ExtraHandler.h
index f380c3d6871..4dda862b3cc 100644
--- a/source/blender/collada/ExtraHandler.h
+++ b/source/blender/collada/ExtraHandler.h
@@ -50,31 +50,31 @@ public:
/** Handle the beginning of an element. */
bool elementBegin( const char* elementName, const char** attributes);
-
+
/** Handle the end of an element. */
bool elementEnd(const char* elementName );
-
+
/** Receive the data in text format. */
bool textData(const char* text, size_t textLength);
/** Method to ask, if the current callback handler want to read the data of the given extra element. */
- bool parseElement (
- const char* profileName,
- const unsigned long& elementHash,
+ bool parseElement (
+ const char* profileName,
+ const unsigned long& elementHash,
const COLLADAFW::UniqueId& uniqueId,
COLLADAFW::Object* object);
/** For backwards compatibility with older OpenCollada, new version added object parameter */
- bool parseElement (
- const char* profileName,
- const unsigned long& elementHash,
+ bool parseElement (
+ const char* profileName,
+ const unsigned long& elementHash,
const COLLADAFW::UniqueId& uniqueId);
private:
/** Disable default copy constructor. */
ExtraHandler(const ExtraHandler& pre);
/** Disable default assignment operator. */
const ExtraHandler& operator= ( const ExtraHandler& pre );
-
+
/** Handle to DocumentImporter for interface to extra element data saving. */
DocumentImporter* dimp;
AnimationImporter* aimp;
diff --git a/source/blender/collada/ExtraTags.cpp b/source/blender/collada/ExtraTags.cpp
index ea225d8a4ae..fd249884c3f 100644
--- a/source/blender/collada/ExtraTags.cpp
+++ b/source/blender/collada/ExtraTags.cpp
@@ -50,7 +50,7 @@ bool ExtraTags::isProfile(std::string profile)
bool ExtraTags::addTag(std::string tag, std::string data)
{
tags[tag] = data;
-
+
return true;
}
diff --git a/source/blender/collada/ExtraTags.h b/source/blender/collada/ExtraTags.h
index ad272dcba65..84857622ee8 100644
--- a/source/blender/collada/ExtraTags.h
+++ b/source/blender/collada/ExtraTags.h
@@ -41,35 +41,35 @@ public:
/** Handle the beginning of an element. */
bool addTag(std::string tag, std::string data);
-
+
/** Set given short pointer to value of tag, if it exists. */
bool setData(std::string tag, short *data);
-
+
/** Set given int pointer to value of tag, if it exists. */
bool setData(std::string tag, int *data);
-
+
/** Set given float pointer to value of tag, if it exists. */
bool setData(std::string tag, float *data);
-
+
/** Set given char pointer to value of tag, if it exists. */
bool setData(std::string tag, char *data);
std::string setData(std::string tag, std::string &data);
/** Return true if the extra tags is for specified profile. */
bool isProfile(std::string profile);
-
+
private:
/** Disable default copy constructor. */
ExtraTags(const ExtraTags& pre);
/** Disable default assignment operator. */
const ExtraTags& operator= ( const ExtraTags& pre );
-
+
/** The profile for which the tags are. */
std::string profile;
-
+
/** Map of tag and text pairs. */
std::map<std::string, std::string> tags;
-
+
/** Get text data for tag as an int. */
int asInt(std::string tag, bool *ok);
/** Get text data for tag as a float. */
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 87b47353596..65e844cbe50 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -70,14 +70,14 @@ void GeometryExporter::exportGeom(struct Depsgraph *depsgraph, Scene *sce)
}
void GeometryExporter::operator()(Object *ob)
-{
+{
// XXX don't use DerivedMesh, Mesh instead?
-#if 0
+#if 0
DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH);
#endif
bool use_instantiation = this->export_settings->use_object_instantiation;
- Mesh *me = bc_get_mesh_copy(mDepsgraph, mScene,
+ Mesh *me = bc_get_mesh_copy(mDepsgraph, mScene,
ob,
this->export_settings->export_mesh_type,
this->export_settings->apply_modifiers,
@@ -88,7 +88,7 @@ void GeometryExporter::operator()(Object *ob)
std::vector<BCPolygonNormalsIndices> norind;
// Skip if linked geometry was already exported from another reference
- if (use_instantiation &&
+ if (use_instantiation &&
exportedGeometry.find(geom_id) != exportedGeometry.end())
{
return;
@@ -104,15 +104,15 @@ void GeometryExporter::operator()(Object *ob)
// openMesh(geoId, geoName, meshId)
openMesh(geom_id, geom_name);
-
+
// writes <source> for vertex coords
createVertsSource(geom_id, me);
-
+
// writes <source> for normal coords
createNormalsSource(geom_id, me, nor);
bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
-
+
// writes <source> for uv coords if mesh has uv coords
if (has_uvs) {
createTexcoordsSource(geom_id, me);
@@ -144,9 +144,9 @@ void GeometryExporter::operator()(Object *ob)
createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
}
}
-
+
closeMesh();
-
+
if (me->flag & ME_TWOSIDED) {
mSW->appendTextBlock("<extra><technique profile=\"MAYA\"><double_sided>1</double_sided></technique></extra>");
}
@@ -175,7 +175,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name);
std::vector<Normal> nor;
std::vector<BCPolygonNormalsIndices> norind;
-
+
if (exportedGeometry.find(geom_id) != exportedGeometry.end())
{
return;
@@ -191,15 +191,15 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
// openMesh(geoId, geoName, meshId)
openMesh(geom_id, geom_name);
-
+
// writes <source> for vertex coords
createVertsSource(geom_id, me);
-
+
// writes <source> for normal coords
createNormalsSource(geom_id, me, nor);
bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
-
+
// writes <source> for uv coords if mesh has uv coords
if (has_uvs) {
createTexcoordsSource(geom_id, me);
@@ -220,7 +220,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
//createLooseEdgeList(ob, me, geom_id, norind);
- // XXX slow
+ // XXX slow
if (ob->totcol) {
for (int a = 0; a < ob->totcol; a++) {
createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
@@ -229,9 +229,9 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
else {
createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
}
-
+
closeMesh();
-
+
if (me->flag & ME_TWOSIDED) {
mSW->appendTextBlock("<extra><technique profile=\"MAYA\"><double_sided>1</double_sided></technique></extra>");
}
@@ -250,9 +250,9 @@ void GeometryExporter::createLooseEdgeList(Object *ob,
std::vector<unsigned int> edge_list;
int index;
- // Find all loose edges in Mesh
+ // Find all loose edges in Mesh
// and save vertex indices in edge_list
- for (index = 0; index < totedges; index++)
+ for (index = 0; index < totedges; index++)
{
MEdge *edge = &medges[index];
@@ -273,14 +273,14 @@ void GeometryExporter::createLooseEdgeList(Object *ob,
COLLADASW::InputList &til = lines.getInputList();
-
- // creates <input> in <lines> for vertices
+
+ // creates <input> in <lines> for vertices
COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0);
til.push_back(input1);
lines.prepareToAppendValues();
- for (index = 0; index < edges_in_linelist; index++)
+ for (index = 0; index < edges_in_linelist; index++)
{
lines.appendValues(edge_list[2 * index + 1]);
lines.appendValues(edge_list[2 * index]);
@@ -318,7 +318,7 @@ void GeometryExporter::createPolylist(short material_index,
// count faces with this material
for (i = 0; i < totpolys; i++) {
MPoly *p = &mpolys[i];
-
+
if (p->mat_nr == material_index) {
faces_in_polylist++;
vcount_list.push_back(p->totloop);
@@ -330,13 +330,13 @@ void GeometryExporter::createPolylist(short material_index,
fprintf(stderr, "%s: material with index %d is not used.\n", id_name(ob).c_str(), material_index);
return;
}
-
+
Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL;
COLLADASW::Polylist polylist(mSW);
-
+
// sets count attribute in <polylist>
polylist.setCount(faces_in_polylist);
-
+
// sets material name
if (ma) {
std::string material_id = get_material_id(ma);
@@ -344,18 +344,18 @@ void GeometryExporter::createPolylist(short material_index,
ostr << translate_id(material_id);
polylist.setMaterial(ostr.str());
}
-
+
COLLADASW::InputList &til = polylist.getInputList();
-
- // creates <input> in <polylist> for vertices
+
+ // creates <input> in <polylist> for vertices
COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0);
-
+
// creates <input> in <polylist> for normals
COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1);
-
+
til.push_back(input1);
til.push_back(input2);
-
+
// if mesh has uv coords writes <input> for TEXCOORD
int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1;
@@ -387,13 +387,13 @@ void GeometryExporter::createPolylist(short material_index,
map_index++;
}
}
-
+
// sets <vcount>
polylist.setVCountList(vcount_list);
-
+
// performs the actual writing
polylist.prepareToAppendValues();
-
+
// <p>
int texindex = 0;
for (i = 0; i < totpolys; i++) {
@@ -417,7 +417,7 @@ void GeometryExporter::createPolylist(short material_index,
texindex += loop_count;
}
-
+
polylist.finish();
}
@@ -430,7 +430,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
#endif
int totverts = me->totvert;
MVert *verts = me->mvert;
-
+
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) +
@@ -450,7 +450,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
for (i = 0; i < totverts; i++) {
source.appendValues(verts[i].co[0], verts[i].co[1], verts[i].co[2]);
}
-
+
source.finish();
}
@@ -502,7 +502,7 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
);
}
}
-
+
source.finish();
}
}
@@ -537,20 +537,20 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, a);
if (!this->export_settings->active_uv_only || layer_index == active_uv_index) {
MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a);
-
+
COLLADASW::FloatSourceF source(mSW);
std::string layer_id = makeTexcoordSourceId(geom_id, a, this->export_settings->active_uv_only);
source.setId(layer_id);
source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
-
+
source.setAccessorCount(totuv);
source.setAccessorStride(2);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("S");
param.push_back("T");
-
+
source.prepareToAppendValues();
-
+
for (int index = 0; index < totpoly; index++) {
MPoly *mpoly = mpolys+index;
MLoopUV *mloop = mloops+mpoly->loopstart;
@@ -559,7 +559,7 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
mloop[j].uv[1]);
}
}
-
+
source.finish();
}
}
@@ -589,7 +589,7 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v
param.push_back("X");
param.push_back("Y");
param.push_back("Z");
-
+
source.prepareToAppendValues();
std::vector<Normal>::iterator it;
@@ -674,10 +674,10 @@ std::string GeometryExporter::getIdBySemantics(std::string geom_id, COLLADASW::I
COLLADASW::URI GeometryExporter::getUrlBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix)
{
-
+
std::string id(getIdBySemantics(geom_id, type, other_suffix));
return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id);
-
+
}
COLLADASW::URI GeometryExporter::makeUrl(std::string id)
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 88420b4ad2f..b0cd650adcd 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -96,7 +96,7 @@ public:
Mesh *me,
std::string& geom_id,
std::vector<BCPolygonNormalsIndices>& norind);
-
+
// creates <source> for positions
void createVertsSource(std::string geom_id, Mesh *me);
@@ -112,7 +112,7 @@ public:
void createNormalsSource(std::string geom_id, Mesh *me, std::vector<Normal>& nor);
void create_normals(std::vector<Normal> &nor, std::vector<BCPolygonNormalsIndices> &ind, Mesh *me);
-
+
std::string getIdBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix = "");
std::string makeVertexColorSourceId(std::string& geom_id, char *layer_name);
@@ -121,10 +121,10 @@ public:
COLLADASW::URI makeUrl(std::string id);
void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb);
-
+
private:
std::set<std::string> exportedGeometry;
-
+
const ExportSettings *export_settings;
Mesh * get_mesh(Scene *sce, Object *ob, int apply_modifiers);
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index 657037a869a..bb3cebf4cf0 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -34,7 +34,7 @@ extern "C" {
#include "DNA_image_types.h"
#include "DNA_meshdata_types.h"
-#include "BKE_customdata.h"
+#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
@@ -53,7 +53,7 @@ ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings
{
}
-void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
+void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
{
std::string name(id_name(image));
std::string translated_name(translate_id(name));
@@ -113,11 +113,11 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
// make absolute source path
BLI_strncpy(source_path, image->name, sizeof(source_path));
- BLI_path_abs(source_path, G.main->name);
+ BLI_path_abs(source_path, BKE_main_blendfile_path_from_global());
BLI_cleanup_path(NULL, source_path);
if (use_copies) {
-
+
// This image is already located on the file system.
// But we want to create copies here.
// To move images into the same export directory.
@@ -155,7 +155,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
bool ImagesExporter::hasImages(Scene *sce)
{
LinkNode *node;
-
+
for (node = this->export_settings->export_set; node; node = node->next) {
Object *ob = (Object *)node->link;
diff --git a/source/blender/collada/ImageExporter.h b/source/blender/collada/ImageExporter.h
index f3dd2b336e4..1867c44ac9c 100644
--- a/source/blender/collada/ImageExporter.h
+++ b/source/blender/collada/ImageExporter.h
@@ -45,7 +45,7 @@ class ImagesExporter: COLLADASW::LibraryImages
{
public:
ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
-
+
void exportImages(Scene *sce);
void operator()(Material *ma, Object *ob);
private:
diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp
index d96d590597a..68842596550 100644
--- a/source/blender/collada/InstanceWriter.cpp
+++ b/source/blender/collada/InstanceWriter.cpp
@@ -45,7 +45,7 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_materia
{
for (int a = 0; a < ob->totcol; a++) {
Material *ma = give_current_material(ob, a + 1);
-
+
COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList();
if (ma) {
@@ -54,11 +54,11 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_materia
std::ostringstream ostr;
ostr << matid;
COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid));
-
+
// create <bind_vertex_input> for each uv map
Mesh *me = (Mesh *)ob->data;
int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
-
+
int map_index = 0;
int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) -1;
for (int b = 0; b < totlayer; b++) {
@@ -67,7 +67,7 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_materia
im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++));
}
}
-
+
iml.push_back(im);
}
}
diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp
index d17941574d7..11377e06ce8 100644
--- a/source/blender/collada/LightExporter.cpp
+++ b/source/blender/collada/LightExporter.cpp
@@ -54,9 +54,9 @@ LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings
void LightsExporter::exportLights(Scene *sce)
{
openLibrary();
-
+
forEachLampObjectInExportSet(sce, *this, this->export_settings->export_set);
-
+
closeLibrary();
}
@@ -67,11 +67,11 @@ void LightsExporter::operator()(Object *ob)
std::string la_name(id_name(la));
COLLADASW::Color col(la->r * la->energy, la->g * la->energy, la->b * la->energy);
float d, constatt, linatt, quadatt;
-
+
d = la->dist;
-
+
constatt = 1.0f;
-
+
if (la->falloff_type == LA_FALLOFF_INVLINEAR) {
linatt = 1.0f / d;
quadatt = 0.0f;
@@ -80,7 +80,7 @@ void LightsExporter::operator()(Object *ob)
linatt = 0.0f;
quadatt = 1.0f / (d * d);
}
-
+
// sun
if (la->type == LA_SUN) {
COLLADASW::DirectionalLight cla(mSW, la_id, la_name);
@@ -130,7 +130,7 @@ void LightsExporter::operator()(Object *ob)
exportBlenderProfile(cla, la);
addLight(cla);
}
-
+
}
bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Lamp *la)
@@ -164,6 +164,6 @@ bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Lamp *la)
cla.addExtraTechniqueParameter("blender", "area_size", la->area_size);
cla.addExtraTechniqueParameter("blender", "area_sizey", la->area_sizey);
cla.addExtraTechniqueParameter("blender", "area_sizez", la->area_sizez);
-
+
return true;
}
diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h
index ef44bf8a03e..e830a433432 100644
--- a/source/blender/collada/MaterialExporter.h
+++ b/source/blender/collada/MaterialExporter.h
@@ -65,7 +65,7 @@ class ForEachMaterialFunctor
Functor *f;
public:
ForEachMaterialFunctor(Functor*f) : f(f) {}
-
+
void operator ()(Object *ob)
{
int a;
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index add4a93bccd..e95f8ed0888 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -154,7 +154,7 @@ void UVDataWrapper::getUV(int uv_index, float *uv)
if (values->empty()) return;
uv[0] = (*values)[uv_index * stride];
uv[1] = (*values)[uv_index * stride + 1];
-
+
}
break;
case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
@@ -163,7 +163,7 @@ void UVDataWrapper::getUV(int uv_index, float *uv)
if (values->empty()) return;
uv[0] = (float)(*values)[uv_index * stride];
uv[1] = (float)(*values)[uv_index * stride + 1];
-
+
}
break;
case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
@@ -208,7 +208,7 @@ void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
}
MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce, ViewLayer *view_layer):
- unitconverter(unitconv),
+ unitconverter(unitconv),
scene(sce),
view_layer(view_layer),
armature_importer(arm) {
@@ -320,7 +320,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has su
return false;
}
}
-
+
return true;
}
@@ -360,7 +360,7 @@ bool MeshImporter::primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp) {
int normals_count = mp->getNormalIndices().getCount();
if (normals_count > 0) {
int index_count = mp->getPositionIndices().getCount();
- if (index_count == normals_count)
+ if (index_count == normals_count)
has_useable_normals = true;
else {
fprintf(stderr,
@@ -391,7 +391,7 @@ bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) {
break;
}
default: {
- has_faces = false;
+ has_faces = false;
break;
}
}
@@ -435,7 +435,7 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
size_t prim_poly_count = mpvc->getFaceCount();
size_t prim_loop_count = 0;
- for (int index=0; index < prim_poly_count; index++)
+ for (int index=0; index < prim_poly_count; index++)
{
int vcount = get_vertex_count(mpvc, index);
if (vcount > 0) {
@@ -547,7 +547,7 @@ unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh) {
// This functin is copied from source/blender/editors/mesh/mesh_data.c
//
// TODO: (As discussed with sergey-) :
-// Maybe move this function to blenderkernel/intern/mesh.c
+// Maybe move this function to blenderkernel/intern/mesh.c
// and add definition to BKE_mesh.c
// =================================================================
void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
@@ -582,7 +582,7 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
// =================================================================
// Read all loose edges.
-// Important: This function assumes that all edges from existing
+// Important: This function assumes that all edges from existing
// faces have allready been generated and added to me->medge
// So this function MUST be called after read_faces() (see below)
// =================================================================
@@ -593,21 +593,21 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
unsigned int face_edge_count = me->totedge;
/* unsigned int total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */
-
+
mesh_add_edges(me, loose_edge_count);
MEdge *med = me->medge + face_edge_count;
COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
for (int i = 0; i < prim_arr.getCount(); i++) {
-
+
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
int type = mp->getPrimitiveType();
if (type == COLLADAFW::MeshPrimitive::LINES) {
unsigned int edge_count = mp->getFaceCount();
unsigned int *indices = mp->getPositionIndices().getData();
-
+
for (int j = 0; j < edge_count; j++, med++) {
med->bweight = 0;
med->crease = 0;
@@ -624,7 +624,7 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
// =======================================================================
// Read all faces from TRIANGLES, TRIANGLE_FANS, POLYLIST, POLYGON
-// Important: This function MUST be called before read_lines()
+// Important: This function MUST be called before read_lines()
// Otherwise we will loose all edges from faces (see read_lines() above)
//
// TODO: import uv set names
@@ -632,7 +632,7 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
{
unsigned int i;
-
+
allocate_poly_data(collada_mesh, me);
UVDataWrapper uvs(collada_mesh->getUVCoords());
@@ -648,7 +648,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
COLLADAFW::MeshVertexData& nor = collada_mesh->getNormals();
for (i = 0; i < prim_arr.getCount(); i++) {
-
+
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
// faces
@@ -661,7 +661,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
bool mp_has_faces = primitive_has_faces(mp);
int collada_meshtype = mp->getPrimitiveType();
-
+
// since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive
Primitive prim = {mpoly, 0};
@@ -688,7 +688,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
mpoly->flag |= ME_SMOOTH;
normal_indices++;
}
-
+
mpoly++;
mloop += 3;
loop_index += 3;
@@ -798,7 +798,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride)
{
i *= stride;
-
+
switch (arr.getType()) {
case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
{
@@ -888,7 +888,7 @@ static bool bc_has_same_material_configuration(Object *ob1, Object *ob2)
{
if (ob1->totcol != ob2->totcol) return false; // not same number of materials
if (ob1->totcol == 0) return false; // no material at all
-
+
for (int index=0; index < ob1->totcol; index++) {
if (ob1->matbits[index] != ob2->matbits[index]) return false; // shouldn't happen
if (ob1->matbits[index] == 0) return false; // shouldn't happen
@@ -1019,34 +1019,34 @@ void MeshImporter::assign_material_to_geom(
short mat_index)
{
const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
-
+
// do we know this material?
if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
-
+
fprintf(stderr, "Cannot find material by UID.\n");
return;
}
// first time we get geom_uid, ma_uid pair. Save for later check.
materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
-
+
Material *ma = uid_material_map[ma_uid];
// Attention! This temporaly assigns material to object on purpose!
// See note above.
ob->actcol=0;
assign_material(G.main, ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT);
-
+
MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
-
+
// assign material indices to mesh faces
if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
-
+
std::vector<Primitive>& prims = mat_prim_map[mat_id];
-
+
std::vector<Primitive>::iterator it;
-
+
for (it = prims.begin(); it != prims.end(); it++) {
Primitive& prim = *it;
MPoly *mpoly = prim.mpoly;
@@ -1055,7 +1055,7 @@ void MeshImporter::assign_material_to_geom(
mpoly->mat_nr = mat_index;
}
}
- }
+ }
}
Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
@@ -1063,19 +1063,19 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
std::map<COLLADAFW::UniqueId, Material *>& uid_material_map)
{
const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
-
+
// check if node instanciates controller or geometry
if (isController) {
-
+
geom_uid = armature_importer->get_geometry_uid(*geom_uid);
-
+
if (!geom_uid) {
fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
return NULL;
}
}
else {
-
+
if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
// this could happen if a mesh was not created
// (e.g. if it contains unsupported geometry)
@@ -1084,11 +1084,11 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
}
}
if (!uid_mesh_map[*geom_uid]) return NULL;
-
+
// name Object
const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
const char *name = (id.length()) ? id.c_str() : NULL;
-
+
// add object
Object *ob = bc_add_object(scene, view_layer, OB_MESH, name);
bc_set_mark(ob); // used later for material assignement optimization
@@ -1097,7 +1097,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
// store object pointer for ArmatureImporter
uid_object_map[*geom_uid] = ob;
imported_objects.push_back(ob);
-
+
// replace ob->data freeing the old one
Mesh *old_mesh = (Mesh *)ob->data;
Mesh *new_mesh = uid_mesh_map[*geom_uid];
@@ -1110,10 +1110,10 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
COLLADAFW::MaterialBindingArray& mat_array =
geom->getMaterialBindings();
-
+
// loop through geom's materials
for (unsigned int i = 0; i < mat_array.getCount(); i++) {
-
+
if (mat_array[i].getReferencedMaterial().isValid()) {
assign_material_to_geom(
mat_array[i], uid_material_map, ob, geom_uid,
@@ -1136,14 +1136,14 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType()));
return true;
}
-
+
COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom;
-
+
if (!is_nice_mesh(mesh)) {
fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh).c_str());
return true;
}
-
+
const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId();
Mesh *me = BKE_mesh_add(G.main, (char *)str_geom_id.c_str());
id_us_min(&me->id); // is already 1 here, but will be set later in BKE_mesh_assign_object
@@ -1152,7 +1152,7 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
// mesh_geom_map needed to map mesh to its geometry name (for shape key naming)
this->uid_mesh_map[mesh->getUniqueId()] = me;
this->mesh_geom_map[std::string(me->id.name)] = str_geom_id;
-
+
read_vertices(mesh, me);
read_polys(mesh, me);
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 09b3005d795..c98126916d7 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -109,7 +109,7 @@ private:
typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; // crazy name!
std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId> materials_mapped_to_geom; //< materials that have already been mapped to a geometry. A pair of geom uid and mat uid, one geometry can have several materials
-
+
bool set_poly_indices(MPoly *mpoly,
MLoop *mloop,
int loop_index,
@@ -135,7 +135,7 @@ private:
bool is_nice_mesh(COLLADAFW::Mesh *mesh);
void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me);
-
+
bool primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp);
bool primitive_has_faces(COLLADAFW::MeshPrimitive *mp);
@@ -165,7 +165,7 @@ public:
virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid);
virtual Mesh *get_mesh_by_geom_uid(const COLLADAFW::UniqueId& geom_uid);
-
+
void optimize_material_assignements();
void assign_material_to_geom(
@@ -173,8 +173,8 @@ public:
std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
Object *ob, const COLLADAFW::UniqueId *geom_uid,
short mat_index);
-
-
+
+
Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
bool isController,
std::map<COLLADAFW::UniqueId, Material*>& uid_material_map);
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index 5d1df800746..d909203488e 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -39,18 +39,18 @@ SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm,
{
}
-void SceneExporter::exportScene(Depsgraph *depsgraph, Scene *sce)
+void SceneExporter::exportScene(bContext *C, Depsgraph *depsgraph, Scene *sce)
{
// <library_visual_scenes> <visual_scene>
std::string id_naming = id_name(sce);
openVisualScene(translate_id(id_naming), id_naming);
- exportHierarchy(depsgraph, sce);
+ exportHierarchy(C, depsgraph, sce);
closeVisualScene();
closeLibrary();
}
-void SceneExporter::exportHierarchy(Depsgraph *depsgraph, Scene *sce)
-{
+void SceneExporter::exportHierarchy(bContext *C, Depsgraph *depsgraph, Scene *sce)
+{
LinkNode *node;
std::vector<Object *> base_objects;
@@ -59,7 +59,7 @@ void SceneExporter::exportHierarchy(Depsgraph *depsgraph, Scene *sce)
Object *ob = (Object *) node->link;
ob->id.tag |= LIB_TAG_DOIT;
}
-
+
// Now find all exportable base ojects (highest in export hierarchy)
for (node = this->export_settings->export_set; node; node = node->next) {
Object *ob = (Object *) node->link;
@@ -81,13 +81,13 @@ void SceneExporter::exportHierarchy(Depsgraph *depsgraph, Scene *sce)
Object *ob = base_objects[index];
if (bc_is_marked(ob)) {
bc_remove_mark(ob);
- writeNodes(depsgraph, ob, sce);
+ writeNodes(C, depsgraph, ob, sce);
}
}
}
-void SceneExporter::writeNodes(Depsgraph *depsgraph, Object *ob, Scene *sce)
+void SceneExporter::writeNodes(bContext *C, Depsgraph *depsgraph, Object *ob, Scene *sce)
{
// Add associated armature first if available
bool armature_exported = false;
@@ -96,7 +96,7 @@ void SceneExporter::writeNodes(Depsgraph *depsgraph, Object *ob, Scene *sce)
armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm);
if (armature_exported && bc_is_marked(ob_arm)) {
bc_remove_mark(ob_arm);
- writeNodes(depsgraph, ob_arm, sce);
+ writeNodes(C, depsgraph, ob_arm, sce);
armature_exported = true;
}
}
@@ -155,7 +155,7 @@ void SceneExporter::writeNodes(Depsgraph *depsgraph, Object *ob, Scene *sce)
// <instance_controller>
else if (ob->type == OB_ARMATURE) {
- arm_exporter->add_armature_bones(depsgraph, ob, sce, this, child_objects);
+ arm_exporter->add_armature_bones(C, depsgraph, ob, sce, this, child_objects);
}
// <instance_camera>
@@ -203,17 +203,17 @@ void SceneExporter::writeNodes(Depsgraph *depsgraph, Object *ob, Scene *sce)
colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"rot_error",con->rot_error);
colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"tar_space",con->tarspace);
colladaNode.addExtraTechniqueChildParameter("blender",con_tag,"lin_error",con->lin_error);
-
- //not ideal: add the target object name as another parameter.
+
+ //not ideal: add the target object name as another parameter.
//No real mapping in the .dae
//Need support for multiple target objects also.
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
-
+
bConstraintTarget *ct;
Object *obtar;
-
+
cti->get_constraint_targets(con, &targets);
for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) {
@@ -234,7 +234,7 @@ void SceneExporter::writeNodes(Depsgraph *depsgraph, Object *ob, Scene *sce)
for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) {
if (bc_is_marked(*i)) {
bc_remove_mark(*i);
- writeNodes(depsgraph, *i, sce);
+ writeNodes(C, depsgraph, *i, sce);
}
}
diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h
index c330aa81e91..91f98063020 100644
--- a/source/blender/collada/SceneExporter.h
+++ b/source/blender/collada/SceneExporter.h
@@ -96,13 +96,13 @@ class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter,
{
public:
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings);
- void exportScene(Depsgraph *depsgraph, Scene *sce);
+ void exportScene(bContext *C, Depsgraph *depsgraph, Scene *sce);
private:
friend class ArmatureExporter;
- void exportHierarchy(struct Depsgraph *depsgraph, Scene *sce);
- void writeNodes(struct Depsgraph *depsgraph, Object *ob, Scene *sce);
-
+ void exportHierarchy(bContext *C, struct Depsgraph *depsgraph, Scene *sce);
+ void writeNodes(bContext *C, struct Depsgraph *depsgraph, Object *ob, Scene *sce);
+
ArmatureExporter *arm_exporter;
const ExportSettings *export_settings;
};
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index a2cb8237d08..7ec3f04aabf 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -121,7 +121,7 @@ void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData *
unit_converter->dae_matrix_to_mat4_(bind_shape_matrix, skin->getBindShapeMatrix());
}
-
+
void SkinInfo::free()
{
joints_per_vertex.releaseMemory();
@@ -199,7 +199,7 @@ const COLLADAFW::UniqueId& SkinInfo::get_controller_uid()
}
// check if this skin controller references a joint or any descendant of it
-//
+//
// some nodes may not be referenced by SkinController,
// in this case to determine if the node belongs to this armature,
// we need to search down the tree
@@ -259,9 +259,9 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique
// skip joints that have invalid UID
if ((*it).joint_uid == COLLADAFW::UniqueId::INVALID) continue;
-
+
// name group by joint node name
-
+
if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) {
name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]);
}
diff --git a/source/blender/collada/SkinInfo.h b/source/blender/collada/SkinInfo.h
index a399bff9e3c..fdfee0a943a 100644
--- a/source/blender/collada/SkinInfo.h
+++ b/source/blender/collada/SkinInfo.h
@@ -88,7 +88,7 @@ public:
void transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest);
void borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin);
-
+
void free();
// using inverse bind matrices to construct armature
@@ -110,7 +110,7 @@ public:
const COLLADAFW::UniqueId& get_controller_uid();
// check if this skin controller references a joint or any descendant of it
- //
+ //
// some nodes may not be referenced by SkinController,
// in this case to determine if the node belongs to this armature,
// we need to search down the tree
diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp
index 7f742be7e30..bf9c34153b7 100644
--- a/source/blender/collada/TransformReader.cpp
+++ b/source/blender/collada/TransformReader.cpp
@@ -54,7 +54,7 @@ void TransformReader::get_node_mat(
float copy[4][4];
unit_m4(mat);
-
+
for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) {
COLLADAFW::Transformation *tm = node->getTransformations()[i];
@@ -87,11 +87,11 @@ void TransformReader::get_node_mat(
copy_m4_m4(copy, mat);
mul_m4_m4m4(mat, copy, cur);
-
+
if (animation_map) {
// AnimationList that drives this Transformation
const COLLADAFW::UniqueId& anim_list_id = tm->getAnimationList();
-
+
// store this so later we can link animation data with ob
Animation anim = {ob, node, tm};
(*animation_map)[anim_list_id] = anim;
diff --git a/source/blender/collada/TransformReader.h b/source/blender/collada/TransformReader.h
index 08bb17ccac1..6544aa1c040 100644
--- a/source/blender/collada/TransformReader.h
+++ b/source/blender/collada/TransformReader.h
@@ -19,7 +19,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-
+
/** \file TransformReader.h
* \ingroup collada
*/
diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp
index 1fb54e99147..9f75a604f96 100644
--- a/source/blender/collada/TransformWriter.cpp
+++ b/source/blender/collada/TransformWriter.cpp
@@ -119,7 +119,7 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob,
{
float loc[3], rot[3], scale[3];
bc_decompose(f_obmat, loc, rot, NULL, scale);
- add_transform(node, loc, rot, scale);
+ add_transform(node, loc, rot, scale);
break;
}
}
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index 5def6638df6..bf310cb24d8 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -51,7 +51,8 @@ int collada_import(bContext *C, ImportSettings *import_settings)
return (imp.import())? 1:0;
}
-int collada_export(Depsgraph *depsgraph,
+int collada_export(bContext *C,
+ Depsgraph *depsgraph,
Scene *sce,
ExportSettings *export_settings)
{
@@ -80,7 +81,7 @@ int collada_export(Depsgraph *depsgraph,
}
DocumentExporter exporter(depsgraph, export_settings);
- int status = exporter.exportCurrentScene(sce);
+ int status = exporter.exportCurrentScene(C, sce);
BLI_linklist_free(export_settings->export_set, NULL);
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 5cf526af1f2..a47463b5a7a 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -51,8 +51,8 @@ struct ViewLayer;
int collada_import(struct bContext *C,
ImportSettings *import_settings);
-
-int collada_export(struct Depsgraph *depsgraph,
+int collada_export(struct bContext *C,
+ struct Depsgraph *depsgraph,
struct Scene *sce,
ExportSettings *export_settings);
diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h
index 299e13326ce..1eac5b68778 100644
--- a/source/blender/collada/collada_internal.h
+++ b/source/blender/collada/collada_internal.h
@@ -51,7 +51,7 @@ private:
float y_up_mat4[4][4];
float z_up_mat4[4][4];
float scale_mat4[4][4];
-
+
public:
enum UnitSystem {
@@ -66,11 +66,11 @@ public:
void read_asset(const COLLADAFW::FileInfo *asset);
void convertVector3(COLLADABU::Math::Vector3 &vec, float *v);
-
+
UnitConverter::UnitSystem isMetricSystem(void);
-
+
float getLinearMeter(void);
-
+
// TODO need also for angle conversion, time conversion...
void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in);
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index bf441effc81..945dda68745 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -77,7 +77,7 @@ float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned in
if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT)
return array.getFloatValues()->getData()[index];
- else
+ else
return array.getDoubleValues()->getData()[index];
}
@@ -85,10 +85,10 @@ float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned in
int bc_test_parent_loop(Object *par, Object *ob)
{
/* test if 'ob' is a parent somewhere in par's parents */
-
+
if (par == NULL) return 0;
if (ob == par) return 1;
-
+
return bc_test_parent_loop(par->parent, ob);
}
@@ -117,7 +117,7 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
mul_m4_m4m4(mat, par->obmat, ob->obmat);
copy_m4_m4(ob->obmat, mat);
}
-
+
// apply child obmat (i.e. decompose it into rot/loc/size)
BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
@@ -231,7 +231,7 @@ Object *bc_get_assigned_armature(Object *ob)
// IMPORTANT: This function expects that
// all exported objects have set:
// ob->id.tag & LIB_TAG_DOIT
-Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob)
+Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob)
{
Object *ancestor = ob;
while (ob->parent && bc_is_marked(ob->parent)) {
@@ -256,7 +256,7 @@ bool bc_is_in_Export_set(LinkNode *export_set, Object *ob)
bool bc_has_object_type(LinkNode *export_set, short obtype)
{
LinkNode *node;
-
+
for (node = export_set; node; node = node->next) {
Object *ob = (Object *)node->link;
/* XXX - why is this checking for ob->data? - we could be looking for empties */
@@ -290,7 +290,7 @@ void bc_bubble_sort_by_Object_name(LinkNode *export_set)
for (node = export_set; node->next && !sorted; node = node->next) {
sorted = true;
-
+
LinkNode *current;
for (current = export_set; current->next; current = current->next) {
Object *a = (Object *)current->link;
@@ -301,12 +301,12 @@ void bc_bubble_sort_by_Object_name(LinkNode *export_set)
current->next->link = a;
sorted = false;
}
-
+
}
}
}
-/* Check if a bone is the top most exportable bone in the bone hierarchy.
+/* Check if a bone is the top most exportable bone in the bone hierarchy.
* When deform_bones_only == false, then only bones with NO parent
* can be root bones. Otherwise the top most deform bones in the hierarchy
* are root bones.
@@ -367,13 +367,13 @@ void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene)
BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
}
-void bc_match_scale(std::vector<Object *> *objects_done,
+void bc_match_scale(std::vector<Object *> *objects_done,
UnitConverter &bc_unit,
bool scale_to_scene)
{
for (std::vector<Object *>::iterator it = objects_done->begin();
it != objects_done->end();
- ++it)
+ ++it)
{
Object *ob = *it;
if (ob -> parent == NULL) {
@@ -781,7 +781,7 @@ float bc_get_property(Bone *bone, std::string key, float def)
/**
* Read a custom bone property and convert to matrix
* Return true if conversion was succesfull
-*
+*
* Return false if:
* - the property does not exist
* - is not an array of size 16
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index 89765375afb..20c569834d8 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -92,8 +92,8 @@ extern void bc_bubble_sort_by_Object_name(LinkNode *export_set);
extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only);
extern int bc_get_active_UVLayer(Object *ob);
-extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement);
-extern std::string bc_url_encode(std::string data);
+extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement);
+extern std::string bc_url_encode(std::string data);
extern void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene);
extern void bc_match_scale(std::vector<Object *> *objects_done, UnitConverter &unit_converter, bool scale_to_scene);
@@ -135,8 +135,8 @@ class BCPolygonNormalsIndices
normal_indices.push_back(index);
}
- unsigned int operator[](unsigned int i) {
- return normal_indices[i];
+ unsigned int operator[](unsigned int i) {
+ return normal_indices[i];
}
};
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
index 7786359c06a..f7fcf63fabb 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
@@ -31,6 +31,7 @@
#include "BLI_string.h"
#include "BKE_image.h"
#include "BKE_global.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_scene.h"
@@ -100,11 +101,10 @@ void OutputOpenExrSingleLayerMultiViewOperation::deinitExecution()
if (width != 0 && height != 0) {
void *exrhandle;
- Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
BKE_image_path_from_imtype(
- filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_OPENEXR,
+ filename, this->m_path, BKE_main_blendfile_path_from_global(), this->m_rd->cfra, R_IMF_IMTYPE_OPENEXR,
(this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
exrhandle = this->get_handle(filename);
@@ -190,11 +190,10 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinitExecution()
if (width != 0 && height != 0) {
void *exrhandle;
- Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
BKE_image_path_from_imtype(
- filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
+ filename, this->m_path, BKE_main_blendfile_path_from_global(), this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
(this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
exrhandle = this->get_handle(filename);
@@ -283,7 +282,6 @@ void OutputStereoOperation::deinitExecution()
if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) {
ImBuf *ibuf[3] = {NULL};
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
- Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
int i;
@@ -307,7 +305,7 @@ void OutputStereoOperation::deinitExecution()
ibuf[2] = IMB_stereo3d_ImBuf(this->m_format, ibuf[0], ibuf[1]);
BKE_image_path_from_imformat(
- filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
+ filename, this->m_path, BKE_main_blendfile_path_from_global(), this->m_rd->cfra, this->m_format,
(this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
BKE_imbuf_write(ibuf[2], filename, this->m_format);
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index db816816034..39877e35605 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -28,6 +28,7 @@
#include "BLI_string.h"
#include "BKE_image.h"
#include "BKE_global.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_scene.h"
@@ -185,7 +186,6 @@ void OutputSingleLayerOperation::deinitExecution()
int size = get_datatype_size(this->m_datatype);
ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), this->m_format->planes, 0);
- Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
const char *suffix;
@@ -200,7 +200,7 @@ void OutputSingleLayerOperation::deinitExecution()
suffix = BKE_scene_multiview_view_suffix_get(this->m_rd, this->m_viewName);
BKE_image_path_from_imformat(
- filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
+ filename, this->m_path, BKE_main_blendfile_path_from_global(), this->m_rd->cfra, this->m_format,
(this->m_rd->scemode & R_EXTENSION) != 0, true, suffix);
if (0 == BKE_imbuf_write(ibuf, filename, this->m_format))
@@ -271,14 +271,13 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
unsigned int width = this->getWidth();
unsigned int height = this->getHeight();
if (width != 0 && height != 0) {
- Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
const char *suffix;
void *exrhandle = IMB_exr_get_handle();
suffix = BKE_scene_multiview_view_suffix_get(this->m_rd, this->m_viewName);
BKE_image_path_from_imtype(
- filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
+ filename, this->m_path, BKE_main_blendfile_path_from_global(), this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
(this->m_rd->scemode & R_EXTENSION) != 0, true, suffix);
BLI_make_existing_file(filename);
diff --git a/source/blender/datatoc/datatoc_icon.c b/source/blender/datatoc/datatoc_icon.c
index 92048f32a28..e5f82ae09c8 100644
--- a/source/blender/datatoc/datatoc_icon.c
+++ b/source/blender/datatoc/datatoc_icon.c
@@ -386,7 +386,7 @@ int main(int argc, char **argv)
{
const char *path_src;
const char *file_dst;
-
+
if (argc < 3) {
printf("Usage: datatoc_icon <dir_icons> <data_icon_to.png>\n");
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 7a4d9a19335..1c4e11d1197 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -107,14 +107,8 @@ enum {
DEG_ITER_OBJECT_FLAG_DUPLI = (1 << 4),
};
-typedef enum eDepsObjectIteratorMode {
- DEG_ITER_OBJECT_MODE_VIEWPORT = 0,
- DEG_ITER_OBJECT_MODE_RENDER = 1,
-} eDepsObjectIteratorMode;
-
typedef struct DEGObjectIterData {
struct Depsgraph *graph;
- eDepsObjectIteratorMode mode;
int flag;
struct Scene *scene;
@@ -152,11 +146,10 @@ void DEG_iterator_objects_end(struct BLI_Iterator *iter);
* Although they are available they have no overrides (collection_properties)
* and will crash if you try to access it.
*/
-#define DEG_OBJECT_ITER_BEGIN(graph_, instance_, mode_, flag_) \
+#define DEG_OBJECT_ITER_BEGIN(graph_, instance_, flag_) \
{ \
DEGObjectIterData data_ = { \
graph_, \
- mode_, \
flag_ \
}; \
\
@@ -172,8 +165,8 @@ void DEG_iterator_objects_end(struct BLI_Iterator *iter);
/**
* Depsgraph objects iterator for draw manager and final render
*/
-#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(graph_, instance_, mode_) \
- DEG_OBJECT_ITER_BEGIN(graph_, instance_, mode_, \
+#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(graph_, instance_) \
+ DEG_OBJECT_ITER_BEGIN(graph_, instance_, \
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | \
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | \
DEG_ITER_OBJECT_FLAG_VISIBLE | \
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
index 026aa309b02..feaba1a4aa8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
@@ -68,7 +68,9 @@ struct CyclesSolverState {
: graph(graph),
traversal_stack(BLI_stack_new(sizeof(StackEntry),
"DEG detect cycles stack")),
- num_cycles(0) {
+ num_cycles(0)
+ {
+ /* pass */
}
~CyclesSolverState() {
BLI_stack_free(traversal_stack);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 5867e278c78..aaf96a47711 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -311,7 +311,7 @@ ID *DepsgraphNodeBuilder::get_cow_id(const ID *id_orig) const
ID *DepsgraphNodeBuilder::ensure_cow_id(ID *id_orig)
{
- if (id_orig->tag & LIB_TAG_COPY_ON_WRITE) {
+ if (id_orig->tag & LIB_TAG_COPIED_ON_WRITE) {
/* ID is already remapped to copy-on-write. */
return id_orig;
}
@@ -378,17 +378,32 @@ void DepsgraphNodeBuilder::end_build()
}
}
-void DepsgraphNodeBuilder::build_id(ID* id) {
+void DepsgraphNodeBuilder::build_id(ID *id) {
if (id == NULL) {
return;
}
switch (GS(id->name)) {
+ case ID_AR:
+ build_armature((bArmature *)id);
+ break;
+ case ID_CA:
+ build_camera((Camera *)id);
+ break;
case ID_GR:
- build_collection((Collection *)id);
+ build_collection(DEG_COLLECTION_OWNER_UNKNOWN, (Collection *)id);
break;
case ID_OB:
build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY);
break;
+ case ID_KE:
+ build_shapekeys((Key *)id);
+ break;
+ case ID_LA:
+ build_lamp((Lamp *)id);
+ break;
+ case ID_LP:
+ build_lightprobe((LightProbe *)id);
+ break;
case ID_NT:
build_nodetree((bNodeTree *)id);
break;
@@ -410,33 +425,45 @@ void DepsgraphNodeBuilder::build_id(ID* id) {
case ID_MC:
build_movieclip((MovieClip *)id);
break;
+ case ID_ME:
+ case ID_CU:
+ case ID_MB:
+ case ID_LT:
+ build_object_data_geometry_datablock(id);
+ break;
default:
fprintf(stderr, "Unhandled ID %s\n", id->name);
+ BLI_assert(!"Should never happen");
+ break;
}
}
-void DepsgraphNodeBuilder::build_collection(Collection *collection)
+void DepsgraphNodeBuilder::build_collection(
+ eDepsNode_CollectionOwner owner_type,
+ Collection *collection)
{
if (built_map_.checkIsBuiltAndTag(collection)) {
return;
}
-
- const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ?
- COLLECTION_RESTRICT_VIEW : COLLECTION_RESTRICT_RENDER;
- if (collection->flag & restrict_flag) {
- return;
+ const bool allow_restrict_flags = (owner_type == DEG_COLLECTION_OWNER_SCENE);
+ if (allow_restrict_flags) {
+ const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT)
+ ? COLLECTION_RESTRICT_VIEW
+ : COLLECTION_RESTRICT_RENDER;
+ if (collection->flag & restrict_flag) {
+ return;
+ }
}
-
+ /* Collection itself. */
+ add_id_node(&collection->id);
/* Build collection objects. */
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
build_object(-1, cob->ob, DEG_ID_LINKED_INDIRECTLY);
}
/* Build child collections. */
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- build_collection(child->collection);
+ build_collection(owner_type, child->collection);
}
-
- add_id_node(&collection->id);
}
void DepsgraphNodeBuilder::build_object(int base_index,
@@ -508,7 +535,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
}
/* Object dupligroup. */
if (object->dup_group != NULL) {
- build_collection(object->dup_group);
+ build_collection(DEG_COLLECTION_OWNER_OBJECT, object->dup_group);
}
}
@@ -549,7 +576,7 @@ void DepsgraphNodeBuilder::build_object_data(Object *object)
case OB_SURF:
case OB_MBALL:
case OB_LATTICE:
- build_obdata_geom(object);
+ build_object_data_geometry(object);
/* TODO(sergey): Only for until we support granular
* update of curves.
*/
@@ -569,13 +596,13 @@ void DepsgraphNodeBuilder::build_object_data(Object *object)
}
break;
case OB_LAMP:
- build_lamp(object);
+ build_object_data_lamp(object);
break;
case OB_CAMERA:
- build_camera(object);
+ build_object_data_camera(object);
break;
case OB_LIGHTPROBE:
- build_lightprobe(object);
+ build_object_data_lightprobe(object);
break;
default:
{
@@ -588,6 +615,28 @@ void DepsgraphNodeBuilder::build_object_data(Object *object)
}
}
+void DepsgraphNodeBuilder::build_object_data_camera(Object *object)
+{
+ Camera *camera = (Camera *)object->data;
+ build_camera(camera);
+}
+
+void DepsgraphNodeBuilder::build_object_data_lamp(Object *object)
+{
+ Lamp *lamp = (Lamp *)object->data;
+ build_lamp(lamp);
+}
+
+void DepsgraphNodeBuilder::build_object_data_lightprobe(Object *object)
+{
+ LightProbe *probe = (LightProbe *)object->data;
+ build_lightprobe(probe);
+ add_operation_node(&object->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ NULL,
+ DEG_OPCODE_LIGHT_PROBE_EVAL);
+}
+
void DepsgraphNodeBuilder::build_object_transform(Object *object)
{
OperationDepsNode *op_node;
@@ -923,7 +972,7 @@ void DepsgraphNodeBuilder::build_particles(Object *object)
break;
case PART_DRAW_GR:
if (part->dup_group != NULL) {
- build_collection(part->dup_group);
+ build_collection(DEG_COLLECTION_OWNER_OBJECT, part->dup_group);
}
break;
}
@@ -968,6 +1017,9 @@ void DepsgraphNodeBuilder::build_cloth(Object *object)
/* Shapekeys */
void DepsgraphNodeBuilder::build_shapekeys(Key *key)
{
+ if (built_map_.checkIsBuiltAndTag(key)) {
+ return;
+ }
build_animdata(&key->id);
add_operation_node(&key->id,
DEG_NODE_TYPE_GEOMETRY,
@@ -977,12 +1029,11 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key)
/* ObData Geometry Evaluation */
// XXX: what happens if the datablock is shared!
-void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
+void DepsgraphNodeBuilder::build_object_data_geometry(Object *object)
{
OperationDepsNode *op_node;
Scene *scene_cow = get_cow_datablock(scene_);
Object *object_cow = get_cow_datablock(object);
-
/* Temporary uber-update node, which does everything.
* It is for the being we're porting old dependencies into the new system.
* We'll get rid of this node as soon as all the granular update functions
@@ -1005,17 +1056,14 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
DEG_OPCODE_PLACEHOLDER,
"Eval Init");
op_node->set_as_entry();
-
// TODO: "Done" operation
-
/* Cloth modifier. */
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
if (md->type == eModifierType_Cloth) {
build_cloth(object);
}
}
-
- /* materials */
+ /* Materials. */
if (object->totcol != 0) {
if (object->type == OB_MESH) {
add_operation_node(&object->id,
@@ -1033,37 +1081,36 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
}
}
}
-
- /* geometry collision */
+ /* Geometry collision. */
if (ELEM(object->type, OB_MESH, OB_CURVE, OB_LATTICE)) {
// add geometry collider relations
}
+ build_object_data_geometry_datablock((ID *)object->data);
+}
- ID *obdata = (ID *)object->data;
+void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata)
+{
if (built_map_.checkIsBuiltAndTag(obdata)) {
return;
}
+ OperationDepsNode *op_node;
/* Make sure we've got an ID node before requesting CoW pointer. */
(void) add_id_node((ID *)obdata);
ID *obdata_cow = get_cow_id(obdata);
-
+ /* Animation. */
+ build_animdata(obdata);
/* ShapeKeys */
- Key *key = BKE_key_from_object(object);
+ Key *key = BKE_key_from_id(obdata);
if (key) {
build_shapekeys(key);
}
-
- build_animdata(obdata);
-
/* Nodes for result of obdata's evaluation, and geometry
* evaluation on object.
*/
- switch (object->type) {
- case OB_MESH:
+ const ID_Type id_type = GS(obdata->name);
+ switch (id_type) {
+ case ID_ME:
{
- //Mesh *me = (Mesh *)object->data;
-
- /* evaluation operations */
op_node = add_operation_node(obdata,
DEG_NODE_TYPE_GEOMETRY,
function_bind(BKE_mesh_eval_geometry,
@@ -1074,41 +1121,18 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
op_node->set_as_entry();
break;
}
-
- case OB_MBALL:
+ case ID_MB:
{
- Object *mom = BKE_mball_basis_find(scene_, object);
- /* NOTE: Only the motherball gets evaluated, it's children are
- * having empty placeholders for the correct relations being built.
- */
- if (mom == object) {
- /* metaball evaluation operations */
- op_node = add_operation_node(obdata,
- DEG_NODE_TYPE_GEOMETRY,
- function_bind(
- BKE_mball_eval_geometry,
- _1,
- (MetaBall *)obdata_cow),
- DEG_OPCODE_PLACEHOLDER,
- "Geometry Eval");
- }
- else {
- op_node = add_operation_node(obdata,
- DEG_NODE_TYPE_GEOMETRY,
- NULL,
- DEG_OPCODE_PLACEHOLDER,
- "Geometry Eval");
- op_node->set_as_entry();
- }
+ op_node = add_operation_node(obdata,
+ DEG_NODE_TYPE_GEOMETRY,
+ NULL,
+ DEG_OPCODE_PLACEHOLDER,
+ "Geometry Eval");
+ op_node->set_as_entry();
break;
}
-
- case OB_CURVE:
- case OB_SURF:
- case OB_FONT:
+ case ID_CU:
{
- /* Curve/nurms evaluation operations. */
- /* - calculate curve geometry (including path) */
op_node = add_operation_node(obdata,
DEG_NODE_TYPE_GEOMETRY,
function_bind(BKE_curve_eval_geometry,
@@ -1127,15 +1151,13 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
if (cu->taperobj != NULL) {
build_object(-1, cu->taperobj, DEG_ID_LINKED_INDIRECTLY);
}
- if (object->type == OB_FONT && cu->textoncurve != NULL) {
+ if (cu->textoncurve != NULL) {
build_object(-1, cu->textoncurve, DEG_ID_LINKED_INDIRECTLY);
}
break;
}
-
- case OB_LATTICE:
+ case ID_LT:
{
- /* Lattice evaluation operations. */
op_node = add_operation_node(obdata,
DEG_NODE_TYPE_GEOMETRY,
function_bind(BKE_lattice_eval_geometry,
@@ -1146,18 +1168,18 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
op_node->set_as_entry();
break;
}
+ default:
+ BLI_assert(!"Should not happen");
+ break;
}
-
op_node = add_operation_node(obdata, DEG_NODE_TYPE_GEOMETRY, NULL,
DEG_OPCODE_PLACEHOLDER, "Eval Done");
op_node->set_as_exit();
-
/* Parameters for driver sources. */
add_operation_node(obdata,
DEG_NODE_TYPE_PARAMETERS,
NULL,
DEG_OPCODE_PARAMETERS_EVAL);
-
/* Batch cache. */
add_operation_node(obdata,
DEG_NODE_TYPE_BATCH_CACHE,
@@ -1167,35 +1189,46 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
DEG_OPCODE_GEOMETRY_SELECT_UPDATE);
}
-/* Cameras */
-void DepsgraphNodeBuilder::build_camera(Object *object)
+void DepsgraphNodeBuilder::build_armature(bArmature *armature)
{
- /* Object data. */
- /* TODO: Link scene-camera links in somehow... */
- Camera *camera = (Camera *)object->data;
- if (built_map_.checkIsBuiltAndTag(camera)) {
+ if (built_map_.checkIsBuiltAndTag(armature)) {
return;
}
- build_animdata(&camera->id);
- add_operation_node(&camera->id,
+ build_animdata(&armature->id);
+ /* Make sure pose is up-to-date with armature updates. */
+ add_operation_node(&armature->id,
DEG_NODE_TYPE_PARAMETERS,
NULL,
- DEG_OPCODE_PARAMETERS_EVAL);
+ DEG_OPCODE_PLACEHOLDER,
+ "Armature Eval");
}
-/* Lamps */
-void DepsgraphNodeBuilder::build_lamp(Object *object)
+void DepsgraphNodeBuilder::build_camera(Camera *camera)
+{
+ if (built_map_.checkIsBuiltAndTag(camera)) {
+ return;
+ }
+ OperationDepsNode *op_node;
+ build_animdata(&camera->id);
+ op_node = add_operation_node(&camera->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ NULL,
+ DEG_OPCODE_PARAMETERS_EVAL);
+ op_node->set_as_exit();
+}
+
+void DepsgraphNodeBuilder::build_lamp(Lamp *lamp)
{
- /* Object data. */
- Lamp *lamp = (Lamp *)object->data;
if (built_map_.checkIsBuiltAndTag(lamp)) {
return;
}
+ OperationDepsNode *op_node;
build_animdata(&lamp->id);
- add_operation_node(&lamp->id,
- DEG_NODE_TYPE_PARAMETERS,
- NULL,
- DEG_OPCODE_PARAMETERS_EVAL);
+ op_node = add_operation_node(&lamp->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ NULL,
+ DEG_OPCODE_PARAMETERS_EVAL);
+ op_node->set_as_exit();
/* lamp's nodetree */
build_nodetree(lamp->nodetree);
}
@@ -1405,9 +1438,8 @@ void DepsgraphNodeBuilder::build_movieclip(MovieClip *clip)
DEG_OPCODE_MOVIECLIP_EVAL);
}
-void DepsgraphNodeBuilder::build_lightprobe(Object *object)
+void DepsgraphNodeBuilder::build_lightprobe(LightProbe *probe)
{
- LightProbe *probe = (LightProbe *)object->data;
if (built_map_.checkIsBuiltAndTag(probe)) {
return;
}
@@ -1415,13 +1447,7 @@ void DepsgraphNodeBuilder::build_lightprobe(Object *object)
add_operation_node(&probe->id,
DEG_NODE_TYPE_PARAMETERS,
NULL,
- DEG_OPCODE_PLACEHOLDER,
- "LightProbe Eval");
- add_operation_node(&object->id,
- DEG_NODE_TYPE_PARAMETERS,
- NULL,
- DEG_OPCODE_PLACEHOLDER,
- "LightProbe Eval");
+ DEG_OPCODE_LIGHT_PROBE_EVAL);
build_animdata(&probe->id);
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index b7c5a33f2c0..72aa5dbe003 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -36,7 +36,9 @@
#include "DEG_depsgraph.h"
struct Base;
+struct bArmature;
struct CacheFile;
+struct Camera;
struct bGPdata;
struct ListBase;
struct GHash;
@@ -45,7 +47,9 @@ struct Image;
struct FCurve;
struct Collection;
struct Key;
+struct Lamp;
struct LayerCollection;
+struct LightProbe;
struct Main;
struct Material;
struct Mask;
@@ -155,9 +159,10 @@ struct DepsgraphNodeBuilder {
void build_id(ID* id);
void build_layer_collections(ListBase *lb);
void build_view_layer(Scene *scene,
- ViewLayer *view_layer,
- eDepsNode_LinkedState_Type linked_state);
- void build_collection(Collection *collection);
+ ViewLayer *view_layer,
+ eDepsNode_LinkedState_Type linked_state);
+ void build_collection(eDepsNode_CollectionOwner owner_type,
+ Collection *collection);
void build_object(int base_index,
Object *object,
eDepsNode_LinkedState_Type linked_state);
@@ -165,6 +170,11 @@ struct DepsgraphNodeBuilder {
Object *object,
eDepsNode_LinkedState_Type linked_state);
void build_object_data(Object *object);
+ void build_object_data_camera(Object *object);
+ void build_object_data_geometry(Object *object);
+ void build_object_data_geometry_datablock(ID *obdata);
+ void build_object_data_lamp(Object *object);
+ void build_object_data_lightprobe(Object *object);
void build_object_transform(Object *object);
void build_object_constraints(Object *object);
void build_pose_constraints(Object *object, bPoseChannel *pchan, int pchan_index);
@@ -184,10 +194,10 @@ struct DepsgraphNodeBuilder {
bConstraint *con);
void build_rig(Object *object);
void build_proxy_rig(Object *object);
+ void build_armature(bArmature *armature);
void build_shapekeys(Key *key);
- void build_obdata_geom(Object *object);
- void build_camera(Object *object);
- void build_lamp(Object *object);
+ void build_camera(Camera *camera);
+ void build_lamp(Lamp *lamp);
void build_nodetree(bNodeTree *ntree);
void build_material(Material *ma);
void build_texture(Tex *tex);
@@ -198,7 +208,7 @@ struct DepsgraphNodeBuilder {
void build_cachefile(CacheFile *cache_file);
void build_mask(Mask *mask);
void build_movieclip(MovieClip *clip);
- void build_lightprobe(Object *object);
+ void build_lightprobe(LightProbe *probe);
protected:
struct SavedEntryTag {
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 d3c4ce01674..00d7a5da455 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -148,7 +148,6 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
Scene *scene_cow = get_cow_datablock(scene_);
Object *object_cow = get_cow_datablock(object);
OperationDepsNode *op_node;
-
/* Animation and/or drivers linking posebones to base-armature used to
* define them.
*
@@ -158,16 +157,8 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
* mechanism in-between here to ensure that we can use same rig
* multiple times in same scene.
*/
- if (!built_map_.checkIsBuiltAndTag(armature)) {
- build_animdata(&armature->id);
- /* Make sure pose is up-to-date with armature updates. */
- add_operation_node(&armature->id,
- DEG_NODE_TYPE_PARAMETERS,
- NULL,
- DEG_OPCODE_PLACEHOLDER,
- "Armature Eval");
- }
-
+ /* Armature. */
+ build_armature(armature);
/* Rebuild pose if not up to date. */
if (object->pose == NULL || (object->pose->flag & POSE_RECALC)) {
BKE_pose_rebuild(object, armature);
@@ -179,15 +170,13 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
object->adt->recalc |= ADT_RECALC_ANIM;
}
}
-
- /* speed optimization for animation lookups */
+ /* Speed optimization for animation lookups. */
if (object->pose != NULL) {
BKE_pose_channels_hash_make(object->pose);
if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
BKE_pose_update_constraint_flags(object->pose);
}
}
-
/**
* Pose Rig Graph
* ==============
@@ -209,8 +198,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
* only so that we can redirect those to point at either the the post-IK/
* post-constraint/post-matrix steps, as needed.
*/
-
- /* pose eval context */
+ /* Pose eval context. */
op_node = add_operation_node(&object->id,
DEG_NODE_TYPE_EVAL_POSE,
function_bind(BKE_pose_eval_init,
@@ -236,8 +224,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
object_cow),
DEG_OPCODE_POSE_DONE);
op_node->set_as_exit();
-
- /* bones */
+ /* Bones. */
int pchan_index = 0;
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
/* Node for bone evaluation. */
@@ -302,25 +289,23 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
break;
}
}
-
/* Custom shape. */
if (pchan->custom != NULL) {
build_object(-1, pchan->custom, DEG_ID_LINKED_INDIRECTLY);
}
-
pchan_index++;
}
}
void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
{
- bArmature *arm = (bArmature *)object->data;
+ bArmature *armature = (bArmature *)object->data;
OperationDepsNode *op_node;
Object *object_cow = get_cow_datablock(object);
/* Sanity check. */
BLI_assert(object->pose != NULL);
- /* Animation. */
- build_animdata(&arm->id);
+ /* Armature. */
+ build_armature(armature);
/* speed optimization for animation lookups */
BKE_pose_channels_hash_make(object->pose);
if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
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 3fc97ee3fcf..e2526272570 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
@@ -71,13 +71,13 @@ void DepsgraphNodeBuilder::build_layer_collections(ListBase *lb)
COLLECTION_RESTRICT_VIEW : COLLECTION_RESTRICT_RENDER;
for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) {
- if (!(lc->collection->flag & restrict_flag)) {
- if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
- build_collection(lc->collection);
- }
-
- build_layer_collections(&lc->layer_collections);
+ if (lc->collection->flag & restrict_flag) {
+ continue;
+ }
+ if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
+ build_collection(DEG_COLLECTION_OWNER_SCENE, lc->collection);
}
+ build_layer_collections(&lc->layer_collections);
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index d5ea8103742..eb1ee0c1535 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -161,6 +161,9 @@ static bool particle_system_depends_on_time(ParticleSystem *psys)
static bool object_particles_depends_on_time(Object *object)
{
+ if (object->type != OB_MESH) {
+ return false;
+ }
LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
if (particle_system_depends_on_time(psys)) {
return true;
@@ -396,12 +399,27 @@ void DepsgraphRelationBuilder::build_id(ID *id)
return;
}
switch (GS(id->name)) {
+ case ID_AR:
+ build_armature((bArmature *)id);
+ break;
+ case ID_CA:
+ build_camera((Camera *)id);
+ break;
case ID_GR:
- build_collection(NULL, (Collection *)id);
+ build_collection(DEG_COLLECTION_OWNER_UNKNOWN, NULL, (Collection *)id);
break;
case ID_OB:
build_object(NULL, (Object *)id);
break;
+ case ID_KE:
+ build_shapekeys((Key *)id);
+ break;
+ case ID_LA:
+ build_lamp((Lamp *)id);
+ break;
+ case ID_LP:
+ build_lightprobe((LightProbe *)id);
+ break;
case ID_NT:
build_nodetree((bNodeTree *)id);
break;
@@ -420,19 +438,33 @@ void DepsgraphRelationBuilder::build_id(ID *id)
case ID_MC:
build_movieclip((MovieClip *)id);
break;
+ case ID_ME:
+ case ID_CU:
+ case ID_MB:
+ case ID_LT:
+ build_object_data_geometry_datablock(id);
+ break;
default:
fprintf(stderr, "Unhandled ID %s\n", id->name);
+ BLI_assert(!"Should never happen");
+ break;
}
}
-void DepsgraphRelationBuilder::build_collection(Object *object, Collection *collection)
+void DepsgraphRelationBuilder::build_collection(
+ eDepsNode_CollectionOwner owner_type,
+ Object *object,
+ Collection *collection)
{
- const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ?
- COLLECTION_RESTRICT_VIEW : COLLECTION_RESTRICT_RENDER;
- if (collection->flag & restrict_flag) {
- return;
+ const bool allow_restrict_flags = (owner_type == DEG_COLLECTION_OWNER_SCENE);
+ if (allow_restrict_flags) {
+ const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT)
+ ? COLLECTION_RESTRICT_VIEW
+ : COLLECTION_RESTRICT_RENDER;
+ if (collection->flag & restrict_flag) {
+ return;
+ }
}
-
const bool group_done = built_map_.checkIsBuiltAndTag(collection);
OperationKey object_local_transform_key(object != NULL ? &object->id : NULL,
DEG_NODE_TYPE_TRANSFORM,
@@ -442,12 +474,17 @@ void DepsgraphRelationBuilder::build_collection(Object *object, Collection *coll
build_object(NULL, cob->ob);
}
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- build_collection(NULL, child->collection);
+ build_collection(owner_type, NULL, child->collection);
}
}
if (object != NULL) {
const ListBase group_objects = BKE_collection_object_cache_get(collection);
+ const int base_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ?
+ BASE_VISIBLE_VIEWPORT : BASE_VISIBLE_RENDER;
LISTBASE_FOREACH (Base *, base, &group_objects) {
+ if ((base->flag & base_flag) == 0) {
+ continue;
+ }
ComponentKey dupli_transform_key(&base->object->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup");
}
@@ -560,7 +597,7 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
/* Object dupligroup. */
if (object->dup_group != NULL) {
- build_collection(object, object->dup_group);
+ build_collection(DEG_COLLECTION_OWNER_OBJECT, object, object->dup_group);
}
}
@@ -597,7 +634,7 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
case OB_MBALL:
case OB_LATTICE:
{
- build_obdata_geom(object);
+ build_object_data_geometry(object);
break;
}
case OB_ARMATURE:
@@ -609,13 +646,13 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
}
break;
case OB_LAMP:
- build_lamp(object);
+ build_object_data_lamp(object);
break;
case OB_CAMERA:
- build_camera(object);
+ build_object_data_camera(object);
break;
case OB_LIGHTPROBE:
- build_lightprobe(object);
+ build_object_data_lightprobe(object);
break;
}
Key *key = BKE_key_from_object(object);
@@ -627,6 +664,37 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
}
}
+void DepsgraphRelationBuilder::build_object_data_camera(Object *object)
+{
+ Camera *camera = (Camera *)object->data;
+ build_camera(camera);
+ ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
+ ComponentKey camera_parameters_key(&camera->id, DEG_NODE_TYPE_PARAMETERS);
+ add_relation(camera_parameters_key, object_parameters_key, "Camera -> Object");
+}
+
+void DepsgraphRelationBuilder::build_object_data_lamp(Object *object)
+{
+ Lamp *lamp = (Lamp *)object->data;
+ build_lamp(lamp);
+ ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
+ ComponentKey lamp_parameters_key(&lamp->id, DEG_NODE_TYPE_PARAMETERS);
+ add_relation(lamp_parameters_key, object_parameters_key, "Lamp -> Object");
+}
+
+void DepsgraphRelationBuilder::build_object_data_lightprobe(Object *object)
+{
+ LightProbe *probe = (LightProbe *)object->data;
+ build_lightprobe(probe);
+ OperationKey probe_key(&probe->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_LIGHT_PROBE_EVAL);
+ OperationKey object_key(&object->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_LIGHT_PROBE_EVAL);
+ add_relation(probe_key, object_key, "LightProbe Update");
+}
+
void DepsgraphRelationBuilder::build_object_parent(Object *object)
{
/* XXX: for now, need to use the component key (not just direct to the parent op),
@@ -1540,7 +1608,7 @@ void DepsgraphRelationBuilder::build_particles(Object *object)
break;
case PART_DRAW_GR:
if (part->dup_group != NULL) {
- build_collection(NULL, part->dup_group);
+ build_collection(DEG_COLLECTION_OWNER_OBJECT, NULL, part->dup_group);
LISTBASE_FOREACH (CollectionObject *, go, &part->dup_group->gobject) {
build_particles_visualization_object(object,
psys,
@@ -1612,27 +1680,13 @@ void DepsgraphRelationBuilder::build_cloth(Object *object,
}
/* Shapekeys */
-void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key)
+void DepsgraphRelationBuilder::build_shapekeys(Key *key)
{
- ComponentKey obdata_key(obdata, DEG_NODE_TYPE_GEOMETRY);
-
+ if (built_map_.checkIsBuiltAndTag(key)) {
+ return;
+ }
/* attach animdata to geometry */
build_animdata(&key->id);
-
- if (key->adt) {
- // TODO: this should really be handled in build_animdata, since many of these cases will need it
- if (key->adt->action || key->adt->nla_tracks.first) {
- ComponentKey adt_key(&key->id, DEG_NODE_TYPE_ANIMATION);
- add_relation(adt_key, obdata_key, "Animation");
- }
-
- /* NOTE: individual shapekey drivers are handled above already */
- }
-
- /* attach to geometry */
- // XXX: aren't shapekeys now done as a pseudo-modifier on object?
- //ComponentKey key_key(&key->id, DEG_NODE_TYPE_GEOMETRY); // FIXME: this doesn't exist
- //add_relation(key_key, obdata_key, "Shapekeys");
}
/**
@@ -1640,56 +1694,53 @@ void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key)
* ==========================
*
* The evaluation of geometry on objects is as follows:
- * - The actual evaluated of the derived geometry (e.g. DerivedMesh, DispList, etc.)
- * occurs in the Geometry component of the object which references this. This includes
- * modifiers, and the temporary "ubereval" for geometry.
- * - Therefore, each user of a piece of shared geometry data ends up evaluating its own
- * version of the stuff, complete with whatever modifiers it may use.
+ * - The actual evaluated of the derived geometry (e.g. DerivedMesh, DispList)
+ * occurs in the Geometry component of the object which references this.
+ * This includes modifiers, and the temporary "ubereval" for geometry.
+ * Therefore, each user of a piece of shared geometry data ends up evaluating
+ * its own version of the stuff, complete with whatever modifiers it may use.
*
- * - The datablocks for the geometry data - "obdata" (e.g. ID_ME, ID_CU, ID_LT, etc.) are used for
+ * - The datablocks for the geometry data - "obdata" (e.g. ID_ME, ID_CU, ID_LT.)
+ * are used for
* 1) calculating the bounding boxes of the geometry data,
- * 2) aggregating inward links from other objects (e.g. for text on curve, etc.)
+ * 2) aggregating inward links from other objects (e.g. for text on curve)
* and also for the links coming from the shapekey datablocks
- * - Animation/Drivers affecting the parameters of the geometry are made to trigger
- * updates on the obdata geometry component, which then trigger downstream
- * re-evaluation of the individual instances of this geometry.
+ * - Animation/Drivers affecting the parameters of the geometry are made to
+ * trigger updates on the obdata geometry component, which then trigger
+ * downstream re-evaluation of the individual instances of this geometry.
*/
-// TODO: Materials and lighting should probably get their own component, instead of being lumped under geometry?
-void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
+void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
{
ID *obdata = (ID *)object->data;
-
/* Init operation of object-level geometry evaluation. */
- OperationKey geom_init_key(&object->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Init");
-
- /* get nodes for result of obdata's evaluation, and geometry evaluation on object */
+ OperationKey geom_init_key(&object->id,
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_PLACEHOLDER,
+ "Eval Init");
+ /* Get nodes for result of obdata's evaluation, and geometry evaluation
+ * on object.
+ */
ComponentKey obdata_geom_key(obdata, DEG_NODE_TYPE_GEOMETRY);
ComponentKey geom_key(&object->id, DEG_NODE_TYPE_GEOMETRY);
-
- /* link components to each other */
+ /* Link components to each other. */
add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data");
-
OperationKey obdata_ubereval_key(&object->id,
DEG_NODE_TYPE_GEOMETRY,
DEG_OPCODE_GEOMETRY_UBEREVAL);
-
- /* Special case: modifiers and DerivedMesh creation queries scene for various
- * things like data mask to be used. We add relation here to ensure object is
- * never evaluated prior to Scene's CoW is ready.
+ /* Special case: modifiers evaluation queries scene for various things like
+ * data mask to be used. We add relation here to ensure object is never
+ * evaluated prior to Scene's CoW is ready.
*/
OperationKey scene_key(&scene_->id,
- DEG_NODE_TYPE_PARAMETERS,
- DEG_OPCODE_PLACEHOLDER,
- "Scene Eval");
+ DEG_NODE_TYPE_LAYER_COLLECTIONS,
+ DEG_OPCODE_VIEW_LAYER_EVAL);
DepsRelation *rel = add_relation(scene_key, obdata_ubereval_key, "CoW Relation");
rel->flag |= DEPSREL_FLAG_NO_FLUSH;
-
/* Modifiers */
if (object->modifiers.first != NULL) {
ModifierUpdateDepsgraphContext ctx = {};
ctx.scene = scene_;
ctx.object = object;
-
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type);
if (mti->updateDepsgraph) {
@@ -1706,8 +1757,7 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
}
}
}
-
- /* materials */
+ /* Materials. */
if (object->totcol) {
for (int a = 1; a <= object->totcol; a++) {
Material *ma = give_current_material(object, a);
@@ -1718,179 +1768,183 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
OperationKey material_key(&ma->id,
DEG_NODE_TYPE_SHADING,
DEG_OPCODE_MATERIAL_UPDATE);
- OperationKey shading_key(&object->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_SHADING);
+ OperationKey shading_key(&object->id,
+ DEG_NODE_TYPE_SHADING,
+ DEG_OPCODE_SHADING);
add_relation(material_key, shading_key, "Material Update");
}
}
}
}
-
- /* geometry collision */
+ /* Geometry collision. */
if (ELEM(object->type, OB_MESH, OB_CURVE, OB_LATTICE)) {
// add geometry collider relations
}
-
/* Make sure uber update is the last in the dependencies.
*
* TODO(sergey): Get rid of this node.
*/
if (object->type != OB_ARMATURE) {
/* Armatures does no longer require uber node. */
- OperationKey obdata_ubereval_key(&object->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL);
- add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval");
+ OperationKey obdata_ubereval_key(&object->id,
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_GEOMETRY_UBEREVAL);
+ add_relation(geom_init_key,
+ obdata_ubereval_key,
+ "Object Geometry UberEval");
+ }
+ if (object->type == OB_MBALL) {
+ Object *mom = BKE_mball_basis_find(scene_, object);
+ ComponentKey mom_geom_key(&mom->id, DEG_NODE_TYPE_GEOMETRY);
+ /* motherball - mom depends on children! */
+ if (mom == object) {
+ ComponentKey mom_transform_key(&mom->id,
+ DEG_NODE_TYPE_TRANSFORM);
+ add_relation(mom_transform_key,
+ mom_geom_key,
+ "Metaball Motherball Transform -> Geometry");
+ }
+ else {
+ ComponentKey transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(geom_key, mom_geom_key, "Metaball Motherball");
+ add_relation(transform_key, mom_geom_key, "Metaball Motherball");
+ }
+ }
+ /* NOTE: This is compatibility code to support particle systems
+ *
+ * for viewport being properly rendered in final render mode.
+ * This relation is similar to what dag_object_time_update_flags()
+ * was doing for mesh objects with particle system.
+ *
+ * Ideally we need to get rid of this relation.
+ */
+ if (object_particles_depends_on_time(object)) {
+ TimeSourceKey time_key;
+ OperationKey obdata_ubereval_key(&object->id,
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_GEOMETRY_UBEREVAL);
+ add_relation(time_key, obdata_ubereval_key, "Legacy particle time");
+ }
+ /* Object data datablock. */
+ build_object_data_geometry_datablock((ID *)object->data);
+ Key *key = BKE_key_from_object(object);
+ if (key != NULL) {
+ if (key->adt != NULL) {
+ if (key->adt->action || key->adt->nla_tracks.first) {
+ ComponentKey obdata_key((ID *)object->data,
+ DEG_NODE_TYPE_GEOMETRY);
+ ComponentKey adt_key(&key->id, DEG_NODE_TYPE_ANIMATION);
+ add_relation(adt_key, obdata_key, "Animation");
+ }
+ }
}
+}
+void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
+{
if (built_map_.checkIsBuiltAndTag(obdata)) {
return;
}
-
+ /* Animation. */
+ build_animdata(obdata);
+ /* ShapeKeys. */
+ Key *key = BKE_key_from_id(obdata);
+ if (key != NULL) {
+ build_shapekeys(key);
+ }
/* Link object data evaluation node to exit operation. */
- OperationKey obdata_geom_eval_key(obdata, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Geometry Eval");
- OperationKey obdata_geom_done_key(obdata, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Done");
- add_relation(obdata_geom_eval_key, obdata_geom_done_key, "ObData Geom Eval Done");
-
- /* type-specific node/links */
- switch (object->type) {
- case OB_MESH:
- /* NOTE: This is compatibility code to support particle systems
- *
- * for viewport being properly rendered in final render mode.
- * This relation is similar to what dag_object_time_update_flags()
- * was doing for mesh objects with particle system.
- *
- * Ideally we need to get rid of this relation.
- */
- if (object_particles_depends_on_time(object)) {
- TimeSourceKey time_key;
- OperationKey obdata_ubereval_key(&object->id,
- DEG_NODE_TYPE_GEOMETRY,
- DEG_OPCODE_GEOMETRY_UBEREVAL);
- add_relation(time_key, obdata_ubereval_key, "Legacy particle time");
- }
+ OperationKey obdata_geom_eval_key(obdata,
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_PLACEHOLDER,
+ "Geometry Eval");
+ OperationKey obdata_geom_done_key(obdata,
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_PLACEHOLDER,
+ "Eval Done");
+ add_relation(obdata_geom_eval_key,
+ obdata_geom_done_key,
+ "ObData Geom Eval Done");
+ /* Type-specific links. */
+ const ID_Type id_type = GS(obdata->name);
+ switch (id_type) {
+ case ID_ME:
break;
-
- case OB_MBALL:
- {
- Object *mom = BKE_mball_basis_find(scene_, object);
- ComponentKey mom_geom_key(&mom->id, DEG_NODE_TYPE_GEOMETRY);
- /* motherball - mom depends on children! */
- if (mom == object) {
- ComponentKey mom_transform_key(&mom->id,
- DEG_NODE_TYPE_TRANSFORM);
- add_relation(mom_transform_key,
- mom_geom_key,
- "Metaball Motherball Transform -> Geometry");
- }
- else {
- ComponentKey transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
- add_relation(geom_key, mom_geom_key, "Metaball Motherball");
- add_relation(transform_key, mom_geom_key, "Metaball Motherball");
- }
+ case ID_MB:
break;
- }
-
- case OB_CURVE:
- case OB_FONT:
+ case ID_CU:
{
Curve *cu = (Curve *)obdata;
-
- /* curve's dependencies */
- // XXX: these needs geom data, but where is geom stored?
- if (cu->bevobj) {
- ComponentKey bevob_geom_key(&cu->bevobj->id, DEG_NODE_TYPE_GEOMETRY);
- add_relation(bevob_geom_key, obdata_geom_key, "Curve Bevel Geometry");
- /* We only need scale, but we can't tag individual TRANSFORM components. */
- ComponentKey bevob_key(&cu->bevobj->id, DEG_NODE_TYPE_TRANSFORM);
- add_relation(bevob_key, obdata_geom_key, "Curve Bevel Scale");
+ if (cu->bevobj != NULL) {
+ ComponentKey bevob_geom_key(&cu->bevobj->id,
+ DEG_NODE_TYPE_GEOMETRY);
+ add_relation(bevob_geom_key,
+ obdata_geom_eval_key,
+ "Curve Bevel Geometry");
+ ComponentKey bevob_key(&cu->bevobj->id,
+ DEG_NODE_TYPE_TRANSFORM);
+ add_relation(bevob_key,
+ obdata_geom_eval_key,
+ "Curve Bevel Transform");
build_object(NULL, cu->bevobj);
}
- if (cu->taperobj) {
- ComponentKey taperob_key(&cu->taperobj->id, DEG_NODE_TYPE_GEOMETRY);
+ if (cu->taperobj != NULL) {
+ ComponentKey taperob_key(&cu->taperobj->id,
+ DEG_NODE_TYPE_GEOMETRY);
+ add_relation(taperob_key, obdata_geom_eval_key, "Curve Taper");
build_object(NULL, cu->taperobj);
- add_relation(taperob_key, geom_key, "Curve Taper");
}
- if (object->type == OB_FONT) {
- if (cu->textoncurve) {
- ComponentKey textoncurve_key(&cu->textoncurve->id, DEG_NODE_TYPE_GEOMETRY);
- build_object(NULL, cu->textoncurve);
- add_relation(textoncurve_key, geom_key, "Text on Curve");
- }
+ if (cu->textoncurve != NULL) {
+ ComponentKey textoncurve_key(&cu->textoncurve->id,
+ DEG_NODE_TYPE_GEOMETRY);
+ add_relation(textoncurve_key,
+ obdata_geom_eval_key,
+ "Text on Curve");
+ build_object(NULL, cu->textoncurve);
}
break;
}
-
- case OB_SURF: /* Nurbs Surface */
- {
+ case ID_LT:
break;
- }
-
- case OB_LATTICE: /* Lattice */
- {
+ default:
+ BLI_assert(!"Should not happen");
break;
- }
}
+}
- /* ShapeKeys */
- Key *key = BKE_key_from_object(object);
- if (key) {
- build_shapekeys(obdata, key);
+void DepsgraphRelationBuilder::build_armature(bArmature *armature)
+{
+ if (built_map_.checkIsBuiltAndTag(armature)) {
+ return;
}
+ build_animdata(&armature->id);
}
-/* Cameras */
-// TODO: Link scene-camera links in somehow...
-void DepsgraphRelationBuilder::build_camera(Object *object)
+void DepsgraphRelationBuilder::build_camera(Camera *camera)
{
- Camera *camera = (Camera *)object->data;
if (built_map_.checkIsBuiltAndTag(camera)) {
return;
}
-
- ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
- ComponentKey camera_parameters_key(&camera->id, DEG_NODE_TYPE_PARAMETERS);
-
- add_relation(camera_parameters_key, object_parameters_key,
- "Camera -> Object");
-
- /* DOF */
if (camera->dof_ob != NULL) {
+ ComponentKey camera_parameters_key(&camera->id, DEG_NODE_TYPE_PARAMETERS);
ComponentKey dof_ob_key(&camera->dof_ob->id, DEG_NODE_TYPE_TRANSFORM);
- add_relation(dof_ob_key, object_parameters_key, "Camera DOF");
+ add_relation(dof_ob_key, camera_parameters_key, "Camera DOF");
}
}
/* Lamps */
-void DepsgraphRelationBuilder::build_lamp(Object *object)
+void DepsgraphRelationBuilder::build_lamp(Lamp *lamp)
{
- Lamp *lamp = (Lamp *)object->data;
if (built_map_.checkIsBuiltAndTag(lamp)) {
return;
}
-
- ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
- ComponentKey lamp_parameters_key(&lamp->id, DEG_NODE_TYPE_PARAMETERS);
-
- add_relation(lamp_parameters_key, object_parameters_key,
- "Lamp -> Object");
-
/* lamp's nodetree */
if (lamp->nodetree != NULL) {
build_nodetree(lamp->nodetree);
+ ComponentKey lamp_parameters_key(&lamp->id, DEG_NODE_TYPE_PARAMETERS);
ComponentKey nodetree_key(&lamp->nodetree->id, DEG_NODE_TYPE_SHADING);
add_relation(nodetree_key, lamp_parameters_key, "NTree->Lamp Parameters");
build_nested_nodetree(&lamp->id, lamp->nodetree);
}
-
- /* Make sure copy on write of lamp data is always properly updated for
- * visible lamps.
- */
- OperationKey ob_copy_on_write_key(&object->id,
- DEG_NODE_TYPE_COPY_ON_WRITE,
- DEG_OPCODE_COPY_ON_WRITE);
- OperationKey lamp_copy_on_write_key(&lamp->id,
- DEG_NODE_TYPE_COPY_ON_WRITE,
- DEG_OPCODE_COPY_ON_WRITE);
- add_relation(lamp_copy_on_write_key, ob_copy_on_write_key, "Eval Order");
}
void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
@@ -1952,7 +2006,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
if (check_id_has_anim_component(&ntree->id)) {
ComponentKey animation_key(&ntree->id, DEG_NODE_TYPE_ANIMATION);
- add_relation(shading_parameters_key, animation_key, "NTree Shading Parameters");
+ add_relation(animation_key, shading_parameters_key, "NTree Shading Parameters");
}
}
@@ -2045,23 +2099,12 @@ void DepsgraphRelationBuilder::build_movieclip(MovieClip *clip)
build_animdata(&clip->id);
}
-void DepsgraphRelationBuilder::build_lightprobe(Object *object)
+void DepsgraphRelationBuilder::build_lightprobe(LightProbe *probe)
{
- LightProbe *probe = (LightProbe *)object->data;
if (built_map_.checkIsBuiltAndTag(probe)) {
return;
}
build_animdata(&probe->id);
-
- OperationKey probe_key(&probe->id,
- DEG_NODE_TYPE_PARAMETERS,
- DEG_OPCODE_PLACEHOLDER,
- "LightProbe Eval");
- OperationKey object_key(&object->id,
- DEG_NODE_TYPE_PARAMETERS,
- DEG_OPCODE_PLACEHOLDER,
- "LightProbe Eval");
- add_relation(probe_key, object_key, "LightProbe Update");
}
void DepsgraphRelationBuilder::build_copy_on_write_relations()
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index dbfaff4dc18..3d3a73b6551 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -49,15 +49,19 @@
#include "intern/nodes/deg_node_operation.h"
struct Base;
+struct bArmature;
struct bGPdata;
struct CacheFile;
+struct Camera;
struct ListBase;
struct GHash;
struct ID;
struct FCurve;
struct Collection;
struct Key;
+struct Lamp;
struct LayerCollection;
+struct LightProbe;
struct Main;
struct Mask;
struct Material;
@@ -197,10 +201,17 @@ struct DepsgraphRelationBuilder
void build_id(ID *id);
void build_layer_collections(ListBase *lb);
void build_view_layer(Scene *scene, ViewLayer *view_layer);
- void build_collection(Object *object, Collection *collection);
+ void build_collection(eDepsNode_CollectionOwner owner_type,
+ Object *object,
+ Collection *collection);
void build_object(Base *base, Object *object);
void build_object_flags(Base *base, Object *object);
void build_object_data(Object *object);
+ void build_object_data_camera(Object *object);
+ void build_object_data_geometry(Object *object);
+ void build_object_data_geometry_datablock(ID *obdata);
+ void build_object_data_lamp(Object *object);
+ void build_object_data_lightprobe(Object *object);
void build_object_parent(Object *object);
void build_constraints(ID *id,
eDepsNode_Type component_type,
@@ -239,10 +250,10 @@ struct DepsgraphRelationBuilder
RootPChanMap *root_map);
void build_rig(Object *object);
void build_proxy_rig(Object *object);
- void build_shapekeys(ID *obdata, Key *key);
- void build_obdata_geom(Object *object);
- void build_camera(Object *object);
- void build_lamp(Object *object);
+ void build_shapekeys(Key *key);
+ void build_armature(bArmature *armature);
+ void build_camera(Camera *camera);
+ void build_lamp(Lamp *lamp);
void build_nodetree(bNodeTree *ntree);
void build_material(Material *ma);
void build_texture(Tex *tex);
@@ -251,7 +262,7 @@ struct DepsgraphRelationBuilder
void build_cachefile(CacheFile *cache_file);
void build_mask(Mask *mask);
void build_movieclip(MovieClip *clip);
- void build_lightprobe(Object *object);
+ void build_lightprobe(LightProbe *probe);
void build_nested_datablock(ID *owner, ID *id);
void build_nested_nodetree(ID *owner, bNodeTree *ntree);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
index a9895eb3af1..49c107c988f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -304,27 +304,21 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object,
void DepsgraphRelationBuilder::build_rig(Object *object)
{
/* Armature-Data */
- bArmature *arm = (bArmature *)object->data;
-
+ bArmature *armature = (bArmature *)object->data;
// TODO: selection status?
-
- /* attach links between pose operations */
+ /* Attach links between pose operations. */
OperationKey init_key(&object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT);
OperationKey init_ik_key(&object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT_IK);
OperationKey flush_key(&object->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
-
add_relation(init_key, init_ik_key, "Pose Init -> Pose Init IK");
add_relation(init_ik_key, flush_key, "Pose Init IK -> Pose Cleanup");
-
/* Make sure pose is up-to-date with armature updates. */
- if (!built_map_.checkIsBuiltAndTag(arm)) {
- OperationKey armature_key(&arm->id,
- DEG_NODE_TYPE_PARAMETERS,
- DEG_OPCODE_PLACEHOLDER,
- "Armature Eval");
- add_relation(armature_key, init_key, "Data dependency");
- }
-
+ build_armature(armature);
+ OperationKey armature_key(&armature->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ DEG_OPCODE_PLACEHOLDER,
+ "Armature Eval");
+ add_relation(armature_key, init_key, "Data dependency");
/* IK Solvers...
* - These require separate processing steps are pose-level
* to be executed between chains of bones (i.e. once the
@@ -337,7 +331,8 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
* references, or with bones being parented to IK'd bones)
*
* Unsolved Issues:
- * - Care is needed to ensure that multi-headed trees work out the same as in ik-tree building
+ * - Care is needed to ensure that multi-headed trees work out the same as
+ * in ik-tree building
* - Animated chain-lengths are a problem...
*/
RootPChanMap root_map;
@@ -372,7 +367,6 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
}
}
//root_map.print_debug();
-
if (pose_depends_on_local_transform) {
/* TODO(sergey): Once partial updates are possible use relation between
* object transform and solver itself in it's build function.
@@ -381,8 +375,7 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
ComponentKey local_transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(local_transform_key, pose_key, "Local Transforms");
}
-
- /* links between operations for each bone */
+ /* Links between operations for each bone. */
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
OperationKey bone_local_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
OperationKey bone_pose_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT);
@@ -397,7 +390,9 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
if (pchan->parent != NULL) {
eDepsOperation_Code parent_key_opcode;
- /* NOTE: this difference in handling allows us to prevent lockups while ensuring correct poses for separate chains */
+ /* NOTE: this difference in handling allows us to prevent lockups
+ * while ensuring correct poses for separate chains.
+ */
if (root_map.has_common_root(pchan->name, pchan->parent->name)) {
parent_key_opcode = DEG_OPCODE_BONE_READY;
}
@@ -433,14 +428,15 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
/* bone ready -> done
* NOTE: For bones without IK, this is all that's needed.
- * For IK chains however, an additional rel is created from IK to done,
- * with transitive reduction removing this one...
+ * For IK chains however, an additional rel is created from IK
+ * to done, with transitive reduction removing this one..
*/
add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
- /* assume that all bones must be done for the pose to be ready (for deformers) */
+ /* assume that all bones must be done for the pose to be ready
+ * (for deformers)
+ */
add_relation(bone_done_key, flush_key, "PoseEval Result-Bone Link");
-
/* Custom shape. */
if (pchan->custom != NULL) {
build_object(NULL, pchan->custom);
@@ -450,7 +446,9 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
{
+ bArmature *armature = (bArmature *)object->data;
Object *proxy_from = object->proxy_from;
+ build_armature(armature);
OperationKey pose_init_key(&object->id,
DEG_NODE_TYPE_EVAL_POSE,
DEG_OPCODE_POSE_INIT);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index 0f159248ff4..b940fc3035e 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -75,13 +75,13 @@ void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
COLLECTION_RESTRICT_VIEW : COLLECTION_RESTRICT_RENDER;
for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) {
- if (!(lc->collection->flag & restrict_flag)) {
- if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
- build_collection(NULL, lc->collection);
- }
-
- build_layer_collections(&lc->layer_collections);
+ if ((lc->collection->flag & restrict_flag)) {
+ continue;
+ }
+ if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
+ build_collection(DEG_COLLECTION_OWNER_SCENE, NULL, lc->collection);
}
+ build_layer_collections(&lc->layer_collections);
}
}
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index b9681805cfb..26a23cff372 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -310,7 +310,7 @@ IDDepsNode *Depsgraph::find_id_node(const ID *id) const
IDDepsNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint)
{
- BLI_assert((id->tag & LIB_TAG_COPY_ON_WRITE) == 0);
+ BLI_assert((id->tag & LIB_TAG_COPIED_ON_WRITE) == 0);
IDDepsNode *id_node = find_id_node(id);
if (!id_node) {
DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_ID_REF);
@@ -500,7 +500,7 @@ ID *Depsgraph::get_cow_id(const ID *id_orig) const
* We try to enforce that in debug builds, for for release we play a bit
* safer game here.
*/
- if ((id_orig->tag & LIB_TAG_COPY_ON_WRITE) == 0) {
+ if ((id_orig->tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
/* TODO(sergey): This is nice sanity check to have, but it fails
* in following situations:
*
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 06fbe980620..ca9f32d4d8c 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -240,6 +240,6 @@ ID *DEG_get_original_id(ID *id)
if (id->orig_id == NULL) {
return id;
}
- BLI_assert((id->tag & LIB_TAG_COPY_ON_WRITE) != 0);
+ BLI_assert((id->tag & LIB_TAG_COPIED_ON_WRITE) != 0);
return (ID *)id->orig_id;
}
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 4f3769b6768..97a28038b7b 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -120,7 +120,7 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
/* Duplicated elements shouldn't care whether their original collection is visible or not. */
temp_dupli_object->base_flag |= BASE_VISIBLED;
- if (BKE_object_is_visible(temp_dupli_object, (eObjectVisibilityCheck)data->visibility_check) == false) {
+ if (BKE_object_is_visible(temp_dupli_object, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) == false) {
continue;
}
@@ -211,7 +211,9 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
data->scene = DEG_get_evaluated_scene(depsgraph);
data->id_node_index = 0;
data->num_id_nodes = num_id_nodes;
- data->visibility_check = (data->mode == DEG_ITER_OBJECT_MODE_RENDER)
+ eEvaluationMode eval_mode = DEG_get_mode(depsgraph);
+ /* Viewport rendered mode is DAG_EVAL_PREVIEW but still treated as viewport. */
+ data->visibility_check = (eval_mode == DAG_EVAL_RENDER)
? OB_VISIBILITY_CHECK_FOR_RENDER
: OB_VISIBILITY_CHECK_FOR_VIEWPORT;
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index e772aefe8cb..437999a06a9 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -449,17 +449,7 @@ void deg_graph_node_tag_zero(Main *bmain, Depsgraph *graph, IDDepsNode *id_node)
GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components)
{
if (comp_node->type == DEG_NODE_TYPE_ANIMATION) {
- AnimData *adt = BKE_animdata_from_id(id);
- /* NOTE: Animation data might be null if relations are tagged
- * for update.
- */
- if (adt == NULL || (adt->recalc & ADT_RECALC_ANIM) == 0) {
- /* If there is no animation, or animation is not tagged for
- * update yet, we don't force animation channel to be evaluated.
- */
- continue;
- }
- id->recalc |= ID_RECALC_ANIMATION;
+ continue;
}
comp_node->tag_update(graph);
}
@@ -520,7 +510,7 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph)
/* Make sure objects are up to date. */
foreach (DEG::IDDepsNode *id_node, graph->id_nodes) {
const ID_Type id_type = GS(id_node->id_orig->name);
- int flag = DEG_TAG_TIME | DEG_TAG_COPY_ON_WRITE;
+ int flag = DEG_TAG_COPY_ON_WRITE;
/* We only tag components which needs an update. Tagging everything is
* not a good idea because that might reset particles cache (or any
* other type of cache).
diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
index 19cc82a6b10..79d29f72b8d 100644
--- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc
+++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
@@ -138,6 +138,8 @@ const char *operationCodeAsString(eDepsOperation_Code opcode)
STRINGIFY_OPCODE(GEOMETRY_UBEREVAL);
STRINGIFY_OPCODE(GEOMETRY_CLOTH_MODIFIER);
STRINGIFY_OPCODE(GEOMETRY_SHAPEKEY);
+ /* Object data. */
+ STRINGIFY_OPCODE(LIGHT_PROBE_EVAL);
/* Pose. */
STRINGIFY_OPCODE(POSE_INIT);
STRINGIFY_OPCODE(POSE_INIT_IK);
diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h
index 14cd62e6cec..cec279a04bb 100644
--- a/source/blender/depsgraph/intern/depsgraph_types.h
+++ b/source/blender/depsgraph/intern/depsgraph_types.h
@@ -205,6 +205,9 @@ typedef enum eDepsOperation_Code {
DEG_OPCODE_GEOMETRY_CLOTH_MODIFIER,
DEG_OPCODE_GEOMETRY_SHAPEKEY,
+ /* Object data. ------------------------------------- */
+ DEG_OPCODE_LIGHT_PROBE_EVAL,
+
/* Pose. -------------------------------------------- */
/* Init pose, clear flags, etc. */
DEG_OPCODE_POSE_INIT,
@@ -269,7 +272,17 @@ typedef enum eDepsOperation_Code {
DEG_NUM_OPCODES,
} eDepsOperation_Code;
-
const char *operationCodeAsString(eDepsOperation_Code opcode);
+typedef enum eDepsNode_CollectionOwner {
+ /* Unknown owner of collection, collection is pulled directly, maybe
+ * via driver.
+ */
+ DEG_COLLECTION_OWNER_UNKNOWN,
+ /* Collection belongs to a scene. */
+ DEG_COLLECTION_OWNER_SCENE,
+ /* Collection is used by object, as a dupli-system. */
+ DEG_COLLECTION_OWNER_OBJECT,
+} eDepsNode_CollectionOwner;
+
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 2789f189f03..0f49d57a826 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -542,6 +542,9 @@ void update_special_pointers(const Depsgraph *depsgraph,
BLI_assert(object_cow->derivedDeform == NULL);
object_cow->mode = object_orig->mode;
object_cow->sculpt = object_orig->sculpt;
+ if (object_cow->type == OB_MESH) {
+ object_cow->runtime.mesh_orig = (Mesh *)object_cow->data;
+ }
if (object_cow->type == OB_ARMATURE) {
BKE_pose_remap_bone_pointers((bArmature *)object_cow->data,
object_cow->pose);
@@ -724,12 +727,12 @@ static void deg_backup_object_runtime(
Mesh *mesh_eval = object->runtime.mesh_eval;
object_runtime_backup->runtime = object->runtime;
BKE_object_runtime_reset(object);
- /* Currently object update will override actual object->data
- * to an evaluated version. Need to make sure we don't have
- * data set to evaluated one before free anything.
+ /* Object update will override actual object->data to an evaluated version.
+ * Need to make sure we don't have data set to evaluated one before free
+ * anything.
*/
if (mesh_eval != NULL && object->data == mesh_eval) {
- object->data = mesh_eval->id.orig_id;
+ object->data = object->runtime.mesh_orig;
}
/* Store curve cache and make sure we don't free it. */
object_runtime_backup->curve_cache = object->curve_cache;
@@ -742,20 +745,33 @@ static void deg_restore_object_runtime(
Object *object,
const ObjectRuntimeBackup *object_runtime_backup)
{
+ Mesh *mesh_orig = object->runtime.mesh_orig;
object->runtime = object_runtime_backup->runtime;
+ object->runtime.mesh_orig = mesh_orig;
if (object->runtime.mesh_eval != NULL) {
- Mesh *mesh_eval = object->runtime.mesh_eval;
- /* Do same thing as object update: override actual object data
- * pointer with evaluated datablock.
- */
- if (object->type == OB_MESH) {
- object->data = mesh_eval;
- /* Evaluated mesh simply copied edit_btmesh pointer from
- * original mesh during update, need to make sure no dead
- * pointers are left behind.
+ if (object->id.recalc & ID_RECALC_GEOMETRY) {
+ /* If geometry is tagged for update it means, that part of
+ * evaluated mesh are not valid anymore. In this case we can not
+ * have any "persistent" pointers to point to an invalid data.
+ *
+ * We restore object's data datablock to an original copy of
+ * that datablock.
*/
- Mesh *mesh = ((Mesh *)mesh_eval->id.orig_id);
- mesh_eval->edit_btmesh = mesh->edit_btmesh;
+ object->data = mesh_orig;
+ }
+ else {
+ Mesh *mesh_eval = object->runtime.mesh_eval;
+ /* Do same thing as object update: override actual object data
+ * pointer with evaluated datablock.
+ */
+ if (object->type == OB_MESH) {
+ object->data = mesh_eval;
+ /* Evaluated mesh simply copied edit_btmesh pointer from
+ * original mesh during update, need to make sure no dead
+ * pointers are left behind.
+ */
+ mesh_eval->edit_btmesh = mesh_orig->edit_btmesh;
+ }
}
}
if (object_runtime_backup->curve_cache != NULL) {
@@ -995,8 +1011,8 @@ bool deg_validate_copy_on_write_datablock(ID *id_cow)
void deg_tag_copy_on_write_id(ID *id_cow, const ID *id_orig)
{
BLI_assert(id_cow != id_orig);
- BLI_assert((id_orig->tag & LIB_TAG_COPY_ON_WRITE) == 0);
- id_cow->tag |= LIB_TAG_COPY_ON_WRITE;
+ BLI_assert((id_orig->tag & LIB_TAG_COPIED_ON_WRITE) == 0);
+ id_cow->tag |= LIB_TAG_COPIED_ON_WRITE;
id_cow->orig_id = (ID *)id_orig;
}
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 2b6d261d43e..9c3aa34b5d8 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -219,6 +219,8 @@ data_to_c_simple(engines/eevee/shaders/volumetric_scatter_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_integration_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_background_lib.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_cavity_lib.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_cavity_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_common_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_data_lib.glsl SRC)
@@ -279,6 +281,7 @@ data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC)
data_to_c_simple(modes/shaders/overlay_face_orientation_frag.glsl SRC)
data_to_c_simple(modes/shaders/overlay_face_orientation_vert.glsl SRC)
data_to_c_simple(modes/shaders/overlay_face_wireframe_vert.glsl SRC)
+data_to_c_simple(modes/shaders/overlay_face_wireframe_geom.glsl SRC)
data_to_c_simple(modes/shaders/overlay_face_wireframe_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC)
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index c86574f7557..2c771578514 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -155,7 +155,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
continue;
}
if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
- return;
+ continue;
}
ParticleSettings *part = psys->part;
const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index d08fee6039f..5d3717097b1 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -838,7 +838,7 @@ static void clay_cache_populate_particles(void *vedata, Object *ob)
continue;
}
if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
- return;
+ continue;
}
ParticleSettings *part = psys->part;
const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 9147a332764..f159bf21d03 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -129,38 +129,40 @@ static void eevee_cache_populate(void *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool is_active = (ob == draw_ctx->obact);
+ bool cast_shadow = false;
+
if (is_active) {
if (DRW_object_is_mode_shade(ob) == true) {
return;
}
}
- if (DRW_check_object_visible_within_active_context(ob) == false) {
- return;
+ if (ob->base_flag & BASE_VISIBLED) {
+ EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
- bool cast_shadow;
-
- EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
-
- if (cast_shadow) {
- EEVEE_lights_cache_shcaster_object_add(sldata, ob);
+ if (DRW_check_object_visible_within_active_context(ob)) {
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
+ EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
}
- }
- else if (!USE_SCENE_LIGHT(draw_ctx->v3d)) {
- /* do not add any scene light sources to the cache */
- }
- else if (ob->type == OB_LIGHTPROBE) {
- if ((ob->base_flag & BASE_FROMDUPLI) != 0) {
- /* TODO: Special case for dupli objects because we cannot save the object pointer. */
+ else if (!USE_SCENE_LIGHT(draw_ctx->v3d)) {
+ /* do not add any scene light sources to the cache */
+ }
+ else if (ob->type == OB_LIGHTPROBE) {
+ if ((ob->base_flag & BASE_FROMDUPLI) != 0) {
+ /* TODO: Special case for dupli objects because we cannot save the object pointer. */
+ }
+ else {
+ EEVEE_lightprobes_cache_add(sldata, ob);
+ }
}
- else {
- EEVEE_lightprobes_cache_add(sldata, ob);
+ else if (ob->type == OB_LAMP) {
+ EEVEE_lights_cache_add(sldata, ob);
}
}
- else if (ob->type == OB_LAMP) {
- EEVEE_lights_cache_add(sldata, ob);
+
+ if (cast_shadow) {
+ EEVEE_lights_cache_shcaster_object_add(sldata, ob);
}
}
@@ -191,9 +193,6 @@ static void eevee_draw_background(void *vedata)
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- /* Refresh Hair */
- DRW_draw_pass(psl->hair_tf_pass);
-
/* Sort transparents before the loop. */
DRW_pass_sort_shgroup_z(psl->transparent_pass);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index dd69e19e7c1..f5673d1a616 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -40,7 +40,9 @@
static struct {
struct GPUShader *shadow_sh;
struct GPUShader *shadow_store_cube_sh[SHADOW_METHOD_MAX];
+ struct GPUShader *shadow_store_cube_high_sh[SHADOW_METHOD_MAX];
struct GPUShader *shadow_store_cascade_sh[SHADOW_METHOD_MAX];
+ struct GPUShader *shadow_store_cascade_high_sh[SHADOW_METHOD_MAX];
struct GPUShader *shadow_copy_cube_sh[SHADOW_METHOD_MAX];
struct GPUShader *shadow_copy_cascade_sh[SHADOW_METHOD_MAX];
} e_data = {NULL}; /* Engine data */
@@ -172,22 +174,7 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
linfo->shadow_cascade_size = sh_cascade_size;
/* only compile the ones needed. reduce startup time. */
- if ((sh_method == SHADOW_ESM) && !e_data.shadow_store_cube_sh[SHADOW_ESM]) {
- DynStr *ds_frag = BLI_dynstr_new();
- BLI_dynstr_append(ds_frag, datatoc_concentric_samples_lib_glsl);
- BLI_dynstr_append(ds_frag, datatoc_shadow_store_frag_glsl);
- char *store_shadow_shader_str = BLI_dynstr_get_cstring(ds_frag);
- BLI_dynstr_free(ds_frag);
-
- e_data.shadow_store_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
- store_shadow_shader_str,
- "#define ESM\n");
- e_data.shadow_store_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
- store_shadow_shader_str,
- "#define ESM\n"
- "#define CSM\n");
- MEM_freeN(store_shadow_shader_str);
-
+ if ((sh_method == SHADOW_ESM) && !e_data.shadow_copy_cube_sh[SHADOW_ESM]) {
e_data.shadow_copy_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(
datatoc_shadow_copy_frag_glsl,
"#define ESM\n"
@@ -198,22 +185,7 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
"#define COPY\n"
"#define CSM\n");
}
- else if ((sh_method == SHADOW_VSM) && !e_data.shadow_store_cube_sh[SHADOW_VSM]) {
- DynStr *ds_frag = BLI_dynstr_new();
- BLI_dynstr_append(ds_frag, datatoc_concentric_samples_lib_glsl);
- BLI_dynstr_append(ds_frag, datatoc_shadow_store_frag_glsl);
- char *store_shadow_shader_str = BLI_dynstr_get_cstring(ds_frag);
- BLI_dynstr_free(ds_frag);
-
- e_data.shadow_store_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
- store_shadow_shader_str,
- "#define VSM\n");
- e_data.shadow_store_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
- store_shadow_shader_str,
- "#define VSM\n"
- "#define CSM\n");
- MEM_freeN(store_shadow_shader_str);
-
+ else if ((sh_method == SHADOW_VSM) && !e_data.shadow_copy_cube_sh[SHADOW_VSM]) {
e_data.shadow_copy_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(
datatoc_shadow_copy_frag_glsl,
"#define VSM\n"
@@ -226,6 +198,78 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
}
}
+static GPUShader *eevee_lights_get_store_sh(int shadow_method, bool high_blur, bool cascade)
+{
+ GPUShader **shader;
+
+ if (cascade) {
+ shader = (high_blur) ? &e_data.shadow_store_cascade_high_sh[shadow_method]
+ : &e_data.shadow_store_cascade_sh[shadow_method];
+ }
+ else {
+ shader = (high_blur) ? &e_data.shadow_store_cube_high_sh[shadow_method]
+ : &e_data.shadow_store_cube_sh[shadow_method];
+ }
+
+ if (*shader == NULL) {
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, datatoc_concentric_samples_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_shadow_store_frag_glsl);
+ char *store_shadow_shader_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, (shadow_method == SHADOW_VSM) ? "#define VSM\n" : "#define ESM\n");
+ if (high_blur) BLI_dynstr_append(ds_frag, "#define HIGH_BLUR\n");
+ if (cascade) BLI_dynstr_append(ds_frag, "#define CSM\n");
+ char *define_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ *shader = DRW_shader_create_fullscreen(
+ store_shadow_shader_str, define_str);
+
+ MEM_freeN(store_shadow_shader_str);
+ MEM_freeN(define_str);
+ }
+
+ return *shader;
+}
+
+static DRWPass *eevee_lights_cube_store_pass_get(EEVEE_PassList *psl, EEVEE_ViewLayerData *sldata, int shadow_method, int shadow_samples_ct)
+{
+ bool high_blur = shadow_samples_ct > 16;
+ DRWPass **pass = (high_blur) ? &psl->shadow_cube_store_pass : &psl->shadow_cube_store_high_pass;
+ if (*pass == NULL) {
+ EEVEE_LampsInfo *linfo = sldata->lamps;
+ *pass = DRW_pass_create("Shadow Cube Storage Pass", DRW_STATE_WRITE_COLOR);
+ GPUShader *shader = eevee_lights_get_store_sh(shadow_method, high_blur, false);
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, *pass);
+ DRW_shgroup_uniform_texture_ref(grp, "shadowTexture", &sldata->shadow_cube_blur);
+ DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
+ DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+ return *pass;
+}
+
+static DRWPass *eevee_lights_cascade_store_pass_get(EEVEE_PassList *psl, EEVEE_ViewLayerData *sldata, int shadow_method, int shadow_samples_ct)
+{
+ bool high_blur = shadow_samples_ct > 16;
+ DRWPass **pass = (high_blur) ? &psl->shadow_cascade_store_pass : &psl->shadow_cascade_store_high_pass;
+ if (*pass == NULL) {
+ EEVEE_LampsInfo *linfo = sldata->lamps;
+ *pass = DRW_pass_create("Shadow Cascade Storage Pass", DRW_STATE_WRITE_COLOR);
+ GPUShader *shader = eevee_lights_get_store_sh(shadow_method, high_blur, true);
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, *pass);
+ DRW_shgroup_uniform_texture_ref(grp, "shadowTexture", &sldata->shadow_cascade_blur);
+ DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
+ DRW_shgroup_uniform_int(grp, "cascadeId", &linfo->current_shadow_cascade, 1);
+ DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+ return *pass;
+}
+
void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_LampsInfo *linfo = sldata->lamps;
@@ -247,28 +291,10 @@ void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
memset(linfo->shcaster_backbuffer->flags, (char)SHADOW_CASTER_PRUNED, linfo->shcaster_backbuffer->alloc_count);
memset(linfo->shcaster_frontbuffer->flags, 0x00, linfo->shcaster_frontbuffer->alloc_count);
- {
- psl->shadow_cube_store_pass = DRW_pass_create("Shadow Storage Pass", DRW_STATE_WRITE_COLOR);
-
- DRWShadingGroup *grp = DRW_shgroup_create(
- e_data.shadow_store_cube_sh[linfo->shadow_method], psl->shadow_cube_store_pass);
- DRW_shgroup_uniform_texture_ref(grp, "shadowTexture", &sldata->shadow_cube_blur);
- DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
- DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- }
-
- {
- psl->shadow_cascade_store_pass = DRW_pass_create("Shadow Cascade Storage Pass", DRW_STATE_WRITE_COLOR);
-
- DRWShadingGroup *grp = DRW_shgroup_create(
- e_data.shadow_store_cascade_sh[linfo->shadow_method], psl->shadow_cascade_store_pass);
- DRW_shgroup_uniform_texture_ref(grp, "shadowTexture", &sldata->shadow_cascade_blur);
- DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
- DRW_shgroup_uniform_int(grp, "cascadeId", &linfo->current_shadow_cascade, 1);
- DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
- }
+ psl->shadow_cube_store_pass = NULL;
+ psl->shadow_cube_store_high_pass = NULL;
+ psl->shadow_cascade_store_pass = NULL;
+ psl->shadow_cascade_store_high_pass = NULL;
{
psl->shadow_cube_copy_pass = DRW_pass_create("Shadow Copy Pass", DRW_STATE_WRITE_COLOR);
@@ -1124,7 +1150,9 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
GPU_framebuffer_texture_layer_attach(sldata->shadow_cube_store_fb, sldata->shadow_cube_pool, 0, evscd->layer_id, 0);
GPU_framebuffer_bind(sldata->shadow_cube_store_fb);
- DRW_draw_pass(psl->shadow_cube_store_pass);
+
+ DRWPass *store_pass = eevee_lights_cube_store_pass_get(psl, sldata, linfo->shadow_method, srd->shadow_samples_ct);
+ DRW_draw_pass(store_pass);
led->need_update = false;
}
@@ -1224,7 +1252,9 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
int layer = evscd->layer_id + linfo->current_shadow_cascade;
GPU_framebuffer_texture_layer_attach(sldata->shadow_cascade_store_fb, sldata->shadow_cascade_pool, 0, layer, 0);
GPU_framebuffer_bind(sldata->shadow_cascade_store_fb);
- DRW_draw_pass(psl->shadow_cascade_store_pass);
+
+ DRWPass *store_pass = eevee_lights_cascade_store_pass_get(psl, sldata, linfo->shadow_method, srd->shadow_samples_ct);
+ DRW_draw_pass(store_pass);
}
}
@@ -1241,7 +1271,9 @@ void EEVEE_lights_free(void)
DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
for (int i = 0; i < SHADOW_METHOD_MAX; ++i) {
DRW_SHADER_FREE_SAFE(e_data.shadow_store_cube_sh[i]);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_store_cube_high_sh[i]);
DRW_SHADER_FREE_SAFE(e_data.shadow_store_cascade_sh[i]);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_store_cascade_high_sh[i]);
DRW_SHADER_FREE_SAFE(e_data.shadow_copy_cube_sh[i]);
DRW_SHADER_FREE_SAFE(e_data.shadow_copy_cascade_sh[i]);
}
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index 8107aa33d2b..5c626b42ddd 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -42,7 +42,7 @@ void EEVEE_lookdev_cache_init(
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
if (LOOK_DEV_MODE_ENABLED(v3d)) {
- StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_ORIENTATION_WORLD);
+ StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_WORLD);
if ((sl->flag & STUDIOLIGHT_ORIENTATION_WORLD)) {
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
GPUTexture *tex;
@@ -51,7 +51,9 @@ void EEVEE_lookdev_cache_init(
axis_angle_to_mat3_single(stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix);
- DRW_shgroup_uniform_vec3(*grp, "color", &world->horr, 1);
+ if (world) {
+ DRW_shgroup_uniform_vec3(*grp, "color", &world->horr, 1);
+ }
DRW_shgroup_uniform_float(*grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
DRW_shgroup_call_add(*grp, geom, NULL);
if (!pinfo) {
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 42e81373914..52c8ec985b8 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -894,9 +894,9 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
if (is_hair) {
DRWShadingGroup *shgrp = DRW_shgroup_hair_create(ob, psys, md,
- vedata->psl->default_pass[options], vedata->psl->hair_tf_pass,
+ vedata->psl->default_pass[options],
e_data.default_lit[options]);
- add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false, false);
+ add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false);
return shgrp;
}
else {
@@ -941,7 +941,6 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* Create Material Ghash */
{
stl->g_data->material_hash = BLI_ghash_ptr_new("Eevee_material ghash");
- stl->g_data->hair_material_hash = BLI_ghash_ptr_new("Eevee_hair_material ghash");
}
{
@@ -1072,10 +1071,6 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_vec3(grp, "offsets", e_data.noise_offsets, 1);
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
-
- {
- psl->hair_tf_pass = DRW_pass_create("Update Hair Pass", DRW_STATE_TRANS_FEEDBACK);
- }
}
#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) do { \
@@ -1576,10 +1571,19 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
EEVEE_volumes_cache_object_add(sldata, vedata, scene, ob);
}
}
+}
+
+void EEVEE_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+
+ bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
if (ob->type == OB_MESH) {
if (ob != draw_ctx->object_edit) {
- material_hash = stl->g_data->hair_material_hash;
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
if (md->type != eModifierType_ParticleSystem) {
continue;
@@ -1611,17 +1615,19 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
shgrp = DRW_shgroup_hair_create(
ob, psys, md,
- psl->depth_pass, psl->hair_tf_pass,
+ psl->depth_pass,
e_data.default_hair_prepass_sh);
shgrp = DRW_shgroup_hair_create(
ob, psys, md,
- psl->depth_pass_clip, psl->hair_tf_pass,
+ psl->depth_pass_clip,
e_data.default_hair_prepass_clip_sh);
DRW_shgroup_uniform_block(shgrp, "clip_block", sldata->clip_ubo);
shgrp = NULL;
if (ma->use_nodes && ma->nodetree) {
+ static int ssr_id;
+ ssr_id = (use_ssr) ? 1 : -1;
static float half = 0.5f;
static float error_col[3] = {1.0f, 0.0f, 1.0f};
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
@@ -1632,9 +1638,9 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
{
shgrp = DRW_shgroup_material_hair_create(
ob, psys, md,
- psl->material_pass, psl->hair_tf_pass,
+ psl->material_pass,
gpumat);
- add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false, false);
+ add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false);
break;
}
case GPU_MAT_QUEUED:
@@ -1654,7 +1660,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
/* Fallback to default shader */
if (shgrp == NULL) {
- bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
shgrp = EEVEE_default_shading_group_get(sldata, vedata,
ob, psys, md,
true, false, use_ssr,
@@ -1664,6 +1669,13 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
}
+
+ /* Shadows */
+ DRW_shgroup_hair_create(
+ ob, psys, md,
+ psl->shadow_pass,
+ e_data.default_hair_prepass_sh);
+ *cast_shadow = true;
}
}
}
@@ -1713,7 +1725,6 @@ void EEVEE_materials_cache_finish(EEVEE_Data *vedata)
/* END */
BLI_ghash_free(stl->g_data->material_hash, NULL, MEM_freeN);
- BLI_ghash_free(stl->g_data->hair_material_hash, NULL, NULL);
}
void EEVEE_materials_free(void)
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 8aca79255b0..fa9d2453934 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -144,8 +144,10 @@ typedef struct EEVEE_PassList {
struct DRWPass *shadow_pass;
struct DRWPass *shadow_cube_copy_pass;
struct DRWPass *shadow_cube_store_pass;
+ struct DRWPass *shadow_cube_store_high_pass;
struct DRWPass *shadow_cascade_copy_pass;
struct DRWPass *shadow_cascade_store_pass;
+ struct DRWPass *shadow_cascade_store_high_pass;
/* Probes */
struct DRWPass *probe_background;
@@ -212,7 +214,6 @@ typedef struct EEVEE_PassList {
struct DRWPass *background_pass;
struct DRWPass *update_noise_pass;
struct DRWPass *lookdev_pass;
- struct DRWPass *hair_tf_pass;
} EEVEE_PassList;
typedef struct EEVEE_FramebufferList {
@@ -783,7 +784,6 @@ typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *cube_display_shgrp;
struct DRWShadingGroup *planar_display_shgrp;
struct GHash *material_hash;
- struct GHash *hair_material_hash;
float background_alpha; /* TODO find a better place for this. */
/* For planar probes */
float planar_texel_size[2];
@@ -815,6 +815,7 @@ struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl);
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow);
+void EEVEE_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, bool *cast_shadow);
void EEVEE_materials_cache_finish(EEVEE_Data *vedata);
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, struct World *wo);
struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, struct World *wo);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 6cb3fa259eb..76887145ad2 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -143,25 +143,26 @@ void EEVEE_render_cache(
char info[42];
BLI_snprintf(info, sizeof(info), "Syncing %s", ob->id.name + 2);
RE_engine_update_stats(engine, NULL, info);
+ bool cast_shadow = false;
- if (DRW_check_object_visible_within_active_context(ob) == false) {
- return;
+ if (ob->base_flag & BASE_VISIBLED) {
+ EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
- bool cast_shadow;
-
- EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
-
- if (cast_shadow) {
- EEVEE_lights_cache_shcaster_object_add(sldata, ob);
+ if (DRW_check_object_visible_within_active_context(ob)) {
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
+ EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
+ }
+ else if (ob->type == OB_LIGHTPROBE) {
+ EEVEE_lightprobes_cache_add(sldata, ob);
+ }
+ else if (ob->type == OB_LAMP) {
+ EEVEE_lights_cache_add(sldata, ob);
}
}
- else if (ob->type == OB_LIGHTPROBE) {
- EEVEE_lightprobes_cache_add(sldata, ob);
- }
- else if (ob->type == OB_LAMP) {
- EEVEE_lights_cache_add(sldata, ob);
+
+ if (cast_shadow) {
+ EEVEE_lights_cache_shcaster_object_add(sldata, ob);
}
}
@@ -421,6 +422,9 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
/* Push instances attribs to the GPU. */
DRW_render_instance_buffer_finish();
+ /* Need to be called after DRW_render_instance_buffer_finish() */
+ DRW_hair_update();
+
if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR |
SCE_PASS_SUBSURFACE_DIRECT |
SCE_PASS_SUBSURFACE_INDIRECT)) != 0)
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index 704b039e0f6..a1890433b0f 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -143,6 +143,20 @@ vec2 mip_ratio_interp(float mip) {
float low_mip = floor(mip);
return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
}
+
+/* ------- RNG ------- */
+
+float wang_hash_noise(uint s)
+{
+ s = (s ^ 61u) ^ (s >> 16u);
+ s *= 9u;
+ s = s ^ (s >> 4u);
+ s *= 0x27d4eb2du;
+ s = s ^ (s >> 15u);
+
+ return fract(float(s) / 4294967296.0);
+}
+
/* ------- Fast Math ------- */
/* [Drobot2014a] Low Level Optimizations for GCN */
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
index fd1a10de548..c5dbf29a3f4 100644
--- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
@@ -6,14 +6,38 @@ uniform float roughness;
Closure nodetree_exec(void)
{
+#ifdef HAIR_SHADER
+ vec3 B = normalize(cross(worldNormal, hairTangent));
+ float cos_theta;
+ if (hairThicknessRes == 1) {
+ vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ /* Random cosine normal distribution on the hair surface. */
+ cos_theta = rand.x * 2.0 - 1.0;
+ }
+ else {
+ /* Shade as a cylinder. */
+ cos_theta = hairThickTime / hairThickness;
+ }
+ float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));;
+ vec3 N = normalize(worldNormal * sin_theta + B * cos_theta);
+ vec3 vN = mat3(ViewMatrix) * N;
+#else
+ vec3 N = normalize(gl_FrontFacing ? worldNormal : -worldNormal);
+ vec3 vN = normalize(gl_FrontFacing ? viewNormal : -viewNormal);
+#endif
+
vec3 dielectric = vec3(0.034) * specular * 2.0;
vec3 albedo = mix(basecol, vec3(0.0), metallic);
vec3 f0 = mix(dielectric, basecol, metallic);
- vec3 N = (gl_FrontFacing) ? worldNormal : -worldNormal;
vec3 out_diff, out_spec, ssr_spec;
eevee_closure_default(N, albedo, f0, 1, roughness, 1.0, out_diff, out_spec, ssr_spec);
- Closure result = Closure(out_spec + out_diff * albedo, 1.0, vec4(ssr_spec, roughness), normal_encode(normalize(viewNormal), viewCameraVec), 0);
+ Closure result = Closure(
+ out_spec + out_diff * albedo,
+ 1.0,
+ vec4(ssr_spec, roughness),
+ normal_encode(vN, viewCameraVec),
+ 0);
#ifdef LOOKDEV
gl_FragDepth = 0.0;
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index accecaacbde..4e65834e528 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -26,6 +26,7 @@ in vec3 hairTangent; /* world space */
in float hairThickTime;
in float hairThickness;
in float hairTime;
+flat in int hairStrandID;
uniform int hairThicknessRes = 1;
#endif
@@ -177,33 +178,6 @@ void CLOSURE_NAME(
vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
-#ifdef HAIR_SHADER
- if (hairThicknessRes == 1) {
- /* Random normal distribution on the hair surface. */
- vec3 T = normalize(worldNormal); /* meh, TODO fix worldNormal misnaming. */
- vec3 B = normalize(cross(V, T));
- N = cross(T, B); /* Normal facing view */
- /* We want a cosine distribution. */
- float cos_theta = rand.x * 2.0 - 1.0;
- float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));;
- N = N * sin_theta + B * cos_theta;
-
-# ifdef CLOSURE_GLOSSY
- /* Hair random normal does not work with SSR :(.
- * It just create self reflection feedback (which is beautifful btw)
- * but not correct. */
- ssr_id = NO_SSR; /* Force bypass */
-# endif
- }
- else {
- vec3 T = normalize(cross(hairTangent, worldNormal));
- /* We want a cosine distribution. */
- float cos_theta = hairThickTime / hairThickness;
- float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));;
- N = normalize(hairTangent * cos_theta + T * sin_theta);
- }
-#endif
-
/* ---------------------------------------------------------------- */
/* -------------------- SCENE LAMPS LIGHTING ---------------------- */
/* ---------------------------------------------------------------- */
@@ -410,12 +384,6 @@ void CLOSURE_NAME(
}
out_spec += spec_accum.rgb * ssr_spec * spec_occlu * float(specToggle);
-
-# ifdef HAIR_SHADER
- /* Hack: Overide spec color so that ssr will not be computed
- * even if ssr_id match the active ssr. */
- ssr_spec = vec3(0.0);
-# endif
#endif
#ifdef CLOSURE_REFRACTION
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
index d643ebb73dd..58bcea7d605 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
@@ -35,22 +35,25 @@ out vec3 hairTangent;
out float hairThickTime;
out float hairThickness;
out float hairTime;
+flat out int hairStrandID;
#endif
void main()
{
#ifdef HAIR_SHADER
- vec3 pos, nor;
- hair_get_pos_tan_nor_time(
+ hairStrandID = hair_get_strand_id();
+ vec3 pos, binor;
+ hair_get_pos_tan_binor_time(
(ProjectionMatrix[3][3] == 0.0),
ViewMatrixInverse[3].xyz, ViewMatrixInverse[2].xyz,
- pos, nor, hairTangent, hairTime, hairThickness, hairThickTime);
+ pos, hairTangent, binor, hairTime, hairThickness, hairThickTime);
gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
viewPosition = (ViewMatrix * vec4(pos, 1.0)).xyz;
worldPosition = pos;
- worldNormal = nor;
- viewNormal = normalize(mat3(ViewMatrixInverse) * nor);
+ hairTangent = normalize(hairTangent);
+ worldNormal = cross(binor, hairTangent);
+ viewNormal = normalize(mat3(ViewMatrix) * worldNormal);
#else
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
viewPosition = (ModelViewMatrix * vec4(pos, 1.0)).xyz;
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
index 1ed4f5f6500..f2e9e7001e8 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
@@ -15,11 +15,11 @@ void main()
{
#ifdef HAIR_SHADER
float time, thick_time, thickness;
- vec3 pos, nor, binor;
- hair_get_pos_tan_nor_time(
+ vec3 pos, tan, binor;
+ hair_get_pos_tan_binor_time(
(ProjectionMatrix[3][3] == 0.0),
ViewMatrixInverse[3].xyz, ViewMatrixInverse[2].xyz,
- pos, nor, binor, time, thickness, thick_time);
+ pos, tan, binor, time, thickness, thick_time);
gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
vec4 worldPosition = vec4(pos, 1.0);
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
index b40155be454..d5ac821c3fa 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
@@ -165,6 +165,7 @@ void main() {
grouped_samples_accum(cos, concentric[28], concentric[29], concentric[30], concentric[31], accum);
grouped_samples_accum(cos, concentric[32], concentric[33], concentric[34], concentric[35], accum);
}
+#ifdef HIGH_BLUR
if (shadowSampleCount > 36) {
grouped_samples_accum(cos, concentric[36], concentric[37], concentric[38], concentric[39], accum);
grouped_samples_accum(cos, concentric[40], concentric[41], concentric[42], concentric[43], accum);
@@ -230,6 +231,7 @@ void main() {
grouped_samples_accum(cos, concentric[248], concentric[249], concentric[250], concentric[251], accum);
grouped_samples_accum(cos, concentric[252], concentric[253], concentric[254], concentric[255], accum);
}
+#endif
#ifdef ESM
accum.x = ln_space_prefilter(1.0, accum.x, 1.0, accum.y);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
new file mode 100644
index 00000000000..38f55015877
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
@@ -0,0 +1,71 @@
+out vec4 fragColor;
+
+uniform sampler2D depthBuffer;
+uniform sampler2D colorBuffer;
+uniform sampler2D normalBuffer;
+uniform sampler2D positionBuffer;
+
+uniform vec2 invertedViewportSize;
+uniform mat4 WinMatrix; /* inverse WinMatrix */
+
+uniform vec4 viewvecs[3];
+uniform vec4 ssao_params;
+uniform vec4 ssao_settings;
+uniform sampler2D ssao_jitter;
+
+layout(std140) uniform samples_block {
+ vec4 ssao_samples[500];
+};
+
+#define ssao_samples_num ssao_params.x
+#define jitter_tilling ssao_params.yz
+#define dfdy_sign ssao_params.w
+
+#define ssao_distance ssao_settings.x
+#define ssao_factor_cavity ssao_settings.y
+#define ssao_factor_edge ssao_settings.z
+#define ssao_attenuation ssao_settings.a
+
+vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth)
+{
+ if (WinMatrix[3][3] == 0.0) {
+ /* Perspective */
+ float d = 2.0 * depth - 1.0;
+
+ float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]);
+
+ return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz);
+ }
+ else {
+ /* Orthographic */
+ vec3 offset = vec3(uvcoords, depth);
+
+ return viewvecs[0].xyz + offset * viewvecs[1].xyz;
+ }
+}
+
+/* forward declartion */
+void ssao_factors(
+ in float depth, in vec3 normal, in vec3 position, in vec2 screenco,
+ out float cavities, out float edges);
+
+
+void main()
+{
+ vec2 screenco = vec2(gl_FragCoord.xy) * invertedViewportSize;
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+
+ float depth = texelFetch(depthBuffer, texel, 0).x;
+ vec3 position = get_view_space_from_depth(screenco, depth);
+
+ vec4 diffuse_color = texelFetch(colorBuffer, texel, 0);
+ vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg);
+ if (diffuse_color.a == 0.0) {
+ normal_viewport = -normal_viewport;
+ }
+
+ float cavity = 0.0, edges = 0.0;
+ ssao_factors(depth, normal_viewport, position, screenco, cavity, edges);
+
+ fragColor = vec4(cavity, edges, 0.0, 1.0);
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
new file mode 100644
index 00000000000..da0198ab2e7
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
@@ -0,0 +1,79 @@
+
+
+/* from The Alchemy screen-space ambient obscurance algorithm
+ * http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */
+
+void ssao_factors(
+ in float depth, in vec3 normal, in vec3 position, in vec2 screenco,
+ out float cavities, out float edges)
+{
+ cavities = edges = 0.0;
+ /* early out if there is no need for SSAO */
+ if (ssao_factor_cavity == 0.0 && ssao_factor_edge == 0.0)
+ return;
+
+ /* take the normalized ray direction here */
+ vec3 noise = texture(ssao_jitter, screenco.xy * jitter_tilling).rgb;
+
+ /* find the offset in screen space by multiplying a point
+ * in camera space at the depth of the point by the projection matrix. */
+ vec2 offset;
+ float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3];
+ offset.x = WinMatrix[0][0] * ssao_distance / homcoord;
+ offset.y = WinMatrix[1][1] * ssao_distance / homcoord;
+ /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
+ offset *= 0.5;
+
+ int num_samples = int(ssao_samples_num);
+
+ /* Note. Putting noise usage here to put some ALU after texture fetch. */
+ vec2 rotX = noise.rg;
+ vec2 rotY = vec2(-rotX.y, rotX.x);
+
+ for (int x = 0; x < num_samples && x < 500; x++) {
+ /* ssao_samples[x].xy is sample direction (normalized).
+ * ssao_samples[x].z is sample distance from disk center. */
+
+ /* Rotate with random direction to get jittered result. */
+ vec2 dir_jittered = vec2(dot(ssao_samples[x].xy, rotX), dot(ssao_samples[x].xy, rotY));
+ dir_jittered.xy *= ssao_samples[x].z + noise.b;
+
+ vec2 uvcoords = screenco.xy + dir_jittered * offset;
+
+ if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0)
+ continue;
+
+ float depth_new = texture(depthBuffer, uvcoords).r;
+
+ /* Handle Background case */
+ bool is_background = (depth_new == 1.0);
+
+ /* This trick provide good edge effect even if no neighboor is found. */
+ vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new);
+
+ if (is_background)
+ pos_new.z -= ssao_distance;
+
+ vec3 dir = pos_new - position;
+ float len = length(dir);
+ float f_cavities = dot(dir, normal);
+ float f_edge = -f_cavities;
+ float f_bias = 0.05 * len + 0.0001;
+
+ float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation));
+
+ /* use minor bias here to avoid self shadowing */
+ if (f_cavities > -f_bias)
+ cavities += f_cavities * attenuation;
+
+ if (f_edge > f_bias)
+ edges += f_edge * attenuation;
+ }
+
+ cavities /= ssao_samples_num;
+ edges /= ssao_samples_num;
+
+ /* don't let cavity wash out the surface appearance */
+ cavities = clamp(cavities * ssao_factor_cavity, 0.0, 1.0);
+ edges = edges * ssao_factor_edge;
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
index 39c6863e71c..8908891d7e6 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -71,3 +71,24 @@ vec4 calculate_transparent_accum(vec4 premultiplied) {
float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2);
return premultiplied * w;
}
+
+vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat)
+{
+ return (proj_mat[3][3] == 0.0)
+ ? normalize(viewvecs[0].xyz + vec3(uv, 0.0) * viewvecs[1].xyz)
+ : vec3(0.0, 0.0, 1.0);
+}
+
+vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped)
+{
+ /* Quick creation of an orthonormal basis */
+ float a = 1.0 / (1.0 + I.z);
+ float b = -I.x * I.y * a;
+ vec3 b1 = vec3(1.0 - I.x * I.x * a, b, -I.x);
+ vec3 b2 = vec3(b, 1.0 - I.y * I.y * a, -I.y);
+ vec2 matcap_uv = vec2(dot(b1, N), dot(b2, N));
+ if (flipped) {
+ matcap_uv.x = -matcap_uv.x;
+ }
+ return matcap_uv * 0.496 + 0.5;
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
index fc076ee8117..f67d2ff6745 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
@@ -16,7 +16,8 @@ struct WorldData {
vec4 light_direction_vs;
LightData lights[3];
int num_lights;
- int pad[3];
+ int matcap_orientation;
+ int pad[2];
};
struct MaterialData {
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
index 269911189fa..461fb2fb130 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
@@ -1,16 +1,24 @@
out vec4 fragColor;
+uniform mat4 ProjectionMatrix;
+
uniform usampler2D objectId;
uniform sampler2D colorBuffer;
uniform sampler2D specularBuffer;
uniform sampler2D normalBuffer;
/* normalBuffer contains viewport normals */
+uniform sampler2D cavityBuffer;
+
uniform vec2 invertedViewportSize;
+uniform vec4 viewvecs[3];
uniform float shadowMultiplier;
uniform float lightMultiplier;
uniform float shadowShift = 0.1;
uniform mat3 normalWorldMatrix;
+#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
+uniform sampler2D matcapImage;
+#endif
layout(std140) uniform world_block {
WorldData world_data;
@@ -43,47 +51,68 @@ void main()
#endif /* !V3D_SHADING_OBJECT_OUTLINE */
vec4 diffuse_color = texelFetch(colorBuffer, texel, 0);
+
/* Do we need normals */
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
-#ifdef WORKBENCH_ENCODE_NORMALS
+# ifdef WORKBENCH_ENCODE_NORMALS
vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg);
- if (diffuse_color.a == 1.0) {
+ if (diffuse_color.a == 0.0) {
normal_viewport = -normal_viewport;
}
-#else /* WORKBENCH_ENCODE_NORMALS */
+# else /* WORKBENCH_ENCODE_NORMALS */
vec3 normal_viewport = texelFetch(normalBuffer, texel, 0).rgb;
-#endif /* WORKBENCH_ENCODE_NORMALS */
+# endif /* WORKBENCH_ENCODE_NORMALS */
+#endif
+
+ vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix);
+
+#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
+ bool flipped = world_data.matcap_orientation != 0;
+ vec2 matcap_uv = matcap_uv_compute(I_vs, normal_viewport, flipped);
+ diffuse_color = textureLod(matcapImage, matcap_uv, 0.0);
#endif
#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
- /* XXX Should calculate the correct VS Incoming direction */
- vec3 I_vs = vec3(0.0, 0.0, 1.0);
vec4 specular_data = texelFetch(specularBuffer, texel, 0);
vec3 specular_color = get_world_specular_lights(world_data, specular_data, normal_viewport, I_vs);
#else
vec3 specular_color = vec3(0.0);
#endif
+#ifdef V3D_LIGHTING_FLAT
+ vec3 diffuse_light = vec3(1.0);
+#endif
+
+#ifdef V3D_LIGHTING_MATCAP
+ vec3 diffuse_light = texelFetch(specularBuffer, texel, 0).rgb;
+#endif
+
#ifdef V3D_LIGHTING_STUDIO
- #ifdef STUDIOLIGHT_ORIENTATION_CAMERA
+# ifdef STUDIOLIGHT_ORIENTATION_CAMERA
vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport);
- #endif
+# endif
- #ifdef STUDIOLIGHT_ORIENTATION_WORLD
+# ifdef STUDIOLIGHT_ORIENTATION_WORLD
vec3 normal_world = normalWorldMatrix * normal_viewport;
vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world);
- #endif
+# endif
+#endif
vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
-#else /* V3D_LIGHTING_STUDIO */
- vec3 shaded_color = diffuse_color.rgb + specular_color;
-
-#endif /* V3D_LIGHTING_STUDIO */
+#ifdef V3D_SHADING_CAVITY
+ vec2 cavity = texelFetch(cavityBuffer, texel, 0).rg;
+ shaded_color *= 1.0 - cavity.x;
+ shaded_color *= 1.0 + cavity.y;
+#endif
#ifdef V3D_SHADING_SHADOW
- float shadow_mix = step(-shadowShift, dot(normal_viewport, world_data.light_direction_vs.xyz));
- float light_multiplier;
- light_multiplier = mix(lightMultiplier, shadowMultiplier, shadow_mix);
+ float light_factor = -dot(normal_viewport, world_data.light_direction_vs.xyz);
+ /* The step function might be ok for meshes but it's
+ * clearly not the case for hairs. Do smoothstep in this case. */
+ float shadow_mix = (diffuse_color.a == 1.0 || diffuse_color.a == 0.0)
+ ? step(-shadowShift, -light_factor)
+ : smoothstep(1.0, shadowShift, light_factor);
+ float light_multiplier = mix(lightMultiplier, shadowMultiplier, shadow_mix);
#else /* V3D_SHADING_SHADOW */
float light_multiplier = 1.0;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
index 3f271ec439b..e954aa5e9f5 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
@@ -1,8 +1,11 @@
#ifdef OB_TEXTURE
uniform sampler2D image;
#endif
+uniform mat4 ProjectionMatrix;
uniform mat3 normalWorldMatrix;
uniform float alpha = 0.5;
+uniform vec2 invertedViewportSize;
+uniform vec4 viewvecs[3];
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
in vec3 normal_viewport;
@@ -10,6 +13,9 @@ in vec3 normal_viewport;
#ifdef OB_TEXTURE
in vec2 uv_interp;
#endif
+#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
+uniform sampler2D matcapImage;
+#endif
layout(std140) uniform world_block {
WorldData world_data;
@@ -25,6 +31,7 @@ layout(location=0) out vec4 transparentAccum;
void main()
{
vec4 diffuse_color;
+ vec3 diffuse_light = vec3(1.0);
#ifdef OB_SOLID
diffuse_color = material_data.diffuse_color;
#endif /* OB_SOLID */
@@ -32,28 +39,35 @@ void main()
diffuse_color = texture(image, uv_interp);
#endif /* OB_TEXTURE */
+ vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
+ vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix);
+
+ vec3 nor = normalize(normal_viewport);
+
+#ifdef V3D_LIGHTING_MATCAP
+ bool flipped = world_data.matcap_orientation != 0;
+ vec2 matcap_uv = matcap_uv_compute(I_vs, nor, flipped);
+ diffuse_light = texture(matcapImage, matcap_uv).rgb;
+#endif
+
#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
- vec3 specular_color = get_world_specular_lights(world_data, vec4(material_data.specular_color.rgb, material_data.roughness), normal_viewport, vec3(0.0, 0.0, 1.0));
+ vec3 specular_color = get_world_specular_lights(world_data, vec4(material_data.specular_color.rgb, material_data.roughness), nor, I_vs;
#else
vec3 specular_color = vec3(0.0);
#endif
#ifdef V3D_LIGHTING_STUDIO
-#ifdef STUDIOLIGHT_ORIENTATION_CAMERA
- vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport);
-#endif
-#ifdef STUDIOLIGHT_ORIENTATION_WORLD
- vec3 normal_world = normalWorldMatrix * normal_viewport;
- vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world);
+# ifdef STUDIOLIGHT_ORIENTATION_CAMERA
+ diffuse_light = get_camera_diffuse_light(world_data, nor);
+# endif
+# ifdef STUDIOLIGHT_ORIENTATION_WORLD
+ vec3 normal_world = normalWorldMatrix * nor;
+ diffuse_light = get_world_diffuse_light(world_data, normal_world);
+# endif
#endif
vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
-#else /* V3D_LIGHTING_STUDIO */
- vec3 shaded_color = diffuse_color.rgb + specular_color;
-
-#endif /* V3D_LIGHTING_STUDIO */
-
vec4 premultiplied = vec4(shaded_color.rgb * alpha, alpha);
transparentAccum = calculate_transparent_accum(premultiplied);
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
index c0f58271a8c..200850e3036 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
@@ -11,47 +11,67 @@ uniform sampler2D image;
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
in vec3 normal_viewport;
#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
+
#ifdef OB_TEXTURE
in vec2 uv_interp;
#endif /* OB_TEXTURE */
+#ifdef HAIR_SHADER
+flat in float hair_rand;
+#endif
+
layout(location=0) out uint objectId;
layout(location=1) out vec4 diffuseColor;
layout(location=2) out vec4 specularColor;
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
- #ifdef WORKBENCH_ENCODE_NORMALS
+# ifdef WORKBENCH_ENCODE_NORMALS
layout(location=3) out vec2 normalViewport;
- #else /* WORKBENCH_ENCODE_NORMALS */
+# else /* WORKBENCH_ENCODE_NORMALS */
layout(location=3) out vec3 normalViewport;
- #endif /* WORKBENCH_ENCODE_NORMALS */
+# endif /* WORKBENCH_ENCODE_NORMALS */
#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
void main()
{
objectId = uint(object_id);
+
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
+ vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport;
+ n = normalize(n);
+#endif
+
#ifdef OB_SOLID
diffuseColor = vec4(material_data.diffuse_color.rgb, 0.0);
+# ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
+
+ specularColor = vec4(material_data.diffuse_color.rgb, 0.0);
+# endif
#endif /* OB_SOLID */
+
#ifdef OB_TEXTURE
diffuseColor = texture(image, uv_interp);
#endif /* OB_TEXTURE */
+#ifdef HAIR_SHADER
+ float hair_color_variation = hair_rand * 0.1;
+ diffuseColor.rgb = clamp(diffuseColor.rgb - hair_color_variation, 0.0, 1.0);
+#endif
#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
specularColor = vec4(material_data.specular_color.rgb, material_data.roughness);
+# ifdef HAIR_SHADER
+ specularColor.rgb = clamp(specularColor.rgb - hair_color_variation, 0.0, 1.0);
+# endif
#endif
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
- #ifdef WORKBENCH_ENCODE_NORMALS
- if (!gl_FrontFacing) {
- normalViewport = normal_encode(normalize(-normal_viewport));
- diffuseColor.a = 1.0;
- }
- else {
- normalViewport = normal_encode(normalize(normal_viewport));
- diffuseColor.a = 0.0;
- }
- #else /* WORKBENCH_ENCODE_NORMALS */
- normalViewport = normal_viewport;
- #endif /* WORKBENCH_ENCODE_NORMALS */
+# ifdef WORKBENCH_ENCODE_NORMALS
+ diffuseColor.a = float(gl_FrontFacing);
+ normalViewport = normal_encode(n);
+# else /* WORKBENCH_ENCODE_NORMALS */
+ normalViewport = n;
+# endif /* WORKBENCH_ENCODE_NORMALS */
+# ifdef HAIR_SHADER
+ diffuseColor.a = 0.5;
+# endif
#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
index f2df117d897..82443e7336b 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
@@ -1,30 +1,68 @@
uniform mat4 ModelViewProjectionMatrix;
-#ifdef NORMAL_VIEWPORT_PASS_ENABLED
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewProjectionMatrix;
+uniform mat4 ViewMatrixInverse;
uniform mat3 NormalMatrix;
-#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
+#ifndef HAIR_SHADER
in vec3 pos;
-#ifdef NORMAL_VIEWPORT_PASS_ENABLED
in vec3 nor;
-#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
-#ifdef OB_TEXTURE
in vec2 uv;
-#endif
+#else /* HAIR_SHADER */
+# ifdef OB_TEXTURE
+uniform samplerBuffer u; /* active texture layer */
+# endif
+flat out float hair_rand;
+#endif /* HAIR_SHADER */
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
out vec3 normal_viewport;
-#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
+#endif
+
#ifdef OB_TEXTURE
out vec2 uv_interp;
#endif
+/* From http://libnoise.sourceforge.net/noisegen/index.html */
+float integer_noise(int n)
+{
+ n = (n >> 13) ^ n;
+ int nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
+ return (float(nn) / 1073741824.0);
+}
+
void main()
{
+#ifdef HAIR_SHADER
+# ifdef OB_TEXTURE
+ vec2 uv = hair_get_customdata_vec2(u);
+# endif
+ float time, thick_time, thickness;
+ vec3 pos, tan, binor;
+ hair_get_pos_tan_binor_time(
+ (ProjectionMatrix[3][3] == 0.0),
+ ViewMatrixInverse[3].xyz, ViewMatrixInverse[2].xyz,
+ pos, tan, binor, time, thickness, thick_time);
+ /* To "simulate" anisotropic shading, randomize hair normal per strand. */
+ hair_rand = integer_noise(hair_get_strand_id());
+ tan = normalize(tan);
+ vec3 nor = normalize(cross(binor, tan));
+ nor = normalize(mix(nor, -tan, hair_rand * 0.10));
+ float cos_theta = (hair_rand*2.0 - 1.0) * 0.20;
+ float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));
+ nor = nor * sin_theta + binor * cos_theta;
+ gl_Position = ViewProjectionMatrix * vec4(pos, 1.0);
+#else
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+#endif
#ifdef OB_TEXTURE
uv_interp = uv;
#endif
+
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
- normal_viewport = normalize(NormalMatrix * nor);
-#endif /* NORMAL_VIEWPORT_PASS_ENABLED */
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ normal_viewport = NormalMatrix * nor;
+# ifndef HAIR_SHADER
+ normal_viewport = normalize(normal_viewport);
+# endif
+#endif
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
index 32b31718cf8..948392bd8ee 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
@@ -6,9 +6,9 @@
#ifdef DOUBLE_MANIFOLD
# ifdef USE_INVOC_EXT
-# define invoc_ct 4
+# define invoc_ct 2
# else
-# define vert_ct 12
+# define vert_ct 6
# endif
#else
# ifdef USE_INVOC_EXT
@@ -39,17 +39,17 @@ vec4 get_pos(int v, bool backface)
return (backface) ? vData[v].backPosition : vData[v].frontPosition;
}
-void emit_cap(const bool front)
+void emit_cap(const bool front, bool reversed)
{
if (front) {
gl_Position = vData[0].frontPosition; EmitVertex();
- gl_Position = vData[1].frontPosition; EmitVertex();
- gl_Position = vData[2].frontPosition; EmitVertex();
+ gl_Position = vData[reversed ? 2 : 1].frontPosition; EmitVertex();
+ gl_Position = vData[reversed ? 1 : 2].frontPosition; EmitVertex();
}
else {
gl_Position = vData[0].backPosition; EmitVertex();
- gl_Position = vData[2].backPosition; EmitVertex();
- gl_Position = vData[1].backPosition; EmitVertex();
+ gl_Position = vData[reversed ? 1 : 2].backPosition; EmitVertex();
+ gl_Position = vData[reversed ? 2 : 1].backPosition; EmitVertex();
}
EndPrimitive();
}
@@ -64,17 +64,22 @@ void main()
bool backface = facing > 0.0;
+#ifdef DOUBLE_MANIFOLD
+ /* In case of non manifold geom, we only increase/decrease
+ * the stencil buffer by one but do every faces as they were facing the light. */
+ bool invert = backface;
+#else
+ const bool invert = false;
if (!backface) {
+#endif
#ifdef USE_INVOC_EXT
bool do_front = (gl_InvocationID & 1) == 0;
- emit_cap(do_front);
+ emit_cap(do_front, invert);
#else
- emit_cap(true);
- emit_cap(false);
-# ifdef DOUBLE_MANIFOLD
- emit_cap(true);
- emit_cap(false);
-# endif
+ emit_cap(true, invert);
+ emit_cap(false, invert);
#endif
+#ifndef DOUBLE_MANIFOLD
}
+#endif
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
index 3a61bf0a286..50a721f948f 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
@@ -3,6 +3,7 @@
uniform mat4 ModelViewProjectionMatrix;
uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
+uniform float lightDistance = 1e4;
in vec3 pos;
@@ -16,5 +17,5 @@ void main()
{
vData.pos = pos;
vData.frontPosition = ModelViewProjectionMatrix * vec4(pos, 1.0);
- vData.backPosition = ModelViewProjectionMatrix * vec4(pos + lightDirection * INFINITE, 1.0);
+ vData.backPosition = ModelViewProjectionMatrix * vec4(pos + lightDirection * lightDistance, 1.0);
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
index be124257c33..6f4237ebd0a 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
@@ -29,7 +29,7 @@ vec3 get_world_specular_light(vec4 specular_data, LightData light_data, vec3 N,
float shininess = exp2(10*(1.0-specular_data.a) + 1);
-#ifdef BLINN
+# ifdef BLINN
float normalization_factor = (shininess + 8) / (8 * M_PI);
vec3 L = -light_data.light_direction_vs.xyz;
vec3 halfDir = normalize(L + I);
@@ -37,11 +37,11 @@ vec3 get_world_specular_light(vec4 specular_data, LightData light_data, vec3 N,
float NL = max(dot(L, N), 0.0);
float specular_influence = pow(specAngle, shininess) * NL * normalization_factor;
-#else
+# else
vec3 reflection_vector = reflect(I, N);
float specAngle = max(dot(light_data.light_direction_vs.xyz, reflection_vector), 0.0);
float specular_influence = pow(specAngle, shininess);
-#endif
+# endif
vec3 specular_color = specular_light * specular_influence;
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 4ee12a692f5..df0a2bf4684 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -15,7 +15,14 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
if (v3d) {
wpd->shading = v3d->shading;
wpd->drawtype = v3d->drawtype;
- wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light, 0);
+ if (wpd->shading.light == V3D_LIGHTING_MATCAP) {
+ wpd->studio_light = BKE_studiolight_find(
+ wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+ }
+ else {
+ wpd->studio_light = BKE_studiolight_find(
+ wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD);
+ }
}
else {
memset(&wpd->shading, 0, sizeof(wpd->shading));
@@ -23,11 +30,12 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
wpd->shading.shadow_intensity = 0.5;
copy_v3_fl(wpd->shading.single_color, 0.8f);
wpd->drawtype = OB_SOLID;
- wpd->studio_light = BKE_studiolight_findindex(0);
+ wpd->studio_light = BKE_studiolight_find_first(STUDIOLIGHT_INTERNAL);
}
wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity;
WORKBENCH_UBO_World *wd = &wpd->world_data;
+ wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) > 0;
if ((v3d->flag3 & V3D_SHOW_WORLD) &&
(scene->world != NULL))
@@ -51,6 +59,64 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
wd->object_outline_color[3] = 1.0f;
wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data);
+
+ /* Cavity settings */
+ {
+ const int ssao_samples = scene->display.matcap_ssao_samples;
+
+ float invproj[4][4];
+ float dfdyfacs[2];
+ const bool is_persp = DRW_viewport_is_persp_get();
+ /* view vectors for the corners of the view frustum.
+ * Can be used to recreate the world space position easily */
+ float viewvecs[3][4] = {
+ {-1.0f, -1.0f, -1.0f, 1.0f},
+ {1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f}
+ };
+ int i;
+ const float *size = DRW_viewport_size_get();
+
+ DRW_state_dfdy_factors_get(dfdyfacs);
+
+ wpd->ssao_params[0] = ssao_samples;
+ wpd->ssao_params[1] = size[0] / 64.0;
+ wpd->ssao_params[2] = size[1] / 64.0;
+ wpd->ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
+
+ /* distance, factor, factor, attenuation */
+ copy_v4_fl4(wpd->ssao_settings, scene->display.matcap_ssao_distance, wpd->shading.cavity_valley_factor, wpd->shading.cavity_ridge_factor, scene->display.matcap_ssao_attenuation);
+
+ /* invert the view matrix */
+ DRW_viewport_matrix_get(wpd->winmat, DRW_MAT_WIN);
+ invert_m4_m4(invproj, wpd->winmat);
+
+ /* convert the view vectors to view space */
+ for (i = 0; i < 3; i++) {
+ mul_m4_v4(invproj, viewvecs[i]);
+ /* normalized trick see:
+ * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
+ if (is_persp)
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
+ viewvecs[i][3] = 1.0;
+
+ copy_v4_v4(wpd->viewvecs[i], viewvecs[i]);
+ }
+
+ /* we need to store the differences */
+ wpd->viewvecs[1][0] -= wpd->viewvecs[0][0];
+ wpd->viewvecs[1][1] = wpd->viewvecs[2][1] - wpd->viewvecs[0][1];
+
+ /* calculate a depth offset as well */
+ if (!is_persp) {
+ float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
+ mul_m4_v4(invproj, vec_far);
+ mul_v3_fl(vec_far, 1.0f / vec_far[3]);
+ wpd->viewvecs[1][2] = vec_far[2] - wpd->viewvecs[0][2];
+ }
+ }
+
}
void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float light_direction[3])
@@ -71,7 +137,7 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa
wd->num_lights = 1;
}
- if (STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd)) {
+ if (!STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
int light_index = 0;
for (int index = 0 ; index < 3; index++) {
SolidLight *sl = &U.light[index];
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 47700c4bfd3..e1cb8b482ab 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -30,6 +30,7 @@
#include "BLI_alloca.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
+#include "BLI_rand.h"
#include "BKE_node.h"
#include "BKE_particle.h"
@@ -44,6 +45,7 @@
#include "GPU_shader.h"
#include "GPU_texture.h"
+#include "../eevee/eevee_lut.h" /* TODO find somewhere to share blue noise Table */
/* *********** STATIC *********** */
@@ -56,6 +58,7 @@
static struct {
struct GPUShader *prepass_sh_cache[MAX_SHADERS];
struct GPUShader *composite_sh_cache[MAX_SHADERS];
+ struct GPUShader *cavity_sh;
struct GPUShader *shadow_fail_sh;
struct GPUShader *shadow_fail_manifold_sh;
struct GPUShader *shadow_pass_sh;
@@ -65,6 +68,7 @@ static struct {
struct GPUTexture *object_id_tx; /* ref only, not alloced */
struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
+ struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */
struct GPUTexture *specular_buffer_tx; /* ref only, not alloced */
struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */
struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
@@ -73,11 +77,18 @@ static struct {
float light_direction_vs[3];
int next_object_id;
float normal_world_matrix[3][3];
+
+ struct GPUUniformBuffer *sampling_ubo;
+ struct GPUTexture *jitter_tx;
+ int cached_sample_num;
} e_data = {{NULL}};
/* Shaders */
+extern char datatoc_common_hair_lib_glsl[];
+
extern char datatoc_workbench_prepass_vert_glsl[];
extern char datatoc_workbench_prepass_frag_glsl[];
+extern char datatoc_workbench_cavity_frag_glsl[];
extern char datatoc_workbench_deferred_composite_frag_glsl[];
extern char datatoc_workbench_shadow_vert_glsl[];
@@ -86,6 +97,7 @@ extern char datatoc_workbench_shadow_caps_geom_glsl[];
extern char datatoc_workbench_shadow_debug_frag_glsl[];
extern char datatoc_workbench_background_lib_glsl[];
+extern char datatoc_workbench_cavity_lib_glsl[];
extern char datatoc_workbench_common_lib_glsl[];
extern char datatoc_workbench_data_lib_glsl[];
extern char datatoc_workbench_object_outline_lib_glsl[];
@@ -130,17 +142,49 @@ static char *workbench_build_prepass_frag(void)
return str;
}
-static void ensure_deferred_shaders(WORKBENCH_PrivateData *wpd, int index, int drawtype)
+static char *workbench_build_prepass_vert(void)
+{
+ char *str = NULL;
+
+ DynStr *ds = BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
+
+ str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
+}
+
+static char *workbench_build_cavity_frag(void)
+{
+ char *str = NULL;
+
+ DynStr *ds = BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_cavity_frag_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_cavity_lib_glsl);
+
+ str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
+}
+
+static void ensure_deferred_shaders(WORKBENCH_PrivateData *wpd, int index, int drawtype, bool is_hair)
{
if (e_data.prepass_sh_cache[index] == NULL) {
- char *defines = workbench_material_build_defines(wpd, drawtype);
+ char *defines = workbench_material_build_defines(wpd, drawtype, is_hair);
char *composite_frag = workbench_build_composite_frag(wpd);
+ char *prepass_vert = workbench_build_prepass_vert();
char *prepass_frag = workbench_build_prepass_frag();
e_data.prepass_sh_cache[index] = DRW_shader_create(
- datatoc_workbench_prepass_vert_glsl, NULL, prepass_frag, defines);
- if (drawtype == OB_SOLID) {
+ prepass_vert, NULL,
+ prepass_frag, defines);
+ if (drawtype == OB_SOLID && !is_hair) {
e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
}
+ MEM_freeN(prepass_vert);
MEM_freeN(prepass_frag);
MEM_freeN(composite_frag);
MEM_freeN(defines);
@@ -149,24 +193,74 @@ static void ensure_deferred_shaders(WORKBENCH_PrivateData *wpd, int index, int d
static void select_deferred_shaders(WORKBENCH_PrivateData *wpd)
{
- int index_solid = workbench_material_get_shader_index(wpd, OB_SOLID);
- int index_texture = workbench_material_get_shader_index(wpd, OB_TEXTURE);
+ int index_solid = workbench_material_get_shader_index(wpd, OB_SOLID, false);
+ int index_solid_hair = workbench_material_get_shader_index(wpd, OB_SOLID, true);
+ int index_texture = workbench_material_get_shader_index(wpd, OB_TEXTURE, false);
+ int index_texture_hair = workbench_material_get_shader_index(wpd, OB_TEXTURE, true);
- ensure_deferred_shaders(wpd, index_solid, OB_SOLID);
- ensure_deferred_shaders(wpd, index_texture, OB_TEXTURE);
+ ensure_deferred_shaders(wpd, index_solid, OB_SOLID, false);
+ ensure_deferred_shaders(wpd, index_solid_hair, OB_SOLID, true);
+ ensure_deferred_shaders(wpd, index_texture, OB_TEXTURE, false);
+ ensure_deferred_shaders(wpd, index_texture_hair, OB_TEXTURE, true);
wpd->prepass_solid_sh = e_data.prepass_sh_cache[index_solid];
+ wpd->prepass_solid_hair_sh = e_data.prepass_sh_cache[index_solid_hair];
wpd->prepass_texture_sh = e_data.prepass_sh_cache[index_texture];
+ wpd->prepass_texture_hair_sh = e_data.prepass_sh_cache[index_texture_hair];
wpd->composite_sh = e_data.composite_sh_cache[index_solid];
}
+
+/* Using Hammersley distribution */
+static float *create_disk_samples(int num_samples)
+{
+ /* vec4 to ensure memory alignment. */
+ float (*texels)[4] = MEM_mallocN(sizeof(float[4]) * num_samples, "concentric_tex");
+ const float num_samples_inv = 1.0f / num_samples;
+
+ for (int i = 0; i < num_samples; i++) {
+ float r = (i + 0.5f) * num_samples_inv;
+ double dphi;
+ BLI_hammersley_1D(i, &dphi);
+
+ float phi = (float)dphi * 2.0f * M_PI;
+ texels[i][0] = cosf(phi);
+ texels[i][1] = sinf(phi);
+ /* This deliberatly distribute more samples
+ * at the center of the disk (and thus the shadow). */
+ texels[i][2] = r;
+ }
+
+ return (float *)texels;
+}
+
+static struct GPUTexture *create_jitter_texture(int num_samples)
+{
+ float jitter[64 * 64][3];
+ const float num_samples_inv = 1.0f / num_samples;
+
+ for (int i = 0; i < 64 * 64; i++) {
+ float phi = blue_noise[i][0] * 2.0f * M_PI;
+ /* This rotate the sample per pixels */
+ jitter[i][0] = cosf(phi);
+ jitter[i][1] = sinf(phi);
+ /* This offset the sample along it's direction axis (reduce banding) */
+ float bn = blue_noise[i][1] - 0.5f;
+ CLAMP(bn, -0.499f, 0.499f); /* fix fireflies */
+ jitter[i][2] = bn * num_samples_inv;
+ }
+
+ UNUSED_VARS(bsdf_split_sum_ggx, btdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx, ltc_disk_integral);
+
+ return DRW_texture_create_2D(64, 64, GPU_RGB16F, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
+}
/* Functions */
static void workbench_init_object_data(ObjectEngineData *engine_data)
{
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data;
- data->object_id = e_data.next_object_id++;
+ data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
data->shadow_bbox_dirty = true;
}
@@ -219,6 +313,10 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
datatoc_workbench_shadow_caps_geom_glsl,
shadow_frag,
"#define SHADOW_FAIL\n");
+
+ char *cavity_frag = workbench_build_cavity_frag();
+ e_data.cavity_sh = DRW_shader_create_fullscreen(cavity_frag, NULL);
+ MEM_freeN(cavity_frag);
}
if (!stl->g_data) {
@@ -226,13 +324,15 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
}
- workbench_private_data_init(stl->g_data);
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ workbench_private_data_init(wpd);
{
const float *viewport_size = DRW_viewport_size_get();
const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_solid);
e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
+ e_data.cavity_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RG16, &draw_engine_workbench_solid);
e_data.specular_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
e_data.composite_buffer_tx = DRW_texture_pool_query_2D(
size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
@@ -253,16 +353,58 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
GPU_ATTACHMENT_TEXTURE(e_data.specular_buffer_tx),
GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
});
+ GPU_framebuffer_ensure_config(&fbl->cavity_fb, {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.cavity_buffer_tx),
+ });
GPU_framebuffer_ensure_config(&fbl->composite_fb, {
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
});
}
+ {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ /* AO Samples Tex */
+ const int ssao_samples = scene->display.matcap_ssao_samples;
+ if (e_data.sampling_ubo && (e_data.cached_sample_num != ssao_samples)) {
+ DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
+ DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
+ }
+
+ if (e_data.sampling_ubo == NULL) {
+ float *samples = create_disk_samples(ssao_samples);
+ e_data.jitter_tx = create_jitter_texture(ssao_samples);
+ e_data.sampling_ubo = DRW_uniformbuffer_create(sizeof(float[4]) * ssao_samples, samples);
+ e_data.cached_sample_num = ssao_samples;
+ MEM_freeN(samples);
+ }
+ }
+
/* Prepass */
{
int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
psl->prepass_pass = DRW_pass_create("Prepass", state);
+ psl->prepass_hair_pass = DRW_pass_create("Prepass", state);
+ }
+
+ {
+ int state = DRW_STATE_WRITE_COLOR;
+ psl->cavity_pass = DRW_pass_create("Cavity", state);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.cavity_sh, psl->cavity_pass);
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.color_buffer_tx);
+ DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
+
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
+ DRW_shgroup_uniform_vec4(grp, "ssao_params", wpd->ssao_params, 1);
+ DRW_shgroup_uniform_vec4(grp, "ssao_settings", wpd->ssao_settings, 1);
+ DRW_shgroup_uniform_mat4(grp, "WinMatrix", wpd->winmat);
+ DRW_shgroup_uniform_texture(grp, "ssao_jitter", e_data.jitter_tx);
+ DRW_shgroup_uniform_block(grp, "samples_block", e_data.sampling_ubo);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
@@ -272,46 +414,41 @@ void workbench_deferred_engine_free()
DRW_SHADER_FREE_SAFE(e_data.prepass_sh_cache[index]);
DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
}
+ DRW_SHADER_FREE_SAFE(e_data.cavity_sh);
+ DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
+ DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
+
DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_pass_manifold_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_fail_manifold_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_caps_manifold_sh);
+
}
static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
{
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.color_buffer_tx);
DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
- if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
+ if (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
}
- if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
+ if (CAVITY_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "cavityBuffer", &e_data.cavity_buffer_tx);
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "specularBuffer", &e_data.specular_buffer_tx);
-
-#if 0
- float invwinmat[4][4];
- DRW_viewport_matrix_get(invwinmat, DRW_MAT_WININV);
-
- copy_v4_fl4(e_data.screenvecs[0], 1.0f, -1.0f, 0.0f, 1.0f);
- copy_v4_fl4(e_data.screenvecs[1], -1.0f, 1.0f, 0.0f, 1.0f);
- copy_v4_fl4(e_data.screenvecs[2], -1.0f, -1.0f, 0.0f, 1.0f);
- for (int i = 0; i < 3; i++) {
- mul_m4_v4(invwinmat, e_data.screenvecs[i]);
- e_data.screenvecs[i][0] /= e_data.screenvecs[i][3]; /* perspective divide */
- e_data.screenvecs[i][1] /= e_data.screenvecs[i][3]; /* perspective divide */
- e_data.screenvecs[i][2] /= e_data.screenvecs[i][3]; /* perspective divide */
- e_data.screenvecs[i][3] = 1.0f;
- }
- sub_v3_v3(e_data.screenvecs[0], e_data.screenvecs[2]);
- sub_v3_v3(e_data.screenvecs[1], e_data.screenvecs[2]);
- DRW_shgroup_uniform_vec4(grp, "screenvecs[0]", e_data.screenvecs[0], 3);
-#endif
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
}
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
+ BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE);
+ DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirectangular_radiance_gputexture); DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirectangular_radiance_gputexture);
+ }
+
workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix);
}
@@ -362,8 +499,6 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
psl->shadow_depth_fail_caps_mani_pass = DRW_pass_create("Shadow Fail Caps Mani", depth_fail_state);
#ifndef DEBUG_SHADOW_VOLUME
- grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
- DRW_shgroup_stencil_mask(grp, 0xFF);
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
DRW_shgroup_stencil_mask(grp, 0xFF);
grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
@@ -412,7 +547,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
/* Solid */
workbench_material_update_data(wpd, ob, mat, &material_template);
- material_template.object_id = engine_object_data->object_id;
+ material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
material_template.drawtype = drawtype;
material_template.ima = ima;
uint hash = workbench_material_get_hash(&material_template);
@@ -423,7 +558,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
material->shgrp = DRW_shgroup_create(
drawtype == OB_SOLID ? wpd->prepass_solid_sh : wpd->prepass_texture_sh, psl->prepass_pass);
DRW_shgroup_stencil_mask(material->shgrp, 0xFF);
- material->object_id = engine_object_data->object_id;
+ material->object_id = material_template.object_id;
copy_v4_v4(material->material_data.diffuse_color, material_template.material_data.diffuse_color);
copy_v4_v4(material->material_data.specular_color, material_template.material_data.specular_color);
material->material_data.roughness = material_template.material_data.roughness;
@@ -449,27 +584,56 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *ob)
{
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
if (ob == draw_ctx->object_edit) {
return;
}
- for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
+ for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ if (md->type != eModifierType_ParticleSystem) {
+ continue;
+ }
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
if (!psys_check_enabled(ob, psys, false)) {
continue;
}
if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
- return;
+ continue;
}
ParticleSettings *part = psys->part;
const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
- static float mat[4][4];
- unit_m4(mat);
-
if (draw_as == PART_DRAW_PATH) {
- struct Gwn_Batch *geom = DRW_cache_particles_get_hair(ob, psys, NULL);
- WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, NULL, NULL, OB_SOLID);
- DRW_shgroup_call_add(material->shgrp, geom, mat);
+ Image *image = NULL;
+ Material *mat = give_current_material(ob, part->omat);
+ int mat_drawtype = OB_SOLID;
+
+ if (wpd->drawtype == OB_TEXTURE) {
+ ED_object_get_active_image(ob, part->omat, &image, NULL, NULL, NULL);
+ /* use OB_SOLID when no texture could be determined */
+ if (image) {
+ mat_drawtype = OB_TEXTURE;
+ }
+ }
+
+ WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, mat, image, mat_drawtype);
+
+ struct GPUShader *shader = (mat_drawtype == OB_SOLID)
+ ? wpd->prepass_solid_hair_sh
+ : wpd->prepass_texture_hair_sh;
+ DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
+ ob, psys, md,
+ psl->prepass_hair_pass,
+ shader);
+ DRW_shgroup_stencil_mask(shgrp, 0xFF);
+ DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
+ DRW_shgroup_uniform_block(shgrp, "material_block", material->material_ubo);
+ if (image) {
+ GPUTexture *tex = GPU_texture_from_blender(image, NULL, GL_TEXTURE_2D, false, false, false);
+ DRW_shgroup_uniform_texture(shgrp, "image", tex);
+ }
}
}
}
@@ -479,7 +643,6 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_PassList *psl = vedata->psl;
WORKBENCH_PrivateData *wpd = stl->g_data;
-
if (!DRW_object_is_renderable(ob))
return;
@@ -487,6 +650,10 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
workbench_cache_populate_particles(vedata, ob);
}
+ if (!DRW_check_object_visible_within_active_context(ob)) {
+ return;
+ }
+
WORKBENCH_MaterialData *material;
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -573,13 +740,6 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
DRWShadingGroup *grp;
bool use_shadow_pass_technique = !studiolight_camera_in_object_shadow(wpd, ob, engine_object_data);
- /* Unless we expose a parameter to the user, it's better to use the depth pass technique if the object is
- * non manifold. Exposing a switch to the user to force depth fail in this case can be beneficial for
- * planes and non-closed terrains. */
- if (!is_manifold) {
- use_shadow_pass_technique = true;
- }
-
if (use_shadow_pass_technique) {
if (is_manifold) {
grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
@@ -588,12 +748,15 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
}
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_uniform_float_copy(grp, "lightDistance", 1e5f);
DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
#ifdef DEBUG_SHADOW_VOLUME
DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){1.0f, 0.0f, 0.0f, 1.0f});
#endif
}
else {
+ float extrude_distance = studiolight_object_shadow_distance(wpd, ob, engine_object_data);
+
/* TODO(fclem): only use caps if they are in the view frustum. */
const bool need_caps = true;
if (need_caps) {
@@ -604,6 +767,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
}
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
DRW_shgroup_call_add(grp, DRW_cache_object_surface_get(ob), ob->obmat);
}
@@ -614,6 +778,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
}
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
#ifdef DEBUG_SHADOW_VOLUME
DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){0.0f, 1.0f, 0.0f, 1.0f});
@@ -658,6 +823,13 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
/* clear in background */
GPU_framebuffer_bind(fbl->prepass_fb);
DRW_draw_pass(psl->prepass_pass);
+ DRW_draw_pass(psl->prepass_hair_pass);
+
+ if (CAVITY_ENABLED(wpd)) {
+ GPU_framebuffer_bind(fbl->cavity_fb);
+ DRW_draw_pass(psl->cavity_pass);
+ }
+
if (SHADOW_ENABLED(wpd)) {
#ifdef DEBUG_SHADOW_VOLUME
GPU_framebuffer_bind(fbl->composite_fb);
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index dc7d80d51ce..3bc016e139b 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -51,8 +51,9 @@ static struct {
struct GPUShader *composite_sh_cache[MAX_SHADERS];
struct GPUShader *transparent_accum_sh_cache[MAX_SHADERS];
struct GPUShader *transparent_revealage_sh;
+ struct GPUShader *transparent_revealage_hair_sh;
struct GPUShader *object_outline_sh;
- struct GPUShader *depth_sh;
+ struct GPUShader *object_outline_hair_sh;
struct GPUShader *checker_depth_sh;
struct GPUTexture *object_id_tx; /* ref only, not alloced */
@@ -66,6 +67,7 @@ static struct {
} e_data = {{NULL}};
/* Shaders */
+extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_workbench_forward_composite_frag_glsl[];
extern char datatoc_workbench_forward_depth_frag_glsl[];
extern char datatoc_workbench_forward_transparent_accum_frag_glsl[];
@@ -95,6 +97,20 @@ static char *workbench_build_forward_depth_frag(void)
return str;
}
+static char *workbench_build_forward_vert(void)
+{
+ char *str = NULL;
+
+ DynStr *ds = BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
+
+ str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
+}
+
static char *workbench_build_forward_transparent_accum_frag(void)
{
char *str = NULL;
@@ -147,7 +163,7 @@ static char *workbench_build_forward_composite_frag(void)
static void workbench_init_object_data(ObjectEngineData *engine_data)
{
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data;
- data->object_id = e_data.next_object_id++;
+ data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
}
static WORKBENCH_MaterialData *get_or_create_material_data(
@@ -164,7 +180,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
/* Solid */
workbench_material_update_data(wpd, ob, mat, &material_template);
- material_template.object_id = engine_object_data->object_id;
+ material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
material_template.drawtype = drawtype;
material_template.ima = ima;
uint hash = workbench_material_get_hash(&material_template);
@@ -186,7 +202,17 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
material->material_data.roughness = material_template.material_data.roughness;
switch (drawtype) {
case OB_SOLID:
+ {
+ if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
+ BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE);
+ DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirectangular_radiance_gputexture);
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ }
break;
+ }
case OB_TEXTURE:
{
@@ -208,10 +234,10 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
return material;
}
-static void ensure_forward_shaders(WORKBENCH_PrivateData *wpd, int index, int drawtype)
+static void ensure_forward_shaders(WORKBENCH_PrivateData *wpd, int index, int drawtype, bool is_hair)
{
- if (e_data.composite_sh_cache[index] == NULL && drawtype == OB_SOLID) {
- char *defines = workbench_material_build_defines(wpd, drawtype);
+ if (e_data.composite_sh_cache[index] == NULL && drawtype == OB_SOLID && !is_hair) {
+ char *defines = workbench_material_build_defines(wpd, drawtype, is_hair);
char *composite_frag = workbench_build_forward_composite_frag();
e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
MEM_freeN(composite_frag);
@@ -219,27 +245,35 @@ static void ensure_forward_shaders(WORKBENCH_PrivateData *wpd, int index, int dr
}
if (e_data.transparent_accum_sh_cache[index] == NULL) {
- char *defines = workbench_material_build_defines(wpd, drawtype);
+ char *defines = workbench_material_build_defines(wpd, drawtype, is_hair);
+ char *transparent_accum_vert = workbench_build_forward_vert();
char *transparent_accum_frag = workbench_build_forward_transparent_accum_frag();
e_data.transparent_accum_sh_cache[index] = DRW_shader_create(
- datatoc_workbench_prepass_vert_glsl, NULL, transparent_accum_frag, defines);
+ transparent_accum_vert, NULL,
+ transparent_accum_frag, defines);
+ MEM_freeN(transparent_accum_vert);
MEM_freeN(transparent_accum_frag);
-
MEM_freeN(defines);
}
}
static void select_forward_shaders(WORKBENCH_PrivateData *wpd)
{
- int index_solid = workbench_material_get_shader_index(wpd, OB_SOLID);
- int index_texture = workbench_material_get_shader_index(wpd, OB_TEXTURE);
+ int index_solid = workbench_material_get_shader_index(wpd, OB_SOLID, false);
+ int index_solid_hair = workbench_material_get_shader_index(wpd, OB_SOLID, true);
+ int index_texture = workbench_material_get_shader_index(wpd, OB_TEXTURE, false);
+ int index_texture_hair = workbench_material_get_shader_index(wpd, OB_TEXTURE, true);
- ensure_forward_shaders(wpd, index_solid, OB_SOLID);
- ensure_forward_shaders(wpd, index_texture, OB_TEXTURE);
+ ensure_forward_shaders(wpd, index_solid, OB_SOLID, false);
+ ensure_forward_shaders(wpd, index_solid_hair, OB_SOLID, true);
+ ensure_forward_shaders(wpd, index_texture, OB_TEXTURE, false);
+ ensure_forward_shaders(wpd, index_texture_hair, OB_TEXTURE, true);
wpd->composite_sh = e_data.composite_sh_cache[index_solid];
wpd->transparent_accum_sh = e_data.transparent_accum_sh_cache[index_solid];
+ wpd->transparent_accum_hair_sh = e_data.transparent_accum_sh_cache[index_solid_hair];
wpd->transparent_accum_texture_sh = e_data.transparent_accum_sh_cache[index_texture];
+ wpd->transparent_accum_texture_hair_sh = e_data.transparent_accum_sh_cache[index_texture_hair];
}
/* public functions */
@@ -265,23 +299,34 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
memset(e_data.composite_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
memset(e_data.transparent_accum_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
- char *defines = workbench_material_build_defines(wpd, OB_SOLID);
+ char *defines = workbench_material_build_defines(wpd, OB_SOLID, false);
+ char *defines_hair = workbench_material_build_defines(wpd, OB_SOLID, true);
+ char *forward_vert = workbench_build_forward_vert();
char *forward_depth_frag = workbench_build_forward_depth_frag();
e_data.object_outline_sh = DRW_shader_create(
- datatoc_workbench_prepass_vert_glsl, NULL, forward_depth_frag, defines);
+ forward_vert, NULL,
+ forward_depth_frag, defines);
+ e_data.object_outline_hair_sh = DRW_shader_create(
+ forward_vert, NULL,
+ forward_depth_frag, defines_hair);
#ifdef WORKBENCH_REVEALAGE_ENABLED
char *forward_transparent_revealage_frag = workbench_build_forward_transparent_revealage_frag();
e_data.transparent_revealage_sh = DRW_shader_create(
- datatoc_workbench_prepass_vert_glsl, NULL, forward_transparent_revealage_frag, defines);
+ forward_vert, NULL,
+ forward_transparent_revealage_frag, defines);
+ e_data.transparent_revealage_hair_sh = DRW_shader_create(
+ forward_vert, NULL,
+ forward_transparent_revealage_frag, defines_hair);
MEM_freeN(forward_transparent_revealage_frag);
#endif
- e_data.depth_sh = DRW_shader_create_3D_depth_only();
e_data.checker_depth_sh = DRW_shader_create_fullscreen(
datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
+ MEM_freeN(forward_vert);
MEM_freeN(forward_depth_frag);
MEM_freeN(defines);
+ MEM_freeN(defines_hair);
}
select_forward_shaders(wpd);
@@ -332,14 +377,14 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
GPU_framebuffer_clear_color_depth(fbl->object_outline_fb, clear_color, 1.0f);
DRW_stats_group_end();
- /* Treansparecy Accum */
+ /* Transparency Accum */
{
int state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE_FULL;
psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state);
}
#ifdef WORKBENCH_REVEALAGE_ENABLED
- /* Treansparecy Revealage */
+ /* Transparency Revealage */
{
int state = DRW_STATE_WRITE_COLOR | DRW_STATE_TRANSPARENT_REVEALAGE;
psl->transparent_revealage_pass = DRW_pass_create("Transparent Revealage", state);
@@ -386,8 +431,10 @@ void workbench_forward_engine_free()
}
#ifdef WORKBENCH_REVEALAGE_ENABLED
DRW_SHADER_FREE_SAFE(e_data.transparent_revealage_sh);
+ DRW_SHADER_FREE_SAFE(e_data.transparent_revealage_hair_sh);
#endif
DRW_SHADER_FREE_SAFE(e_data.object_outline_sh);
+ DRW_SHADER_FREE_SAFE(e_data.object_outline_hair_sh);
DRW_SHADER_FREE_SAFE(e_data.checker_depth_sh);
}
@@ -397,35 +444,68 @@ void workbench_forward_cache_init(WORKBENCH_Data *UNUSED(vedata))
static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, Object *ob)
{
-#ifdef WORKBENCH_REVEALAGE_ENABLED
WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PassList *psl = vedata->psl;
WORKBENCH_PrivateData *wpd = stl->g_data;
-#endif
const DRWContextState *draw_ctx = DRW_context_state_get();
+
if (ob == draw_ctx->object_edit) {
return;
}
- for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
+ for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ if (md->type != eModifierType_ParticleSystem) {
+ continue;
+ }
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
if (!psys_check_enabled(ob, psys, false)) {
continue;
}
if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
- return;
+ continue;
}
ParticleSettings *part = psys->part;
const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
- static float mat[4][4];
- unit_m4(mat);
-
if (draw_as == PART_DRAW_PATH) {
- struct Gwn_Batch *geom = DRW_cache_particles_get_hair(ob, psys, NULL);
- WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, NULL, NULL, OB_SOLID);
+ Image *image = NULL;
+ Material *mat = give_current_material(ob, part->omat);
+ int mat_drawtype = OB_SOLID;
+
+ if (wpd->drawtype == OB_TEXTURE) {
+ ED_object_get_active_image(ob, part->omat, &image, NULL, NULL, NULL);
+ /* use OB_SOLID when no texture could be determined */
+ if (image) {
+ mat_drawtype = OB_TEXTURE;
+ }
+ }
+
+ WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, mat, image, mat_drawtype);
+
+ struct GPUShader *shader = (mat_drawtype == OB_SOLID)
+ ? wpd->transparent_accum_hair_sh
+ : wpd->transparent_accum_texture_hair_sh;
+ DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
+ ob, psys, md,
+ psl->transparent_accum_pass,
+ shader);
+ workbench_material_set_normal_world_matrix(shgrp, wpd, e_data.normal_world_matrix);
+ DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo);
+ DRW_shgroup_uniform_block(shgrp, "material_block", material->material_ubo);
+ DRW_shgroup_uniform_float(shgrp, "alpha", &wpd->shading.xray_alpha, 1);
+ if (image) {
+ GPUTexture *tex = GPU_texture_from_blender(image, NULL, GL_TEXTURE_2D, false, false, false);
+ DRW_shgroup_uniform_texture(shgrp, "image", tex);
+ }
#ifdef WORKBENCH_REVEALAGE_ENABLED
- DRW_shgroup_call_add(wpd->transparent_revealage_shgrp, geom, mat);
+ shgrp = DRW_shgroup_hair_create(ob, psys, md,
+ psl->transparent_revealage_pass,
+ e_data.transparent_revealage_hair_sh);
+ DRW_shgroup_uniform_float(shgrp, "alpha", &wpd->shading.xray_alpha, 1);
#endif
- DRW_shgroup_call_add(material->shgrp_object_outline, geom, mat);
- DRW_shgroup_call_add(material->shgrp, geom, mat);
+ shgrp = DRW_shgroup_hair_create(ob, psys, md,
+ vedata->psl->object_outline_pass,
+ e_data.object_outline_hair_sh);
+ DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
}
}
}
@@ -441,6 +521,11 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
if (ob->type == OB_MESH) {
workbench_forward_cache_populate_particles(vedata, ob);
}
+
+ if (!DRW_check_object_visible_within_active_context(ob)) {
+ return;
+ }
+
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool is_active = (ob == draw_ctx->obact);
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 55a97b99066..b25938cd0e5 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -12,10 +12,10 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate
/* When in OB_TEXTURE always uyse V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
int color_type = wpd->drawtype == OB_SOLID ? wpd->shading.color_type : V3D_SHADING_MATERIAL_COLOR;
static float default_diffuse_color[] = {0.8f, 0.8f, 0.8f, 1.0f};
- static float default_specular_color[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ static float default_specular_color[] = {0.5f, 0.5f, 0.5f, 0.5f};
copy_v4_v4(data->material_data.diffuse_color, default_diffuse_color);
copy_v4_v4(data->material_data.specular_color, default_specular_color);
- data->material_data.roughness = 0.25f;
+ data->material_data.roughness = 0.5f;
if (DRW_object_is_paint_mode(ob) || color_type == V3D_SHADING_SINGLE_COLOR) {
copy_v3_v3(data->material_data.diffuse_color, wpd->shading.single_color);
@@ -40,7 +40,7 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate
}
}
-char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
+char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair)
{
char *str = NULL;
@@ -52,17 +52,29 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
if (wpd->shading.flag & V3D_SHADING_SHADOW) {
BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n");
}
- if (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) {
+ if (CAVITY_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define V3D_SHADING_CAVITY\n");
+ }
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHT\n");
}
- if (wpd->shading.light & V3D_LIGHTING_STUDIO) {
+ if (STUDIOLIGHT_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_STUDIO\n");
- if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
- BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_WORLD\n");
- }
- else {
- BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_CAMERA\n");
- }
+ }
+ if (FLAT_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_FLAT\n");
+ }
+ if (MATCAP_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_MATCAP\n");
+ }
+ if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_WORLD\n");
+ }
+ if (STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_CAMERA\n");
+ }
+ if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
+ BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_VIEWNORMAL\n");
}
if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
@@ -79,6 +91,9 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
if (NORMAL_ENCODING_ENABLED()) {
BLI_dynstr_appendf(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
}
+ if (is_hair) {
+ BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n");
+ }
#ifdef WORKBENCH_REVEALAGE_ENABLED
BLI_dynstr_appendf(ds, "#define WORKBENCH_REVEALAGE_ENABLED\n");
@@ -91,7 +106,6 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template)
{
- /* TODO: make a C-string with settings and hash the string */
uint input[4];
uint result;
float *color = material_template->material_data.diffuse_color;
@@ -115,19 +129,24 @@ uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template)
return result;
}
-int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype)
+int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair)
{
- const int DRAWOPTIONS_MASK = V3D_SHADING_OBJECT_OUTLINE | V3D_SHADING_SHADOW | V3D_SHADING_SPECULAR_HIGHLIGHT;
- int index = (wpd->shading.flag & DRAWOPTIONS_MASK);
- index = (index << 2) + wpd->shading.light;
- index = (index << 2);
- /* set the drawtype flag
- 0 = OB_SOLID,
- 1 = OB_TEXTURE
- 2 = STUDIOLIGHT_ORIENTATION_WORLD
- */
- SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD, 2);
- SET_FLAG_FROM_TEST(index, drawtype == OB_TEXTURE, 1);
+ /* NOTE: change MAX_SHADERS accordingly when modifying this function. */
+ int index = 0;
+ /* 1 bit OB_SOLID and OB_TEXTURE */
+ SET_FLAG_FROM_TEST(index, drawtype == OB_TEXTURE, 1 << 0);
+ /* 2 bits FLAT/STUDIO/MATCAP/SCENE */
+ SET_FLAG_FROM_TEST(index, wpd->shading.light, wpd->shading.light << 1);
+ /* 1 bit V3D_SHADING_SPECULAR_HIGHLIGHT */
+ SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT, 1 << 3);
+ SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 4);
+ SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_CAVITY, 1 << 5);
+ SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 6);
+ /* 2 bits STUDIOLIGHT_ORIENTATION */
+ SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD, 1 << 7);
+ SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL, 1 << 8);
+ /* 1 bit for hair */
+ SET_FLAG_FROM_TEST(index, is_hair, 1 << 9);
return index;
}
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 6fc3251a085..9c5f97729bf 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -38,22 +38,30 @@
#define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
#define M_GOLDEN_RATION_CONJUGATE 0.618033988749895
-#define MAX_SHADERS 512
-
-
-#define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
+#define MAX_SHADERS (1 << 10)
+
+#define OB_SOLID_ENABLED(wpd) (wpd->drawtype & OB_SOLID)
+#define OB_TEXTURE_ENABLED(wpd) (wpd->drawtype & OB_TEXTURE)
+#define FLAT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_FLAT)
+#define STUDIOLIGHT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_STUDIO)
+#define MATCAP_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_MATCAP && OB_SOLID_ENABLED(wpd))
+#define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD))
+#define STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_CAMERA))
+#define STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd) (MATCAP_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL))
+#define CAVITY_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_CAVITY)
#define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW)
-#define SPECULAR_HIGHLIGHT_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT)
-#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->shading.light & V3D_LIGHTING_STUDIO || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED (wpd))
+#define SPECULAR_HIGHLIGHT_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)))
+#define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
+#define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED(wpd))
+#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) || CAVITY_ENABLED(wpd))
#define NORMAL_ENCODING_ENABLED() (true)
#define WORKBENCH_REVEALAGE_ENABLED
-#define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD)
-#define STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_CAMERA)
typedef struct WORKBENCH_FramebufferList {
/* Deferred render buffers */
struct GPUFrameBuffer *prepass_fb;
+ struct GPUFrameBuffer *cavity_fb;
struct GPUFrameBuffer *composite_fb;
/* Forward render buffers */
@@ -72,6 +80,8 @@ typedef struct WORKBENCH_StorageList {
typedef struct WORKBENCH_PassList {
/* deferred rendering */
struct DRWPass *prepass_pass;
+ struct DRWPass *prepass_hair_pass;
+ struct DRWPass *cavity_pass;
struct DRWPass *shadow_depth_pass_pass;
struct DRWPass *shadow_depth_pass_mani_pass;
struct DRWPass *shadow_depth_fail_pass;
@@ -118,7 +128,8 @@ typedef struct WORKBENCH_UBO_World {
float light_direction_vs[4];
WORKBENCH_UBO_Light lights[3];
int num_lights;
- int pad[3];
+ int matcap_orientation;
+ int pad[2];
} WORKBENCH_UBO_World;
BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16)
@@ -133,10 +144,14 @@ BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_Material, 16)
typedef struct WORKBENCH_PrivateData {
struct GHash *material_hash;
struct GPUShader *prepass_solid_sh;
+ struct GPUShader *prepass_solid_hair_sh;
struct GPUShader *prepass_texture_sh;
+ struct GPUShader *prepass_texture_hair_sh;
struct GPUShader *composite_sh;
struct GPUShader *transparent_accum_sh;
+ struct GPUShader *transparent_accum_hair_sh;
struct GPUShader *transparent_accum_texture_sh;
+ struct GPUShader *transparent_accum_texture_hair_sh;
View3DShading shading;
StudioLight *studio_light;
int drawtype;
@@ -151,11 +166,18 @@ typedef struct WORKBENCH_PrivateData {
float cached_shadow_direction[3];
float shadow_mat[4][4];
float shadow_inv[4][4];
+ float shadow_far_plane[4]; /* Far plane of the view frustum. */
float shadow_near_corners[4][3]; /* Near plane corners in shadow space. */
float shadow_near_min[3]; /* min and max of shadow_near_corners. allow fast test */
float shadow_near_max[3];
float shadow_near_sides[2][4]; /* This is a parallelogram, so only 2 normal and distance to the edges. */
bool shadow_changed;
+
+ /* Ssao */
+ float winmat[4][4];
+ float viewvecs[3][4];
+ float ssao_params[4];
+ float ssao_settings[4];
} WORKBENCH_PrivateData; /* Transient data */
typedef struct WORKBENCH_MaterialData {
@@ -181,7 +203,7 @@ typedef struct WORKBENCH_ObjectData {
/* Accumulated recalc flags, which corresponds to ID->recalc flags. */
int recalc;
/* Shadow direction in local object space. */
- float shadow_dir[3];
+ float shadow_dir[3], shadow_depth;
float shadow_min[3], shadow_max[3]; /* Min, max in shadow space */
BoundBox shadow_bbox;
bool shadow_bbox_dirty;
@@ -216,10 +238,10 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob);
void workbench_forward_cache_finish(WORKBENCH_Data *vedata);
/* workbench_materials.c */
-char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype);
+char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair);
void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data);
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template);
-int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype);
+int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair);
void workbench_material_set_normal_world_matrix(
DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3]);
@@ -227,6 +249,7 @@ void workbench_material_set_normal_world_matrix(
void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd);
void studiolight_update_light(WORKBENCH_PrivateData *wpd, const float light_direction[3]);
bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
+float studiolight_object_shadow_distance(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
/* workbench_data.c */
diff --git a/source/blender/draw/engines/workbench/workbench_studiolight.c b/source/blender/draw/engines/workbench/workbench_studiolight.c
index 4db89717b2a..6451d1f57c8 100644
--- a/source/blender/draw/engines/workbench/workbench_studiolight.c
+++ b/source/blender/draw/engines/workbench/workbench_studiolight.c
@@ -76,9 +76,13 @@ void studiolight_update_light(WORKBENCH_PrivateData *wpd, const float light_dire
invert_m4_m4(wpd->shadow_inv, wpd->shadow_mat);
copy_v3_v3(wpd->cached_shadow_direction, light_direction);
-
}
+ float planes[6][4];
+ DRW_culling_frustum_planes_get(planes);
+ /* we only need the far plane. */
+ copy_v4_v4(wpd->shadow_far_plane, planes[2]);
+
BoundBox frustum_corners;
DRW_culling_frustum_corners_get(&frustum_corners);
@@ -112,8 +116,9 @@ static BoundBox *studiolight_object_shadow_bbox_get(WORKBENCH_PrivateData *wpd,
mul_v3_m4v3(corner, tmp_mat, bbox->vec[i]);
minmax_v3v3_v3(oed->shadow_min, oed->shadow_max, corner);
}
+ oed->shadow_depth = oed->shadow_max[2] - oed->shadow_min[2];
/* Extend towards infinity. */
- oed->shadow_max[2] += 1e4;
+ oed->shadow_max[2] += 1e4f;
/* Get extended AABB in world space. */
BKE_boundbox_init_from_minmax(&oed->shadow_bbox, oed->shadow_min, oed->shadow_max);
@@ -131,6 +136,30 @@ bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd, Object *
return DRW_culling_box_test(shadow_bbox);
}
+float studiolight_object_shadow_distance(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
+{
+ BoundBox *shadow_bbox = studiolight_object_shadow_bbox_get(wpd, ob, oed);
+
+ int corners[4] = {0, 3, 4, 7};
+ float dist = 1e4f, dist_isect;
+ for (int i = 0; i < 4; ++i) {
+ if (isect_ray_plane_v3(shadow_bbox->vec[corners[i]],
+ wpd->cached_shadow_direction,
+ wpd->shadow_far_plane,
+ &dist_isect, true))
+ {
+ if (dist_isect < dist) {
+ dist = dist_isect;
+ }
+ }
+ else {
+ /* All rays are parallels. If one fails, the other will too. */
+ break;
+ }
+ }
+ return max_ii(dist - oed->shadow_depth, 0);
+}
+
bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
{
/* Just to be sure the min, max are updated. */
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 081bae944d8..b74e6ba9204 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -349,6 +349,7 @@ void DRW_shgroup_call_range_add(
void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, unsigned int point_count, float (*obmat)[4]);
void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, unsigned int line_count, float (*obmat)[4]);
void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, unsigned int tria_count, float (*obmat)[4]);
+void DRW_shgroup_call_object_procedural_triangles_culled_add(DRWShadingGroup *shgroup, uint tria_count, struct Object *ob);
void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob, bool bypass_culling);
#define DRW_shgroup_call_object_add(shgroup, geom, ob) DRW_shgroup_call_object_add_ex(shgroup, geom, ob, false)
#define DRW_shgroup_call_object_add_no_cull(shgroup, geom, ob) DRW_shgroup_call_object_add_ex(shgroup, geom, ob, true)
@@ -506,6 +507,7 @@ bool DRW_culling_box_test(BoundBox *bbox);
bool DRW_culling_plane_test(float plane[4]);
void DRW_culling_frustum_corners_get(BoundBox *corners);
+void DRW_culling_frustum_planes_get(float planes[6][4]);
/* Selection */
void DRW_select_load_id(uint id);
@@ -522,8 +524,6 @@ bool DRW_state_show_text(void);
bool DRW_state_draw_support(void);
bool DRW_state_draw_background(void);
-enum eDepsObjectIteratorMode DRW_iterator_mode_get(void);
-
struct DRWTextStore *DRW_state_text_cache_get(void);
/* Avoid too many lookups while drawing */
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index ed9bb6f8ca9..a736f0a31fb 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -319,21 +319,32 @@ static void drw_shgroup_bone_custom_solid(
Object *custom)
{
/* grr, not re-using instances! */
- struct Gwn_Batch *geom = DRW_cache_object_surface_get(custom);
- if (geom) {
- DRWShadingGroup *shgrp_geom_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, geom);
- float final_bonemat[4][4];
+ struct Gwn_Batch *surf = DRW_cache_object_surface_get(custom);
+ struct Gwn_Batch *edges = DRW_cache_object_edge_detection_get(custom, NULL);
+ struct Gwn_Batch *ledges = DRW_cache_object_loose_edges_get(custom);
+ float final_bonemat[4][4];
+
+ if (surf || edges || ledges) {
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
+ }
+
+ if (surf) {
+ DRWShadingGroup *shgrp_geom_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, surf);
DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, bone_color, hint_color);
}
- geom = DRW_cache_object_edge_detection_get(custom, NULL);
- if (geom && outline_color[3] > 0.0f) {
- DRWShadingGroup *shgrp_geom_wire = shgroup_instance_bone_shape_outline(g_data.passes.bone_outline, geom);
- float final_bonemat[4][4];
- mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
+ if (edges && outline_color[3] > 0.0f) {
+ DRWShadingGroup *shgrp_geom_wire = shgroup_instance_bone_shape_outline(g_data.passes.bone_outline, edges);
DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, outline_color);
}
+
+ if (ledges) {
+ DRWShadingGroup *shgrp_geom_ledges = shgroup_instance_wire(g_data.passes.bone_wire, ledges);
+ float final_color[4];
+ copy_v3_v3(final_color, outline_color);
+ final_color[3] = 1.0f; /* hack */
+ DRW_shgroup_call_dynamic_add(shgrp_geom_ledges, final_bonemat, final_color);
+ }
}
static void drw_shgroup_bone_custom_wire(
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 1764d6b89ad..c5d5eac51b7 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -112,6 +112,10 @@ typedef struct EdgeAdjacentPolys {
int face_index[2];
} EdgeAdjacentPolys;
+typedef struct EdgeAdjacentVerts {
+ int vert_index[2]; /* -1 if none */
+} EdgeAdjacentVerts;
+
typedef struct EdgeDrawAttr {
unsigned char v_flag;
unsigned char e_flag;
@@ -1587,8 +1591,9 @@ typedef struct MeshBatchCache {
Gwn_Batch *edge_detection;
+ Gwn_VertBuf *edges_face_overlay;
GPUTexture *edges_face_overlay_tx;
- int edges_face_overlay_tri_count; /* Number of tri in edges_face_overlay_tx */
+ int edges_face_overlay_tri_count; /* Number of tri in edges_face_overlay(_adj)_tx */
/* Maybe have shaded_triangles_data split into pos_nor and uv_tangent
* to minimise data transfer for skinned mesh. */
@@ -1869,6 +1874,7 @@ static void mesh_batch_cache_clear(Mesh *me)
GWN_INDEXBUF_DISCARD_SAFE(cache->edges_adjacency);
GWN_BATCH_DISCARD_SAFE(cache->edge_detection);
+ GWN_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay);
DRW_TEXTURE_FREE_SAFE(cache->edges_face_overlay_tx);
GWN_VERTBUF_DISCARD_SAFE(cache->shaded_triangles_data);
@@ -3339,28 +3345,66 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata,
}
#undef NO_EDGE
-static GPUTexture *mesh_batch_cache_get_edges_overlay_texture_buf(MeshRenderData *rdata, MeshBatchCache *cache)
+static EdgeHash *create_looptri_edge_adjacency_hash(MeshRenderData *rdata)
{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
-
- BLI_assert(rdata->edit_bmesh == NULL); /* Not supported in edit mode */
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
+ /* Create adjacency info in looptri */
+ EdgeHash *eh = BLI_edgehash_new_ex(__func__, tri_len * 3);
+ /* Create edges for each pair of triangles sharing an edge. */
+ for (int i = 0; i < tri_len; i++) {
+ for (int e = 0; e < 3; ++e) {
+ uint v0, v1, v2;
+ if (rdata->edit_bmesh) {
+ const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+ if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
+ break;
+ }
+ v0 = BM_elem_index_get(bm_looptri[e]->v);
+ v1 = BM_elem_index_get(bm_looptri[(e + 1) % 3]->v);
+ v2 = BM_elem_index_get(bm_looptri[(e + 2) % 3]->v);
+ }
+ else {
+ MLoop *mloop = rdata->mloop;
+ MLoopTri *mlt = rdata->mlooptri + i;
+ v0 = mloop[mlt->tri[e]].v;
+ v1 = mloop[mlt->tri[(e + 1) % 3]].v;
+ v2 = mloop[mlt->tri[(e + 2) % 3]].v;
+ }
- if (cache->edges_face_overlay_tx != NULL) {
- return cache->edges_face_overlay_tx;
+ EdgeAdjacentVerts **eav;
+ bool value_is_init = BLI_edgehash_ensure_p(eh, v1, v2, (void ***)&eav);
+ if (!value_is_init) {
+ *eav = MEM_mallocN(sizeof(**eav), "EdgeAdjacentVerts");
+ (*eav)->vert_index[0] = v0;
+ (*eav)->vert_index[1] = -1;
+ }
+ else {
+ if ((*eav)->vert_index[1] == -1) {
+ (*eav)->vert_index[1] = v0;
+ }
+ else {
+ /* Not a manifold edge. */
+ }
+ }
+ }
}
+ return eh;
+}
+static Gwn_VertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(MeshRenderData *rdata)
+{
const int tri_len = mesh_render_data_looptri_len_get(rdata);
- cache->is_manifold = true;
-
Gwn_VertFormat format = {0};
- uint index_id = GWN_vertformat_attr_add(&format, "index", GWN_COMP_I32, 1, GWN_FETCH_INT);
+ uint index_id = GWN_vertformat_attr_add(&format, "index", GWN_COMP_U32, 1, GWN_FETCH_INT);
Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
int vbo_len_capacity = tri_len * 3;
GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
int vidx = 0;
+ EdgeHash *eh = NULL;
+ eh = create_looptri_edge_adjacency_hash(rdata);
for (int i = 0; i < tri_len; i++) {
bool edge_is_real[3] = {false, false, false};
@@ -3382,23 +3426,49 @@ static GPUTexture *mesh_batch_cache_get_edges_overlay_texture_buf(MeshRenderData
}
for (int e = 0; e < 3; ++e) {
- /* Save if there is an edge or not inside the sign bit. */
- int value = (int)mloop[mlt->tri[e]].v + 1; /* Int 0 cannot be signed */
- value = (edge_is_real[e]) ? -value : value;
+ int v0 = mloop[mlt->tri[e]].v;
+ int v1 = mloop[mlt->tri[(e + 1) % 3]].v;
+ EdgeAdjacentVerts *eav = BLI_edgehash_lookup(eh, v0, v1);
+ uint value = (uint)v0;
+ /* Real edge */
+ if (edge_is_real[e]) {
+ value |= (1 << 30);
+ }
+ /* Non-manifold edge */
+ if (eav->vert_index[1] == -1) {
+ value |= (1 << 31);
+ }
GWN_vertbuf_attr_set(vbo, index_id, vidx++, &value);
}
}
+ BLI_edgehash_free(eh, MEM_freeN);
+
int vbo_len_used = vidx;
if (vbo_len_capacity != vbo_len_used) {
GWN_vertbuf_data_resize(vbo, vbo_len_used);
}
+ return vbo;
+}
+
+static GPUTexture *mesh_batch_cache_get_edges_overlay_texture_buf(MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
+
+ BLI_assert(rdata->edit_bmesh == NULL); /* Not supported in edit mode */
+
+ if (cache->edges_face_overlay_tx != NULL) {
+ return cache->edges_face_overlay_tx;
+ }
+
+ Gwn_VertBuf *vbo = cache->edges_face_overlay = mesh_batch_cache_create_edges_overlay_texture_buf(rdata);
+
/* Upload data early because we need to create the texture for it. */
GWN_vertbuf_use(vbo);
cache->edges_face_overlay_tx = GPU_texture_create_from_vertbuf(vbo);
- cache->edges_face_overlay_tri_count = vbo_len_used / 3;
+ cache->edges_face_overlay_tri_count = vbo->vertex_alloc / 3;
return cache->edges_face_overlay_tx;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index 1348968bad7..380cb089628 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -181,7 +181,7 @@ static void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache)
for (int i = 0; i < MAX_HAIR_SUBDIV; ++i) {
GWN_VERTBUF_DISCARD_SAFE(hair_cache->final[i].proc_buf);
DRW_TEXTURE_FREE_SAFE(hair_cache->final[i].proc_tex);
- for (int j = 0; j < MAX_THICKRES - 1; ++j) {
+ for (int j = 0; j < MAX_THICKRES; ++j) {
GWN_BATCH_DISCARD_SAFE(hair_cache->final[i].proc_hairs[j]);
}
}
@@ -779,7 +779,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
- if (psmd != NULL) {
+ if (psmd != NULL && psmd->mesh_final != NULL) {
if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) {
cache->num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV);
active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV);
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index e4c038006b5..6227130fb05 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -162,14 +162,16 @@ void DRW_shgroup_armature_edit(struct Object *ob, struct DRWArmaturePasses passe
* The draw call is already added by this function, just add additional uniforms. */
struct DRWShadingGroup *DRW_shgroup_hair_create(
struct Object *object, struct ParticleSystem *psys, struct ModifierData *md,
- struct DRWPass *hair_pass, struct DRWPass *tf_pass,
+ struct DRWPass *hair_pass,
struct GPUShader *shader);
struct DRWShadingGroup *DRW_shgroup_material_hair_create(
struct Object *object, struct ParticleSystem *psys, struct ModifierData *md,
- struct DRWPass *hair_pass, struct DRWPass *tf_pass,
+ struct DRWPass *hair_pass,
struct GPUMaterial *material);
+void DRW_hair_init(void);
+void DRW_hair_update(void);
void DRW_hair_free(void);
/* pose_mode.c */
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 8cb9e0886a9..d5923419b37 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -57,6 +57,7 @@ typedef enum ParticleRefineShader {
} ParticleRefineShader;
static GPUShader *g_refine_shaders[PART_REFINE_MAX_SHADER] = {NULL};
+static DRWPass *g_tf_pass; /* XXX can be a problem with mulitple DRWManager in the future */
extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_common_hair_refine_vert_glsl[];
@@ -79,9 +80,14 @@ static GPUShader *hair_refine_shader_get(ParticleRefineShader sh)
return g_refine_shaders[sh];
}
+void DRW_hair_init(void)
+{
+ g_tf_pass = DRW_pass_create("Update Hair Pass", DRW_STATE_TRANS_FEEDBACK);
+}
+
static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(
Object *object, ParticleSystem *psys, ModifierData *md,
- DRWPass *hair_pass, DRWPass *tf_pass,
+ DRWPass *hair_pass,
struct GPUMaterial *gpu_mat, GPUShader *gpu_shader)
{
/* TODO(fclem): Pass the scene as parameter */
@@ -103,6 +109,7 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(
shgrp = DRW_shgroup_create(gpu_shader, hair_pass);
}
else {
+ shgrp = NULL;
BLI_assert(0);
}
@@ -132,7 +139,7 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(
if (need_ft_update) {
int final_points_ct = hair_cache->final[subdiv].strands_res * hair_cache->strands_count;
GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
- DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(tf_shader, tf_pass,
+ DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(tf_shader, g_tf_pass,
hair_cache->final[subdiv].proc_buf);
DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", hair_cache->point_tex);
DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", hair_cache->strand_tex);
@@ -145,18 +152,23 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(
DRWShadingGroup *DRW_shgroup_hair_create(
Object *object, ParticleSystem *psys, ModifierData *md,
- DRWPass *hair_pass, DRWPass *tf_pass,
+ DRWPass *hair_pass,
GPUShader *shader)
{
- return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, tf_pass, NULL, shader);
+ return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, NULL, shader);
}
DRWShadingGroup *DRW_shgroup_material_hair_create(
Object *object, ParticleSystem *psys, ModifierData *md,
- DRWPass *hair_pass, DRWPass *tf_pass,
+ DRWPass *hair_pass,
struct GPUMaterial *material)
{
- return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, tf_pass, material, NULL);
+ return drw_shgroup_create_hair_procedural_ex(object, psys, md, hair_pass, material, NULL);
+}
+
+void DRW_hair_update(void)
+{
+ DRW_draw_pass(g_tf_pass);
}
void DRW_hair_free(void)
diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h
index 86c4429a091..0ea40a50a6b 100644
--- a/source/blender/draw/intern/draw_instance_data.h
+++ b/source/blender/draw/intern/draw_instance_data.h
@@ -31,7 +31,7 @@
#include "GPU_batch.h"
-#define MAX_INSTANCE_DATA_SIZE 48 /* Can be adjusted for more */
+#define MAX_INSTANCE_DATA_SIZE 64 /* Can be adjusted for more */
typedef struct DRWInstanceData DRWInstanceData;
typedef struct DRWInstanceDataList DRWInstanceDataList;
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 60e9af78df9..75649f7eebb 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -764,6 +764,7 @@ ObjectEngineData *DRW_object_engine_data_ensure(
const size_t t = sizeof(float) - 1;
size = (size + t) & ~t;
size_t fsize = size / sizeof(float);
+ BLI_assert(fsize < MAX_INSTANCE_DATA_SIZE);
if (DST.object_instance_data[fsize] == NULL) {
DST.object_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize);
}
@@ -1232,7 +1233,9 @@ void DRW_draw_view(const bContext *C)
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
- DST.options.draw_text = (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0;
+ DST.options.draw_text = (
+ (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0 &&
+ (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C);
}
@@ -1279,6 +1282,7 @@ void DRW_draw_render_loop_ex(
DRW_globals_update();
drw_debug_init();
+ DRW_hair_init();
/* No framebuffer allowed before drawing. */
BLI_assert(GPU_framebuffer_current_get() == 0);
@@ -1291,7 +1295,7 @@ void DRW_draw_render_loop_ex(
PROFILE_START(stime);
drw_engines_cache_init();
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob, DRW_iterator_mode_get())
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
{
drw_engines_cache_populate(ob);
}
@@ -1308,6 +1312,7 @@ void DRW_draw_render_loop_ex(
}
DRW_stats_begin();
+ DRW_hair_update();
GPU_framebuffer_bind(DST.default_framebuffer);
@@ -1540,7 +1545,9 @@ void DRW_render_object_iter(
void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph,
void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
{
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob, DRW_iterator_mode_get())
+ DRW_hair_init();
+
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
{
DST.ob_state = NULL;
callback(vedata, ob, engine, depsgraph);
@@ -1666,6 +1673,7 @@ void DRW_draw_select_loop(
/* Init engines */
drw_engines_init();
+ DRW_hair_init();
{
drw_engines_cache_init();
@@ -1682,13 +1690,17 @@ void DRW_draw_select_loop(
}
else {
DEG_OBJECT_ITER_BEGIN(
- depsgraph, ob, DRW_iterator_mode_get(),
+ depsgraph, ob,
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_DUPLI)
{
if ((ob->base_flag & BASE_SELECTABLED) != 0) {
- DRW_select_load_id(ob->select_color);
+ /* This relies on dupli instances being after their instancing object. */
+ if ((ob->base_flag & BASE_FROMDUPLI) == 0) {
+ Object *ob_orig = DEG_get_original_object(ob);
+ DRW_select_load_id(ob_orig->select_color);
+ }
drw_engines_cache_populate(ob);
}
}
@@ -1700,6 +1712,8 @@ void DRW_draw_select_loop(
DRW_render_instance_buffer_finish();
}
+ DRW_hair_update();
+
/* Setup framebuffer */
draw_select_framebuffer_setup(rect);
GPU_framebuffer_bind(g_select_buffer.framebuffer);
@@ -1839,6 +1853,7 @@ void DRW_draw_depth_loop(
/* Init engines */
drw_engines_init();
+ DRW_hair_init();
/* TODO : tag to refresh by the dependency graph */
/* ideally only refresh when objects are added/removed */
@@ -1846,7 +1861,7 @@ void DRW_draw_depth_loop(
if (cache_is_dirty) {
drw_engines_cache_init();
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob, DRW_iterator_mode_get())
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
{
drw_engines_cache_populate(ob);
}
@@ -1857,6 +1872,8 @@ void DRW_draw_depth_loop(
DRW_render_instance_buffer_finish();
}
+ DRW_hair_update();
+
/* Start Drawing */
DRW_state_reset();
DRW_draw_callbacks_pre_scene();
@@ -1959,15 +1976,6 @@ bool DRW_state_is_opengl_render(void)
}
/**
- * Gives you the iterator mode to use for depsgraph.
- */
-eDepsObjectIteratorMode DRW_iterator_mode_get(void)
-{
- return DRW_state_is_scene_render() ? DEG_ITER_OBJECT_MODE_RENDER :
- DEG_ITER_OBJECT_MODE_VIEWPORT;
-}
-
-/**
* Should text draw in this mode?
*/
bool DRW_state_show_text(void)
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index ae485ba9489..7cb6aef818b 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -182,6 +182,8 @@ typedef enum {
DRW_UNIFORM_BLOCK_PERSIST
} DRWUniformType;
+#define MAX_UNIFORM_NAME 13
+
struct DRWUniform {
DRWUniform *next; /* single-linked list */
union {
@@ -195,6 +197,9 @@ struct DRWUniform {
char type; /* DRWUniformType */
char length; /* cannot be more than 16 */
char arraysize; /* cannot be more than 16 too */
+#ifndef NDEBUG
+ char name[MAX_UNIFORM_NAME];
+#endif
};
typedef enum {
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 9b707a81761..b49af47223f 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -132,6 +132,11 @@ static void drw_shgroup_uniform(DRWShadingGroup *shgroup, const char *name,
BLI_assert(length >= 0 && length <= 16);
drw_shgroup_uniform_create_ex(shgroup, location, type, value, length, arraysize);
+
+#ifndef NDEBUG
+ /* Save uniform name to easily identify it when debugging. */
+ BLI_strncpy(shgroup->uniforms->name, name, MAX_UNIFORM_NAME);
+#endif
}
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
@@ -386,12 +391,17 @@ void DRW_shgroup_call_range_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float
}
static void drw_shgroup_call_procedural_add_ex(
- DRWShadingGroup *shgroup, Gwn_PrimType prim_type, uint vert_count, float (*obmat)[4])
+ DRWShadingGroup *shgroup, Gwn_PrimType prim_type, uint vert_count, float (*obmat)[4], Object *ob)
{
BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
- call->state = drw_call_state_create(shgroup, obmat, NULL);
+ if (ob) {
+ call->state = drw_call_state_object(shgroup, ob->obmat, ob);
+ }
+ else {
+ call->state = drw_call_state_create(shgroup, obmat, NULL);
+ }
call->type = DRW_CALL_PROCEDURAL;
call->procedural.prim_type = prim_type;
call->procedural.vert_count = vert_count;
@@ -404,17 +414,24 @@ static void drw_shgroup_call_procedural_add_ex(
void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, uint point_count, float (*obmat)[4])
{
- drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_POINTS, point_count, obmat);
+ drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_POINTS, point_count, obmat, NULL);
}
void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, uint line_count, float (*obmat)[4])
{
- drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_LINES, line_count * 2, obmat);
+ drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_LINES, line_count * 2, obmat, NULL);
}
void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, uint tria_count, float (*obmat)[4])
{
- drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_TRIS, tria_count * 3, obmat);
+ drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_TRIS, tria_count * 3, obmat, NULL);
+}
+
+/* TODO (fclem): this is a sign that the api is starting to be limiting.
+ * Maybe add special function that general purpose for special cases. */
+void DRW_shgroup_call_object_procedural_triangles_culled_add(DRWShadingGroup *shgroup, uint tria_count, Object *ob)
+{
+ drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_TRIS, tria_count * 3, NULL, ob);
}
/* These calls can be culled and are optimized for redraw */
@@ -431,7 +448,8 @@ void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, Gwn_Batch *geom, O
call->select_id = DST.select_id;
#endif
- SET_FLAG_FROM_TEST(call->state->flag, bypass_culling, DRW_CALL_BYPASS_CULLING);
+ /* NOTE this will disable culling for the whole object. */
+ call->state->flag |= (bypass_culling) ? DRW_CALL_BYPASS_CULLING : 0;
BLI_LINKS_APPEND(&shgroup->calls, call);
}
@@ -726,7 +744,14 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass
return NULL;
}
- DRWShadingGroup *grp = drw_shgroup_create_ex(GPU_pass_shader(gpupass), pass);
+ GPUShader *sh = GPU_pass_shader_get(gpupass);
+
+ if (!sh) {
+ /* Shader not yet compiled */
+ return NULL;
+ }
+
+ DRWShadingGroup *grp = drw_shgroup_create_ex(sh, pass);
return grp;
}
@@ -774,7 +799,7 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp, struct
}
}
- GPUUniformBuffer *ubo = GPU_material_get_uniform_buffer(material);
+ GPUUniformBuffer *ubo = GPU_material_uniform_buffer_get(material);
if (ubo != NULL) {
DRW_shgroup_uniform_block(grp, GPU_UBO_BLOCK_NAME, ubo);
}
@@ -802,7 +827,7 @@ DRWShadingGroup *DRW_shgroup_material_create(
DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass);
if (shgroup) {
- drw_shgroup_init(shgroup, GPU_pass_shader(gpupass));
+ drw_shgroup_init(shgroup, GPU_pass_shader_get(gpupass));
drw_shgroup_material_inputs(shgroup, material);
}
@@ -819,7 +844,7 @@ DRWShadingGroup *DRW_shgroup_material_instance_create(
shgroup->type = DRW_SHG_INSTANCE;
shgroup->instance_geom = geom;
drw_call_calc_orco(ob, shgroup->instance_orcofac);
- drw_shgroup_instance_init(shgroup, GPU_pass_shader(gpupass), geom, format);
+ drw_shgroup_instance_init(shgroup, GPU_pass_shader_get(gpupass), geom, format);
drw_shgroup_material_inputs(shgroup, material);
}
@@ -837,7 +862,7 @@ DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create(
if (shgroup) {
/* Calling drw_shgroup_init will cause it to call GWN_draw_primitive(). */
- drw_shgroup_init(shgroup, GPU_pass_shader(gpupass));
+ drw_shgroup_init(shgroup, GPU_pass_shader_get(gpupass));
shgroup->type = DRW_SHG_TRIANGLE_BATCH;
shgroup->instance_count = tri_count * 3;
drw_shgroup_material_inputs(shgroup, material);
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index cb2cad8a36e..f6b6438395d 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -516,12 +516,12 @@ static void draw_clipping_setup_from_view(void)
for (int p = 0; p < 6; p++) {
int q, r;
switch (p) {
- case 0: q = 1; r = 2; break;
- case 1: q = 0; r = 5; break;
- case 2: q = 1; r = 5; break;
- case 3: q = 2; r = 6; break;
- case 4: q = 0; r = 3; break;
- default: q = 4; r = 7; break;
+ case 0: q = 1; r = 2; break; /* -X */
+ case 1: q = 0; r = 5; break; /* -Y */
+ case 2: q = 1; r = 5; break; /* +Z (far) */
+ case 3: q = 2; r = 6; break; /* +Y */
+ case 4: q = 0; r = 3; break; /* -Z (near) */
+ default: q = 4; r = 7; break; /* +X */
}
if (DST.frontface == GL_CW) {
SWAP(int, q, r);
@@ -713,6 +713,13 @@ void DRW_culling_frustum_corners_get(BoundBox *corners)
memcpy(corners, &DST.clipping.frustum_corners, sizeof(BoundBox));
}
+/* See draw_clipping_setup_from_view() for the plane order. */
+void DRW_culling_frustum_planes_get(float planes[6][4])
+{
+ draw_clipping_setup_from_view();
+ memcpy(planes, &DST.clipping.frustum_planes, sizeof(DST.clipping.frustum_planes));
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 56a7c5db08e..0b6974b7b36 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -62,7 +62,6 @@ typedef struct DRWDeferredShader {
struct DRWDeferredShader *prev, *next;
GPUMaterial *mat;
- char *vert, *geom, *frag, *defs;
} DRWDeferredShader;
typedef struct DRWShaderCompiler {
@@ -80,11 +79,6 @@ typedef struct DRWShaderCompiler {
static void drw_deferred_shader_free(DRWDeferredShader *dsh)
{
/* Make sure it is not queued before freeing. */
- MEM_SAFE_FREE(dsh->vert);
- MEM_SAFE_FREE(dsh->geom);
- MEM_SAFE_FREE(dsh->frag);
- MEM_SAFE_FREE(dsh->defs);
-
MEM_freeN(dsh);
}
@@ -129,12 +123,7 @@ static void drw_deferred_shader_compilation_exec(void *custom_data, short *stop,
BLI_spin_unlock(&comp->list_lock);
/* Do the compilation. */
- GPU_material_generate_pass(
- comp->mat_compiling->mat,
- comp->mat_compiling->vert,
- comp->mat_compiling->geom,
- comp->mat_compiling->frag,
- comp->mat_compiling->defs);
+ GPU_material_compile(comp->mat_compiling->mat);
*progress = (float)comp->shaders_done / (float)total;
*do_update = true;
@@ -165,25 +154,20 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
MEM_freeN(comp);
}
-static void drw_deferred_shader_add(
- GPUMaterial *mat, const char *vert, const char *geom, const char *frag_lib, const char *defines)
+static void drw_deferred_shader_add(GPUMaterial *mat)
{
/* Do not deferre the compilation if we are rendering for image. */
if (DRW_state_is_image_render() || !USE_DEFERRED_COMPILATION) {
/* Double checking that this GPUMaterial is not going to be
* compiled by another thread. */
DRW_deferred_shader_remove(mat);
- GPU_material_generate_pass(mat, vert, geom, frag_lib, defines);
+ GPU_material_compile(mat);
return;
}
DRWDeferredShader *dsh = MEM_callocN(sizeof(DRWDeferredShader), "Deferred Shader");
dsh->mat = mat;
- if (vert) dsh->vert = BLI_strdup(vert);
- if (geom) dsh->geom = BLI_strdup(geom);
- if (frag_lib) dsh->frag = BLI_strdup(frag_lib);
- if (defines) dsh->defs = BLI_strdup(defines);
BLI_assert(DST.draw_ctx.evil_C);
wmWindowManager *wm = CTX_wm_manager(DST.draw_ctx.evil_C);
@@ -361,10 +345,13 @@ GPUMaterial *DRW_shader_create_from_world(
if (mat == NULL) {
mat = GPU_material_from_nodetree(
- scene, wo->nodetree, &wo->gpumaterial, engine_type, options);
+ scene, wo->nodetree, &wo->gpumaterial, engine_type, options,
+ vert, geom, frag_lib, defines);
}
- drw_deferred_shader_add(mat, vert, geom, frag_lib, defines);
+ if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
+ drw_deferred_shader_add(mat);
+ }
return mat;
}
@@ -380,10 +367,13 @@ GPUMaterial *DRW_shader_create_from_material(
if (mat == NULL) {
mat = GPU_material_from_nodetree(
- scene, ma->nodetree, &ma->gpumaterial, engine_type, options);
+ scene, ma->nodetree, &ma->gpumaterial, engine_type, options,
+ vert, geom, frag_lib, defines);
}
- drw_deferred_shader_add(mat, vert, geom, frag_lib, defines);
+ if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
+ drw_deferred_shader_add(mat);
+ }
return mat;
}
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index ff6fcdb83d2..ba44e5dea10 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -1992,16 +1992,12 @@ static void OBJECT_cache_populate_particles(Object *ob,
continue;
}
if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
- return;
+ continue;
}
ParticleSettings *part = psys->part;
int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
- if (draw_as == PART_DRAW_PATH && !psys->pathcache && !psys->childcache) {
- draw_as = PART_DRAW_DOT;
- }
-
static float mat[4][4];
unit_m4(mat);
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 505472460a1..97403b14ac5 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -28,6 +28,7 @@
#include "BKE_object.h"
#include "GPU_shader.h"
+#include "GPU_extensions.h"
#include "DRW_render.h"
#include "draw_mode_engines.h"
@@ -51,8 +52,10 @@ typedef struct OVERLAY_Data {
} OVERLAY_Data;
typedef struct OVERLAY_PrivateData {
+ GPUShader *wire_sh; /* reference */
DRWShadingGroup *face_orientation_shgrp;
View3DOverlay overlay;
+ float wire_step_param[2];
} OVERLAY_PrivateData; /* Transient data */
/* *********** STATIC *********** */
@@ -61,6 +64,7 @@ static struct {
struct GPUShader *face_orientation_sh;
/* Wireframe shader */
struct GPUShader *face_wireframe_sh;
+ struct GPUShader *face_wireframe_pretty_sh;
} e_data = {NULL};
/* Shaders */
@@ -68,6 +72,7 @@ extern char datatoc_overlay_face_orientation_frag_glsl[];
extern char datatoc_overlay_face_orientation_vert_glsl[];
extern char datatoc_overlay_face_wireframe_vert_glsl[];
+extern char datatoc_overlay_face_wireframe_geom_glsl[];
extern char datatoc_overlay_face_wireframe_frag_glsl[];
extern struct GlobalsUboStorage ts; /* draw_common.c */
@@ -91,9 +96,22 @@ static void overlay_engine_init(void *vedata)
}
if (!e_data.face_wireframe_sh) {
+ bool use_geom = GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY);
+
e_data.face_wireframe_sh = DRW_shader_create(
- datatoc_overlay_face_wireframe_vert_glsl, NULL,
- datatoc_overlay_face_wireframe_frag_glsl, NULL);
+ datatoc_overlay_face_wireframe_vert_glsl,
+ use_geom ? datatoc_overlay_face_wireframe_geom_glsl : NULL,
+ datatoc_overlay_face_wireframe_frag_glsl,
+ use_geom ? "#define USE_GEOM_SHADER\n"
+ : NULL);
+
+ e_data.face_wireframe_pretty_sh = DRW_shader_create(
+ datatoc_overlay_face_wireframe_vert_glsl,
+ use_geom ? datatoc_overlay_face_wireframe_geom_glsl : NULL,
+ datatoc_overlay_face_wireframe_frag_glsl,
+ use_geom ? "#define USE_GEOM_SHADER\n"
+ "#define LIGHT_EDGES\n"
+ : "#define LIGHT_EDGES\n");
}
}
@@ -123,6 +141,25 @@ static void overlay_cache_init(void *vedata)
if (stl->g_data->overlay.flag & V3D_OVERLAY_WIREFRAMES) {
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
psl->face_wireframe_pass = DRW_pass_create("Face Wires", state);
+ /* Sticky uniforms (don't need to respecify each time since shader does not change). */
+ stl->g_data->wire_sh = (stl->g_data->overlay.wireframe_threshold == 1.0f) ? e_data.face_wireframe_sh
+ : e_data.face_wireframe_pretty_sh;
+ DRWShadingGroup *shgrp = DRW_shgroup_create(stl->g_data->wire_sh, psl->face_wireframe_pass);
+ DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_vec2(shgrp, "wireStepParam", stl->g_data->wire_step_param, 1);
+
+ /**
+ * The wireframe threshold ranges from 0.0 to 1.0
+ * When 1.0 we show all the edges, when 0.5 we show as many as 2.7.
+ *
+ * If we wanted 0.0 to match 2.7, factor would need to be 0.003f.
+ * The range controls the falloff effect. If range was 0.0f we would get a hard cut (as in 2.7).
+ * That said we are using a different algorithm so the results will always differ.
+ */
+ const float factor = 0.0045f;
+ const float range = 0.00125f;
+ stl->g_data->wire_step_param[1] = (1.0f - factor) + stl->g_data->overlay.wireframe_threshold * factor;
+ stl->g_data->wire_step_param[0] = stl->g_data->wire_step_param[1] + range;
}
}
@@ -155,14 +192,12 @@ static void overlay_cache_populate(void *vedata, Object *ob)
if ((ob->base_flag & BASE_SELECTED) != 0) {
rim_col = (ob == draw_ctx->obact) ? ts.colorActive : ts.colorSelect;
}
- /* TODO(fclem): Compare performance with a geom shader based approach. */
- DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.face_wireframe_sh, psl->face_wireframe_pass);
+ DRWShadingGroup *shgrp = DRW_shgroup_create(stl->g_data->wire_sh, psl->face_wireframe_pass);
DRW_shgroup_uniform_texture(shgrp, "vertData", verts);
DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids);
DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1);
DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
- DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1);
- DRW_shgroup_call_procedural_triangles_add(shgrp, tri_count, ob->obmat);
+ DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob);
}
}
}
@@ -191,6 +226,7 @@ static void overlay_engine_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.face_orientation_sh);
DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sh);
+ DRW_SHADER_FREE_SAFE(e_data.face_wireframe_pretty_sh);
}
static const DrawEngineDataSize overlay_data_size = DRW_VIEWPORT_DATA_SIZE(OVERLAY_Data);
diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c
index dacd4b72834..19c3ddd4b50 100644
--- a/source/blender/draw/modes/particle_mode.c
+++ b/source/blender/draw/modes/particle_mode.c
@@ -183,6 +183,12 @@ static void particle_cache_populate(void *vedata, Object *object)
Object *object_orig = DEG_get_original_object(object);
PTCacheEdit *edit = PE_create_current(
draw_ctx->depsgraph, scene_orig, object_orig);
+ if (edit == NULL) {
+ /* Happens when trying to edit particles in EMITTER mode without
+ * having them cached.
+ */
+ return;
+ }
/* NOTE: We need to pass evaluated particle system, which we need
* to find first.
*/
diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c
index 586fb590ebf..ad9567cd9c0 100644
--- a/source/blender/draw/modes/pose_mode.c
+++ b/source/blender/draw/modes/pose_mode.c
@@ -72,13 +72,15 @@ typedef struct POSE_Data {
typedef struct POSE_PrivateData {
DRWShadingGroup *bone_selection_shgrp;
+ DRWShadingGroup *bone_selection_invert_shgrp;
+ float blend_color[4];
+ float blend_color_invert[4];
} POSE_PrivateData; /* Transient data */
static struct {
struct GPUShader *bone_selection_sh;
} e_data = {NULL};
-static float blend_color[4] = {0.0, 0.0, 0.0, 0.5};
/* *********** FUNCTIONS *********** */
static bool POSE_is_bone_selection_overlay_active(void)
@@ -105,11 +107,14 @@ static void POSE_cache_init(void *vedata)
{
POSE_PassList *psl = ((POSE_Data *)vedata)->psl;
POSE_StorageList *stl = ((POSE_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
if (!stl->g_data) {
/* Alloc transient pointers */
stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
}
+ POSE_PrivateData *ppd = stl->g_data;
{
/* Solid bones */
@@ -150,13 +155,18 @@ static void POSE_cache_init(void *vedata)
{
if (POSE_is_bone_selection_overlay_active()) {
+ copy_v4_fl4(ppd->blend_color, 0.0f, 0.0f, 0.0f, v3d->overlay.bone_selection_alpha);
+ copy_v4_fl4(ppd->blend_color_invert, 0.0f, 0.0f, 0.0f, pow(v3d->overlay.bone_selection_alpha, 4));
DRWShadingGroup *grp;
psl->bone_selection = DRW_pass_create(
"Bone Selection",
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND);
grp = DRW_shgroup_create(e_data.bone_selection_sh, psl->bone_selection);
- DRW_shgroup_uniform_vec4(grp, "color", blend_color, 1);
+ DRW_shgroup_uniform_vec4(grp, "color", ppd->blend_color, 1);
stl->g_data->bone_selection_shgrp = grp;
+ grp = DRW_shgroup_create(e_data.bone_selection_sh, psl->bone_selection);
+ DRW_shgroup_uniform_vec4(grp, "color", ppd->blend_color_invert, 1);
+ stl->g_data->bone_selection_invert_shgrp = grp;
}
}
}
@@ -206,12 +216,16 @@ static void POSE_cache_populate(void *vedata, Object *ob)
}
else if (ob->type == OB_MESH &&
!DRW_state_is_select() &&
- POSE_is_bone_selection_overlay_active() &&
- POSE_is_driven_by_active_armature(ob))
+ POSE_is_bone_selection_overlay_active())
{
struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
- DRW_shgroup_call_object_add(stl->g_data->bone_selection_shgrp, geom, ob);
+ if (POSE_is_driven_by_active_armature(ob)) {
+ DRW_shgroup_call_object_add(stl->g_data->bone_selection_shgrp, geom, ob);
+ }
+ else {
+ DRW_shgroup_call_object_add(stl->g_data->bone_selection_invert_shgrp, geom, ob);
+ }
}
}
}
diff --git a/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
index 11924b19cf8..4d6f3e94693 100644
--- a/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
@@ -69,7 +69,7 @@ void main(void)
return;
/* Don't outline if concave edge. */
- if (dot(n0, v13) > 0.0)
+ if (dot(n0, v13) > 0.0001)
return;
vec2 thick = vColSize[0].w * (lineThickness / viewportSize);
diff --git a/source/blender/draw/modes/shaders/common_hair_lib.glsl b/source/blender/draw/modes/shaders/common_hair_lib.glsl
index 3fe44b4e142..552690ba972 100644
--- a/source/blender/draw/modes/shaders/common_hair_lib.glsl
+++ b/source/blender/draw/modes/shaders/common_hair_lib.glsl
@@ -134,9 +134,9 @@ float hair_shaperadius(float shape, float root, float tip, float time)
return (radius * (root - tip)) + tip;
}
-void hair_get_pos_tan_nor_time(
+void hair_get_pos_tan_binor_time(
bool is_persp, vec3 camera_pos, vec3 camera_z,
- out vec3 wpos, out vec3 wtan, out vec3 wnor, out float time, out float thickness, out float thick_time)
+ out vec3 wpos, out vec3 wtan, out vec3 wbinor, out float time, out float thickness, out float thick_time)
{
int id = hair_get_base_id();
vec4 data = texelFetch(hairPointBuffer, id);
@@ -151,7 +151,7 @@ void hair_get_pos_tan_nor_time(
}
vec3 camera_vec = (is_persp) ? wpos - camera_pos : -camera_z;
- wnor = normalize(cross(camera_vec, wtan));
+ wbinor = normalize(cross(camera_vec, wtan));
thickness = hair_shaperadius(hairRadShape, hairRadRoot, hairRadTip, time);
@@ -159,7 +159,7 @@ void hair_get_pos_tan_nor_time(
thick_time = float(gl_VertexID % hairThicknessRes) / float(hairThicknessRes - 1);
thick_time = thickness * (thick_time * 2.0 - 1.0);
- wpos += wnor * thick_time;
+ wpos += wbinor * thick_time;
}
}
diff --git a/source/blender/draw/modes/shaders/common_hair_refine_vert.glsl b/source/blender/draw/modes/shaders/common_hair_refine_vert.glsl
index 96a3103f666..9f412c57db3 100644
--- a/source/blender/draw/modes/shaders/common_hair_refine_vert.glsl
+++ b/source/blender/draw/modes/shaders/common_hair_refine_vert.glsl
@@ -3,13 +3,53 @@
out vec4 outData;
+vec4 get_weights_cardinal(float t)
+{
+ float t2 = t * t;
+ float t3 = t2 * t;
+#if defined(CARDINAL)
+ float fc = 0.71;
+#else /* defined(CATMULL_ROM) */
+ float fc = 0.5;
+#endif
+
+ vec4 weights;
+ /* GLSL Optimized version of key_curve_position_weights() */
+ float fct = t * fc;
+ float fct2 = t2 * fc;
+ float fct3 = t3 * fc;
+ weights.x = ( fct2 * 2.0 - fct3) - fct;
+ weights.y = ( t3 * 2.0 - fct3) + (-t2 * 3.0 + fct2) + 1.0;
+ weights.z = (-t3 * 2.0 + fct3) + ( t2 * 3.0 - (2.0 * fct2)) + fct;
+ weights.w = fct3 - fct2;
+ return weights;
+}
+
+/* TODO(fclem): This one is buggy, find why. (it's not the optimization!!) */
+vec4 get_weights_bspline(float t)
+{
+ float t2 = t * t;
+ float t3 = t2 * t;
+
+ vec4 weights;
+ /* GLSL Optimized version of key_curve_position_weights() */
+ weights.xz = vec2(-0.16666666, -0.5) * t3 + (0.5 * t2 + 0.5 * vec2(-t, t) + 0.16666666);
+ weights.y = ( 0.5 * t3 - t2 + 0.66666666);
+ weights.w = ( 0.16666666 * t3);
+ return weights;
+}
+
+vec4 interp_data(vec4 v0, vec4 v1, vec4 v2, vec4 v3, vec4 w)
+{
+ return v0 * w.x + v1 * w.y + v2 * w.z + v3 * w.w;
+}
+
void main(void)
{
float interp_time;
vec4 data0, data1, data2, data3;
hair_get_interp_attribs(data0, data1, data2, data3, interp_time);
- /* TODO some interpolation. */
-
- outData = mix(data1, data2, interp_time);
+ vec4 weights = get_weights_cardinal(interp_time);
+ outData = interp_data(data0, data1, data2, data3, weights);
}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
index 86e3bb959e9..00ababc624d 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
@@ -6,16 +6,21 @@ flat in vec3 ssVec1;
flat in vec3 ssVec2;
in float facing;
+#ifdef LIGHT_EDGES
+in float edgeSharpness;
+#endif
+
out vec4 fragColor;
float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
+float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
/* In pixels */
const float wire_size = 0.0; /* Expands the core of the wire (part that is 100% wire color) */
-const float wire_smooth = 1.4; /* Smoothing distance after the 100% core. */
+const float wire_smooth = 1.2; /* Smoothing distance after the 100% core. */
/* Alpha constants could be exposed in the future. */
-const float front_alpha = 0.55;
+const float front_alpha = 0.35;
const float rim_alpha = 0.75;
void main()
@@ -27,10 +32,22 @@ void main()
dot(ss_pos, ssVec2)
);
- float fac = smoothstep(wire_size, wire_size + wire_smooth, min_v3(abs(dist_to_edge)));
+#ifdef LIGHT_EDGES
+ vec3 fac = abs(dist_to_edge);
+#else
+ float fac = min_v3(abs(dist_to_edge));
+#endif
+
+ fac = smoothstep(wire_size + wire_smooth, wire_size, fac);
+
float facing_clamped = clamp((gl_FrontFacing) ? facing : -facing, 0.0, 1.0);
- vec3 final_front_col = rimColor * 0.5 + wireColor * 0.5;
+ vec3 final_front_col = mix(rimColor, wireColor, 0.05);
fragColor = mix(vec4(rimColor, rim_alpha), vec4(final_front_col, front_alpha), facing_clamped);
- fragColor.a *= (1.0 - fac);
+
+#ifdef LIGHT_EDGES
+ fragColor.a *= max_v3(fac * edgeSharpness);
+#else
+ fragColor.a *= fac;
+#endif
}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
new file mode 100644
index 00000000000..6e833a4e16b
--- /dev/null
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
@@ -0,0 +1,78 @@
+
+/* This shader is only used for intel GPU where the Geom shader is faster
+ * than doing everything thrice in the vertex shader. */
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+uniform vec2 wireStepParam;
+
+in vec2 ssPos[];
+in float facingOut[];
+
+flat out vec3 ssVec0;
+flat out vec3 ssVec1;
+flat out vec3 ssVec2;
+out float facing;
+
+#ifdef LIGHT_EDGES
+in vec3 obPos[];
+in vec3 vNor[];
+in float forceEdge[];
+
+out float edgeSharpness;
+#endif
+
+#define NO_EDGE vec3(10000.0);
+
+/* TODO(fclem) remove code duplication. */
+vec3 compute_vec(vec2 v0, vec2 v1)
+{
+ vec2 v = normalize(v1 - v0);
+ v = vec2(-v.y, v.x);
+ return vec3(v, -dot(v, v0));
+}
+
+float get_edge_sharpness(vec3 fnor, vec3 vnor)
+{
+ float sharpness = abs(dot(fnor, vnor));
+ return smoothstep(wireStepParam.x, wireStepParam.y, sharpness);
+}
+
+void main(void)
+{
+ vec3 facings = vec3(facingOut[0], facingOut[1], facingOut[2]);
+ bvec3 do_edge = greaterThan(abs(facings), vec3(1.0));
+ facings = fract(facings) - clamp(-sign(facings), 0.0, 1.0);
+
+ ssVec0 = do_edge.x ? compute_vec(ssPos[0], ssPos[1]) : NO_EDGE;
+ ssVec1 = do_edge.y ? compute_vec(ssPos[1], ssPos[2]) : NO_EDGE;
+ ssVec2 = do_edge.z ? compute_vec(ssPos[2], ssPos[0]) : NO_EDGE;
+
+#ifdef LIGHT_EDGES
+ vec3 fnor = normalize(cross(obPos[1] - obPos[0], obPos[2] - obPos[0]));
+
+ edgeSharpness = get_edge_sharpness(fnor, vNor[0]);
+ edgeSharpness = (forceEdge[0] == 1.0 || forceEdge[2] == 1.0) ? 1.0 : edgeSharpness;
+#endif
+ gl_Position = gl_in[0].gl_Position;
+ facing = facings.x;
+ EmitVertex();
+
+#ifdef LIGHT_EDGES
+ edgeSharpness = get_edge_sharpness(fnor, vNor[1]);
+ edgeSharpness = (forceEdge[1] == 1.0 || forceEdge[0] == 1.0) ? 1.0 : edgeSharpness;
+#endif
+ gl_Position = gl_in[1].gl_Position;
+ facing = facings.y;
+ EmitVertex();
+
+#ifdef LIGHT_EDGES
+ edgeSharpness = get_edge_sharpness(fnor, vNor[2]);
+ edgeSharpness = (forceEdge[2] == 1.0 || forceEdge[1] == 1.0) ? 1.0 : edgeSharpness;
+#endif
+ gl_Position = gl_in[2].gl_Position;
+ facing = facings.z;
+ EmitVertex();
+ EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
index 67f4a5c7668..616cd5379e9 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -1,18 +1,35 @@
+
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;
+uniform vec2 wireStepParam;
uniform vec2 viewportSize;
uniform float nearDist;
uniform samplerBuffer vertData;
-uniform isamplerBuffer faceIds;
+uniform usamplerBuffer faceIds;
+#ifdef USE_GEOM_SHADER
+out vec2 ssPos;
+out float facingOut; /* abs(facing) > 1.0 if we do edge */
+#else
flat out vec3 ssVec0;
flat out vec3 ssVec1;
flat out vec3 ssVec2;
out float facing;
+#endif
+
+#ifdef LIGHT_EDGES
+#ifdef USE_GEOM_SHADER
+out vec3 obPos;
+out vec3 vNor;
+out float forceEdge;
+#else
+out float edgeSharpness;
+#endif
+#endif
/* project to screen space */
vec2 proj(vec4 pos)
@@ -36,9 +53,9 @@ float short_to_unit_float(uint s)
return float(value) / float(0x7FFF);
}
-vec3 get_vertex_nor(int v_id)
+vec3 get_vertex_nor(uint id)
{
- v_id *= 5; /* See vertex format for explanation. */
+ int v_id = int(id) * 5; /* See vertex format for explanation. */
/* Fetch compressed normal as float and unpack them. */
vec2 data;
data.x = texelFetch(vertData, v_id + 3).r;
@@ -53,9 +70,9 @@ vec3 get_vertex_nor(int v_id)
return nor;
}
-vec3 get_vertex_pos(int v_id)
+vec3 get_vertex_pos(uint id)
{
- v_id *= 5; /* See vertex format for explanation. */
+ int v_id = int(id) * 5; /* See vertex format for explanation. */
vec3 pos;
pos.x = texelFetch(vertData, v_id).r;
pos.y = texelFetch(vertData, v_id + 1).r;
@@ -63,21 +80,55 @@ vec3 get_vertex_pos(int v_id)
return pos;
}
+float get_edge_sharpness(vec3 fnor, vec3 vnor)
+{
+ float sharpness = abs(dot(fnor, vnor));
+ return smoothstep(wireStepParam.x, wireStepParam.y, sharpness);
+}
+
#define NO_EDGE vec3(10000.0);
void main()
{
+#ifdef USE_GEOM_SHADER
+ uint v_id = texelFetch(faceIds, gl_VertexID).r;
+
+ bool do_edge = (v_id & (1u << 30u)) != 0u;
+ bool force_edge = (v_id & (1u << 31u)) != 0u;
+ v_id = (v_id << 2u) >> 2u;
+
+ vec3 pos = get_vertex_pos(v_id);
+ vec3 nor = get_vertex_nor(v_id);
+ facingOut = normalize(NormalMatrix * nor).z;
+ facingOut += (do_edge) ? ((facingOut > 0.0) ? 2.0 : -2.0) : 0.0;
+
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ ssPos = proj(gl_Position);
+
+# ifdef LIGHT_EDGES
+ obPos = pos;
+ vNor = nor;
+ forceEdge = float(force_edge); /* meh, could try to also encode it in facingOut */
+# endif
+#else
int v_0 = (gl_VertexID / 3) * 3;
int v_n = gl_VertexID % 3;
+
/* Getting the same positions for each of the 3 verts. */
- ivec3 v_id;
+ uvec3 v_id;
v_id.x = texelFetch(faceIds, v_0).r;
v_id.y = texelFetch(faceIds, v_0 + 1).r;
v_id.z = texelFetch(faceIds, v_0 + 2).r;
- bvec3 do_edge = lessThan(v_id, ivec3(0));
- v_id = abs(v_id) - 1;
+ bvec3 do_edge, force_edge;
+ do_edge.x = (v_id.x & (1u << 30u)) != 0u;
+ do_edge.y = (v_id.y & (1u << 30u)) != 0u;
+ do_edge.z = (v_id.z & (1u << 30u)) != 0u;
+ force_edge.x = (v_id.x & (1u << 31u)) != 0u;
+ force_edge.y = (v_id.y & (1u << 31u)) != 0u;
+ force_edge.z = (v_id.z & (1u << 31u)) != 0u;
+ v_id = (v_id << 2u) >> 2u;
vec3 pos[3];
pos[0] = get_vertex_pos(v_id.x);
@@ -102,5 +153,23 @@ void main()
gl_Position = p_pos[v_n];
vec3 nor = get_vertex_nor(v_id[v_n]);
- facing = (NormalMatrix * nor).z;
+ facing = normalize(NormalMatrix * nor).z;
+
+# ifdef LIGHT_EDGES
+ vec3 fnor = normalize(cross(pos[1] - pos[0], pos[2] - pos[0]));
+ edgeSharpness = get_edge_sharpness(fnor, nor);
+
+ /* Fix disapearing edges. */
+ if (v_n == 0) {
+ force_edge.xy = force_edge.xz;
+ }
+ else if (v_n == 2) {
+ force_edge.xy = force_edge.yz;
+ }
+ if (any(force_edge.xy)) {
+ edgeSharpness = 1.0;
+ }
+# endif
+
+#endif
}
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index d48798ece97..e4213a8d907 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -65,6 +65,7 @@
#include "BKE_animsys.h"
#include "BKE_curve.h"
#include "BKE_key.h"
+#include "BKE_main.h"
#include "BKE_nla.h"
#include "BKE_context.h"
@@ -119,10 +120,10 @@ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, floa
short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
float color[3];
-
+
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
-
+
/* 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_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
@@ -162,7 +163,7 @@ static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale
static bool acf_show_channel_colors(bAnimContext *ac)
{
bool showGroupColors = false;
-
+
if (ac->sl) {
switch (ac->spacetype) {
case SPACE_ACTION:
@@ -181,7 +182,7 @@ static bool acf_show_channel_colors(bAnimContext *ac)
}
}
}
-
+
return showGroupColors;
}
@@ -192,19 +193,19 @@ static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, floa
bActionGroup *grp = NULL;
short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
bool showGroupColors = acf_show_channel_colors(ac);
-
+
if (ale->type == ANIMTYPE_FCURVE) {
FCurve *fcu = (FCurve *)ale->data;
grp = fcu->grp;
}
-
- /* set color for normal channels
+
+ /* set color for normal channels
* - use 3 shades of color group/standard color for 3 indention level
* - only use group colors if allowed to, and if actually feasible
*/
if (showGroupColors && (grp) && (grp->customCol)) {
unsigned char cp[3];
-
+
if (indent == 2) {
copy_v3_v3_char((char *)cp, grp->cs.solid);
}
@@ -214,7 +215,7 @@ static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, floa
else {
copy_v3_v3_char((char *)cp, grp->cs.active);
}
-
+
/* copy the colors over, transforming from bytes to floats */
rgb_uchar_to_float(r_color, cp);
}
@@ -234,13 +235,13 @@ static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, f
float color[3];
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
+
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3fv(color);
-
+
/* no rounded corners - just rectangular box */
immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
@@ -269,16 +270,16 @@ static short acf_generic_indention_2(bAnimContext *ac, bAnimListElem *ale)
static short acf_generic_indention_flexible(bAnimContext *UNUSED(ac), bAnimListElem *ale)
{
short indent = 0;
-
+
/* grouped F-Curves need extra level of indention */
if (ale->type == ANIMTYPE_FCURVE) {
FCurve *fcu = (FCurve *)ale->data;
-
+
// TODO: we need some way of specifying that the indention color should be one less...
if (fcu->grp)
indent++;
}
-
+
/* no indention */
return indent;
}
@@ -287,7 +288,7 @@ static short acf_generic_indention_flexible(bAnimContext *UNUSED(ac), bAnimListE
static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale)
{
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
+
if (acf && acf->get_indent_level)
return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
else
@@ -300,21 +301,21 @@ static short acf_nodetree_rootType_offset(bNodeTree *ntree)
if (ntree) {
switch (ntree->type) {
case NTREE_SHADER:
- /* 1 additional level (i.e. is indented one level in from material,
- * so shift all right by one step)
+ /* 1 additional level (i.e. is indented one level in from material,
+ * so shift all right by one step)
*/
- return INDENT_STEP_SIZE;
-
+ return INDENT_STEP_SIZE;
+
case NTREE_COMPOSIT:
/* no additional levels needed */
- return 0;
-
+ return 0;
+
case NTREE_TEXTURE:
/* 2 additional levels */
return INDENT_STEP_SIZE * 2;
}
}
-
+
/* unknown */
return 0;
}
@@ -323,7 +324,7 @@ static short acf_nodetree_rootType_offset(bNodeTree *ntree)
static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
{
short offset = acf_generic_basic_offset(ac, ale);
-
+
if (ale->id) {
/* texture animdata */
if (GS(ale->id->name) == ID_TE) {
@@ -332,17 +333,17 @@ static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
/* materials and particles animdata */
else if (ELEM(GS(ale->id->name), ID_MA, ID_PA))
offset += (short)(0.7f * U.widget_unit);
-
+
/* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */
else if (ac->datatype != ANIMCONT_ACTION)
offset += (short)(0.7f * U.widget_unit);
-
+
/* nodetree animdata */
if (GS(ale->id->name) == ID_NT) {
offset += acf_nodetree_rootType_offset((bNodeTree *)ale->id);
}
}
-
+
/* offset is just the normal type - i.e. based on indention */
return offset;
}
@@ -353,7 +354,7 @@ static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
static void acf_generic_idblock_name(bAnimListElem *ale, char *name)
{
ID *id = (ID *)ale->data; /* data pointed to should be an ID block */
-
+
/* just copy the name... */
if (id && name)
BLI_strncpy(name, id->name + 2, ANIM_CHAN_NAME_SIZE);
@@ -364,7 +365,7 @@ static bool acf_generic_idblock_name_prop(bAnimListElem *ale, PointerRNA *ptr, P
{
RNA_id_pointer_create(ale->data, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
@@ -375,7 +376,7 @@ static bool acf_generic_idfill_name_prop(bAnimListElem *ale, PointerRNA *ptr, Pr
/* actual ID we're representing is stored in ale->data not ale->id, as id gives the owner */
RNA_id_pointer_create(ale->data, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
@@ -396,11 +397,11 @@ static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem
/* expand is always supported */
case ACHANNEL_SETTING_EXPAND:
return true;
-
+
/* mute is only supported for NLA */
case ACHANNEL_SETTING_MUTE:
return ((ac) && (ac->spacetype == SPACE_NLA));
-
+
/* select is ok for most "ds*" channels (e.g. dsmat) */
case ACHANNEL_SETTING_SELECT:
return true;
@@ -432,13 +433,13 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
View2D *v2d = &ac->ar->v2d;
float color[3];
-
+
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
-
- /* rounded corners on LHS only
- * - top and bottom
- * - special hack: make the top a bit higher, since we are first...
+
+ /* rounded corners on LHS only
+ * - top and bottom
+ * - special hack: make the top a bit higher, since we are first...
*/
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
UI_draw_roundbox_3fvAlpha(true, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
@@ -483,14 +484,14 @@ static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setti
static void *acf_summary_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
bAnimContext *ac = (bAnimContext *)ale->data;
-
- /* if data is valid, return pointer to active dopesheet's relevant flag
+
+ /* if data is valid, return pointer to active dopesheet's relevant flag
* - this is restricted to DopeSheet/Action Editor only
*/
if ((ac->sl) && (ac->spacetype == SPACE_ACTION) && (setting == ACHANNEL_SETTING_EXPAND)) {
SpaceAction *saction = (SpaceAction *)ac->sl;
bDopeSheet *ads = &saction->ads;
-
+
/* return pointer to DopeSheet's flag */
return GET_ACF_FLAG_PTR(ads->flag, type);
}
@@ -502,7 +503,7 @@ static void *acf_summary_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings s
}
/* all animation summary (DopeSheet only) type define */
-static bAnimChannelType ACF_SUMMARY =
+static bAnimChannelType ACF_SUMMARY =
{
"Summary", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
@@ -534,13 +535,13 @@ static bool acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale)
{
switch (setting) {
/* muted only in NLA */
- case ACHANNEL_SETTING_MUTE:
+ case ACHANNEL_SETTING_MUTE:
return ((ac) && (ac->spacetype == SPACE_NLA));
-
+
/* visible only in Graph Editor */
- case ACHANNEL_SETTING_VISIBLE:
+ case ACHANNEL_SETTING_VISIBLE:
return ((ac) && (ac->spacetype == SPACE_IPO));
-
+
/* only select and expand supported otherwise */
case ACHANNEL_SETTING_SELECT:
case ACHANNEL_SETTING_EXPAND:
@@ -559,18 +560,18 @@ static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return SCE_DS_SELECTED;
-
+
case ACHANNEL_SETTING_EXPAND: /* expanded */
*neg = true;
return SCE_DS_COLLAPSED;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
@@ -584,30 +585,30 @@ static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_scene_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Scene *scene = (Scene *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return GET_ACF_FLAG_PTR(scene->flag, type);
-
+
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(scene->flag, type);
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (scene->adt)
return GET_ACF_FLAG_PTR(scene->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
}
/* scene type define */
-static bAnimChannelType ACF_SCENE =
+static bAnimChannelType ACF_SCENE =
{
"Scene", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
@@ -632,20 +633,20 @@ static int acf_object_icon(bAnimListElem *ale)
{
Base *base = (Base *)ale->data;
Object *ob = base->object;
-
+
/* icon depends on object-type */
switch (ob->type) {
case OB_LAMP:
return ICON_OUTLINER_OB_LAMP;
- case OB_MESH:
+ case OB_MESH:
return ICON_OUTLINER_OB_MESH;
- case OB_CAMERA:
+ case OB_CAMERA:
return ICON_OUTLINER_OB_CAMERA;
- case OB_CURVE:
+ case OB_CURVE:
return ICON_OUTLINER_OB_CURVE;
- case OB_MBALL:
+ case OB_MBALL:
return ICON_OUTLINER_OB_META;
- case OB_LATTICE:
+ case OB_LATTICE:
return ICON_OUTLINER_OB_LATTICE;
case OB_SPEAKER:
return ICON_OUTLINER_OB_SPEAKER;
@@ -653,11 +654,11 @@ static int acf_object_icon(bAnimListElem *ale)
return ICON_OUTLINER_OB_LIGHTPROBE;
case OB_ARMATURE:
return ICON_OUTLINER_OB_ARMATURE;
- case OB_FONT:
+ case OB_FONT:
return ICON_OUTLINER_OB_FONT;
- case OB_SURF:
+ case OB_SURF:
return ICON_OUTLINER_OB_SURFACE;
- case OB_EMPTY:
+ case OB_EMPTY:
return ICON_OUTLINER_OB_EMPTY;
default:
return ICON_OBJECT_DATA;
@@ -669,7 +670,7 @@ static void acf_object_name(bAnimListElem *ale, char *name)
{
Base *base = (Base *)ale->data;
Object *ob = base->object;
-
+
/* just copy the name... */
if (ob && name)
BLI_strncpy(name, ob->id.name + 2, ANIM_CHAN_NAME_SIZE);
@@ -680,7 +681,7 @@ static bool acf_object_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRN
{
RNA_id_pointer_create(ale->id, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
@@ -689,16 +690,16 @@ static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnim
{
Base *base = (Base *)ale->data;
Object *ob = base->object;
-
+
switch (setting) {
/* muted only in NLA */
- case ACHANNEL_SETTING_MUTE:
+ case ACHANNEL_SETTING_MUTE:
return ((ac) && (ac->spacetype == SPACE_NLA));
-
+
/* visible only in Graph Editor */
- case ACHANNEL_SETTING_VISIBLE:
+ case ACHANNEL_SETTING_VISIBLE:
return ((ac) && (ac->spacetype == SPACE_IPO) && (ob->adt));
-
+
/* only select and expand supported otherwise */
case ACHANNEL_SETTING_SELECT:
case ACHANNEL_SETTING_EXPAND:
@@ -717,18 +718,18 @@ static int acf_object_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return SELECT;
-
+
case ACHANNEL_SETTING_EXPAND: /* expanded */
*neg = 1;
return OB_ADS_COLLAPSED;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
@@ -746,17 +747,17 @@ static void *acf_object_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings se
{
Base *base = (Base *)ale->data;
Object *ob = base->object;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return GET_ACF_FLAG_PTR(ob->flag, type);
-
+
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(ob->nlaflag, type); // xxx
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
case ACHANNEL_SETTING_ALWAYS_VISIBLE:
@@ -770,11 +771,11 @@ static void *acf_object_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings se
}
/* object type define */
-static bAnimChannelType ACF_OBJECT =
+static bAnimChannelType ACF_OBJECT =
{
"Object", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_root_color, /* backdrop color */
acf_generic_root_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
@@ -796,16 +797,16 @@ static void acf_group_color(bAnimContext *ac, bAnimListElem *ale, float r_color[
{
bActionGroup *agrp = (bActionGroup *)ale->data;
bool showGroupColors = acf_show_channel_colors(ac);
-
+
if (showGroupColors && agrp->customCol) {
unsigned char cp[3];
-
+
/* highlight only for active */
if (ale->flag & AGRP_ACTIVE)
copy_v3_v3_char((char *)cp, agrp->cs.select);
else
copy_v3_v3_char((char *)cp, agrp->cs.solid);
-
+
/* copy the colors over, transforming from bytes to floats */
rgb_uchar_to_float(r_color, cp);
}
@@ -826,10 +827,10 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc
short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
float color[3];
-
+
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
-
+
/* 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_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
@@ -839,7 +840,7 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc
static void acf_group_name(bAnimListElem *ale, char *name)
{
bActionGroup *agrp = (bActionGroup *)ale->data;
-
+
/* just copy the name... */
if (agrp && name)
BLI_strncpy(name, agrp->name, ANIM_CHAN_NAME_SIZE);
@@ -850,7 +851,7 @@ static bool acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA
{
RNA_pointer_create(ale->id, &RNA_ActionGroup, ale->data, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
@@ -862,7 +863,7 @@ static bool acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale)
/* unsupported */
case ACHANNEL_SETTING_SOLO: /* Only available in NLA Editor for tracks */
return false;
-
+
/* conditionally supported */
case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
return (ac->spacetype == SPACE_IPO);
@@ -880,22 +881,22 @@ static int acf_group_setting_flag(bAnimContext *ac, eAnimChannel_Settings settin
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return AGRP_SELECTED;
-
+
case ACHANNEL_SETTING_EXPAND: /* expanded */
{
/* NOTE: Graph Editor uses a different flag to everywhere else for this,
* allowing different collapsing of groups there, since sharing the flag
* proved to be a hazard for workflows...
*/
- return (ac->spacetype == SPACE_IPO) ?
+ return (ac->spacetype == SPACE_IPO) ?
AGRP_EXPANDED_G : /* Graph Editor case */
AGRP_EXPANDED; /* DopeSheet and elsewhere */
}
-
+
case ACHANNEL_SETTING_MUTE: /* muted */
return AGRP_MUTED;
@@ -905,7 +906,7 @@ static int acf_group_setting_flag(bAnimContext *ac, eAnimChannel_Settings settin
case ACHANNEL_SETTING_PROTECT: /* protected */
return AGRP_PROTECTED;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
*neg = 1;
return AGRP_NOTVISIBLE;
@@ -923,17 +924,17 @@ static int acf_group_setting_flag(bAnimContext *ac, eAnimChannel_Settings settin
static void *acf_group_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
bActionGroup *agrp = (bActionGroup *)ale->data;
-
+
/* all flags are just in agrp->flag for now... */
return GET_ACF_FLAG_PTR(agrp->flag, type);
}
/* group type define */
-static bAnimChannelType ACF_GROUP =
+static bAnimChannelType ACF_GROUP =
{
"Group", /* type name */
ACHANNEL_ROLE_CHANNEL, /* role */
-
+
acf_group_color, /* backdrop color */
acf_group_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
@@ -960,9 +961,9 @@ static void acf_fcurve_name(bAnimListElem *ale, char *name)
static bool acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
FCurve *fcu = (FCurve *)ale->data;
-
- /* Ctrl-Click Usability Convenience Hack:
- * For disabled F-Curves, allow access to the RNA Path
+
+ /* Ctrl-Click Usability Convenience Hack:
+ * For disabled F-Curves, allow access to the RNA Path
* as our "name" so that user can perform quick fixes
*/
if (fcu->flag & FCURVE_DISABLED) {
@@ -973,7 +974,7 @@ static bool acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRN
/* for "normal" F-Curves - no editable name, but *prop may not be set properly yet... */
*prop = NULL;
}
-
+
return (*prop != NULL);
}
@@ -981,21 +982,21 @@ static bool acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRN
static bool acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
FCurve *fcu = (FCurve *)ale->data;
-
+
switch (setting) {
/* unsupported */
case ACHANNEL_SETTING_SOLO: /* Solo Flag is only for NLA */
case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */
case ACHANNEL_SETTING_PINNED: /* This is only for NLA Actions */
return false;
-
+
/* conditionally available */
case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */
if (fcu->bezt)
return true;
else
return false; // NOTE: in this special case, we need to draw ICON_ZOOMOUT
-
+
case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
return (ac->spacetype == SPACE_IPO);
@@ -1013,20 +1014,20 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return FCURVE_SELECTED;
-
+
case ACHANNEL_SETTING_MUTE: /* muted */
return FCURVE_MUTED;
-
+
case ACHANNEL_SETTING_PROTECT: /* protected */
return FCURVE_PROTECTED;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
return FCURVE_VISIBLE;
-
+
case ACHANNEL_SETTING_MOD_OFF:
*neg = 1;
return FCURVE_MOD_OFF;
@@ -1040,17 +1041,17 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
static void *acf_fcurve_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
FCurve *fcu = (FCurve *)ale->data;
-
+
/* all flags are just in agrp->flag for now... */
return GET_ACF_FLAG_PTR(fcu->flag, type);
}
/* fcurve type define */
-static bAnimChannelType ACF_FCURVE =
+static bAnimChannelType ACF_FCURVE =
{
"F-Curve", /* type name */
ACHANNEL_ROLE_CHANNEL, /* role */
-
+
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_flexible, /* indent level */ // xxx rename this to f-curves only?
@@ -1082,11 +1083,11 @@ static void acf_nla_controls_backdrop(bAnimContext *ac, bAnimListElem *ale, floa
short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
float color[3];
-
+
/* set backdrop drawing color */
acf->get_backdrop_color(ac, ale, color);
-
- /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
+
+ /* 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_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5, color, 1.0f);
}
@@ -1105,9 +1106,9 @@ static bool acf_nla_controls_setting_valid(bAnimContext *UNUSED(ac), bAnimListEl
/* supported */
case ACHANNEL_SETTING_EXPAND:
return true;
-
+
// TOOD: selected?
-
+
default: /* unsupported */
return false;
}
@@ -1118,12 +1119,12 @@ static int acf_nla_controls_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
*neg = true;
return ADT_NLA_SKEYS_COLLAPSED;
-
+
default:
/* this shouldn't happen */
return 0;
@@ -1134,7 +1135,7 @@ static int acf_nla_controls_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_
static void *acf_nla_controls_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
AnimData *adt = (AnimData *)ale->data;
-
+
/* all flags are just in adt->flag for now... */
return GET_ACF_FLAG_PTR(adt->flag, type);
}
@@ -1145,11 +1146,11 @@ static int acf_nla_controls_icon(bAnimListElem *UNUSED(ale))
}
/* NLA Control FCurves Expander type define */
-static bAnimChannelType ACF_NLACONTROLS =
+static bAnimChannelType ACF_NLACONTROLS =
{
"NLA Controls Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_nla_controls_color, /* backdrop color */
acf_nla_controls_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
@@ -1173,7 +1174,7 @@ static void acf_nla_curve_name(bAnimListElem *ale, char *name)
NlaStrip *strip = ale->owner;
FCurve *fcu = ale->data;
PropertyRNA *prop;
-
+
/* try to get RNA property that this shortened path (relative to the strip) refers to */
prop = RNA_struct_type_find_property(&RNA_NlaStrip, fcu->rna_path);
if (prop) {
@@ -1188,11 +1189,11 @@ static void acf_nla_curve_name(bAnimListElem *ale, char *name)
/* NLA Control F-Curve type define */
-static bAnimChannelType ACF_NLACURVE =
+static bAnimChannelType ACF_NLACURVE =
{
"NLA Control F-Curve", /* type name */
ACHANNEL_ROLE_CHANNEL, /* role */
-
+
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1223,7 +1224,7 @@ static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
case ACHANNEL_SETTING_SELECT:
case ACHANNEL_SETTING_EXPAND:
return true;
-
+
default:
return false;
}
@@ -1234,15 +1235,15 @@ static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Sett
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
case ACHANNEL_SETTING_EXPAND: /* expanded */
*neg = true;
return ACT_COLLAPSED;
-
+
default: /* unsupported */
return 0;
}
@@ -1253,10 +1254,10 @@ static void *acf_fillactd_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings
{
bAction *act = (bAction *)ale->data;
AnimData *adt = ale->adt;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
if (adt) {
@@ -1266,18 +1267,18 @@ static void *acf_fillactd_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(act->flag, type);
-
+
default: /* unsupported */
return NULL;
}
}
/* object action expander type define */
-static bAnimChannelType ACF_FILLACTD =
+static bAnimChannelType ACF_FILLACTD =
{
"Ob-Action Filler", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1313,7 +1314,7 @@ static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListEle
/* only expand supported */
case ACHANNEL_SETTING_EXPAND:
return true;
-
+
default:
return false;
}
@@ -1324,12 +1325,12 @@ static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_S
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
*neg = true;
return ADT_DRIVERS_COLLAPSED;
-
+
default: /* unsupported */
return 0;
}
@@ -1339,25 +1340,25 @@ static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_S
static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
AnimData *adt = (AnimData *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(adt->flag, type);
-
+
default: /* unsupported */
return NULL;
}
}
/* drivers expander type define */
-static bAnimChannelType ACF_FILLDRIVERS =
+static bAnimChannelType ACF_FILLDRIVERS =
{
"Drivers Filler", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1386,21 +1387,21 @@ static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return MA_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -1410,14 +1411,14 @@ static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dsmat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Material *ma = (Material *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(ma->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
@@ -1435,7 +1436,7 @@ static bAnimChannelType ACF_DSMAT =
{
"Material Data Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1463,21 +1464,21 @@ static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return LA_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -1487,21 +1488,21 @@ static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dslam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Lamp *la = (Lamp *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(la->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (la->adt)
return GET_ACF_FLAG_PTR(la->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -1512,7 +1513,7 @@ static bAnimChannelType ACF_DSLAM =
{
"Lamp Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1547,21 +1548,21 @@ static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return TEX_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -1571,21 +1572,21 @@ static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dstex_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Tex *tex = (Tex *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(tex->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (tex->adt)
return GET_ACF_FLAG_PTR(tex->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -1596,7 +1597,7 @@ static bAnimChannelType ACF_DSTEX =
{
"Texture Data Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1706,18 +1707,18 @@ static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return CAM_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
@@ -1733,14 +1734,14 @@ static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dscam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Camera *ca = (Camera *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(ca->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
@@ -1748,7 +1749,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set
if (ca->adt)
return GET_ACF_FLAG_PTR(ca->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -1759,7 +1760,7 @@ static bAnimChannelType ACF_DSCAM =
{
"Camera Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1781,7 +1782,7 @@ static int acf_dscur_icon(bAnimListElem *ale)
{
Curve *cu = (Curve *)ale->data;
short obtype = BKE_curve_type_get(cu);
-
+
switch (obtype) {
case OB_FONT:
return ICON_FONT_DATA;
@@ -1797,21 +1798,21 @@ static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return CU_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -1821,21 +1822,21 @@ static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dscur_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Curve *cu = (Curve *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(cu->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (cu->adt)
return GET_ACF_FLAG_PTR(cu->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -1846,7 +1847,7 @@ static bAnimChannelType ACF_DSCUR =
{
"Curve Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1874,21 +1875,21 @@ static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return KEY_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -1898,21 +1899,21 @@ static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
static void *acf_dsskey_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Key *key = (Key *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(key->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (key->adt)
return GET_ACF_FLAG_PTR(key->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -1923,7 +1924,7 @@ static bAnimChannelType ACF_DSSKEY =
{
"Shape Key Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -1951,21 +1952,21 @@ static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return WO_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -1975,21 +1976,21 @@ static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dswor_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
World *wo = (World *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(wo->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (wo->adt)
return GET_ACF_FLAG_PTR(wo->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2000,7 +2001,7 @@ static bAnimChannelType ACF_DSWOR =
{
"World Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -2028,21 +2029,21 @@ static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return 0;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2053,16 +2054,16 @@ static void *acf_dspart_setting_ptr(bAnimListElem *UNUSED(ale), eAnimChannel_Set
{
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return NULL;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2073,7 +2074,7 @@ static bAnimChannelType ACF_DSPART =
{
"Particle Data Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -2101,21 +2102,21 @@ static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setti
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return MB_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2125,21 +2126,21 @@ static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setti
static void *acf_dsmball_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
MetaBall *mb = (MetaBall *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(mb->flag2, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (mb->adt)
return GET_ACF_FLAG_PTR(mb->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2150,7 +2151,7 @@ static bAnimChannelType ACF_DSMBALL =
{
"Metaball Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -2178,21 +2179,21 @@ static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return ARM_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2202,21 +2203,21 @@ static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dsarm_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
bArmature *arm = (bArmature *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(arm->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (arm->adt)
return GET_ACF_FLAG_PTR(arm->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2227,7 +2228,7 @@ static bAnimChannelType ACF_DSARM =
{
"Armature Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -2255,9 +2256,9 @@ static short acf_dsntree_offset(bAnimContext *ac, bAnimListElem *ale)
{
bNodeTree *ntree = (bNodeTree *)ale->data;
short offset = acf_generic_basic_offset(ac, ale);
-
- offset += acf_nodetree_rootType_offset(ntree);
-
+
+ offset += acf_nodetree_rootType_offset(ntree);
+
return offset;
}
@@ -2266,21 +2267,21 @@ static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setti
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return NTREE_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2290,21 +2291,21 @@ static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setti
static void *acf_dsntree_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
bNodeTree *ntree = (bNodeTree *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(ntree->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (ntree->adt)
return GET_ACF_FLAG_PTR(ntree->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2315,7 +2316,7 @@ static bAnimChannelType ACF_DSNTREE =
{
"Node Tree Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -2343,21 +2344,21 @@ static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_S
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return LS_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2367,21 +2368,21 @@ static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_S
static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(linestyle->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (linestyle->adt)
return GET_ACF_FLAG_PTR(linestyle->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2392,16 +2393,16 @@ static bAnimChannelType ACF_DSLINESTYLE =
{
"Line Style Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop,/* backdrop */
acf_generic_indention_1, /* indent level */
acf_generic_basic_offset, /* offset */
-
+
acf_generic_idblock_name, /* name */
acf_generic_idblock_name_prop, /* name prop */
acf_dslinestyle_icon, /* icon */
-
+
acf_generic_dataexpand_setting_valid, /* has setting */
acf_dslinestyle_setting_flag, /* flag for setting */
acf_dslinestyle_setting_ptr /* pointer for setting */
@@ -2420,21 +2421,21 @@ static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return ME_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2444,21 +2445,21 @@ static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settin
static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Mesh *me = (Mesh *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(me->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (me->adt)
return GET_ACF_FLAG_PTR(me->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2469,7 +2470,7 @@ static bAnimChannelType ACF_DSMESH =
{
"Mesh Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */ // XXX this only works for compositing
@@ -2497,21 +2498,21 @@ static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return LT_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2521,21 +2522,21 @@ static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dslat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Lattice *lt = (Lattice *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(lt->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (lt->adt)
return GET_ACF_FLAG_PTR(lt->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2546,7 +2547,7 @@ static bAnimChannelType ACF_DSLAT =
{
"Lattice Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */ // XXX this only works for compositing
@@ -2574,21 +2575,21 @@ static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return SPK_DS_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2598,21 +2599,21 @@ static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setting
static void *acf_dsspk_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
Speaker *spk = (Speaker *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(spk->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (spk->adt)
return GET_ACF_FLAG_PTR(spk->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2623,7 +2624,7 @@ static bAnimChannelType ACF_DSSPK =
{
"Speaker Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -2651,21 +2652,21 @@ static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Set
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GP_DATA_EXPAND;
-
+
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
*neg = true;
return ADT_CURVES_NOT_VISIBLE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return ADT_UI_SELECTED;
-
+
default: /* unsupported */
return 0;
}
@@ -2675,21 +2676,21 @@ static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Set
static void *acf_dsgpencil_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
bGPdata *gpd = (bGPdata *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GET_ACF_FLAG_PTR(gpd->flag, type);
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
if (gpd->adt)
return GET_ACF_FLAG_PTR(gpd->adt->flag, type);
return NULL;
-
+
default: /* unsupported */
return NULL;
}
@@ -2700,7 +2701,7 @@ static bAnimChannelType ACF_DSGPENCIL =
{
"GPencil DS Expander", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_generic_dataexpand_color, /* backdrop color */
acf_generic_dataexpand_backdrop, /* backdrop */
acf_generic_indention_1, /* indent level */
@@ -2799,7 +2800,7 @@ static bAnimChannelType ACF_DSMCLIP =
static void acf_shapekey_name(bAnimListElem *ale, char *name)
{
KeyBlock *kb = (KeyBlock *)ale->data;
-
+
/* just copy the name... */
if (kb && name) {
/* if the KeyBlock had a name, use it, otherwise use the index */
@@ -2814,15 +2815,15 @@ static void acf_shapekey_name(bAnimListElem *ale, char *name)
static bool acf_shapekey_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
KeyBlock *kb = (KeyBlock *)ale->data;
-
+
/* if the KeyBlock had a name, use it, otherwise use the index */
if (kb && kb->name[0]) {
RNA_pointer_create(ale->id, &RNA_ShapeKey, kb, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
-
+
return false;
}
@@ -2834,7 +2835,7 @@ static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
case ACHANNEL_SETTING_MUTE: /* muted */
case ACHANNEL_SETTING_PROTECT: /* protected */
return true;
-
+
/* nothing else is supported */
default:
return false;
@@ -2846,17 +2847,17 @@ static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Sett
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_MUTE: /* mute */
return KEYBLOCK_MUTE;
-
+
case ACHANNEL_SETTING_SELECT: /* selected */
return KEYBLOCK_SEL;
-
+
case ACHANNEL_SETTING_PROTECT: /* locked */
return KEYBLOCK_LOCKED;
-
+
default: /* unsupported */
return 0;
}
@@ -2866,16 +2867,16 @@ static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Sett
static void *acf_shapekey_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
KeyBlock *kb = (KeyBlock *)ale->data;
-
+
/* clear extra return data first */
*type = 0;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted */
case ACHANNEL_SETTING_PROTECT: /* protected */
return GET_ACF_FLAG_PTR(kb->flag, type);
-
+
default: /* unsupported */
return NULL;
}
@@ -2886,7 +2887,7 @@ static bAnimChannelType ACF_SHAPEKEY =
{
"Shape Key", /* type name */
ACHANNEL_ROLE_CHANNEL, /* role */
-
+
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
@@ -2924,7 +2925,7 @@ static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSE
case ACHANNEL_SETTING_SELECT:
case ACHANNEL_SETTING_EXPAND:
return true;
-
+
default:
return false;
}
@@ -2935,14 +2936,14 @@ static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return AGRP_SELECTED;
-
+
case ACHANNEL_SETTING_EXPAND: /* expanded */
return GP_DATA_EXPAND;
-
+
default:
/* these shouldn't happen */
return 0;
@@ -2953,17 +2954,17 @@ static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings
static void *acf_gpd_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
bGPdata *gpd = (bGPdata *)ale->data;
-
+
/* all flags are just in gpd->flag for now... */
return GET_ACF_FLAG_PTR(gpd->flag, type);
}
/* gpencil datablock type define */
-static bAnimChannelType ACF_GPD =
+static bAnimChannelType ACF_GPD =
{
"GPencil Datablock", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_gpd_color, /* backdrop color */
acf_group_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
@@ -2984,7 +2985,7 @@ static bAnimChannelType ACF_GPD =
static void acf_gpl_name(bAnimListElem *ale, char *name)
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
+
if (gpl && name)
BLI_strncpy(name, gpl->info, ANIM_CHAN_NAME_SIZE);
}
@@ -2995,10 +2996,10 @@ static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA *
if (ale->data) {
RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
-
+
return false;
}
@@ -3010,7 +3011,7 @@ static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSE
case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */
case ACHANNEL_SETTING_SOLO: /* nla editor only */
return false;
-
+
/* always available */
default:
return true;
@@ -3022,21 +3023,21 @@ static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return GP_LAYER_SELECT;
-
+
case ACHANNEL_SETTING_MUTE: /* animation muting - similar to frame lock... */
return GP_LAYER_FRAMELOCK;
-
+
case ACHANNEL_SETTING_VISIBLE: /* visiblity of the layers (NOT muting) */
*neg = true;
return GP_LAYER_HIDE;
-
+
case ACHANNEL_SETTING_PROTECT: /* protected */
return GP_LAYER_LOCKED;
-
+
default: /* unsupported */
return 0;
}
@@ -3046,26 +3047,26 @@ static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings
static void *acf_gpl_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
+
/* all flags are just in gpl->flag for now... */
return GET_ACF_FLAG_PTR(gpl->flag, type);
}
/* grease pencil layer type define */
-static bAnimChannelType ACF_GPL =
+static bAnimChannelType ACF_GPL =
{
"GPencil Layer", /* type name */
ACHANNEL_ROLE_CHANNEL, /* role */
-
+
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_flexible, /* indent level */
acf_generic_group_offset, /* offset */
-
+
acf_gpl_name, /* name */
acf_gpl_name_prop, /* name prop */
NULL, /* icon */
-
+
acf_gpl_setting_valid, /* has setting */
acf_gpl_setting_flag, /* flag for setting */
acf_gpl_setting_ptr /* pointer for setting */
@@ -3095,7 +3096,7 @@ static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUS
case ACHANNEL_SETTING_SELECT:
case ACHANNEL_SETTING_EXPAND:
return true;
-
+
default:
return false;
}
@@ -3106,15 +3107,15 @@ static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return AGRP_SELECTED;
-
+
case ACHANNEL_SETTING_EXPAND: /* expanded */
return MASK_ANIMF_EXPAND;
-
- default:
+
+ default:
/* this shouldn't happen */
return 0;
}
@@ -3124,7 +3125,7 @@ static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings
static void *acf_mask_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
Mask *mask = (Mask *)ale->data;
-
+
/* all flags are just in mask->flag for now... */
return GET_ACF_FLAG_PTR(mask->flag, type);
}
@@ -3134,16 +3135,16 @@ static bAnimChannelType ACF_MASKDATA =
{
"Mask Datablock", /* type name */
ACHANNEL_ROLE_EXPANDER, /* role */
-
+
acf_mask_color, /* backdrop color */
acf_group_backdrop, /* backdrop */
acf_generic_indention_0, /* indent level */
acf_generic_group_offset, /* offset */
-
+
acf_generic_idblock_name, /* name */
acf_generic_idfill_name_prop, /* name prop */
acf_mask_icon, /* icon */
-
+
acf_mask_setting_valid, /* has setting */
acf_mask_setting_flag, /* flag for setting */
acf_mask_setting_ptr /* pointer for setting */
@@ -3155,7 +3156,7 @@ static bAnimChannelType ACF_MASKDATA =
static void acf_masklay_name(bAnimListElem *ale, char *name)
{
MaskLayer *masklay = (MaskLayer *)ale->data;
-
+
if (masklay && name)
BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE);
}
@@ -3166,7 +3167,7 @@ static bool acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyR
if (ale->data) {
RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
@@ -3182,7 +3183,7 @@ static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *U
case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
case ACHANNEL_SETTING_SOLO: /* nla editor only */
return false;
-
+
/* always available */
default:
return true;
@@ -3194,14 +3195,14 @@ static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setti
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return MASK_LAYERFLAG_SELECT;
-
+
case ACHANNEL_SETTING_PROTECT: /* protected */
return MASK_LAYERFLAG_LOCKED;
-
+
default: /* unsupported */
return 0;
}
@@ -3211,7 +3212,7 @@ static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Setti
static void *acf_masklay_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
{
MaskLayer *masklay = (MaskLayer *)ale->data;
-
+
/* all flags are just in masklay->flag for now... */
return GET_ACF_FLAG_PTR(masklay->flag, type);
}
@@ -3221,16 +3222,16 @@ static bAnimChannelType ACF_MASKLAYER =
{
"Mask Layer", /* type name */
ACHANNEL_ROLE_CHANNEL, /* role */
-
+
acf_generic_channel_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_flexible, /* indent level */
acf_generic_group_offset, /* offset */
-
+
acf_masklay_name, /* name */
acf_masklay_name_prop, /* name prop */
NULL, /* icon */
-
+
acf_masklay_setting_valid, /* has setting */
acf_masklay_setting_flag, /* flag for setting */
acf_masklay_setting_ptr /* pointer for setting */
@@ -3244,7 +3245,7 @@ static void acf_nlatrack_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, flo
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
bool nonSolo = false;
-
+
/* is track enabled for solo drawing? */
if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) {
if ((nlt->flag & NLATRACK_SOLO) == 0) {
@@ -3252,7 +3253,7 @@ static void acf_nlatrack_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, flo
nonSolo = true;
}
}
-
+
/* set color for nla track */
UI_GetThemeColorShade3fv(TH_HEADER, ((nonSolo == false) ? 20 : -20), r_color);
}
@@ -3261,7 +3262,7 @@ static void acf_nlatrack_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, flo
static void acf_nlatrack_name(bAnimListElem *ale, char *name)
{
NlaTrack *nlt = (NlaTrack *)ale->data;
-
+
if (nlt && name)
BLI_strncpy(name, nlt->name, ANIM_CHAN_NAME_SIZE);
}
@@ -3272,10 +3273,10 @@ static bool acf_nlatrack_name_prop(bAnimListElem *ale, PointerRNA *ptr, Property
if (ale->data) {
RNA_pointer_create(ale->id, &RNA_NlaTrack, ale->data, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
-
+
return false;
}
@@ -3284,14 +3285,14 @@ static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
{
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
-
+
/* visibility of settings depends on various states... */
switch (setting) {
/* always supported */
case ACHANNEL_SETTING_SELECT:
case ACHANNEL_SETTING_SOLO:
return true;
-
+
/* conditionally supported... */
case ACHANNEL_SETTING_PROTECT:
case ACHANNEL_SETTING_MUTE:
@@ -3308,8 +3309,8 @@ static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
return false;
}
}
-
-
+
+
/* ok - no tracks are solo'd, and this isn't being tweaked */
return true;
}
@@ -3317,7 +3318,7 @@ static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *
/* unsupported - this track is being tweaked */
return false;
}
-
+
/* unsupported */
default:
return false;
@@ -3329,20 +3330,20 @@ static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Sett
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
return NLATRACK_SELECTED;
-
+
case ACHANNEL_SETTING_MUTE: /* muted */
return NLATRACK_MUTED;
-
+
case ACHANNEL_SETTING_PROTECT: /* protected */
return NLATRACK_PROTECTED;
-
+
case ACHANNEL_SETTING_SOLO: /* solo */
return NLATRACK_SOLO;
-
+
default: /* unsupported */
return 0;
}
@@ -3356,20 +3357,20 @@ static void *acf_nlatrack_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings
}
/* nla track type define */
-static bAnimChannelType ACF_NLATRACK =
+static bAnimChannelType ACF_NLATRACK =
{
"NLA Track", /* type name */
ACHANNEL_ROLE_CHANNEL, /* role */
-
+
acf_nlatrack_color, /* backdrop color */
acf_generic_channel_backdrop, /* backdrop */
acf_generic_indention_flexible, /* indent level */
acf_generic_group_offset, /* offset */ // XXX?
-
+
acf_nlatrack_name, /* name */
acf_nlatrack_name_prop, /* name prop */
NULL, /* icon */
-
+
acf_nlatrack_setting_valid, /* has setting */
acf_nlatrack_setting_flag, /* flag for setting */
acf_nlatrack_setting_ptr /* pointer for setting */
@@ -3381,7 +3382,7 @@ static bAnimChannelType ACF_NLATRACK =
static int acf_nlaaction_icon(bAnimListElem *ale)
{
AnimData *adt = ale->adt;
-
+
/* indicate tweaking-action state by changing the icon... */
if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
return ICON_ACTION_TWEAK;
@@ -3391,28 +3392,28 @@ static int acf_nlaaction_icon(bAnimListElem *ale)
}
}
-/* Backdrop color for nla action channel
+/* Backdrop color for nla action channel
* Although this can't be used directly for NLA Action drawing,
* it is still needed for use behind the RHS toggles
*/
static void acf_nlaaction_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float r_color[3])
{
float color[4];
-
+
/* Action Line
- * The alpha values action_get_color returns are only useful for drawing
+ * The alpha values action_get_color returns are only useful for drawing
* strips backgrounds but here we're doing channel list backgrounds instead
* so we ignore that and use our own when needed
*/
nla_action_get_color(ale->adt, (bAction *)ale->data, color);
-
+
/* NOTE: since the return types only allow rgb, we cannot do the alpha-blending we'd
* like for the solo-drawing case. Hence, this method isn't actually used for drawing
* most of the channel...
*/
copy_v3_v3(r_color, color);
}
-
+
/* backdrop for nla action channel */
static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
@@ -3421,14 +3422,14 @@ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float y
AnimData *adt = ale->adt;
short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
float color[4];
-
+
/* Action Line
- * The alpha values action_get_color returns are only useful for drawing
+ * The alpha values action_get_color returns are only useful for drawing
* strips backgrounds but here we're doing channel list backgrounds instead
* so we ignore that and use our own when needed
*/
nla_action_get_color(adt, (bAction *)ale->data, color);
-
+
if (adt && (adt->flag & ADT_NLA_EDIT_ON))
color[3] = 1.0f;
else
@@ -3449,7 +3450,7 @@ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float y
static void acf_nlaaction_name(bAnimListElem *ale, char *name)
{
bAction *act = (bAction *)ale->data;
-
+
if (name) {
if (act) {
// TODO: add special decoration when doing this in tweaking mode?
@@ -3467,10 +3468,10 @@ static bool acf_nlaaction_name_prop(bAnimListElem *ale, PointerRNA *ptr, Propert
if (ale->data) {
RNA_pointer_create(ale->id, &RNA_Action, ale->data, ptr);
*prop = RNA_struct_name_property(ptr->type);
-
+
return (*prop != NULL);
}
-
+
return false;
}
@@ -3478,7 +3479,7 @@ static bool acf_nlaaction_name_prop(bAnimListElem *ale, PointerRNA *ptr, Propert
static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, eAnimChannel_Settings setting)
{
AnimData *adt = ale->adt;
-
+
/* visibility of settings depends on various states... */
switch (setting) {
/* conditionally supported */
@@ -3490,7 +3491,7 @@ static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem
else {
return false;
}
-
+
/* unsupported */
default:
return false;
@@ -3502,12 +3503,12 @@ static int acf_nlaaction_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Set
{
/* clear extra return data first */
*neg = false;
-
+
switch (setting) {
case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
*neg = true; // XXX
return ADT_NLA_EDIT_NOMAP;
-
+
default: /* unsupported */
return 0;
}
@@ -3521,20 +3522,20 @@ static void *acf_nlaaction_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings
}
/* nla action type define */
-static bAnimChannelType ACF_NLAACTION =
+static bAnimChannelType ACF_NLAACTION =
{
"NLA Active Action", /* type name */
ACHANNEL_ROLE_CHANNEL, /* role */
-
+
acf_nlaaction_color, /* backdrop color (NOTE: the backdrop handles this too, since it needs special hacks) */
acf_nlaaction_backdrop, /* backdrop */
acf_generic_indention_flexible, /* indent level */
acf_generic_group_offset, /* offset */ // XXX?
-
+
acf_nlaaction_name, /* name */
acf_nlaaction_name_prop, /* name prop */
acf_nlaaction_icon, /* icon */
-
+
acf_nlaaction_setting_valid, /* has setting */
acf_nlaaction_setting_flag, /* flag for setting */
acf_nlaaction_setting_ptr /* pointer for setting */
@@ -3552,31 +3553,31 @@ static short ACF_INIT = 1; /* when non-zero, the list needs to be updated */
static void ANIM_init_channel_typeinfo_data(void)
{
int type = 0;
-
+
/* start initializing if necessary... */
if (ACF_INIT) {
ACF_INIT = 0;
-
+
/* NOTE: need to keep the order of these synchronized with the definition of
* channel types (eAnim_ChannelType) in ED_anim_api.h
*/
animchannelTypeInfo[type++] = NULL; /* None */
animchannelTypeInfo[type++] = NULL; /* AnimData */
animchannelTypeInfo[type++] = NULL; /* Special */
-
+
animchannelTypeInfo[type++] = &ACF_SUMMARY; /* Motion Summary */
-
+
animchannelTypeInfo[type++] = &ACF_SCENE; /* Scene */
animchannelTypeInfo[type++] = &ACF_OBJECT; /* Object */
animchannelTypeInfo[type++] = &ACF_GROUP; /* Group */
animchannelTypeInfo[type++] = &ACF_FCURVE; /* F-Curve */
-
+
animchannelTypeInfo[type++] = &ACF_NLACONTROLS; /* NLA Control FCurve Expander */
animchannelTypeInfo[type++] = &ACF_NLACURVE; /* NLA Control FCurve Channel */
-
+
animchannelTypeInfo[type++] = &ACF_FILLACTD; /* Object Action Expander */
animchannelTypeInfo[type++] = &ACF_FILLDRIVERS; /* Drivers Expander */
-
+
animchannelTypeInfo[type++] = &ACF_DSMAT; /* Material Channel */
animchannelTypeInfo[type++] = &ACF_DSLAM; /* Lamp Channel */
animchannelTypeInfo[type++] = &ACF_DSCAM; /* Camera Channel */
@@ -3595,19 +3596,19 @@ static void ANIM_init_channel_typeinfo_data(void)
animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */
animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */
animchannelTypeInfo[type++] = &ACF_DSMCLIP; /* MovieClip Channel */
-
+
animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */
-
+
animchannelTypeInfo[type++] = &ACF_GPD; /* Grease Pencil Datablock */
animchannelTypeInfo[type++] = &ACF_GPL; /* Grease Pencil Layer */
-
+
animchannelTypeInfo[type++] = &ACF_MASKDATA; /* Mask Datablock */
animchannelTypeInfo[type++] = &ACF_MASKLAYER; /* Mask Layer */
-
+
animchannelTypeInfo[type++] = &ACF_NLATRACK; /* NLA Track */
animchannelTypeInfo[type++] = &ACF_NLAACTION; /* NLA Action */
}
-}
+}
/* Get type info from given channel type */
const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale)
@@ -3615,10 +3616,10 @@ const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale)
/* santiy checks */
if (ale == NULL)
return NULL;
-
+
/* init the typeinfo if not available yet... */
ANIM_init_channel_typeinfo_data();
-
+
/* check if type is in bounds... */
if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES))
return animchannelTypeInfo[ale->type];
@@ -3632,21 +3633,21 @@ const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale)
void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level)
{
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
+
/* print indents */
for (; indent_level > 0; indent_level--)
printf(" ");
-
+
/* print info */
if (acf) {
char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
-
+
/* get UI name */
if (acf->name)
acf->name(ale, name);
else
BLI_strncpy(name, "<No name>", sizeof(name));
-
+
/* print type name + ui name */
printf("ChanType: <%s> Name: \"%s\"\n", acf->channel_type_name, name);
}
@@ -3658,13 +3659,13 @@ void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level)
/* --------------------------- */
-/* Check if some setting for a channel is enabled
+/* Check if some setting for a channel is enabled
* Returns: 1 = On, 0 = Off, -1 = Invalid
*/
short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
+
/* 1) check that the setting exists for the current context */
if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
/* 2) get pointer to check for flag in, and the flag to check for */
@@ -3672,17 +3673,17 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne
bool negflag;
int flag;
void *ptr;
-
+
flag = acf->setting_flag(ac, setting, &negflag);
ptr = acf->setting_ptr(ale, setting, &ptrsize);
-
+
/* check if flag is enabled */
if (ptr && flag) {
switch (ptrsize) {
case sizeof(int): /* integer pointer for setting */
{
const int *val = (int *)ptr;
-
+
if (negflag)
return ((*val) & flag) == 0;
else
@@ -3691,7 +3692,7 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne
case sizeof(short): /* short pointer for setting */
{
const short *val = (short *)ptr;
-
+
if (negflag)
return ((*val) & flag) == 0;
else
@@ -3700,7 +3701,7 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne
case sizeof(char): /* char pointer for setting */
{
const char *val = (char *)ptr;
-
+
if (negflag)
return ((*val) & flag) == 0;
else
@@ -3709,10 +3710,10 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne
}
}
}
-
+
/* not found... */
return -1;
-}
+}
/* quick macro for use in ANIM_channel_setting_set - set flag for setting according the mode given */
@@ -3730,14 +3731,14 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne
} \
} (void)0
-/* Change value of some setting for a channel
+/* Change value of some setting for a channel
* - setting: eAnimChannel_Settings
* - mode: eAnimChannels_SetFlag
*/
void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode)
{
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
+
/* 1) check that the setting exists for the current context */
if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
/* 2) get pointer to check for flag in, and the flag to check for */
@@ -3745,10 +3746,10 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, eAnimChannel
bool negflag;
int flag;
void *ptr;
-
+
flag = acf->setting_flag(ac, setting, &negflag);
ptr = acf->setting_ptr(ale, setting, &ptrsize);
-
+
/* check if flag is enabled */
if (ptr && flag) {
switch (ptrsize) {
@@ -3794,7 +3795,7 @@ static bool achannel_is_being_renamed(const bAnimContext *ac, const bAnimChannel
return true;
}
}
-
+
/* not being renamed */
return false;
}
@@ -3807,52 +3808,52 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
View2D *v2d = &ac->ar->v2d;
short selected, offset;
float y, ymid, ytext;
-
+
/* sanity checks - don't draw anything */
if (ELEM(NULL, acf, ale))
return;
-
+
/* get initial offset */
if (acf->get_offset)
offset = acf->get_offset(ac, ale);
else
offset = 0;
-
+
/* calculate appropriate y-coordinates for icon buttons */
y = (ymaxc - yminc) / 2 + yminc;
ymid = y - 0.5f * ICON_WIDTH;
/* y-coordinates for text is only 4 down from middle */
ytext = y - 0.2f * U.widget_unit;
-
+
/* check if channel is selected */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
selected = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
else
selected = 0;
-
+
/* set blending again, as may not be set in previous step */
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
+
/* step 1) draw backdrop ........................................... */
if (acf->draw_backdrop)
acf->draw_backdrop(ac, ale, yminc, ymaxc);
-
+
/* step 2) draw expand widget ....................................... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
/* just skip - drawn as widget now */
- offset += ICON_WIDTH;
+ offset += ICON_WIDTH;
}
-
+
/* step 3) draw icon ............................................... */
if (acf->icon) {
UI_icon_draw(offset, ymid, acf->icon(ale));
- offset += ICON_WIDTH;
+ offset += ICON_WIDTH;
}
-
+
/* turn off blending, since not needed anymore... */
glDisable(GL_BLEND);
-
+
/* step 4) draw special toggles .................................
* - in Graph Editor, checkboxes for visibility in curves area
* - in NLA Editor, glowing dots for solo/not solo...
@@ -3869,12 +3870,12 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever
- * color the curve has stored
+
+ /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever
+ * color the curve has stored
*/
immUniformColor3fv(fcu->color);
-
+
/* just a solid color rect
*/
immRectf(pos, offset, yminc, offset + ICON_WIDTH, ymaxc);
@@ -3891,7 +3892,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
}
else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
/* just skip - drawn as widget now */
- offset += ICON_WIDTH;
+ offset += ICON_WIDTH;
}
else if (ale->type == ANIMTYPE_GPLAYER) {
/* just skip - drawn as a widget */
@@ -3900,7 +3901,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
}
/* step 5) draw name ............................................... */
- /* Don't draw this if renaming... */
+ /* Don't draw this if renaming... */
if (acf->name && !achannel_is_being_renamed(ac, acf, channel_index)) {
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
@@ -3916,10 +3917,10 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* get name */
acf->name(ale, name);
-
+
offset += 3;
UI_fontstyle_draw_simple(fstyle, offset, ytext, name, col);
-
+
/* draw red underline if channel is disabled */
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE) && (ale->flag & FCURVE_DISABLED)) {
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -3953,11 +3954,11 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
+
/* get and set backdrop color */
acf->get_backdrop_color(ac, ale, color);
immUniformColor3fv(color);
-
+
/* check if we need to show the sliders */
if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_IPO)) {
switch (ac->spacetype) {
@@ -3981,24 +3982,24 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* protect... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT))
offset += ICON_WIDTH;
-
+
/* mute... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE))
offset += ICON_WIDTH;
if (ale->type == ANIMTYPE_GPLAYER)
offset += ICON_WIDTH;
-
+
/* pinned... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED))
offset += ICON_WIDTH;
-
+
/* NOTE: technically, NLA Action "pushdown" should be here too, but there are no sliders there */
-
+
/* NLA action channels have slightly different spacing requirements... */
if (ale->type == ANIMTYPE_NLAACTION)
ymin_ofs = NLACHANNEL_SKIP;
}
-
+
/* draw slider
* - even if we can draw sliders for this view, we must also check that the channel-type supports them
* (only only F-Curves really can support them for now)
@@ -4008,10 +4009,10 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* adjust offset */
offset += SLIDER_WIDTH;
}
-
-
+
+
/* finally draw a backdrop rect behind these
- * - starts from the point where the first toggle/slider starts,
+ * - starts from the point where the first toggle/slider starts,
* - ends past the space that might be reserved for a scroller
*/
immRectf(pos, v2d->cur.xmax - (float)offset, yminc + ymin_ofs, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
@@ -4037,7 +4038,7 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void
int filter;
int setting = GET_INT_FROM_POINTER(setting_wrap);
short on = 0;
-
+
/* send notifiers before doing anything else... */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
@@ -4048,7 +4049,7 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void
if (ale_setting->type == ANIMTYPE_GPLAYER)
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
-
+
/* tag copy-on-write flushing (so that the settings will have an effect) */
if (ale_setting->id) {
DEG_id_tag_update(ale_setting->id, DEG_TAG_COPY_ON_WRITE);
@@ -4057,11 +4058,11 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void
/* action is it's own datablock, so has to be tagged specifically... */
DEG_id_tag_update(&ale_setting->adt->action->id, DEG_TAG_COPY_ON_WRITE);
}
-
+
/* verify animation context */
if (ANIM_animdata_get_context(C, &ac) == 0)
return;
-
+
/* check if the setting is on... */
on = ANIM_channel_setting_get(&ac, ale_setting, setting);
@@ -4069,14 +4070,14 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void
if (on == -1) {
return;
}
-
+
/* get all channels that can possibly be chosen - but ignore hierarchy */
filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* call API method to flush the setting */
ANIM_flush_setting_anim_channels(&ac, &anim_data, ale_setting, setting, on);
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
}
@@ -4086,7 +4087,7 @@ static void achannel_nlatrack_solo_widget_cb(bContext *C, void *adt_poin, void *
{
AnimData *adt = adt_poin;
NlaTrack *nlt = nlt_poin;
-
+
/* Toggle 'solo' mode. There are several complications here which need explaining:
* - The method call is needed to perform a few additional validation operations
* to ensure that the mode is applied properly
@@ -4096,7 +4097,7 @@ static void achannel_nlatrack_solo_widget_cb(bContext *C, void *adt_poin, void *
*/
nlt->flag ^= NLATRACK_SOLO;
BKE_nlatrack_solo_toggle(adt, nlt);
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
}
@@ -4107,7 +4108,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
ID *id = (ID *)id_poin;
AnimData *adt = BKE_animdata_from_id(id);
FCurve *fcu = (FCurve *)fcu_poin;
-
+
Depsgraph *depsgraph = CTX_data_depsgraph(C);
ReportList *reports = CTX_wm_reports(C);
Scene *scene = CTX_data_scene(C);
@@ -4117,25 +4118,25 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
short flag = 0;
bool done = false;
float cfra;
-
+
/* get current frame and apply NLA-mapping to it (if applicable) */
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
-
+
/* get flags for keyframing */
flag = ANIM_get_keyframing_flags(scene, 1);
-
+
/* get RNA pointer, and resolve the path */
RNA_id_pointer_create(id, &id_ptr);
-
+
/* try to resolve the path stored in the F-Curve */
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
/* set the special 'replace' flag if on a keyframe */
if (fcurve_frame_has_keyframe(fcu, cfra, 0))
flag |= INSERTKEY_REPLACE;
-
+
/* insert a keyframe for this F-Curve */
done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, flag);
-
+
if (done)
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
@@ -4144,10 +4145,11 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
/* callback for shapekey widget sliders - insert keyframes */
static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, void *kb_poin)
{
+ Main *bmain = CTX_data_main(C);
Key *key = (Key *)key_poin;
KeyBlock *kb = (KeyBlock *)kb_poin;
char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
-
+
Depsgraph *depsgraph = CTX_data_depsgraph(C);
ReportList *reports = CTX_wm_reports(C);
Scene *scene = CTX_data_scene(C);
@@ -4157,34 +4159,34 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
short flag = 0;
bool done = false;
float cfra;
-
+
/* get current frame and apply NLA-mapping to it (if applicable) */
cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
-
+
/* get flags for keyframing */
flag = ANIM_get_keyframing_flags(scene, 1);
-
+
/* get RNA pointer, and resolve the path */
RNA_id_pointer_create((ID *)key, &id_ptr);
-
+
/* try to resolve the path stored in the F-Curve */
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
/* find or create new F-Curve */
// XXX is the group name for this ok?
- bAction *act = verify_adt_action((ID *)key, 1);
+ bAction *act = verify_adt_action(bmain, (ID *)key, 1);
FCurve *fcu = verify_fcurve(act, NULL, &ptr, rna_path, 0, 1);
-
+
/* set the special 'replace' flag if on a keyframe */
if (fcurve_frame_has_keyframe(fcu, cfra, 0))
flag |= INSERTKEY_REPLACE;
-
+
/* insert a keyframe for this F-Curve */
done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, flag);
-
+
if (done)
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
-
+
/* free the path */
if (rna_path)
MEM_freeN(rna_path);
@@ -4195,11 +4197,11 @@ static void achannel_setting_slider_nla_curve_cb(bContext *C, void *UNUSED(id_po
{
/* ID *id = (ID *)id_poin; */
FCurve *fcu = (FCurve *)fcu_poin;
-
+
PointerRNA ptr;
PropertyRNA *prop;
int index;
-
+
Depsgraph *depsgraph = CTX_data_depsgraph(C);
ReportList *reports = CTX_wm_reports(C);
Scene *scene = CTX_data_scene(C);
@@ -4207,24 +4209,24 @@ static void achannel_setting_slider_nla_curve_cb(bContext *C, void *UNUSED(id_po
short flag = 0;
bool done = false;
float cfra;
-
+
/* get current frame - *no* NLA mapping should be done */
cfra = (float)CFRA;
-
+
/* get flags for keyframing */
flag = ANIM_get_keyframing_flags(scene, 1);
-
+
/* get pointer and property from the slider - this should all match up with the NlaStrip required... */
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
+
if (fcu && prop) {
/* set the special 'replace' flag if on a keyframe */
if (fcurve_frame_has_keyframe(fcu, cfra, 0))
flag |= INSERTKEY_REPLACE;
-
+
/* insert a keyframe for this F-Curve */
done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, flag);
-
+
if (done)
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
@@ -4241,18 +4243,18 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, const bAni
void *ptr;
const char *tooltip;
uiBut *but = NULL;
-
+
/* get the flag and the pointer to that flag */
flag = acf->setting_flag(ac, setting, &negflag);
ptr = acf->setting_ptr(ale, setting, &ptrsize);
/* enabled = ANIM_channel_setting_get(ac, ale, setting); */ /* UNUSED */
-
+
/* get the base icon for the setting */
switch (setting) {
case ACHANNEL_SETTING_VISIBLE: /* visibility eyes */
//icon = ((enabled) ? ICON_VISIBLE_IPO_ON : ICON_VISIBLE_IPO_OFF);
icon = ICON_VISIBLE_IPO_OFF;
-
+
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE))
tooltip = TIP_("F-Curve is visible in Graph Editor for editing");
else if (ale->type == ANIMTYPE_GPLAYER)
@@ -4277,30 +4279,30 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, const bAni
icon = ICON_TRIA_RIGHT;
tooltip = TIP_("Make channels grouped under this channel visible");
break;
-
+
case ACHANNEL_SETTING_SOLO: /* NLA Tracks only */
//icon = ((enabled) ? ICON_SOLO_OFF : ICON_SOLO_ON);
icon = ICON_SOLO_OFF;
tooltip = TIP_("NLA Track is the only one evaluated in this animation data-block, with all others muted");
break;
-
+
/* --- */
-
+
case ACHANNEL_SETTING_PROTECT: /* protected lock */
// TODO: what about when there's no protect needed?
//icon = ((enabled) ? ICON_LOCKED : ICON_UNLOCKED);
icon = ICON_UNLOCKED;
-
+
if (ale->datatype != ALE_NLASTRIP)
tooltip = TIP_("Editability of keyframes for this channel");
else
tooltip = TIP_("Editability of NLA Strips in this track");
break;
-
+
case ACHANNEL_SETTING_MUTE: /* muted speaker */
//icon = ((enabled) ? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF);
icon = ICON_MUTE_IPO_OFF;
-
+
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
tooltip = TIP_("Does F-Curve contribute to result");
}
@@ -4314,11 +4316,11 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, const bAni
tooltip = TIP_("Do channels contribute to result (toggle channel muting)");
}
break;
-
+
case ACHANNEL_SETTING_PINNED: /* pin icon */
//icon = ((enabled) ? ICON_PINNED : ICON_UNPINNED);
icon = ICON_UNPINNED;
-
+
if (ale->type == ANIMTYPE_NLAACTION) {
tooltip = TIP_("Display action without any time remapping (when unpinned)");
}
@@ -4327,13 +4329,13 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, const bAni
tooltip = NULL;
}
break;
-
+
default:
tooltip = NULL;
icon = 0;
break;
}
-
+
/* type of button */
if (usetoggle) {
if (negflag)
@@ -4351,21 +4353,21 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, const bAni
if (ptr && flag) {
switch (ptrsize) {
case sizeof(int): /* integer pointer for setting */
- but = uiDefIconButBitI(block, butType, flag, 0, icon,
+ but = uiDefIconButBitI(block, butType, flag, 0, icon,
xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
break;
-
+
case sizeof(short): /* short pointer for setting */
- but = uiDefIconButBitS(block, butType, flag, 0, icon,
+ but = uiDefIconButBitS(block, butType, flag, 0, icon,
xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
break;
-
+
case sizeof(char): /* char pointer for setting */
- but = uiDefIconButBitC(block, butType, flag, 0, icon,
+ but = uiDefIconButBitC(block, butType, flag, 0, icon,
xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
break;
}
-
+
/* set call to send relevant notifiers and/or perform type-specific updates */
if (but) {
switch (setting) {
@@ -4378,12 +4380,12 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, const bAni
case ACHANNEL_SETTING_ALWAYS_VISIBLE:
UI_but_funcN_set(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting));
break;
-
+
/* settings needing special attention */
case ACHANNEL_SETTING_SOLO: /* NLA Tracks - Solo toggle */
UI_but_func_set(but, achannel_nlatrack_solo_widget_cb, ale->adt, ale->data);
break;
-
+
/* no flushing */
case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush, otherwise all would open/close at once */
default:
@@ -4402,37 +4404,37 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
float y, ymid /*, ytext*/;
short offset;
const bool is_being_renamed = achannel_is_being_renamed(ac, acf, channel_index);
-
+
/* sanity checks - don't draw anything */
if (ELEM(NULL, acf, ale, block))
return;
-
+
/* get initial offset */
if (acf->get_offset)
offset = acf->get_offset(ac, ale);
else
offset = 0;
-
- /* calculate appropriate y-coordinates for icon buttons
+
+ /* calculate appropriate y-coordinates for icon buttons
*/
y = (ymaxc - yminc) / 2 + yminc;
ymid = y - 0.5f * ICON_WIDTH;
-
+
/* no button backdrop behind icons */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
+
/* step 1) draw expand widget ....................................... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_EXPAND);
- offset += ICON_WIDTH;
+ offset += ICON_WIDTH;
}
-
+
/* step 2) draw icon ............................................... */
if (acf->icon) {
/* icon is not drawn here (not a widget) */
- offset += ICON_WIDTH;
+ offset += ICON_WIDTH;
}
-
+
/* step 3) draw special toggles .................................
* - in Graph Editor, checkboxes for visibility in curves area
* - in NLA Editor, glowing dots for solo/not solo...
@@ -4457,7 +4459,7 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
/* 'solo' setting for NLA Tracks */
draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_SOLO);
- offset += ICON_WIDTH;
+ offset += ICON_WIDTH;
}
else if (ale->type == ANIMTYPE_GPLAYER) {
#if 0
@@ -4466,18 +4468,18 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
bGPDlayer *gpl = (bGPDlayer *)ale->data;
PointerRNA ptr;
float w = ICON_WIDTH / 2.0f;
-
+
RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr);
-
+
UI_block_align_begin(block);
UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_stroke_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
- uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset, yminc, w, ICON_WIDTH,
- &ptr, "color", -1,
+ uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset, yminc, w, ICON_WIDTH,
+ &ptr, "color", -1,
0, 0, 0, 0, gpl->info);
-
+
UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_fill_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
- uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset + w, yminc, w, ICON_WIDTH,
- &ptr, "fill_color", -1,
+ uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset + w, yminc, w, ICON_WIDTH,
+ &ptr, "fill_color", -1,
0, 0, 0, 0, gpl->info);
UI_block_emboss_set(block, UI_EMBOSS_NONE);
UI_block_align_end(block);
@@ -4486,14 +4488,14 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
#endif
}
}
-
+
/* step 4) draw text - check if renaming widget is in use... */
if (is_being_renamed) {
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
-
- /* draw renaming widget if we can get RNA pointer for it
- * NOTE: property may only be available in some cases, even if we have
+
+ /* draw renaming widget if we can get RNA pointer for it
+ * NOTE: property may only be available in some cases, even if we have
* a callback available (e.g. broken F-Curve rename)
*/
if (acf->name_prop(ale, &ptr, &prop)) {
@@ -4501,21 +4503,21 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
const short channel_height = round_fl_to_int(ymaxc - yminc);
const short width = ac->ar->winx - offset - (margin_x * 2);
uiBut *but;
-
+
UI_block_emboss_set(block, UI_EMBOSS);
-
+
but = uiDefButR(block, UI_BTYPE_TEXT, 1, "", offset + margin_x, yminc,
MAX2(width, RENAME_TEXT_MIN_WIDTH), channel_height,
&ptr, RNA_property_identifier(prop), -1, 0, 0, -1, -1, NULL);
-
+
/* copy what outliner does here, see outliner_buttons */
if (UI_but_active_only(C, ac->ar, block, but) == false) {
ac->ads->renameIndex = 0;
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
}
-
+
UI_block_emboss_set(block, UI_EMBOSS_NONE);
}
else {
@@ -4526,15 +4528,15 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
}
}
-
+
/* step 5) draw mute+protection toggles + (sliders) ....................... */
/* reset offset - now goes from RHS of panel */
offset = 0;
-
+
// TODO: when drawing sliders, make those draw instead of these toggles if not enough space
if (v2d && !is_being_renamed) {
short draw_sliders = 0;
-
+
/* check if we need to show the sliders */
if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_IPO)) {
switch (ac->spacetype) {
@@ -4552,12 +4554,12 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
}
}
}
-
+
/* check if there's enough space for the toggles if the sliders are drawn too */
if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2) ) {
/* protect... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
- offset += ICON_WIDTH;
+ offset += ICON_WIDTH;
draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax - offset, ymid, ACHANNEL_SETTING_PROTECT);
}
/* mute... */
@@ -4570,43 +4572,43 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
offset += ICON_WIDTH;
draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax - offset, ymid, ACHANNEL_SETTING_VISIBLE);
}
-
+
/* modifiers disable */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MOD_OFF)) {
offset += ICON_WIDTH * 1.2f; /* hack: extra spacing, to avoid touching the mute toggle */
draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax - offset, ymid, ACHANNEL_SETTING_MOD_OFF);
}
-
+
/* ----------- */
-
+
/* pinned... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED)) {
offset += ICON_WIDTH;
draw_setting_widget(ac, ale, acf, block, (int)v2d->cur.xmax - offset, ymid, ACHANNEL_SETTING_PINNED);
}
-
+
/* NLA Action "pushdown" */
if ((ale->type == ANIMTYPE_NLAACTION) && (ale->adt && ale->adt->action) && !(ale->adt->flag & ADT_NLA_EDIT_ON)) {
uiBut *but;
PointerRNA *opptr_b;
-
+
UI_block_emboss_set(block, UI_EMBOSS);
-
+
offset += UI_UNIT_X;
- but = uiDefIconButO(block, UI_BTYPE_BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN,
+ but = uiDefIconButO(block, UI_BTYPE_BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN,
(int)v2d->cur.xmax - offset, ymid, UI_UNIT_X, UI_UNIT_X, NULL);
-
+
opptr_b = UI_but_operator_ptr_get(but);
RNA_int_set(opptr_b, "channel_index", channel_index);
-
+
UI_block_emboss_set(block, UI_EMBOSS_NONE);
}
}
-
+
/* draw slider
* - even if we can draw sliders for this view, we must also check that the channel-type supports them
* (only only F-Curves really can support them for now)
- * - to make things easier, we use RNA-autobuts for this so that changes are reflected immediately,
+ * - to make things easier, we use RNA-autobuts for this so that changes are reflected immediately,
* wherever they occurred. BUT, we don't use the layout engine, otherwise we'd get wrong alignment,
* and wouldn't be able to auto-keyframe...
* - slider should start before the toggles (if they're visible) to keep a clean line down the side
@@ -4615,25 +4617,25 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
/* adjust offset */
// TODO: make slider width dynamic, so that they can be easier to use when the view is wide enough
offset += SLIDER_WIDTH;
-
+
/* need backdrop behind sliders... */
UI_block_emboss_set(block, UI_EMBOSS);
-
+
if (ale->owner) { /* Slider using custom RNA Access ---------- */
if (ale->type == ANIMTYPE_NLACURVE) {
NlaStrip *strip = (NlaStrip *)ale->owner;
FCurve *fcu = (FCurve *)ale->data;
PointerRNA ptr;
PropertyRNA *prop;
-
+
/* create RNA pointers */
RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, &ptr);
prop = RNA_struct_find_property(&ptr, fcu->rna_path);
-
+
/* create property slider */
if (prop) {
uiBut *but;
-
+
/* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
but = uiDefAutoButR(block, &ptr, prop, fcu->array_index, "", ICON_NONE, (int)v2d->cur.xmax - offset, ymid, SLIDER_WIDTH, (int)ymaxc - yminc);
UI_but_func_set(but, achannel_setting_slider_nla_curve_cb, ale->id, ale->data);
@@ -4646,41 +4648,41 @@ void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListEle
char *rna_path = NULL;
int array_index = 0;
short free_path = 0;
-
+
/* get destination info */
if (ale->type == ANIMTYPE_FCURVE) {
FCurve *fcu = (FCurve *)ale->data;
-
+
rna_path = fcu->rna_path;
array_index = fcu->array_index;
}
else if (ale->type == ANIMTYPE_SHAPEKEY) {
KeyBlock *kb = (KeyBlock *)ale->data;
Key *key = (Key *)ale->id;
-
+
rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
free_path = 1;
}
-
+
/* only if RNA-Path found */
if (rna_path) {
/* get RNA pointer, and resolve the path */
RNA_id_pointer_create(ale->id, &id_ptr);
-
+
/* try to resolve the path */
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
uiBut *but;
-
+
/* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
but = uiDefAutoButR(block, &ptr, prop, array_index, "", ICON_NONE, (int)v2d->cur.xmax - offset, ymid, SLIDER_WIDTH, (int)ymaxc - yminc);
-
+
/* assign keyframing function according to slider type */
if (ale->type == ANIMTYPE_SHAPEKEY)
UI_but_func_set(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
else
UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data);
}
-
+
/* free the path if necessary */
if (free_path)
MEM_freeN(rna_path);
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 6d9a2d3b2b7..ebe977420c6 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -30,7 +30,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
+#include <string.h>
#include "MEM_guardedalloc.h"
@@ -82,24 +82,24 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
-
+
/* try to build list of filtered items */
ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
if (BLI_listbase_is_empty(&anim_data))
return;
-
+
/* only clear the 'active' flag for the channels of the same type */
for (ale = anim_data.first; ale; ale = ale->next) {
/* skip if types don't match */
if (channel_type != ale->type)
continue;
-
+
/* flag to set depends on type */
switch (ale->type) {
case ANIMTYPE_GROUP:
{
bActionGroup *agrp = (bActionGroup *)ale->data;
-
+
ACHANNEL_SET_FLAG(agrp, ACHANNEL_SETFLAG_CLEAR, AGRP_ACTIVE);
break;
}
@@ -107,14 +107,14 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
case ANIMTYPE_NLACURVE:
{
FCurve *fcu = (FCurve *)ale->data;
-
+
ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE);
break;
}
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt = (NlaTrack *)ale->data;
-
+
ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE);
break;
}
@@ -146,13 +146,13 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
case ANIMTYPE_GPLAYER:
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
+
ACHANNEL_SET_FLAG(gpl, ACHANNEL_SETFLAG_CLEAR, GP_LAYER_ACTIVE);
break;
}
}
}
-
+
/* set active flag */
if (channel_data) {
switch (channel_type) {
@@ -201,26 +201,26 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
}
break;
}
-
+
case ANIMTYPE_GPLAYER:
{
bGPDlayer *gpl = (bGPDlayer *)channel_data;
gpl->flag |= GP_LAYER_ACTIVE;
break;
}
-
+
/* unhandled currently, but may be interesting */
case ANIMTYPE_MASKLAYER:
case ANIMTYPE_SHAPEKEY:
case ANIMTYPE_NLAACTION:
break;
-
+
/* other types */
default:
break;
}
}
-
+
/* clean up */
ANIM_animdata_freelist(&anim_data);
}
@@ -252,7 +252,7 @@ static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp,
}
}
-/* Deselect all animation channels
+/* Deselect all animation channels
* - data: pointer to datatype, as contained in bAnimContext
* - datatype: the type of data that 'data' represents (eAnimCont_Types)
* - test: check if deselecting instead of selecting
@@ -263,18 +263,18 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
/* NOTE: no list visible, otherwise, we get dangling */
filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
-
+
/* See if we should be selecting or deselecting */
if (test) {
for (ale = anim_data.first; ale; ale = ale->next) {
- if (sel == 0)
+ if (sel == 0)
break;
-
+
switch (ale->type) {
case ANIMTYPE_SCENE:
if (ale->flag & SCE_DS_SELECTED)
@@ -303,7 +303,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
if (ale->flag & NLATRACK_SELECTED)
sel = ACHANNEL_SETFLAG_CLEAR;
break;
-
+
case ANIMTYPE_FILLACTD: /* Action Expander */
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
case ANIMTYPE_DSLAM:
@@ -339,16 +339,16 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
}
}
}
-
+
/* Now set the flags */
for (ale = anim_data.first; ale; ale = ale->next) {
switch (ale->type) {
case ANIMTYPE_SCENE:
{
Scene *scene = (Scene *)ale->data;
-
+
ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED);
-
+
if (scene->adt) {
ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED);
}
@@ -381,7 +381,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
case ANIMTYPE_NLACURVE:
{
FCurve *fcu = (FCurve *)ale->data;
-
+
ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED);
fcu->flag &= ~FCURVE_ACTIVE;
break;
@@ -389,14 +389,14 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
case ANIMTYPE_SHAPEKEY:
{
KeyBlock *kb = (KeyBlock *)ale->data;
-
+
ACHANNEL_SET_FLAG(kb, sel, KEYBLOCK_SEL);
break;
}
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt = (NlaTrack *)ale->data;
-
+
ACHANNEL_SET_FLAG(nlt, sel, NLATRACK_SELECTED);
nlt->flag &= ~NLATRACK_ACTIVE;
break;
@@ -431,27 +431,27 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
case ANIMTYPE_GPLAYER:
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
+
ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT);
break;
}
case ANIMTYPE_MASKLAYER:
{
MaskLayer *masklay = (MaskLayer *)ale->data;
-
+
ACHANNEL_SET_FLAG(masklay, sel, MASK_LAYERFLAG_SELECT);
break;
}
}
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
/* ---------------------------- Graph Editor ------------------------------------- */
-/* Flush visibility (for Graph Editor) changes up/down hierarchy for changes in the given setting
+/* Flush visibility (for Graph Editor) changes up/down hierarchy for changes in the given setting
* - anim_data: list of the all the anim channels that can be chosen
* -> filtered using ANIMFILTER_CHANNELS only, since if we took VISIBLE too,
* then the channels under closed expanders get ignored...
@@ -464,7 +464,7 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
{
bAnimListElem *ale, *match = NULL;
int prevLevel = 0, matchLevel = 0;
-
+
/* sanity check */
if (ELEM(NULL, anim_data, anim_data->first))
return;
@@ -491,23 +491,23 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
}
else {
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale_setting);
-
+
if (acf == NULL) {
printf("ERROR: no channel info for the changed channel\n");
return;
}
-
+
/* get the level of the channel that was affected
* - we define the level as simply being the offset for the start of the channel
*/
matchLevel = (acf->get_offset) ? acf->get_offset(ac, ale_setting) : 0;
prevLevel = matchLevel;
}
-
- /* flush up?
+
+ /* flush up?
*
* For Visibility:
- * - only flush up if the current state is now enabled (positive 'on' state is default)
+ * - only flush up if the current state is now enabled (positive 'on' state is default)
* (otherwise, it's too much work to force the parents to be inactive too)
*
* For everything else:
@@ -521,25 +521,25 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
for (ale = match->prev; ale; ale = ale->prev) {
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
int level;
-
+
/* if no channel info was found, skip, since this type might not have any useful info */
if (acf == NULL)
continue;
-
- /* get the level of the current channel traversed
+
+ /* get the level of the current channel traversed
* - we define the level as simply being the offset for the start of the channel
*/
level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
-
+
/* if the level is 'less than' (i.e. more important) the level we're matching
- * but also 'less than' the level just tried (i.e. only the 1st group above grouped F-Curves,
+ * but also 'less than' the level just tried (i.e. only the 1st group above grouped F-Curves,
* when toggling visibility of F-Curves, gets flushed, which should happen if we don't let prevLevel
* get updated below once the first 1st group is found)...
*/
if (level < prevLevel) {
/* flush the new status... */
ANIM_channel_setting_set(ac, ale, setting, mode);
-
+
/* store this level as the 'old' level now */
prevLevel = level;
}
@@ -551,31 +551,31 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
if (prevLevel == 0)
break;
/* otherwise, this level weaves into another sibling hierarchy to the previous one just
- * finished, so skip until we get to the parent of this level
+ * finished, so skip until we get to the parent of this level
*/
else
continue;
}
}
}
-
+
/* flush down (always) */
{
/* go forwards in the list, until the lowest-ranking element (by indention has been covered) */
for (ale = match->next; ale; ale = ale->next) {
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
int level;
-
+
/* if no channel info was found, skip, since this type might not have any useful info */
if (acf == NULL)
continue;
-
- /* get the level of the current channel traversed
+
+ /* get the level of the current channel traversed
* - we define the level as simply being the offset for the start of the channel
*/
level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
-
- /* if the level is 'greater than' (i.e. less important) the channel that was changed,
+
+ /* if the level is 'greater than' (i.e. less important) the channel that was changed,
* flush the new status...
*/
if (level > matchLevel)
@@ -586,7 +586,7 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
*/
else
break;
-
+
/* store this level as the 'old' level now */
// prevLevel = level; // XXX: prevLevel is unused
}
@@ -598,13 +598,13 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
/* Delete the given F-Curve from its AnimData block */
void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu)
{
- /* - if no AnimData, we've got nowhere to remove the F-Curve from
+ /* - if no AnimData, we've got nowhere to remove the F-Curve from
* (this doesn't guarantee that the F-Curve is in there, but at least we tried
* - if no F-Curve, there is nothing to remove
*/
if (ELEM(NULL, adt, fcu))
return;
-
+
/* remove from whatever list it came from
* - Action Group
* - Action
@@ -617,15 +617,15 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
}
else if (adt->action) {
bAction *act = adt->action;
-
+
/* remove from group or action, whichever one "owns" the F-Curve */
if (fcu->grp) {
bActionGroup *agrp = fcu->grp;
-
+
/* remove F-Curve from group+action */
action_groups_remove_channel(act, fcu);
-
- /* if group has no more channels, remove it too,
+
+ /* if group has no more channels, remove it too,
* otherwise can have many dangling groups [#33541]
*/
if (BLI_listbase_is_empty(&agrp->channels)) {
@@ -635,7 +635,7 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
else {
BLI_remlink(&act->curves, fcu);
}
-
+
/* if action has no more F-Curves as a result of this, unlink it from
* AnimData if it did not come from a NLA Strip being tweaked.
*
@@ -648,7 +648,7 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
adt->action = NULL;
}
}
-
+
/* free the F-Curve itself */
free_fcurve(fcu);
}
@@ -662,7 +662,7 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
static int animedit_poll_channels_active(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
-
+
/* channels region test */
/* TODO: could enhance with actually testing if channels region? */
if (ELEM(NULL, sa, CTX_wm_region(C)))
@@ -687,13 +687,13 @@ static int animedit_poll_channels_nla_tweakmode_off(bContext *C)
/* animation editor test */
if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_IPO, SPACE_NLA) == 0)
return 0;
-
+
/* NLA TweakMode test */
if (sa->spacetype == SPACE_NLA) {
if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON))
return 0;
}
-
+
return 1;
}
@@ -722,7 +722,7 @@ static const EnumPropertyItem prop_animchannel_rearrange_types[] = {
/* Island definition - just a listbase container */
typedef struct tReorderChannelIsland {
struct tReorderChannelIsland *next, *prev;
-
+
ListBase channels; /* channels within this region with the same state */
int flag; /* eReorderIslandFlag */
} tReorderChannelIsland;
@@ -743,7 +743,7 @@ static bool rearrange_island_ok(tReorderChannelIsland *island)
/* island must not be untouchable */
if (island->flag & REORDER_ISLAND_UNTOUCHABLE)
return 0;
-
+
/* island should be selected to be moved */
return (island->flag & REORDER_ISLAND_SELECTED) && !(island->flag & REORDER_ISLAND_MOVED);
}
@@ -755,13 +755,13 @@ static bool rearrange_island_top(ListBase *list, tReorderChannelIsland *island)
if (rearrange_island_ok(island)) {
/* remove from current position */
BLI_remlink(list, island);
-
+
/* make it first element */
BLI_insertlinkbefore(list, list->first, island);
-
+
return 1;
}
-
+
return 0;
}
@@ -779,14 +779,14 @@ static bool rearrange_island_up(ListBase *list, tReorderChannelIsland *island)
if (prev) {
/* remove from current position */
BLI_remlink(list, island);
-
+
/* push it up */
BLI_insertlinkbefore(list, prev, island);
-
+
return 1;
}
}
-
+
return 0;
}
@@ -806,16 +806,16 @@ static bool rearrange_island_down(ListBase *list, tReorderChannelIsland *island)
if ((next->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
/* remove from current position */
BLI_remlink(list, island);
-
+
/* push it down */
BLI_insertlinkafter(list, next, island);
-
+
return true;
}
}
/* else: no next channel, so we're at the bottom already, so can't move */
}
-
+
return false;
}
@@ -823,10 +823,10 @@ static bool rearrange_island_bottom(ListBase *list, tReorderChannelIsland *islan
{
if (rearrange_island_ok(island)) {
tReorderChannelIsland *last = list->last;
-
+
/* remove island from current position */
BLI_remlink(list, island);
-
+
/* add before or after the last channel? */
if ((last->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
/* can add after it */
@@ -835,12 +835,12 @@ static bool rearrange_island_bottom(ListBase *list, tReorderChannelIsland *islan
else {
/* can at most go just before it, since last cannot be moved */
BLI_insertlinkbefore(list, last, island);
-
+
}
-
+
return true;
}
-
+
return false;
}
@@ -881,13 +881,13 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
{
tReorderChannelIsland *island = islands->last; /* always try to add to last island if possible */
bool is_sel = false, is_untouchable = false;
-
+
/* get flags - selected and untouchable from the channel */
switch (type) {
case ANIMTYPE_GROUP:
{
bActionGroup *agrp = (bActionGroup *)channel;
-
+
is_sel = SEL_AGRP(agrp);
is_untouchable = (agrp->flag & AGRP_TEMP) != 0;
break;
@@ -896,21 +896,21 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
case ANIMTYPE_NLACURVE:
{
FCurve *fcu = (FCurve *)channel;
-
+
is_sel = SEL_FCU(fcu);
break;
}
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt = (NlaTrack *)channel;
-
+
is_sel = SEL_NLT(nlt);
break;
}
case ANIMTYPE_GPLAYER:
{
bGPDlayer *gpl = (bGPDlayer *)channel;
-
+
is_sel = SEL_GPL(gpl);
break;
}
@@ -918,7 +918,7 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
printf("rearrange_animchannel_add_to_islands(): don't know how to handle channels of type %u\n", type);
return;
}
-
+
/* do we need to add to a new island? */
if (/* 1) no islands yet */
(island == NULL) ||
@@ -933,7 +933,7 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
/* create a new island now */
island = MEM_callocN(sizeof(tReorderChannelIsland), "tReorderChannelIsland");
BLI_addtail(islands, island);
-
+
if (is_sel)
island->flag |= REORDER_ISLAND_SELECTED;
if (is_untouchable)
@@ -951,14 +951,14 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
static void rearrange_animchannel_flatten_islands(ListBase *islands, ListBase *srcList)
{
tReorderChannelIsland *island, *isn = NULL;
-
+
/* make sure srcList is empty now */
BLI_assert(BLI_listbase_is_empty(srcList));
-
+
/* go through merging islands */
for (island = islands->first; island; island = isn) {
isn = island->next;
-
+
/* merge island channels back to main list, then delete the island */
BLI_movelisttolist(srcList, &island->channels);
BLI_freelinkN(islands, island);
@@ -973,19 +973,19 @@ static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible, b
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale, *ale_next;
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
-
+
/* get all visible channels */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* now, only keep the ones that are of the types we are interested in */
for (ale = anim_data.first; ale; ale = ale_next) {
ale_next = ale->next;
-
+
if (ale->type != type) {
BLI_freelinkN(&anim_data, ale);
}
}
-
+
/* return cleaned up list */
*anim_data_visible = anim_data;
}
@@ -998,11 +998,11 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
ListBase islands = {NULL, NULL};
Link *channel, *chanNext = NULL;
bool done = false;
-
+
/* don't waste effort on an empty list */
if (BLI_listbase_is_empty(list))
return 0;
-
+
/* group channels into islands */
for (channel = list->first; channel; channel = chanNext) {
/* find out whether this channel is present in anim_data_visible or not! */
@@ -1010,18 +1010,18 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
chanNext = channel->next;
rearrange_animchannel_add_to_islands(&islands, list, channel, type, is_hidden);
}
-
- /* perform moving of selected islands now, but only if there is more than one of 'em so that something will happen
- * - scanning of the list is performed in the opposite direction to the direction we're moving things, so that we
+
+ /* perform moving of selected islands now, but only if there is more than one of 'em so that something will happen
+ * - scanning of the list is performed in the opposite direction to the direction we're moving things, so that we
* shouldn't need to encounter items we've moved already
*/
if (islands.first != islands.last) {
tReorderChannelIsland *first = (mode > 0) ? islands.last : islands.first;
tReorderChannelIsland *island, *isn = NULL;
-
+
for (island = first; island; island = isn) {
isn = (mode > 0) ? island->prev : island->next;
-
+
/* perform rearranging */
if (rearrange_func(&islands, island)) {
island->flag |= REORDER_ISLAND_MOVED;
@@ -1029,10 +1029,10 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
}
}
}
-
+
/* ungroup islands */
rearrange_animchannel_flatten_islands(&islands, list);
-
+
/* did we do anything? */
return done;
}
@@ -1047,21 +1047,21 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn
{
AnimChanRearrangeFp rearrange_func;
ListBase anim_data_visible = {NULL, NULL};
-
+
/* hack: invert mode so that functions will work in right order */
mode *= -1;
-
+
/* get rearranging function */
rearrange_func = rearrange_get_mode_func(mode);
if (rearrange_func == NULL)
return;
-
+
/* Filter visible data. */
rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK);
-
+
/* perform rearranging on tracks list */
rearrange_animchannel_islands(&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
-
+
/* free temp data */
BLI_freelistN(&anim_data_visible);
}
@@ -1076,20 +1076,20 @@ static void rearrange_driver_channels(bAnimContext *ac, AnimData *adt, eRearrang
/* get rearranging function */
AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
ListBase anim_data_visible = {NULL, NULL};
-
+
if (rearrange_func == NULL)
return;
-
+
/* only consider drivers if they're accessible */
if (EXPANDED_DRVD(adt) == 0)
return;
-
+
/* Filter visible data. */
rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
-
+
/* perform rearranging on drivers list (drivers are really just F-Curves) */
rearrange_animchannel_islands(&adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
-
+
/* free temp data */
BLI_freelistN(&anim_data_visible);
}
@@ -1101,29 +1101,29 @@ static void split_groups_action_temp(bAction *act, bActionGroup *tgrp)
{
bActionGroup *agrp;
FCurve *fcu;
-
+
if (act == NULL)
return;
-
+
/* Separate F-Curves into lists per group */
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
if (agrp->channels.first) {
fcu = agrp->channels.last;
act->curves.first = fcu->next;
-
+
fcu = agrp->channels.first;
fcu->prev = NULL;
-
+
fcu = agrp->channels.last;
fcu->next = NULL;
}
}
-
+
/* Initialize memory for temp-group */
memset(tgrp, 0, sizeof(bActionGroup));
tgrp->flag |= (AGRP_EXPANDED | AGRP_TEMP);
BLI_strncpy(tgrp->name, "#TempGroup", sizeof(tgrp->name));
-
+
/* Move any action-channels not already moved, to the temp group */
if (act->curves.first) {
/* start of list */
@@ -1131,21 +1131,21 @@ static void split_groups_action_temp(bAction *act, bActionGroup *tgrp)
fcu->prev = NULL;
tgrp->channels.first = fcu;
act->curves.first = NULL;
-
+
/* end of list */
fcu = act->curves.last;
fcu->next = NULL;
tgrp->channels.last = fcu;
act->curves.last = NULL;
-
- /* ensure that all of these get their group set to this temp group
+
+ /* ensure that all of these get their group set to this temp group
* (so that visibility filtering works)
*/
for (fcu = tgrp->channels.first; fcu; fcu = fcu->next) {
fcu->grp = tgrp;
}
}
-
+
/* Add temp-group to list */
BLI_addtail(&act->groups, tgrp);
}
@@ -1154,36 +1154,36 @@ static void split_groups_action_temp(bAction *act, bActionGroup *tgrp)
static void join_groups_action_temp(bAction *act)
{
bActionGroup *agrp;
-
+
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
ListBase tempGroup;
-
+
/* add list of channels to action's channels */
tempGroup = agrp->channels;
BLI_movelisttolist(&act->curves, &agrp->channels);
agrp->channels = tempGroup;
-
+
/* clear moved flag */
agrp->flag &= ~AGRP_MOVED;
-
+
/* if group was temporary one:
* - unassign all FCurves which were temporarily added to it
* - remove from list (but don't free as it's on the stack!)
*/
if (agrp->flag & AGRP_TEMP) {
FCurve *fcu;
-
+
for (fcu = agrp->channels.first; fcu; fcu = fcu->next) {
fcu->grp = NULL;
}
-
+
BLI_remlink(&act->groups, agrp);
break;
}
}
}
-/* Change the order of anim-channels within action
+/* Change the order of anim-channels within action
* mode: REARRANGE_ANIMCHAN_*
*/
static void rearrange_action_channels(bAnimContext *ac, bAction *act, eRearrangeAnimChan_Mode mode)
@@ -1191,35 +1191,35 @@ static void rearrange_action_channels(bAnimContext *ac, bAction *act, eRearrange
bActionGroup tgrp;
ListBase anim_data_visible = {NULL, NULL};
bool do_channels;
-
+
/* get rearranging function */
AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
-
+
if (rearrange_func == NULL)
return;
-
+
/* make sure we're only operating with groups (vs a mixture of groups+curves) */
split_groups_action_temp(act, &tgrp);
-
+
/* Filter visible data. */
rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GROUP);
-
- /* rearrange groups first
+
+ /* rearrange groups first
* - the group's channels will only get considered if nothing happened when rearranging the groups
* i.e. the rearrange function returned 0
*/
do_channels = (rearrange_animchannel_islands(&act->groups, rearrange_func, mode, ANIMTYPE_GROUP,
&anim_data_visible) == 0);
-
+
/* free temp data */
BLI_freelistN(&anim_data_visible);
-
+
if (do_channels) {
bActionGroup *agrp;
-
+
/* Filter visible data. */
rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
-
+
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
/* only consider F-Curves if they're visible (group expanded) */
if (EXPANDED_AGRP(ac, agrp)) {
@@ -1227,11 +1227,11 @@ static void rearrange_action_channels(bAnimContext *ac, bAction *act, eRearrange
&anim_data_visible);
}
}
-
+
/* free temp data */
BLI_freelistN(&anim_data_visible);
}
-
+
/* assemble lists into one list (and clear moved tags) */
join_groups_action_temp(act);
}
@@ -1241,23 +1241,23 @@ static void rearrange_action_channels(bAnimContext *ac, bAction *act, eRearrange
static void rearrange_nla_control_channels(bAnimContext *ac, AnimData *adt, eRearrangeAnimChan_Mode mode)
{
ListBase anim_data_visible = {NULL, NULL};
-
+
NlaTrack *nlt;
NlaStrip *strip;
-
+
/* get rearranging function */
AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
-
+
if (rearrange_func == NULL)
return;
-
+
/* skip if these curves aren't being shown */
if (adt->flag & ADT_NLA_SKEYS_COLLAPSED)
return;
-
+
/* Filter visible data. */
rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLACURVE);
-
+
/* we cannot rearrange between strips, but within each strip, we can rearrange those curves */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
for (strip = nlt->strips.first; strip; strip = strip->next) {
@@ -1265,7 +1265,7 @@ static void rearrange_nla_control_channels(bAnimContext *ac, AnimData *adt, eRea
&anim_data_visible);
}
}
-
+
/* free temp data */
BLI_freelistN(&anim_data_visible);
}
@@ -1277,36 +1277,36 @@ static void rearrange_gpencil_channels(bAnimContext *ac, eRearrangeAnimChan_Mode
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get rearranging function */
AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
-
+
if (rearrange_func == NULL)
return;
-
+
/* get Grease Pencil datablocks */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
ListBase anim_data_visible = {NULL, NULL};
bGPdata *gpd = ale->data;
-
+
/* only consider layers if this datablock is open */
BLI_assert(ale->type == ANIMTYPE_GPDATABLOCK);
if ((gpd->flag & GP_DATA_EXPAND) == 0)
continue;
-
+
/* Filter visible data. */
rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GPLAYER);
-
+
/* rearrange datablock's layers */
rearrange_animchannel_islands(&gpd->layers, rearrange_func, mode, ANIMTYPE_GPLAYER, &anim_data_visible);
-
+
/* free visible layers data */
BLI_freelistN(&anim_data_visible);
}
-
+
/* free GPD channel data */
ANIM_animdata_freelist(&anim_data);
}
@@ -1317,14 +1317,14 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
eRearrangeAnimChan_Mode mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get mode */
mode = RNA_enum_get(op->ptr, "direction");
-
+
/* method to move channels depends on the editor */
if (ac.datatype == ANIMCONT_GPENCIL) {
/* Grease Pencil channels */
@@ -1342,23 +1342,23 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get animdata blocks */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->data;
-
+
switch (ac.datatype) {
case ANIMCONT_NLA: /* NLA-tracks only */
rearrange_nla_channels(&ac, adt, mode);
break;
-
+
case ANIMCONT_DRIVERS: /* Drivers list only */
rearrange_driver_channels(&ac, adt, mode);
break;
-
+
case ANIMCONT_ACTION: /* Single Action only... */
case ANIMCONT_SHAPEKEY: // DOUBLE CHECK ME...
{
@@ -1368,13 +1368,13 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
printf("Animdata has no action\n");
break;
}
-
+
default: /* DopeSheet/Graph Editor - Some Actions + NLA Control Curves */
{
/* NLA Control Curves */
if (adt->nla_tracks.first)
rearrange_nla_control_channels(&ac, adt, mode);
-
+
/* Action */
if (adt->action)
rearrange_action_channels(&ac, adt->action, mode);
@@ -1384,14 +1384,14 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
}
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1401,14 +1401,14 @@ static void ANIM_OT_channels_move(wmOperatorType *ot)
ot->name = "Move Channels";
ot->idname = "ANIM_OT_channels_move";
ot->description = "Rearrange selected animation channels";
-
+
/* api callbacks */
ot->exec = animchannels_rearrange_exec;
ot->poll = animedit_poll_channels_nla_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_enum(ot->srna, "direction", prop_animchannel_rearrange_types, REARRANGE_ANIMCHAN_DOWN, "Direction", "");
}
@@ -1424,16 +1424,16 @@ static int animchannels_grouping_poll(bContext *C)
/* TODO: could enhance with actually testing if channels region? */
if (ELEM(NULL, sa, CTX_wm_region(C)))
return 0;
-
+
/* animation editor test - must be suitable modes only */
sl = CTX_wm_space_data(C);
-
+
switch (sa->spacetype) {
/* supported... */
case SPACE_ACTION:
{
SpaceAction *saction = (SpaceAction *)sl;
-
+
/* dopesheet and action only - all others are for other datatypes or have no groups */
if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_DOPESHEET) == 0)
return 0;
@@ -1443,7 +1443,7 @@ static int animchannels_grouping_poll(bContext *C)
case SPACE_IPO:
{
SpaceIpo *sipo = (SpaceIpo *)sl;
-
+
/* drivers can't have groups... */
if (sipo->mode != SIPO_MODE_ANIMATION)
return 0;
@@ -1454,50 +1454,50 @@ static int animchannels_grouping_poll(bContext *C)
default:
return 0;
}
-
+
return 1;
}
/* ----------------------------------------------------------- */
static void animchannels_group_channels(bAnimContext *ac, bAnimListElem *adt_ref, const char name[])
-{
+{
AnimData *adt = adt_ref->adt;
bAction *act = adt->action;
-
+
if (act) {
ListBase anim_data = {NULL, NULL};
int filter;
-
+
/* find selected F-Curves to re-group */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
ANIM_animdata_filter(ac, &anim_data, filter, adt_ref, ANIMCONT_CHANNEL);
-
+
if (anim_data.first) {
bActionGroup *agrp;
bAnimListElem *ale;
-
+
/* create new group, which should now be part of the action */
agrp = action_groups_add_new(act, name);
BLI_assert(agrp != NULL);
-
+
/* transfer selected F-Curves across to new group */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
bActionGroup *grp = fcu->grp;
-
+
/* remove F-Curve from group, then group too if it is now empty */
action_groups_remove_channel(act, fcu);
-
+
if ((grp) && BLI_listbase_is_empty(&grp->channels)) {
BLI_freelinkN(&act->groups, grp);
}
-
+
/* add F-Curve to group */
action_groups_add_channel(act, agrp, fcu);
}
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -1507,35 +1507,35 @@ static int animchannels_group_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
char name[MAX_NAME];
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get name for new group */
RNA_string_get(op->ptr, "name", name);
-
+
/* XXX: name for group should never be empty... */
if (name[0]) {
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* handle each animdata block separately, so that the regrouping doesn't flow into blocks */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
animchannels_group_channels(&ac, ale, name);
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* updatss */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -1545,18 +1545,18 @@ static void ANIM_OT_channels_group(wmOperatorType *ot)
ot->name = "Group Channels";
ot->idname = "ANIM_OT_channels_group";
ot->description = "Add selected F-Curves to a new group";
-
+
/* callbacks */
ot->invoke = WM_operator_props_popup;
ot->exec = animchannels_group_exec;
ot->poll = animchannels_grouping_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
- ot->prop = RNA_def_string(ot->srna, "name", "New Group",
- sizeof(((bActionGroup *)NULL)->name),
+ ot->prop = RNA_def_string(ot->srna, "name", "New Group",
+ sizeof(((bActionGroup *)NULL)->name),
"Name", "Name of newly created group");
/* RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); */ /* XXX: still not too sure about this - keeping same text is confusing... */
}
@@ -1566,33 +1566,33 @@ static void ANIM_OT_channels_group(wmOperatorType *ot)
static int animchannels_ungroup_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* just selected F-Curves... */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
/* find action for this F-Curve... */
if (ale->adt && ale->adt->action) {
FCurve *fcu = (FCurve *)ale->data;
bAction *act = ale->adt->action;
-
+
/* only proceed to remove if F-Curve is in a group... */
- if (fcu->grp) {
+ if (fcu->grp) {
bActionGroup *agrp = fcu->grp;
-
+
/* remove F-Curve from group and add at tail (ungrouped) */
action_groups_remove_channel(act, fcu);
BLI_addtail(&act->curves, fcu);
-
+
/* delete group if it is now empty */
if (BLI_listbase_is_empty(&agrp->channels)) {
BLI_freelinkN(&act->groups, agrp);
@@ -1600,13 +1600,13 @@ static int animchannels_ungroup_exec(bContext *C, wmOperator *UNUSED(op))
}
}
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
-
+
/* updates */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1616,11 +1616,11 @@ static void ANIM_OT_channels_ungroup(wmOperatorType *ot)
ot->name = "Ungroup Channels";
ot->idname = "ANIM_OT_channels_ungroup";
ot->description = "Remove selected F-Curves from their current groups";
-
+
/* callbacks */
ot->exec = animchannels_ungroup_exec;
ot->poll = animchannels_grouping_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1633,22 +1633,22 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* cannot delete in shapekey */
- if (ac.datatype == ANIMCONT_SHAPEKEY)
+ if (ac.datatype == ANIMCONT_SHAPEKEY)
return OPERATOR_CANCELLED;
-
-
+
+
/* do groups only first (unless in Drivers mode, where there are none) */
if (ac.datatype != ANIMCONT_DRIVERS) {
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* delete selected groups and their associated channels */
for (ale = anim_data.first; ale; ale = ale->next) {
/* only groups - don't check other types yet, since they may no-longer exist */
@@ -1656,20 +1656,20 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
bActionGroup *agrp = (bActionGroup *)ale->data;
AnimData *adt = ale->adt;
FCurve *fcu, *fcn;
-
+
/* skip this group if no AnimData available, as we can't safely remove the F-Curves */
if (adt == NULL)
continue;
-
+
/* delete all of the Group's F-Curves, but no others */
for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcn) {
fcn = fcu->next;
-
+
/* remove from group and action, then free */
action_groups_remove_channel(adt->action, fcu);
free_fcurve(fcu);
}
-
+
/* free the group itself */
if (adt->action)
BLI_freelinkN(&adt->action->groups, agrp);
@@ -1677,24 +1677,24 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
MEM_freeN(agrp);
}
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
}
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* delete selected data channels */
for (ale = anim_data.first; ale; ale = ale->next) {
switch (ale->type) {
- case ANIMTYPE_FCURVE:
+ case ANIMTYPE_FCURVE:
{
/* F-Curves if we can identify its parent */
AnimData *adt = ale->adt;
FCurve *fcu = (FCurve *)ale->data;
-
+
/* try to free F-Curve */
ANIM_fcurve_delete_from_animdata(&ac, adt, fcu);
break;
@@ -1704,7 +1704,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
/* NLA Control Curve - Deleting it should disable the corresponding setting... */
NlaStrip *strip = (NlaStrip *)ale->owner;
FCurve *fcu = (FCurve *)ale->data;
-
+
if (STREQ(fcu->rna_path, "strip_time")) {
strip->flag &= ~NLASTRIP_FLAG_USR_TIME;
}
@@ -1714,7 +1714,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
else {
printf("ERROR: Trying to delete NLA Control Curve for unknown property '%s'\n", fcu->rna_path);
}
-
+
/* unlink and free the F-Curve */
BLI_remlink(&strip->fcurves, fcu);
free_fcurve(fcu);
@@ -1725,7 +1725,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
/* Grease Pencil layer */
bGPdata *gpd = (bGPdata *)ale->id;
bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
+
/* try to delete the layer's data and the layer itself */
BKE_gpencil_free_frames(gpl);
BLI_freelinkN(&gpd->layers, gpl);
@@ -1736,35 +1736,35 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
/* Mask layer */
Mask *mask = (Mask *)ale->id;
MaskLayer *masklay = (MaskLayer *)ale->data;
-
+
/* try to delete the layer's data and the layer itself */
BKE_mask_layer_remove(mask, masklay);
break;
}
}
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
DEG_relations_tag_update(CTX_data_main(C));
return OPERATOR_FINISHED;
}
-
+
static void ANIM_OT_channels_delete(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Delete Channels";
ot->idname = "ANIM_OT_channels_delete";
ot->description = "Delete all selected animation channels";
-
+
/* api callbacks */
ot->exec = animchannels_delete_exec;
ot->poll = animedit_poll_channels_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1791,7 +1791,7 @@ static const EnumPropertyItem prop_animchannel_settings_types[] = {
/* ------------------- */
-/* Set/clear a particular flag (setting) for all selected + visible channels
+/* Set/clear a particular flag (setting) for all selected + visible channels
* setting: the setting to modify
* mode: eAnimChannels_SetFlag
* onlysel: only selected channels get the flag set
@@ -1803,20 +1803,20 @@ static void setflag_anim_channels(bAnimContext *ac, eAnimChannel_Settings settin
ListBase all_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data that we need if flush is on */
if (flush) {
- /* get list of all channels that selection may need to be flushed to
+ /* get list of all channels that selection may need to be flushed to
* - hierarchy visibility needs to be ignored so that settings can get flushed
* "down" inside closed containers
*/
filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
ANIM_animdata_filter(ac, &all_data, filter, ac->data, ac->datatype);
}
-
- /* filter data that we're working on
+
+ /* filter data that we're working on
* - hierarchy matters if we're doing this from the channels region
- * since we only want to apply this to channels we can "see",
+ * since we only want to apply this to channels we can "see",
* and have these affect their relatives
* - but for Graph Editor, this gets used also from main region
* where hierarchy doesn't apply [#21276]
@@ -1831,12 +1831,12 @@ static void setflag_anim_channels(bAnimContext *ac, eAnimChannel_Settings settin
}
if (onlysel) filter |= ANIMFILTER_SEL;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* if toggling, check if disable or enable */
if (mode == ACHANNEL_SETFLAG_TOGGLE) {
/* default to turn all on, unless we encounter one that's on... */
mode = ACHANNEL_SETFLAG_ADD;
-
+
/* see if we should turn off instead... */
for (ale = anim_data.first; ale; ale = ale->next) {
/* set the setting in the appropriate way (if available) */
@@ -1846,21 +1846,21 @@ static void setflag_anim_channels(bAnimContext *ac, eAnimChannel_Settings settin
}
}
}
-
+
/* apply the setting */
for (ale = anim_data.first; ale; ale = ale->next) {
/* skip channel if setting is not available */
if (ANIM_channel_setting_get(ac, ale, setting) == -1)
continue;
-
+
/* set the setting in the appropriate way */
ANIM_channel_setting_set(ac, ale, setting, mode);
-
+
/* if flush status... */
if (flush)
ANIM_flush_setting_anim_channels(ac, &all_data, ale, setting, mode);
}
-
+
ANIM_animdata_freelist(&anim_data);
BLI_freelistN(&all_data);
}
@@ -1873,27 +1873,27 @@ static int animchannels_setflag_exec(bContext *C, wmOperator *op)
eAnimChannel_Settings setting;
eAnimChannels_SetFlag mode;
bool flush = true;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* mode (eAnimChannels_SetFlag), setting (eAnimChannel_Settings) */
mode = RNA_enum_get(op->ptr, "mode");
setting = RNA_enum_get(op->ptr, "type");
-
+
/* check if setting is flushable */
if (setting == ACHANNEL_SETTING_EXPAND)
flush = false;
-
- /* modify setting
+
+ /* modify setting
* - only selected channels are affected
*/
setflag_anim_channels(&ac, setting, mode, true, flush);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1901,20 +1901,20 @@ static int animchannels_setflag_exec(bContext *C, wmOperator *op)
static void ANIM_OT_channels_setting_enable(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Enable Channel Setting";
ot->idname = "ANIM_OT_channels_setting_enable";
ot->description = "Enable specified setting on all selected animation channels";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = animchannels_setflag_exec;
ot->poll = animedit_poll_channels_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
/* flag-setting mode */
prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
@@ -1926,20 +1926,20 @@ static void ANIM_OT_channels_setting_enable(wmOperatorType *ot)
static void ANIM_OT_channels_setting_disable(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Disable Channel Setting";
ot->idname = "ANIM_OT_channels_setting_disable";
ot->description = "Disable specified setting on all selected animation channels";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = animchannels_setflag_exec;
ot->poll = animedit_poll_channels_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
/* flag-setting mode */
prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
@@ -1951,20 +1951,20 @@ static void ANIM_OT_channels_setting_disable(wmOperatorType *ot)
static void ANIM_OT_channels_setting_toggle(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Toggle Channel Setting";
ot->idname = "ANIM_OT_channels_setting_toggle";
ot->description = "Toggle specified setting on all selected animation channels";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = animchannels_setflag_exec;
ot->poll = animedit_poll_channels_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
/* flag-setting mode */
prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
@@ -1976,19 +1976,19 @@ static void ANIM_OT_channels_setting_toggle(wmOperatorType *ot)
static void ANIM_OT_channels_editable_toggle(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Toggle Channel Editability";
ot->idname = "ANIM_OT_channels_editable_toggle";
ot->description = "Toggle editability of selected channels";
-
+
/* api callbacks */
ot->exec = animchannels_setflag_exec;
ot->poll = animedit_poll_channels_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
/* flag-setting mode */
RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
@@ -2003,21 +2003,21 @@ static int animchannels_expand_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
bool onlysel = true;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* only affect selected channels? */
if (RNA_boolean_get(op->ptr, "all"))
onlysel = false;
-
+
/* modify setting */
setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_ADD, onlysel, false);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2027,14 +2027,14 @@ static void ANIM_OT_channels_expand(wmOperatorType *ot)
ot->name = "Expand Channels";
ot->idname = "ANIM_OT_channels_expand";
ot->description = "Expand (i.e. open) all selected expandable animation channels";
-
+
/* api callbacks */
ot->exec = animchannels_expand_exec;
ot->poll = animedit_poll_channels_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All", "Expand all channels (not just selected ones)");
}
@@ -2045,21 +2045,21 @@ static int animchannels_collapse_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
bool onlysel = true;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* only affect selected channels? */
if (RNA_boolean_get(op->ptr, "all"))
onlysel = false;
-
+
/* modify setting */
setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_CLEAR, onlysel, false);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2069,14 +2069,14 @@ static void ANIM_OT_channels_collapse(wmOperatorType *ot)
ot->name = "Collapse Channels";
ot->idname = "ANIM_OT_channels_collapse";
ot->description = "Collapse (i.e. close) all selected expandable animation channels";
-
+
/* api callbacks */
ot->exec = animchannels_collapse_exec;
ot->poll = animedit_poll_channels_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_boolean(ot->srna, "all", true, "All", "Collapse all channels (not just selected ones)");
}
@@ -2092,37 +2092,37 @@ static void ANIM_OT_channels_collapse(wmOperatorType *ot)
* or are no longer wanted
* 3) No drivers
*/
-
+
static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get animdata blocks */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
ID *id = ale->id;
AnimData *adt = ale->data;
-
+
bool action_empty = false;
bool nla_empty = false;
bool drivers_empty = false;
-
+
/* sanity checks */
BLI_assert((id != NULL) && (adt != NULL));
-
+
/* check if this is "empty" and can be deleted */
/* (For now, there are only these 3 criteria) */
-
+
/* 1) Active Action is missing or empty */
if (ELEM(NULL, adt->action, adt->action->curves.first)) {
action_empty = true;
@@ -2130,18 +2130,18 @@ static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op))
else {
/* TODO: check for keyframe + fmodifier data on these too */
}
-
+
/* 2) No NLA Tracks and/or NLA Strips */
if (adt->nla_tracks.first == NULL) {
nla_empty = true;
}
else {
NlaTrack *nlt;
-
+
/* empty tracks? */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
if (nlt->strips.first) {
- /* stop searching, as we found one that actually had stuff we don't want lost
+ /* stop searching, as we found one that actually had stuff we don't want lost
* NOTE: nla_empty gets reset to false, as a previous track may have been empty
*/
nla_empty = false;
@@ -2153,23 +2153,23 @@ static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op))
}
}
}
-
+
/* 3) Drivers */
drivers_empty = (adt->drivers.first == NULL);
-
-
+
+
/* remove AnimData? */
if (action_empty && nla_empty && drivers_empty) {
BKE_animdata_free(id, true);
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2179,11 +2179,11 @@ static void ANIM_OT_channels_clean_empty(wmOperatorType *ot)
ot->name = "Remove Empty Animation Data";
ot->idname = "ANIM_OT_channels_clean_empty";
ot->description = "Delete all empty animation data containers from visible data-blocks";
-
+
/* api callbacks */
ot->exec = animchannels_clean_empty_exec;
ot->poll = animedit_poll_channels_nla_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2193,56 +2193,56 @@ static void ANIM_OT_channels_clean_empty(wmOperatorType *ot)
static int animchannels_enable_poll(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
-
+
/* channels region test */
/* TODO: could enhance with actually testing if channels region? */
if (ELEM(NULL, sa, CTX_wm_region(C)))
return 0;
-
+
/* animation editor test - Action/Dopesheet/etc. and Graph only */
if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_IPO) == 0)
return 0;
-
+
return 1;
}
static int animchannels_enable_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* loop through filtered data and clean curves */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
-
+
/* remove disabled flags from F-Curves */
fcu->flag &= ~FCURVE_DISABLED;
-
+
/* for drivers, let's do the same too */
if (fcu->driver)
fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
-
+
/* tag everything for updates - in particular, this is needed to get drivers working again */
ale->update |= ANIM_UPDATE_DEPS;
}
-
+
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2252,11 +2252,11 @@ static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
ot->name = "Revive Disabled F-Curves";
ot->idname = "ANIM_OT_channels_fcurves_enable";
ot->description = "Clears 'disabled' tag from all F-Curves to get broken F-Curves working again";
-
+
/* api callbacks */
ot->exec = animchannels_enable_exec;
ot->poll = animchannels_enable_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2267,10 +2267,10 @@ static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
static int animchannels_find_poll(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
-
+
if (sa == NULL)
return 0;
-
+
/* animation editor with dopesheet */
return ELEM(sa->spacetype, SPACE_ACTION, SPACE_IPO, SPACE_NLA);
}
@@ -2279,14 +2279,14 @@ static int animchannels_find_poll(bContext *C)
static int animchannels_find_invoke(bContext *C, wmOperator *op, const wmEvent *evt)
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* set initial filter text, and enable filter */
RNA_string_set(op->ptr, "query", ac.ads->searchstr);
-
+
/* defer to popup */
return WM_operator_props_popup(C, op, evt);
}
@@ -2295,26 +2295,26 @@ static int animchannels_find_invoke(bContext *C, wmOperator *op, const wmEvent *
static int animchannels_find_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* update filter text, and ensure that filter is enabled if there's something there
* NOTE: we turn the filter off if there's nothing (this is a quick shortcut for dismissing)
*/
RNA_string_get(op->ptr, "query", ac.ads->searchstr);
-
+
if (ac.ads->searchstr[0]) {
ac.ads->filterflag |= ADS_FILTER_BY_FCU_NAME;
}
else {
ac.ads->filterflag &= ~ADS_FILTER_BY_FCU_NAME;
}
-
+
/* redraw */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2324,15 +2324,15 @@ static void ANIM_OT_channels_find(wmOperatorType *ot)
ot->name = "Find Channels";
ot->idname = "ANIM_OT_channels_find";
ot->description = "Filter the set of channels shown to only include those with matching names";
-
+
/* callbacks */
ot->invoke = animchannels_find_invoke;
ot->exec = animchannels_find_exec;
ot->poll = animchannels_find_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_string(ot->srna, "query", "Query", sizeof(((bDopeSheet *)NULL)->searchstr), "", "Text to search for in channel names");
}
@@ -2342,37 +2342,37 @@ static void ANIM_OT_channels_find(wmOperatorType *ot)
static int animchannels_deselectall_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* 'standard' behavior - check if selected, then apply relevant selection */
if (RNA_boolean_get(op->ptr, "invert"))
ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_INVERT);
else
ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_ADD);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
static void ANIM_OT_channels_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select All";
ot->idname = "ANIM_OT_channels_select_all_toggle";
ot->description = "Toggle selection of all animation channels";
-
+
/* api callbacks */
ot->exec = animchannels_deselectall_exec;
ot->poll = animedit_poll_channels_nla_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_boolean(ot->srna, "invert", false, "Invert", "");
}
@@ -2384,12 +2384,12 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
SpaceNla *snla = (SpaceNla *)ac->sl;
View2D *v2d = &ac->ar->v2d;
rctf rectf;
float ymin, ymax;
-
+
/* set initial y extents */
if (ac->datatype == ANIMCONT_NLA) {
ymin = (float)(-NLACHANNEL_HEIGHT(snla));
@@ -2399,27 +2399,27 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec
ymin = 0.0f;
ymax = (float)(-ACHANNEL_HEIGHT(ac));
}
-
+
/* convert border-region to view coordinates */
UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin + 2, &rectf.xmin, &rectf.ymin);
UI_view2d_region_to_view(v2d, rect->xmax, rect->ymax - 2, &rectf.xmax, &rectf.ymax);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop over data, doing border select */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ac->datatype == ANIMCONT_NLA)
ymin = ymax - NLACHANNEL_STEP(snla);
else
ymin = ymax - ACHANNEL_STEP(ac);
-
+
/* if channel is within border-select region, alter it */
if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
/* set selection flags only */
ANIM_channel_setting_set(ac, ale, ACHANNEL_SETTING_SELECT, selectmode);
-
+
/* type specific actions */
switch (ale->type) {
case ANIMTYPE_GROUP:
@@ -2433,20 +2433,20 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt = (NlaTrack *)ale->data;
-
- /* for now, it's easier just to do this here manually, as defining a new type
- * currently adds complications when doing other stuff
+
+ /* for now, it's easier just to do this here manually, as defining a new type
+ * currently adds complications when doing other stuff
*/
ACHANNEL_SET_FLAG(nlt, selectmode, NLATRACK_SELECTED);
break;
}
}
}
-
+
/* set minimum extent to be the maximum of the next channel */
ymax = ymin;
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -2460,11 +2460,11 @@ static int animchannels_borderselect_exec(bContext *C, wmOperator *op)
short selectmode = 0;
const bool select = !RNA_boolean_get(op->ptr, "deselect");
const bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get settings from operator */
WM_operator_properties_border_to_rcti(op, &rect);
@@ -2478,15 +2478,15 @@ static int animchannels_borderselect_exec(bContext *C, wmOperator *op)
else {
selectmode = ACHANNEL_SETFLAG_CLEAR;
}
-
+
/* apply borderselect animation channels */
borderselect_anim_channels(&ac, &rect, selectmode);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
-}
+}
static void ANIM_OT_channels_select_border(wmOperatorType *ot)
{
@@ -2494,18 +2494,18 @@ static void ANIM_OT_channels_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->idname = "ANIM_OT_channels_select_border";
ot->description = "Select all animation channels within the specified region";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = animchannels_borderselect_exec;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = animedit_poll_channels_nla_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
}
@@ -2520,33 +2520,33 @@ static bool rename_anim_channels(bAnimContext *ac, int channel_index)
bAnimListElem *ale;
int filter;
bool success = false;
-
+
/* get the channel that was clicked on */
/* filter channels */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* get channel from index */
ale = BLI_findlink(&anim_data, channel_index);
if (ale == NULL) {
/* channel not found */
if (G.debug & G_DEBUG)
printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n", channel_index);
-
+
ANIM_animdata_freelist(&anim_data);
return false;
}
-
+
/* check that channel can be renamed */
acf = ANIM_channel_get_typeinfo(ale);
if (acf && acf->name_prop) {
PointerRNA ptr;
PropertyRNA *prop;
-
+
/* ok if we can get name property to edit from this channel */
if (acf->name_prop(ale, &ptr, &prop)) {
/* actually showing the rename textfield is done on redraw,
- * so here we just store the index of this channel in the
+ * so here we just store the index of this channel in the
* dopesheet data, which will get utilized when drawing the
* channel...
*
@@ -2558,7 +2558,7 @@ static bool rename_anim_channels(bAnimContext *ac, int channel_index)
}
}
}
-
+
/* free temp data and tag for refresh */
ANIM_animdata_freelist(&anim_data);
ED_region_tag_redraw(ac->ar);
@@ -2571,18 +2571,18 @@ static int animchannels_channel_get(bAnimContext *ac, const int mval[2])
View2D *v2d;
int channel_index;
float x, y;
-
+
/* get useful pointers from animation context data */
ar = ac->ar;
v2d = &ar->v2d;
-
- /* figure out which channel user clicked in
+
+ /* figure out which channel user clicked in
* Note: although channels technically start at (y = ACHANNEL_FIRST), we need to adjust by half a channel's height
* so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
* ACHANNEL_HEIGHT_HALF.
*/
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
-
+
if (ac->datatype == ANIMCONT_NLA) {
SpaceNla *snla = (SpaceNla *)ac->sl;
UI_view2d_listview_view_to_cell(v2d, NLACHANNEL_NAMEWIDTH, NLACHANNEL_STEP(snla), 0, (float)NLACHANNEL_HEIGHT_HALF(snla), x, y, NULL, &channel_index);
@@ -2619,7 +2619,7 @@ static void ANIM_OT_channels_rename(wmOperatorType *ot)
ot->name = "Rename Channels";
ot->idname = "ANIM_OT_channels_rename";
ot->description = "Rename animation channel under mouse";
-
+
/* api callbacks */
ot->invoke = animchannels_rename_invoke;
ot->poll = animedit_poll_channels_active;
@@ -2634,19 +2634,19 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
bAnimListElem *ale;
int filter;
int notifierFlags = 0;
-
+
/* get the channel that was clicked on */
/* filter channels */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* get channel from index */
ale = BLI_findlink(&anim_data, channel_index);
if (ale == NULL) {
/* channel not found */
if (G.debug & G_DEBUG)
printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n", channel_index);
-
+
ANIM_animdata_freelist(&anim_data);
return 0;
}
@@ -2666,7 +2666,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
{
Scene *sce = (Scene *)ale->data;
AnimData *adt = sce->adt;
-
+
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
@@ -2677,7 +2677,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
sce->flag |= SCE_DS_SELECTED;
if (adt) adt->flag |= ADT_UI_SELECTED;
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
@@ -2691,7 +2691,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
Base *base = (Base *)ale->data;
Object *ob = base->object;
AnimData *adt = ob->adt;
-
+
/* set selection status */
if (base->flag & BASE_SELECTABLED) {
if (selectmode == SELECT_INVERT) {
@@ -2765,28 +2765,28 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
ale->adt->flag |= ADT_UI_SELECTED;
}
-
+
/* set active? */
if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
ale->adt->flag |= ADT_UI_ACTIVE;
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
- case ANIMTYPE_GROUP:
+ case ANIMTYPE_GROUP:
{
bActionGroup *agrp = (bActionGroup *)ale->data;
-
+
Object *ob = NULL;
bPoseChannel *pchan = NULL;
-
-
+
+
/* Armatures-Specific Feature:
* Since groups are used to collect F-Curves of the same Bone by default
* (via Keying Sets) so that they can be managed better, we try to make
* things here easier for animators by mapping group selection to bone
- * selection.
+ * selection.
*
* Only do this if "Only Selected" dopesheet filter is not active, or else it
* becomes too unpredictable/tricky to manage
@@ -2794,7 +2794,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
ob = (Object *)ale->id;
-
+
if (ob->type == OB_ARMATURE) {
/* Assume for now that any group with corresponding name is what we want
* (i.e. for an armature whose location is animated, things would break
@@ -2803,10 +2803,10 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
* TODO: check the first F-Curve or so to be sure...
*/
pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
- }
+ }
}
}
-
+
/* select/deselect group */
if (selectmode == SELECT_INVERT) {
/* inverse selection status of this group only */
@@ -2815,11 +2815,11 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
else if (selectmode == -1) {
/* select all in group (and deselect everthing else) */
FCurve *fcu;
-
+
/* deselect all other channels */
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
if (pchan) ED_pose_deselect_all(ob, SEL_DESELECT, false);
-
+
/* only select channels in group and group itself */
for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next)
fcu->flag |= FCURVE_SELECTED;
@@ -2829,10 +2829,10 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
/* select group by itself */
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
if (pchan) ED_pose_deselect_all(ob, SEL_DESELECT, false);
-
+
agrp->flag |= AGRP_SELECTED;
}
-
+
/* if group is selected now, make group the 'active' one in the visible list */
if (agrp->flag & AGRP_SELECTED) {
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
@@ -2842,7 +2842,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, NULL, ANIMTYPE_GROUP);
if (pchan) ED_pose_bone_select(ob, pchan, false);
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
@@ -2850,7 +2850,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
case ANIMTYPE_NLACURVE:
{
FCurve *fcu = (FCurve *)ale->data;
-
+
/* select/deselect */
if (selectmode == SELECT_INVERT) {
/* inverse selection status of this F-Curve only */
@@ -2861,18 +2861,18 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
fcu->flag |= FCURVE_SELECTED;
}
-
+
/* if F-Curve is selected now, make F-Curve the 'active' one in the visible list */
if (fcu->flag & FCURVE_SELECTED)
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
- case ANIMTYPE_SHAPEKEY:
+ case ANIMTYPE_SHAPEKEY:
{
KeyBlock *kb = (KeyBlock *)ale->data;
-
+
/* select/deselect */
if (selectmode == SELECT_INVERT) {
/* inverse selection status of this ShapeKey only */
@@ -2883,39 +2883,39 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
kb->flag |= KEYBLOCK_SEL;
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
case ANIMTYPE_NLACONTROLS:
{
AnimData *adt = (AnimData *)ale->data;
-
+
/* toggle expand
* - Although the triangle widget already allows this, since there's nothing else that can be done here now,
* let's just use it for easier expand/collapse for now
*/
adt->flag ^= ADT_NLA_SKEYS_COLLAPSED;
-
+
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
break;
}
case ANIMTYPE_GPDATABLOCK:
{
bGPdata *gpd = (bGPdata *)ale->data;
-
- /* toggle expand
+
+ /* toggle expand
* - although the triangle widget already allows this, the whole channel can also be used for this purpose
*/
gpd->flag ^= GP_DATA_EXPAND;
-
+
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
break;
}
case ANIMTYPE_GPLAYER:
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
+
/* select/deselect */
if (selectmode == SELECT_INVERT) {
/* invert selection status of this layer only */
@@ -2926,12 +2926,12 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
gpl->flag |= GP_LAYER_SELECT;
}
-
+
/* change active layer, if this is selected (since we must always have an active layer) */
if (gpl->flag & GP_LAYER_SELECT) {
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, gpl, ANIMTYPE_GPLAYER);
}
-
+
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* Grease Pencil updates */
notifierFlags |= (ND_ANIMCHAN | NA_EDITED); /* Animation Ediotrs updates */
break;
@@ -2939,19 +2939,19 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
case ANIMTYPE_MASKDATABLOCK:
{
Mask *mask = (Mask *)ale->data;
-
+
/* toggle expand
* - although the triangle widget already allows this, the whole channel can also be used for this purpose
*/
mask->flag ^= MASK_ANIMF_EXPAND;
-
+
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
break;
}
case ANIMTYPE_MASKLAYER:
{
MaskLayer *masklay = (MaskLayer *)ale->data;
-
+
/* select/deselect */
if (selectmode == SELECT_INVERT) {
/* invert selection status of this layer only */
@@ -2962,7 +2962,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
masklay->flag |= MASK_LAYERFLAG_SELECT;
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
break;
}
@@ -2971,10 +2971,10 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
printf("Error: Invalid channel type in mouse_anim_channels()\n");
break;
}
-
+
/* free channels */
ANIM_animdata_freelist(&anim_data);
-
+
/* return notifier flags */
return notifierFlags;
}
@@ -2991,16 +2991,16 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE
int notifierFlags = 0;
short selectmode;
float x, y;
-
-
+
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get useful pointers from animation context data */
ar = ac.ar;
v2d = &ar->v2d;
-
+
/* select mode is either replace (deselect all, then add) or add/extend */
if (RNA_boolean_get(op->ptr, "extend"))
selectmode = SELECT_INVERT;
@@ -3008,45 +3008,45 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE
selectmode = -1; /* this is a bit of a special case for ActionGroups only... should it be removed or extended to all instead? */
else
selectmode = SELECT_REPLACE;
-
- /* figure out which channel user clicked in
+
+ /* figure out which channel user clicked in
* Note: although channels technically start at (y = ACHANNEL_FIRST), we need to adjust by half a channel's height
* so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
* ACHANNEL_HEIGHT_HALF.
*/
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP(&ac), 0, (float)ACHANNEL_HEIGHT_HALF(&ac), x, y, NULL, &channel_index);
-
+
/* handle mouse-click in the relevant channel then */
notifierFlags = mouse_anim_channels(C, &ac, channel_index, selectmode);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
static void ANIM_OT_channels_click(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Mouse Click on Channels";
ot->idname = "ANIM_OT_channels_click";
ot->description = "Handle mouse-clicks over animation channels";
-
+
/* api callbacks */
ot->invoke = animchannels_mouseclick_invoke;
ot->poll = animedit_poll_channels_active;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
/* NOTE: don't save settings, otherwise, can end up with some weird behaviour (sticky extend) */
prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
+
prop = RNA_def_boolean(ot->srna, "children_only", false, "Select Children Only", ""); // CTRLKEY|SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -3157,13 +3157,13 @@ void ED_operatortypes_animchannels(void)
{
WM_operatortype_append(ANIM_OT_channels_select_all_toggle);
WM_operatortype_append(ANIM_OT_channels_select_border);
-
+
WM_operatortype_append(ANIM_OT_channels_click);
WM_operatortype_append(ANIM_OT_channel_select_keys);
WM_operatortype_append(ANIM_OT_channels_rename);
WM_operatortype_append(ANIM_OT_channels_find);
-
+
WM_operatortype_append(ANIM_OT_channels_setting_enable);
WM_operatortype_append(ANIM_OT_channels_setting_disable);
WM_operatortype_append(ANIM_OT_channels_setting_toggle);
@@ -3172,16 +3172,16 @@ void ED_operatortypes_animchannels(void)
/* XXX does this need to be a separate operator? */
WM_operatortype_append(ANIM_OT_channels_editable_toggle);
-
+
WM_operatortype_append(ANIM_OT_channels_move);
-
+
WM_operatortype_append(ANIM_OT_channels_expand);
WM_operatortype_append(ANIM_OT_channels_collapse);
-
+
WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
-
+
WM_operatortype_append(ANIM_OT_channels_clean_empty);
-
+
WM_operatortype_append(ANIM_OT_channels_group);
WM_operatortype_append(ANIM_OT_channels_ungroup);
}
@@ -3191,7 +3191,7 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Animation Channels", 0, 0);
wmKeyMapItem *kmi;
-
+
/* click-select */
/* XXX for now, only leftmouse.... */
WM_keymap_add_item(keymap, "ANIM_OT_channels_click", LEFTMOUSE, KM_PRESS, 0, 0);
@@ -3206,31 +3206,31 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
/* find (i.e. a shortcut for setting the name filter) */
WM_keymap_add_item(keymap, "ANIM_OT_channels_find", FKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* deselect all */
WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", AKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", true);
-
+
/* borderselect */
WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", EVT_TWEAK_L, KM_ANY, 0, 0);
-
+
/* delete */
WM_keymap_add_item(keymap, "ANIM_OT_channels_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ANIM_OT_channels_delete", DELKEY, KM_PRESS, 0, 0);
-
+
/* settings */
WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_enable", WKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_disable", WKEY, KM_PRESS, KM_ALT, 0);
-
+
/* settings - specialized hotkeys */
WM_keymap_add_item(keymap, "ANIM_OT_channels_editable_toggle", TABKEY, KM_PRESS, 0, 0);
-
+
/* expand/collapse */
WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "ANIM_OT_channels_expand", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "all", false);
kmi = WM_keymap_add_item(keymap, "ANIM_OT_channels_collapse", PADMINUS, KM_PRESS, KM_CTRL, 0);
@@ -3241,7 +3241,7 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "direction", REARRANGE_ANIMCHAN_DOWN);
RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_move", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "direction", REARRANGE_ANIMCHAN_BOTTOM);
-
+
/* grouping */
WM_keymap_add_item(keymap, "ANIM_OT_channels_group", GKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ANIM_OT_channels_ungroup", GKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index bfa9570b3f5..adb5a10c19d 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -46,10 +46,10 @@
#include "BKE_animsys.h"
#include "BKE_action.h"
+#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_gpencil.h"
-#include "BKE_context.h"
-#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_sequencer.h"
@@ -64,7 +64,7 @@
/* tags the given anim list element for refreshes (if applicable)
* due to Animation Editor editing
*/
-void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale)
+void ANIM_list_elem_update(Main *bmain, Scene *scene, bAnimListElem *ale)
{
ID *id;
FCurve *fcu;
@@ -73,7 +73,7 @@ void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale)
id = ale->id;
if (!id)
return;
-
+
/* tag AnimData for refresh so that other views will update in realtime with these changes */
adt = BKE_animdata_from_id(id);
if (adt) {
@@ -86,18 +86,18 @@ void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale)
/* update data */
fcu = (ale->datatype == ALE_FCURVE) ? ale->key_data : NULL;
-
+
if (fcu && fcu->rna_path) {
/* if we have an fcurve, call the update for the property we
* are editing, this is then expected to do the proper redraws
* and depsgraph updates */
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
-
+
RNA_id_pointer_create(id, &id_ptr);
-
+
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop))
- RNA_property_update_main(G.main, scene, &ptr, prop);
+ RNA_property_update_main(bmain, scene, &ptr, prop);
}
else {
/* in other case we do standard depsgraph update, ideally
@@ -106,17 +106,17 @@ void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale)
}
}
-/* tags the given ID block for refreshes (if applicable) due to
+/* tags the given ID block for refreshes (if applicable) due to
* Animation Editor editing */
void ANIM_id_update(Scene *UNUSED(scene), ID *id)
{
if (id) {
AnimData *adt = BKE_animdata_from_id(id);
-
+
/* tag AnimData for refresh so that other views will update in realtime with these changes */
if (adt)
adt->recalc |= ADT_RECALC_ANIM;
-
+
/* set recalc flags */
DEG_id_tag_update(id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); // XXX or do we want something more restrictive?
}
@@ -137,33 +137,33 @@ static void animchan_sync_group(bAnimContext *ac, bAnimListElem *ale, bActionGro
{
bActionGroup *agrp = (bActionGroup *)ale->data;
ID *owner_id = ale->id;
-
+
/* major priority is selection status
* so we need both a group and an owner
*/
if (ELEM(NULL, agrp, owner_id))
return;
-
+
/* for standard Objects, check if group is the name of some bone */
if (GS(owner_id->name) == ID_OB) {
Object *ob = (Object *)owner_id;
-
- /* check if there are bones, and whether the name matches any
+
+ /* check if there are bones, and whether the name matches any
* NOTE: this feature will only really work if groups by default contain the F-Curves for a single bone
*/
if (ob->pose) {
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
bArmature *arm = ob->data;
-
+
if (pchan) {
bActionGroup *bgrp;
-
+
/* if one matches, sync the selection status */
if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))
agrp->flag |= AGRP_SELECTED;
else
agrp->flag &= ~AGRP_SELECTED;
-
+
/* also sync active group status */
if ((ob == ac->obact) && (pchan->bone == arm->act_bone)) {
/* if no previous F-Curve has active flag, then we're the first and only one to get it */
@@ -180,7 +180,7 @@ static void animchan_sync_group(bAnimContext *ac, bAnimListElem *ale, bActionGro
/* this can't possibly be active now */
agrp->flag &= ~AGRP_ACTIVE;
}
-
+
/* sync group colors */
bgrp = (bActionGroup *)BLI_findlink(&ob->pose->agroups, (pchan->agrp_index - 1));
if (bgrp) {
@@ -191,33 +191,33 @@ static void animchan_sync_group(bAnimContext *ac, bAnimListElem *ale, bActionGro
}
}
}
-
+
/* perform syncing updates for F-Curves */
static void animchan_sync_fcurve(bAnimContext *ac, bAnimListElem *ale, FCurve **active_fcurve)
{
FCurve *fcu = (FCurve *)ale->data;
ID *owner_id = ale->id;
-
- /* major priority is selection status, so refer to the checks done in anim_filter.c
+
+ /* major priority is selection status, so refer to the checks done in anim_filter.c
* skip_fcurve_selected_data() for reference about what's going on here...
*/
if (ELEM(NULL, fcu, fcu->rna_path, owner_id))
return;
-
+
if (GS(owner_id->name) == ID_OB) {
Object *ob = (Object *)owner_id;
-
+
/* only affect if F-Curve involves pose.bones */
if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) {
bArmature *arm = (bArmature *)ob->data;
bPoseChannel *pchan;
char *bone_name;
-
+
/* get bone-name, and check if this bone is selected */
bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
if (bone_name) MEM_freeN(bone_name);
-
+
/* F-Curve selection depends on whether the bone is selected */
if ((pchan) && (pchan->bone)) {
/* F-Curve selection */
@@ -225,8 +225,8 @@ static void animchan_sync_fcurve(bAnimContext *ac, bAnimListElem *ale, FCurve **
fcu->flag |= FCURVE_SELECTED;
else
fcu->flag &= ~FCURVE_SELECTED;
-
- /* Active F-Curve - it should be the first one for this bone on the
+
+ /* Active F-Curve - it should be the first one for this bone on the
* active object to be considered as active
*/
if ((ob == ac->obact) && (pchan->bone == arm->act_bone)) {
@@ -249,18 +249,18 @@ static void animchan_sync_fcurve(bAnimContext *ac, bAnimListElem *ale, FCurve **
}
else if (GS(owner_id->name) == ID_SCE) {
Scene *scene = (Scene *)owner_id;
-
+
/* only affect if F-Curve involves sequence_editor.sequences */
if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
char *seq_name;
-
+
/* get strip name, and check if this strip is selected */
seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
if (seq_name) MEM_freeN(seq_name);
-
+
/* update selection status */
if (seq) {
if (seq->flag & SELECT)
@@ -272,17 +272,17 @@ static void animchan_sync_fcurve(bAnimContext *ac, bAnimListElem *ale, FCurve **
}
else if (GS(owner_id->name) == ID_NT) {
bNodeTree *ntree = (bNodeTree *)owner_id;
-
+
/* check for selected nodes */
if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
bNode *node;
char *node_name;
-
+
/* get strip name, and check if this strip is selected */
node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
node = nodeFindNodebyName(ntree, node_name);
if (node_name) MEM_freeN(node_name);
-
+
/* update selection/active status */
if (node) {
/* update selection status */
@@ -290,7 +290,7 @@ static void animchan_sync_fcurve(bAnimContext *ac, bAnimListElem *ale, FCurve **
fcu->flag |= FCURVE_SELECTED;
else
fcu->flag &= ~FCURVE_SELECTED;
-
+
/* update active status */
/* XXX: this may interfere with setting bones as active if both exist at once;
* then again, if that's the case, production setups aren't likely to be animating
@@ -317,7 +317,7 @@ static void animchan_sync_fcurve(bAnimContext *ac, bAnimListElem *ale, FCurve **
static void animchan_sync_gplayer(bAnimContext *UNUSED(ac), bAnimListElem *ale)
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
+
/* Make sure the selection flags agree with the "active" flag.
* The selection flags are used in the Dopesheet only, whereas
* the active flag is used everywhere else. Hence, we try to
@@ -336,7 +336,7 @@ static void animchan_sync_gplayer(bAnimContext *UNUSED(ac), bAnimListElem *ale)
}
/* ---------------- */
-
+
/* Main call to be exported to animation editors */
void ANIM_sync_animchannels_to_data(const bContext *C)
{
@@ -344,38 +344,38 @@ void ANIM_sync_animchannels_to_data(const bContext *C)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
bActionGroup *active_agrp = NULL;
FCurve *active_fcurve = NULL;
-
+
/* get animation context info for filtering the channels */
if (ANIM_animdata_get_context(C, &ac) == 0)
return;
-
+
/* filter data */
- /* NOTE: we want all channels, since we want to be able to set selection status on some of them even when collapsed
+ /* NOTE: we want all channels, since we want to be able to set selection status on some of them even when collapsed
* However, don't include duplicates so that selection statuses don't override each other
*/
filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS;
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* flush settings as appropriate depending on the types of the channels */
for (ale = anim_data.first; ale; ale = ale->next) {
switch (ale->type) {
case ANIMTYPE_GROUP:
animchan_sync_group(&ac, ale, &active_agrp);
break;
-
+
case ANIMTYPE_FCURVE:
animchan_sync_fcurve(&ac, ale, &active_fcurve);
break;
-
+
case ANIMTYPE_GPLAYER:
animchan_sync_gplayer(&ac, ale);
break;
}
}
-
+
ANIM_animdata_freelist(&anim_data);
}
@@ -396,43 +396,43 @@ void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data)
for (ale = anim_data->first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
bGPDlayer *gpl = ale->data;
-
+
if (ale->update & ANIM_UPDATE_ORDER) {
ale->update &= ~ANIM_UPDATE_ORDER;
if (gpl) {
//gpencil_sort_frames(gpl);
}
}
-
+
if (ale->update & ANIM_UPDATE_DEPS) {
ale->update &= ~ANIM_UPDATE_DEPS;
- ANIM_list_elem_update(ac->scene, ale);
+ ANIM_list_elem_update(ac->bmain, ac->scene, ale);
}
}
else if (ale->datatype == ALE_FCURVE) {
FCurve *fcu = ale->key_data;
-
+
if (ale->update & ANIM_UPDATE_ORDER) {
ale->update &= ~ANIM_UPDATE_ORDER;
if (fcu)
sort_time_fcurve(fcu);
}
-
+
if (ale->update & ANIM_UPDATE_HANDLES) {
ale->update &= ~ANIM_UPDATE_HANDLES;
if (fcu)
calchandles_fcurve(fcu);
}
-
+
if (ale->update & ANIM_UPDATE_DEPS) {
ale->update &= ~ANIM_UPDATE_DEPS;
- ANIM_list_elem_update(ac->scene, ale);
+ ANIM_list_elem_update(ac->bmain, ac->scene, ale);
}
}
else if (ale->datatype == ALE_NLASTRIP) {
if (ale->update & ANIM_UPDATE_DEPS) {
ale->update &= ~ANIM_UPDATE_DEPS;
- ANIM_list_elem_update(ac->scene, ale);
+ ANIM_list_elem_update(ac->bmain, ac->scene, ale);
}
}
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 3b13ceefdfd..c2cfb877745 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -75,7 +75,7 @@ void ANIM_draw_cfra_number(const bContext *C, View2D *v2d, short flag)
const float time = scene->r.cfra + scene->r.subframe;
const float cfra = (float)(time * scene->r.framelen);
const bool show_time = (flag & DRAWCFRA_UNIT_SECONDS) != 0;
-
+
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
unsigned char col[4];
float color[4];
@@ -83,13 +83,13 @@ void ANIM_draw_cfra_number(const bContext *C, View2D *v2d, short flag)
char numstr[32] = " t "; /* t is the character to start replacing from */
float hlen;
int slen;
-
+
/* because the frame number text is subject to the same scaling as the contents of the view */
UI_view2d_scale_get(v2d, &xscale, NULL);
gpuPushMatrix();
gpuScale2f(1.0f / xscale, 1.0f);
-
- /* get timecode string
+
+ /* get timecode string
* - padding on str-buf passed so that it doesn't sit on the frame indicator
*/
if (show_time) {
@@ -101,7 +101,7 @@ void ANIM_draw_cfra_number(const bContext *C, View2D *v2d, short flag)
slen = UI_fontstyle_string_width(fstyle, numstr) - 1;
hlen = slen * 0.5f;
-
+
/* get starting coordinates for drawing */
x = cfra * xscale;
y = -0.1f * U.widget_unit;
@@ -163,7 +163,7 @@ void ANIM_draw_cfra(const bContext *C, View2D *v2d, short flag)
void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
{
Scene *scene = CTX_data_scene(C);
-
+
/* only draw this if preview range is set */
if (PRVRANGEON) {
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -243,10 +243,10 @@ AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
/* sanity checks */
if (ac == NULL)
return NULL;
-
+
/* abort if rendering - we may get some race condition issues... */
if (G.is_rendering) return NULL;
-
+
/* apart from strictly keyframe-related contexts, this shouldn't even happen */
// XXX: nla and channel here may not be necessary...
if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_SHAPEKEY, ANIMCONT_DOPESHEET,
@@ -259,7 +259,7 @@ AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
return ale->adt;
}
}
-
+
/* cannot handle... */
return NULL;
}
@@ -272,15 +272,15 @@ static short bezt_nlamapping_restore(KeyframeEditData *ked, BezTriple *bezt)
/* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
AnimData *adt = (AnimData *)ked->data;
short only_keys = (short)ked->i1;
-
+
/* adjust BezTriple handles only if allowed to */
if (only_keys == 0) {
bezt->vec[0][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_UNMAP);
bezt->vec[2][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_UNMAP);
}
-
+
bezt->vec[1][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_UNMAP);
-
+
return 0;
}
@@ -290,20 +290,20 @@ static short bezt_nlamapping_apply(KeyframeEditData *ked, BezTriple *bezt)
/* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
AnimData *adt = (AnimData *)ked->data;
short only_keys = (short)ked->i1;
-
+
/* adjust BezTriple handles only if allowed to */
if (only_keys == 0) {
bezt->vec[0][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_MAP);
bezt->vec[2][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_MAP);
}
-
+
bezt->vec[1][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_MAP);
-
+
return 0;
}
-/* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve
+/* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve
* - restore = whether to map points back to non-mapped time
* - only_keys = whether to only adjust the location of the center point of beztriples
*/
@@ -311,20 +311,20 @@ void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, boo
{
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc map_cb;
-
- /* init edit data
+
+ /* init edit data
* - AnimData is stored in 'data'
* - only_keys is stored in 'i1'
*/
ked.data = (void *)adt;
ked.i1 = (int)only_keys;
-
+
/* get editing callback */
if (restore)
map_cb = bezt_nlamapping_restore;
else
map_cb = bezt_nlamapping_apply;
-
+
/* apply to F-Curve */
ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, map_cb, NULL);
}
@@ -503,7 +503,7 @@ float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short flag
if (id && fcu && fcu->rna_path) {
PointerRNA ptr, id_ptr;
PropertyRNA *prop;
-
+
/* get RNA property that F-Curve affects */
RNA_id_pointer_create(id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
@@ -517,7 +517,7 @@ float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short flag
return RAD2DEGF(1.0f); /* radians to degrees */
}
}
-
+
/* TODO: other rotation types here as necessary */
}
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 0fd97dfb182..8892fed025a 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -113,13 +113,13 @@
static void animedit_get_yscale_factor(bAnimContext *ac)
{
bTheme *btheme = UI_GetTheme();
-
+
/* grab scale factor directly from action editor setting
* NOTE: This theme setting doesn't have an ID, as it cannot be accessed normally
* since it is a float, and the theme settings methods can only handle chars.
*/
ac->yscale_fac = btheme->tact.keyframe_scale_fac;
-
+
/* clamp to avoid problems with uninitialised values... */
if (ac->yscale_fac < 0.1f)
ac->yscale_fac = 1.0f;
@@ -135,22 +135,22 @@ static Key *actedit_get_shapekeys(bAnimContext *ac)
ViewLayer *view_layer = ac->view_layer;
Object *ob;
Key *key;
-
+
ob = OBACT(view_layer);
- if (ob == NULL)
+ if (ob == NULL)
return NULL;
-
+
/* XXX pinning is not available in 'ShapeKey' mode... */
//if (saction->pin) return NULL;
-
+
/* shapekey data is stored with geometry data */
key = BKE_key_from_object(ob);
-
+
if (key) {
if (key->type == KEY_RELATIVE)
return key;
}
-
+
return NULL;
}
@@ -159,7 +159,7 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction)
{
/* get dopesheet */
ac->ads = &saction->ads;
-
+
/* sync settings with current view status, then return appropriate data */
switch (saction->mode) {
case SACTCONT_ACTION: /* 'Action Editor' */
@@ -170,37 +170,37 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction)
else
saction->action = NULL;
}
-
+
ac->datatype = ANIMCONT_ACTION;
ac->data = saction->action;
-
+
ac->mode = saction->mode;
return true;
-
+
case SACTCONT_SHAPEKEY: /* 'ShapeKey Editor' */
ac->datatype = ANIMCONT_SHAPEKEY;
ac->data = actedit_get_shapekeys(ac);
-
+
/* if not pinned, sync with active object */
if (/*saction->pin == 0*/ true) {
Key *key = (Key *)ac->data;
-
+
if (key && key->adt)
saction->action = key->adt->action;
else
saction->action = NULL;
}
-
+
ac->mode = saction->mode;
return true;
-
+
case SACTCONT_GPENCIL: /* Grease Pencil */ /* XXX review how this mode is handled... */
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
saction->ads.source = (ID *)ac->scene;
-
+
ac->datatype = ANIMCONT_GPENCIL;
ac->data = &saction->ads;
-
+
ac->mode = saction->mode;
return true;
@@ -213,48 +213,48 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction)
ac->mode = saction->mode;
return true;
-
+
case SACTCONT_MASK: /* Mask */ /* XXX review how this mode is handled... */
{
/* TODO, other methods to get the mask */
// Sequence *seq = BKE_sequencer_active_get(ac->scene);
//MovieClip *clip = ac->scene->clip;
// struct Mask *mask = seq ? seq->mask : NULL;
-
+
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
saction->ads.source = (ID *)ac->scene;
-
+
ac->datatype = ANIMCONT_MASK;
ac->data = &saction->ads;
-
+
ac->mode = saction->mode;
return true;
}
-
+
case SACTCONT_DOPESHEET: /* DopeSheet */
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
saction->ads.source = (ID *)ac->scene;
-
+
ac->datatype = ANIMCONT_DOPESHEET;
ac->data = &saction->ads;
-
+
ac->mode = saction->mode;
return true;
-
+
case SACTCONT_TIMELINE: /* Timeline */
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
saction->ads.source = (ID *)ac->scene;
-
+
ac->datatype = ANIMCONT_TIMELINE;
ac->data = &saction->ads;
-
+
ac->mode = saction->mode;
return true;
-
+
default: /* unhandled yet */
ac->datatype = ANIMCONT_NONE;
ac->data = NULL;
-
+
ac->mode = -1;
return false;
}
@@ -271,41 +271,41 @@ static bool graphedit_get_context(bAnimContext *ac, SpaceIpo *sipo)
sipo->ads->source = (ID *)ac->scene;
}
ac->ads = sipo->ads;
-
+
/* set settings for Graph Editor - "Selected = Editable" */
if (sipo->flag & SIPO_SELCUVERTSONLY)
sipo->ads->filterflag |= ADS_FILTER_SELEDIT;
else
sipo->ads->filterflag &= ~ADS_FILTER_SELEDIT;
-
+
/* sync settings with current view status, then return appropriate data */
switch (sipo->mode) {
case SIPO_MODE_ANIMATION: /* Animation F-Curve Editor */
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
sipo->ads->source = (ID *)ac->scene;
sipo->ads->filterflag &= ~ADS_FILTER_ONLYDRIVERS;
-
+
ac->datatype = ANIMCONT_FCURVES;
ac->data = sipo->ads;
-
+
ac->mode = sipo->mode;
return true;
-
+
case SIPO_MODE_DRIVERS: /* Driver F-Curve Editor */
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
sipo->ads->source = (ID *)ac->scene;
sipo->ads->filterflag |= ADS_FILTER_ONLYDRIVERS;
-
+
ac->datatype = ANIMCONT_DRIVERS;
ac->data = sipo->ads;
-
+
ac->mode = sipo->mode;
return true;
-
+
default: /* unhandled yet */
ac->datatype = ANIMCONT_NONE;
ac->data = NULL;
-
+
ac->mode = -1;
return false;
}
@@ -320,21 +320,21 @@ static bool nlaedit_get_context(bAnimContext *ac, SpaceNla *snla)
if (snla->ads == NULL)
snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
ac->ads = snla->ads;
-
+
/* sync settings with current view status, then return appropriate data */
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
snla->ads->source = (ID *)ac->scene;
snla->ads->filterflag |= ADS_FILTER_ONLYNLA;
-
+
ac->datatype = ANIMCONT_NLA;
ac->data = snla->ads;
-
+
return true;
}
/* ----------- Public API --------------- */
-/* Obtain current anim-data context, given that context info from Blender context has already been set
+/* Obtain current anim-data context, given that context info from Blender context has already been set
* - AnimContext to write to is provided as pointer to var on stack so that we don't have
* allocation/freeing costs (which are not that avoidable with channels).
*/
@@ -342,7 +342,7 @@ bool ANIM_animdata_context_getdata(bAnimContext *ac)
{
SpaceLink *sl = ac->sl;
bool ok = false;
-
+
/* context depends on editor we are currently in */
if (sl) {
switch (ac->spacetype) {
@@ -366,28 +366,30 @@ bool ANIM_animdata_context_getdata(bAnimContext *ac)
}
}
}
-
+
/* check if there's any valid data */
return (ok && ac->data);
}
-/* Obtain current anim-data context from Blender Context info
+/* Obtain current anim-data context from Blender Context info
* - AnimContext to write to is provided as pointer to var on stack so that we don't have
* allocation/freeing costs (which are not that avoidable with channels).
* - Clears data and sets the information from Blender Context which is useful
*/
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
{
+ Main *bmain = CTX_data_main(C);
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
SpaceLink *sl = CTX_wm_space_data(C);
Scene *scene = CTX_data_scene(C);
-
+
/* clear old context info */
if (ac == NULL) return false;
memset(ac, 0, sizeof(bAnimContext));
-
+
/* get useful default context settings from context */
+ ac->bmain = bmain;
ac->scene = scene;
if (scene) {
ac->markers = ED_context_get_markers(C);
@@ -400,10 +402,10 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->sl = sl;
ac->spacetype = (sa) ? sa->spacetype : 0;
ac->regiontype = (ar) ? ar->regiontype : 0;
-
+
/* initialise default y-scale factor */
animedit_get_yscale_factor(ac);
-
+
/* get data context info */
// XXX: if the below fails, try to grab this info from context instead... (to allow for scripting)
return ANIM_animdata_context_getdata(ac);
@@ -461,7 +463,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
/* quick macro to test if AnimData is usable for NLA */
#define ANIMDATA_HAS_NLA(id) ((id)->adt && (id)->adt->nla_tracks.first)
-/* Quick macro to test for all three above usability tests, performing the appropriate provided
+/* Quick macro to test for all three above usability tests, performing the appropriate provided
* action for each when the AnimData context is appropriate.
*
* Priority order for this goes (most important, to least): AnimData blocks, NLA, Drivers, Keyframes.
@@ -525,7 +527,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
/* ............................... */
-/* Add a new animation channel, taking into account the "peek" flag, which is used to just check
+/* Add a new animation channel, taking into account the "peek" flag, which is used to just check
* whether any channels will be added (but without needing them to actually get created).
*
* ! This causes the calling function to return early if we're only "peeking" for channels
@@ -542,12 +544,12 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ale_statement \
} \
} (void)0
-
+
#define ANIMCHANNEL_NEW_CHANNEL(channel_data, channel_type, owner_id) \
ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, {})
-
+
/* ............................... */
-
+
/* quick macro to test if an anim-channel representing an AnimData block is suitably active */
#define ANIMCHANNEL_ACTIVEOK(ale) \
(!(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) )
@@ -557,8 +559,8 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
(!(filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL)) || \
((filter_mode & ANIMFILTER_SEL) && test_func) || \
((filter_mode & ANIMFILTER_UNSEL) && test_func == 0) )
-
-/* quick macro to test if an anim-channel (F-Curve) is selected ok for editing purposes
+
+/* quick macro to test if an anim-channel (F-Curve) is selected ok for editing purposes
* - _SELEDIT means that only selected curves will have visible+editable keyframes
*
* checks here work as follows:
@@ -573,29 +575,29 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
/* ----------- 'Private' Stuff --------------- */
-/* this function allocates memory for a new bAnimListElem struct for the
+/* this function allocates memory for a new bAnimListElem struct for the
* provided animation channel-data.
*/
static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owner_id)
{
bAnimListElem *ale = NULL;
-
+
/* only allocate memory if there is data to convert */
if (data) {
/* allocate and set generic data */
ale = MEM_callocN(sizeof(bAnimListElem), "bAnimListElem");
-
+
ale->data = data;
ale->type = datatype;
-
+
ale->id = owner_id;
ale->adt = BKE_animdata_from_id(owner_id);
-
+
/* do specifics */
switch (datatype) {
case ANIMTYPE_SUMMARY:
{
- /* nothing to include for now... this is just a dummy wrappy around all the other channels
+ /* nothing to include for now... this is just a dummy wrappy around all the other channels
* in the DopeSheet, and gets included at the start of the list
*/
ale->key_data = NULL;
@@ -605,12 +607,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
case ANIMTYPE_SCENE:
{
Scene *sce = (Scene *)data;
-
+
ale->flag = sce->flag;
-
+
ale->key_data = sce;
ale->datatype = ALE_SCE;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -618,21 +620,21 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Base *base = (Base *)data;
Object *ob = base->object;
-
+
ale->flag = ob->flag;
-
+
ale->key_data = ob;
ale->datatype = ALE_OB;
-
+
ale->adt = BKE_animdata_from_id(&ob->id);
break;
}
case ANIMTYPE_FILLACTD:
{
bAction *act = (bAction *)data;
-
+
ale->flag = act->flag;
-
+
ale->key_data = act;
ale->datatype = ALE_ACT;
break;
@@ -640,9 +642,9 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
case ANIMTYPE_FILLDRIVERS:
{
AnimData *adt = (AnimData *)data;
-
+
ale->flag = adt->flag;
-
+
// XXX... drivers don't show summary for now
ale->key_data = NULL;
ale->datatype = ALE_NONE;
@@ -652,12 +654,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Material *ma = (Material *)data;
AnimData *adt = ma->adt;
-
+
ale->flag = FILTER_MAT_OBJD(ma);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -665,12 +667,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Lamp *la = (Lamp *)data;
AnimData *adt = la->adt;
-
+
ale->flag = FILTER_LAM_OBJD(la);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -678,12 +680,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Camera *ca = (Camera *)data;
AnimData *adt = ca->adt;
-
+
ale->flag = FILTER_CAM_OBJD(ca);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -704,12 +706,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Curve *cu = (Curve *)data;
AnimData *adt = cu->adt;
-
+
ale->flag = FILTER_CUR_OBJD(cu);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -717,12 +719,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
bArmature *arm = (bArmature *)data;
AnimData *adt = arm->adt;
-
+
ale->flag = FILTER_ARM_OBJD(arm);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -730,12 +732,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Mesh *me = (Mesh *)data;
AnimData *adt = me->adt;
-
+
ale->flag = FILTER_MESH_OBJD(me);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -743,12 +745,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Lattice *lt = (Lattice *)data;
AnimData *adt = lt->adt;
-
+
ale->flag = FILTER_LATTICE_OBJD(lt);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -756,12 +758,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Speaker *spk = (Speaker *)data;
AnimData *adt = spk->adt;
-
+
ale->flag = FILTER_SPK_OBJD(spk);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -769,12 +771,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Key *key = (Key *)data;
AnimData *adt = key->adt;
-
+
ale->flag = FILTER_SKE_OBJD(key);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -782,12 +784,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
World *wo = (World *)data;
AnimData *adt = wo->adt;
-
+
ale->flag = FILTER_WOR_SCED(wo);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -795,12 +797,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
bNodeTree *ntree = (bNodeTree *)data;
AnimData *adt = ntree->adt;
-
+
ale->flag = FILTER_NTREE_DATA(ntree);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -808,12 +810,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data;
AnimData *adt = linestyle->adt;
-
- ale->flag = FILTER_LS_SCED(linestyle);
-
+
+ ale->flag = FILTER_LS_SCED(linestyle);
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -821,12 +823,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
ParticleSettings *part = (ParticleSettings *)ale->data;
AnimData *adt = part->adt;
-
+
ale->flag = FILTER_PART_OBJD(part);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -834,12 +836,12 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
Tex *tex = (Tex *)data;
AnimData *adt = tex->adt;
-
+
ale->flag = FILTER_TEX_DATA(tex);
-
+
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -847,14 +849,14 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
bGPdata *gpd = (bGPdata *)data;
AnimData *adt = gpd->adt;
-
+
/* NOTE: we just reuse the same expand filter for this case */
ale->flag = EXPANDED_GPD(gpd);
-
+
// XXX: currently, this is only used for access to its animation data
ale->key_data = (adt) ? adt->action : NULL;
ale->datatype = ALE_ACT;
-
+
ale->adt = BKE_animdata_from_id(data);
break;
}
@@ -874,9 +876,9 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
case ANIMTYPE_NLACONTROLS:
{
AnimData *adt = (AnimData *)data;
-
+
ale->flag = adt->flag;
-
+
ale->key_data = NULL;
ale->datatype = ALE_NONE;
break;
@@ -884,9 +886,9 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
case ANIMTYPE_GROUP:
{
bActionGroup *agrp = (bActionGroup *)data;
-
+
ale->flag = agrp->flag;
-
+
ale->key_data = NULL;
ale->datatype = ALE_GROUP;
break;
@@ -895,9 +897,9 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
case ANIMTYPE_NLACURVE: /* practically the same as ANIMTYPE_FCURVE. Differences are applied post-creation */
{
FCurve *fcu = (FCurve *)data;
-
+
ale->flag = fcu->flag;
-
+
ale->key_data = fcu;
ale->datatype = ALE_FCURVE;
break;
@@ -906,19 +908,19 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
{
KeyBlock *kb = (KeyBlock *)data;
Key *key = (Key *)ale->id;
-
+
ale->flag = kb->flag;
-
+
/* whether we have keyframes depends on whether there is a Key block to find it from */
if (key) {
/* index of shapekey is defined by place in key's list */
ale->index = BLI_findindex(&key->block, kb);
-
+
/* the corresponding keyframes are from the animdata */
if (ale->adt && ale->adt->action) {
bAction *act = ale->adt->action;
char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
-
+
/* try to find the F-Curve which corresponds to this exactly,
* then free the MEM_alloc'd string
*/
@@ -934,9 +936,9 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
case ANIMTYPE_GPLAYER:
{
bGPDlayer *gpl = (bGPDlayer *)data;
-
+
ale->flag = gpl->flag;
-
+
ale->key_data = NULL;
ale->datatype = ALE_GPFRAME;
break;
@@ -944,9 +946,9 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
case ANIMTYPE_MASKLAYER:
{
MaskLayer *masklay = (MaskLayer *)data;
-
+
ale->flag = masklay->flag;
-
+
ale->key_data = NULL;
ale->datatype = ALE_MASKLAY;
break;
@@ -954,9 +956,9 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt = (NlaTrack *)data;
-
+
ale->flag = nlt->flag;
-
+
ale->key_data = &nlt->strips;
ale->datatype = ALE_NLASTRIP;
break;
@@ -970,11 +972,11 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
}
}
}
-
+
/* return created datatype */
return ale;
}
-
+
/* ----------------------------------------- */
/* 'Only Selected' selected data and/or 'Include Hidden' filtering
@@ -987,26 +989,26 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
}
/* hidden items should be skipped if we only care about visible data, but we aren't interested in hidden stuff */
const bool skip_hidden = (filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN);
-
+
if (GS(owner_id->name) == ID_OB) {
Object *ob = (Object *)owner_id;
-
+
/* only consider if F-Curve involves pose.bones */
if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) {
bPoseChannel *pchan;
char *bone_name;
-
+
/* get bone-name, and check if this bone is selected */
bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
if (bone_name) MEM_freeN(bone_name);
-
+
/* check whether to continue or skip */
if ((pchan) && (pchan->bone)) {
/* if only visible channels, skip if bone not visible unless user wants channels from hidden data too */
if (skip_hidden) {
bArmature *arm = (bArmature *)ob->data;
-
+
/* skipping - not visible on currently visible layers */
if ((arm->layer & pchan->bone->layer) == 0)
return true;
@@ -1014,7 +1016,7 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
if (pchan->bone->flag & BONE_HIDDEN_P)
return true;
}
-
+
/* can only add this F-Curve if it is selected */
if (ads->filterflag & ADS_FILTER_ONLYSEL) {
if ((pchan->bone->flag & BONE_SELECTED) == 0)
@@ -1025,20 +1027,20 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
}
else if (GS(owner_id->name) == ID_SCE) {
Scene *scene = (Scene *)owner_id;
-
+
/* only consider if F-Curve involves sequence_editor.sequences */
if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = NULL;
char *seq_name;
-
+
if (ed) {
/* get strip name, and check if this strip is selected */
seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
if (seq_name) MEM_freeN(seq_name);
}
-
+
/* can only add this F-Curve if it is selected */
if (ads->filterflag & ADS_FILTER_ONLYSEL) {
if ((seq == NULL) || (seq->flag & SELECT) == 0)
@@ -1048,17 +1050,17 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
}
else if (GS(owner_id->name) == ID_NT) {
bNodeTree *ntree = (bNodeTree *)owner_id;
-
+
/* check for selected nodes */
if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
bNode *node;
char *node_name;
-
+
/* get strip name, and check if this strip is selected */
node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
node = nodeFindNodebyName(ntree, node_name);
if (node_name) MEM_freeN(node_name);
-
+
/* can only add this F-Curve if it is selected */
if (ads->filterflag & ADS_FILTER_ONLYSEL) {
if ((node) && (node->flag & NODE_SELECT) == 0)
@@ -1066,7 +1068,7 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
}
}
}
-
+
return false;
}
@@ -1077,11 +1079,11 @@ static bool name_matches_dopesheet_filter(bDopeSheet *ads, char *name)
/* full fuzzy, multi-word, case insensitive matches */
const size_t str_len = strlen(ads->searchstr);
const int words_max = (str_len / 2) + 1;
-
+
int (*words)[2] = BLI_array_alloca(words, words_max);
const int words_len = BLI_string_find_split_words(ads->searchstr, str_len, ' ', words, words_max);
bool found = false;
-
+
/* match name against all search words */
for (int index = 0; index < words_len; index++) {
if (BLI_strncasestr(name, ads->searchstr + words[index][0], words[index][1])) {
@@ -1089,7 +1091,7 @@ static bool name_matches_dopesheet_filter(bDopeSheet *ads, char *name)
break;
}
}
-
+
/* if we have a match somewhere, this returns true */
return found;
}
@@ -1106,27 +1108,27 @@ static bool skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, eAnim_ChannelTyp
{
bAnimListElem ale_dummy = {NULL};
const bAnimChannelType *acf;
-
+
/* create a dummy wrapper for the F-Curve, so we can get typeinfo for it */
ale_dummy.type = channel_type;
ale_dummy.owner = owner;
ale_dummy.id = owner_id;
ale_dummy.data = fcu;
-
+
/* get type info for channel */
acf = ANIM_channel_get_typeinfo(&ale_dummy);
if (acf && acf->name) {
char name[256]; /* hopefully this will be enough! */
-
+
/* get name */
acf->name(&ale_dummy, name);
-
- /* check for partial match with the match string, assuming case insensitive filtering
+
+ /* check for partial match with the match string, assuming case insensitive filtering
* if match, this channel shouldn't be ignored!
*/
return !name_matches_dopesheet_filter(ads, name);
}
-
+
/* just let this go... */
return true;
}
@@ -1142,19 +1144,19 @@ static bool fcurve_has_errors(FCurve *fcu)
if (fcu->flag & FCURVE_DISABLED) {
return true;
}
-
+
/* driver? */
if (fcu->driver) {
ChannelDriver *driver = fcu->driver;
DriverVar *dvar;
-
+
/* error flag on driver usually means that there is an error
* BUT this may not hold with PyDrivers as this flag gets cleared
* if no critical errors prevent the driver from working...
*/
if (driver->flag & DRIVER_FLAG_INVALID)
return true;
-
+
/* check variables for other things that need linting... */
// TODO: maybe it would be more efficient just to have a quick flag for this?
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
@@ -1166,7 +1168,7 @@ static bool fcurve_has_errors(FCurve *fcu)
DRIVER_TARGETS_LOOPER_END
}
}
-
+
/* no errors found */
return false;
}
@@ -1176,8 +1178,8 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_Chan
{
bActionGroup *grp = (channel_type == ANIMTYPE_FCURVE) ? owner : NULL;
FCurve *fcu = NULL;
-
- /* loop over F-Curves - assume that the caller of this has already checked that these should be included
+
+ /* loop over F-Curves - assume that the caller of this has already checked that these should be included
* NOTE: we need to check if the F-Curves belong to the same group, as this gets called for groups too...
*/
for (fcu = first; ((fcu) && (fcu->grp == grp)); fcu = fcu->next) {
@@ -1197,7 +1199,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_Chan
}
}
}
-
+
/* only include if visible (Graph Editor check, not channels check) */
if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
/* only work with this channel and its subchannels if it is editable */
@@ -1211,14 +1213,14 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_Chan
if (skip_fcurve_with_name(ads, fcu, channel_type, owner, owner_id))
continue;
}
-
+
/* error-based filtering... */
if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) {
/* skip if no errors... */
if (fcurve_has_errors(fcu) == false)
continue;
}
-
+
/* this F-Curve can be used, so return it */
return fcu;
}
@@ -1226,7 +1228,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_Chan
}
}
}
-
+
/* no (more) F-Curves from the list are suitable... */
return NULL;
}
@@ -1238,14 +1240,14 @@ static size_t animfilter_fcurves(ListBase *anim_data, bDopeSheet *ads,
{
FCurve *fcu;
size_t items = 0;
-
- /* loop over every F-Curve able to be included
- * - this for-loop works like this:
+
+ /* loop over every F-Curve able to be included
+ * - this for-loop works like this:
* 1) the starting F-Curve is assigned to the fcu pointer so that we have a starting point to search from
- * 2) the first valid F-Curve to start from (which may include the one given as 'first') in the remaining
+ * 2) the first valid F-Curve to start from (which may include the one given as 'first') in the remaining
* list of F-Curves is found, and verified to be non-null
* 3) the F-Curve referenced by fcu pointer is added to the list
- * 4) the fcu pointer is set to the F-Curve after the one we just added, so that we can keep going through
+ * 4) the fcu pointer is set to the F-Curve after the one we just added, so that we can keep going through
* the rest of the F-Curve list without an eternal loop. Back to step 2 :)
*/
for (fcu = first; ( (fcu = animfilter_fcurve_next(ads, fcu, fcurve_type, filter_mode, owner, owner_id)) ); fcu = fcu->next) {
@@ -1261,7 +1263,7 @@ static size_t animfilter_fcurves(ListBase *anim_data, bDopeSheet *ads,
ANIMCHANNEL_NEW_CHANNEL(fcu, ANIMTYPE_FCURVE, owner_id);
}
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1272,8 +1274,8 @@ static size_t animfilter_act_group(bAnimContext *ac, ListBase *anim_data, bDopeS
size_t tmp_items = 0;
size_t items = 0;
//int ofilter = filter_mode;
-
- /* if we care about the selection status of the channels,
+
+ /* if we care about the selection status of the channels,
* but the group isn't expanded (1)...
* (1) this only matters if we actually care about the hierarchy though.
* - Hierarchy matters: this hack should be applied
@@ -1285,7 +1287,7 @@ static size_t animfilter_act_group(bAnimContext *ac, ListBase *anim_data, bDopeS
/* if the group itself isn't selected appropriately, we shouldn't consider it's children either */
if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) == 0)
return 0;
-
+
/* if we're still here, then the selection status of the curves within this group should not matter,
* since this creates too much overhead for animators (i.e. making a slow workflow)
*
@@ -1296,14 +1298,14 @@ static size_t animfilter_act_group(bAnimContext *ac, ListBase *anim_data, bDopeS
*/
filter_mode &= ~(ANIMFILTER_SEL | ANIMFILTER_UNSEL | ANIMFILTER_LIST_VISIBLE);
}
-
+
/* add grouped F-Curves */
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_AGRP(ac, agrp))
{
/* special filter so that we can get just the F-Curves within the active group */
if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
/* for the Graph Editor, curves may be set to not be visible in the view to lessen clutter,
- * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing
+ * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing
* all its sub-curves to be shown
*/
if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE)) {
@@ -1311,7 +1313,7 @@ static size_t animfilter_act_group(bAnimContext *ac, ListBase *anim_data, bDopeS
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
/* get first F-Curve which can be used here */
FCurve *first_fcu = animfilter_fcurve_next(ads, agrp->channels.first, ANIMTYPE_FCURVE, filter_mode, agrp, owner_id);
-
+
/* filter list, starting from this F-Curve */
tmp_items += animfilter_fcurves(&tmp_data, ads, first_fcu, ANIMTYPE_FCURVE, filter_mode, agrp, owner_id);
}
@@ -1319,26 +1321,26 @@ static size_t animfilter_act_group(bAnimContext *ac, ListBase *anim_data, bDopeS
}
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* add this group as a channel first */
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
/* restore original filter mode so that this next step works ok... */
//filter_mode = ofilter;
-
+
/* filter selection of channel specially here again, since may be open and not subject to previous test */
if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
ANIMCHANNEL_NEW_CHANNEL(agrp, ANIMTYPE_GROUP, owner_id);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1348,30 +1350,30 @@ static size_t animfilter_action(bAnimContext *ac, ListBase *anim_data, bDopeShee
bActionGroup *agrp;
FCurve *lastchan = NULL;
size_t items = 0;
-
+
/* don't include anything from this action if it is linked in from another file,
* and we're getting stuff for editing...
*/
if ((filter_mode & ANIMFILTER_FOREDIT) && ID_IS_LINKED(act))
return 0;
-
+
/* do groups */
// TODO: do nested groups?
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
/* store reference to last channel of group */
- if (agrp->channels.last)
+ if (agrp->channels.last)
lastchan = agrp->channels.last;
-
+
/* action group's channels */
items += animfilter_act_group(ac, anim_data, ads, act, agrp, filter_mode, owner_id);
}
-
+
/* un-grouped F-Curves (only if we're not only considering those channels in the active group) */
if (!(filter_mode & ANIMFILTER_ACTGROUPED)) {
FCurve *firstfcu = (lastchan) ? (lastchan->next) : (act->curves.first);
items += animfilter_fcurves(anim_data, ads, firstfcu, ANIMTYPE_FCURVE, filter_mode, NULL, owner_id);
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1389,10 +1391,10 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop
NlaTrack *nlt;
NlaTrack *first = NULL, *next = NULL;
size_t items = 0;
-
+
/* if showing channels, include active action */
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* if NLA action-line filtering is off, don't show unless there are keyframes,
+ /* if NLA action-line filtering is off, don't show unless there are keyframes,
* in order to keep things more compact for doing transforms
*/
if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || (adt->action)) {
@@ -1402,13 +1404,13 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop
* - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
* overwrite this with the real value - REVIEW THIS...
*/
- ANIMCHANNEL_NEW_CHANNEL_FULL((void *)(&adt->action), ANIMTYPE_NLAACTION, owner_id,
+ ANIMCHANNEL_NEW_CHANNEL_FULL((void *)(&adt->action), ANIMTYPE_NLAACTION, owner_id,
{
- ale->data = adt->action ? adt->action : NULL;
+ ale->data = adt->action ? adt->action : NULL;
});
}
}
-
+
/* first track to include will be the last one if we're filtering by channels */
first = adt->nla_tracks.last;
}
@@ -1416,22 +1418,22 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop
/* first track to include will the first one (as per normal) */
first = adt->nla_tracks.first;
}
-
+
/* loop over NLA Tracks - assume that the caller of this has already checked that these should be included */
for (nlt = first; nlt; nlt = next) {
/* 'next' NLA-Track to use depends on whether we're filtering for drawing or not */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS)
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS)
next = nlt->prev;
else
next = nlt->next;
-
- /* if we're in NLA-tweakmode, don't show this track if it was disabled (due to tweaking) for now
+
+ /* if we're in NLA-tweakmode, don't show this track if it was disabled (due to tweaking) for now
* - active track should still get shown though (even though it has disabled flag set)
*/
// FIXME: the channels after should still get drawn, just 'differently', and after an active-action channel
if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED) && (adt->act_track != nlt))
continue;
-
+
/* only work with this channel and its subchannels if it is editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_NLT(nlt)) {
/* only include this track if selected in a way consistent with the filtering requirements */
@@ -1441,10 +1443,10 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop
/* name based filtering... */
if (((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) && (owner_id)) {
bool track_ok = false, strip_ok = false;
-
+
/* check if the name of the track, or the strips it has are ok... */
track_ok = name_matches_dopesheet_filter(ads, nlt->name);
-
+
if (track_ok == false) {
NlaStrip *strip;
for (strip = nlt->strips.first; strip; strip = strip->next) {
@@ -1454,20 +1456,20 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop
}
}
}
-
+
/* skip if both fail this test... */
if (!track_ok && !strip_ok) {
continue;
}
}
-
+
/* add the track now that it has passed all our tests */
ANIMCHANNEL_NEW_CHANNEL(nlt, ANIMTYPE_NLATRACK, owner_id);
}
}
}
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1480,14 +1482,14 @@ static size_t animfilter_nla_controls(ListBase *anim_data, bDopeSheet *ads, Anim
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
/* add control curves from each NLA strip... */
/* NOTE: ANIMTYPE_FCURVES are created here, to avoid duplicating the code needed */
BEGIN_ANIMFILTER_SUBCHANNELS(((adt->flag & ADT_NLA_SKEYS_COLLAPSED) == 0))
{
NlaTrack *nlt;
NlaStrip *strip;
-
+
/* for now, we only go one level deep - so controls on grouped FCurves are not handled */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
for (strip = nlt->strips.first; strip; strip = strip->next) {
@@ -1497,7 +1499,7 @@ static size_t animfilter_nla_controls(ListBase *anim_data, bDopeSheet *ads, Anim
}
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* add the expander as a channel first */
@@ -1507,13 +1509,13 @@ static size_t animfilter_nla_controls(ListBase *anim_data, bDopeSheet *ads, Anim
ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_NLACONTROLS, owner_id);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the numebr of items added to the list */
return items;
}
@@ -1523,11 +1525,11 @@ static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDope
{
AnimData *adt = BKE_animdata_from_id(id);
size_t items = 0;
-
+
/* image object datablocks have no anim-data so check for NULL */
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id;
-
+
/* NOTE: this macro is used instead of inlining the logic here, since this sort of filtering is still needed
* in a few places in the rest of the code still - notably for the few cases where special mode-based
* different types of data expanders are required.
@@ -1553,7 +1555,7 @@ static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDope
}
);
}
-
+
return items;
}
@@ -1563,22 +1565,22 @@ static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDope
static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Key *key, int filter_mode)
{
size_t items = 0;
-
+
/* check if channels or only F-Curves */
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
KeyBlock *kb;
-
+
/* loop through the channels adding ShapeKeys as appropriate */
for (kb = key->block.first; kb; kb = kb->next) {
/* skip the first one, since that's the non-animatable basis */
if (kb == key->block.first) continue;
-
+
/* only work with this channel and its subchannels if it is editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_SHAPEKEY(kb)) {
/* only include this track if selected in a way consistent with the filtering requirements */
if (ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb)) ) {
// TODO: consider 'active' too?
-
+
/* owner-id here must be key so that the F-Curve can be resolved... */
ANIMCHANNEL_NEW_CHANNEL(kb, ANIMTYPE_SHAPEKEY, key);
}
@@ -1599,7 +1601,7 @@ static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Ke
}
}
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1609,7 +1611,7 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, bDopeShee
{
bGPDlayer *gpl;
size_t items = 0;
-
+
/* loop over layers as the conditions are acceptable */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* only if selected */
@@ -1623,15 +1625,15 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, bDopeShee
if (name_matches_dopesheet_filter(ads, gpl->info) == false)
continue;
}
-
-
+
+
/* add to list */
ANIMCHANNEL_NEW_CHANNEL(gpl, ANIMTYPE_GPLAYER, gpd);
}
}
}
}
-
+
return items;
}
@@ -1639,7 +1641,7 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, bDopeShee
static size_t animdata_filter_gpencil_data(ListBase *anim_data, bDopeSheet *ads, bGPdata *gpd, int filter_mode)
{
size_t items = 0;
-
+
/* When asked from "AnimData" blocks (i.e. the top-level containers for normal animation),
* for convenience, this will return GP Datablocks instead. This may cause issues down
* the track, but for now, this will do...
@@ -1651,14 +1653,14 @@ static size_t animdata_filter_gpencil_data(ListBase *anim_data, bDopeSheet *ads,
else {
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
-
+
/* add gpencil animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
{
tmp_items += animdata_filter_gpencil_layers_data(&tmp_data, ads, gpd, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include data-expand widget first */
@@ -1666,14 +1668,14 @@ static size_t animdata_filter_gpencil_data(ListBase *anim_data, bDopeSheet *ads,
/* add gpd as channel too (if for drawing, and it has layers) */
ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL);
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
}
-
+
return items;
}
@@ -1683,7 +1685,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
{
bDopeSheet *ads = ac->ads;
size_t items = 0;
-
+
if (ads->filterflag & ADS_FILTER_GP_3DONLY) {
Scene *scene = (Scene *)ads->source;
ViewLayer *view_layer = (ViewLayer *)ac->view_layer;
@@ -1693,37 +1695,37 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
if (scene->gpd) {
items += animdata_filter_gpencil_data(anim_data, ads, scene->gpd, filter_mode);
}
-
+
/* Objects in the scene */
for (base = view_layer->object_bases.first; base; base = base->next) {
/* Only consider this object if it has got some GP data (saving on all the other tests) */
if (base->object && base->object->gpd) {
Object *ob = base->object;
-
+
/* firstly, check if object can be included, by the following factors:
* - if only visible, must check for layer and also viewport visibility
* --> while tools may demand only visible, user setting takes priority
* as user option controls whether sets of channels get included while
* tool-flag takes into account collapsed/open channels too
- * - if only selected, must check if object is selected
- * - there must be animation data to edit (this is done recursively as we
+ * - if only selected, must check if object is selected
+ * - there must be animation data to edit (this is done recursively as we
* try to add the channels)
*/
if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
/* layer visibility - we check both object and base, since these may not be in sync yet */
if ((base->flag & BASE_VISIBLED) == 0) continue;
-
+
/* outliner restrict-flag */
if (ob->restrictflag & OB_RESTRICT_VIEW) continue;
}
-
+
/* check selection and object type filters */
if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & BASE_SELECTED) /*|| (base == scene->basact)*/) ) {
/* only selected should be shown */
continue;
}
-
- /* check if object belongs to the filtering group if option to filter
+
+ /* check if object belongs to the filtering group if option to filter
* objects by the grouped status is on
* - used to ease the process of doing multiple-character choreographies
*/
@@ -1731,7 +1733,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0)
continue;
}
-
+
/* finally, include this object's grease pencil datablock */
/* XXX: Should we store these under expanders per item? */
items += animdata_filter_gpencil_data(anim_data, ads, ob->gpd, filter_mode);
@@ -1740,18 +1742,18 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
}
else {
bGPdata *gpd;
-
+
/* Grab all Grease Pencil datablocks directly from main, but only those that seem to be useful somewhere */
- for (gpd = G.main->gpencil.first; gpd; gpd = gpd->id.next) {
+ for (gpd = ac->bmain->gpencil.first; gpd; gpd = gpd->id.next) {
/* only show if gpd is used by something... */
if (ID_REAL_USERS(gpd) < 1)
continue;
-
+
/* add GP frames from this datablock */
items += animdata_filter_gpencil_data(anim_data, ads, gpd, filter_mode);
}
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1762,19 +1764,19 @@ static size_t animdata_filter_ds_gpencil(bAnimContext *ac, ListBase *anim_data,
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
/* add relevant animation channels for Grease Pencil */
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
{
/* add animation channels */
tmp_items += animfilter_block_data(ac, &tmp_data, ads, &gpd->id, filter_mode);
-
+
/* add Grease Pencil layers */
// TODO: do these need a separate expander?
// XXX: what order should these go in?
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include data-expand widget first */
@@ -1785,13 +1787,13 @@ static size_t animdata_filter_ds_gpencil(bAnimContext *ac, ListBase *anim_data,
ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_DSGPENCIL, gpd);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1858,28 +1860,28 @@ static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const i
}
/* Grab all mask data */
-static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int filter_mode)
+static size_t animdata_filter_mask(Main *bmain, ListBase *anim_data, void *UNUSED(data), int filter_mode)
{
Mask *mask;
size_t items = 0;
-
+
/* for now, grab mask datablocks directly from main */
// XXX: this is not good...
- for (mask = G.main->mask.first; mask; mask = mask->id.next) {
+ for (mask = bmain->mask.first; mask; mask = mask->id.next) {
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
-
+
/* only show if mask is used by something... */
if (ID_REAL_USERS(mask) < 1)
continue;
-
+
/* add mask animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MASK(mask))
{
tmp_items += animdata_filter_mask_data(&tmp_data, mask, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include data-expand widget first */
@@ -1887,14 +1889,14 @@ static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int
/* add gpd as channel too (if for drawing, and it has layers) */
ANIMCHANNEL_NEW_CHANNEL(mask, ANIMTYPE_MASKDATABLOCK, NULL);
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1905,7 +1907,7 @@ static size_t animdata_filter_ds_nodetree_group(bAnimContext *ac, ListBase *anim
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
/* add nodetree animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_NTREE_DATA(ntree))
{
@@ -1913,7 +1915,7 @@ static size_t animdata_filter_ds_nodetree_group(bAnimContext *ac, ListBase *anim
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ntree, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include data-expand widget first */
@@ -1923,13 +1925,13 @@ static size_t animdata_filter_ds_nodetree_group(bAnimContext *ac, ListBase *anim
ANIMCHANNEL_NEW_CHANNEL(ntree, ANIMTYPE_DSNTREE, owner_id);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -1938,9 +1940,9 @@ static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data,
{
bNode *node;
size_t items = 0;
-
+
items += animdata_filter_ds_nodetree_group(ac, anim_data, ads, owner_id, ntree, filter_mode);
-
+
for (node = ntree->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP) {
if (node->id) {
@@ -1961,7 +1963,7 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data
ViewLayer *view_layer;
FreestyleLineSet *lineset;
size_t items = 0;
-
+
for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
if (lineset->linestyle) {
@@ -1969,7 +1971,7 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data
}
}
}
-
+
for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
/* skip render layers without Freestyle enabled */
if ((view_layer->flag & VIEW_LAYER_FREESTYLE) == 0) {
@@ -1988,7 +1990,7 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data
continue;
}
linestyle->id.tag &= ~LIB_TAG_DOIT;
-
+
/* add scene-level animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_LS_SCED(linestyle))
{
@@ -1996,7 +1998,7 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)linestyle, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include anim-expand widget first */
@@ -2006,7 +2008,7 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data
ANIMCHANNEL_NEW_CHANNEL(linestyle, ANIMTYPE_DSLINESTYLE, sce);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
@@ -2014,24 +2016,24 @@ static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data
}
}
}
-
+
/* return the number of items added to the list */
return items;
}
-static size_t animdata_filter_ds_texture(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads,
+static size_t animdata_filter_ds_texture(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads,
Tex *tex, ID *owner_id, int filter_mode)
{
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
/* add texture's animation data to temp collection */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_TEX_DATA(tex))
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_TEX_DATA(tex))
{
/* texture animdata */
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)tex, filter_mode);
-
+
/* nodes */
if ((tex->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
/* owner_id as id instead of texture, since it'll otherwise be impossible to track the depth */
@@ -2041,7 +2043,7 @@ static size_t animdata_filter_ds_texture(bAnimContext *ac, ListBase *anim_data,
}
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include texture-expand widget? */
@@ -2051,13 +2053,13 @@ static size_t animdata_filter_ds_texture(bAnimContext *ac, ListBase *anim_data,
ANIMCHANNEL_NEW_CHANNEL(tex, ANIMTYPE_DSTEX, owner_id);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2070,11 +2072,11 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data,
MTex **mtex = NULL;
size_t items = 0;
int a = 0;
-
+
/* get datatype specific data first */
if (owner_id == NULL)
return 0;
-
+
switch (GS(owner_id->name)) {
case ID_PA:
{
@@ -2082,7 +2084,7 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data,
mtex = (MTex **)(&part->mtex);
break;
}
- default:
+ default:
{
/* invalid/unsupported option */
if (G.debug & G_DEBUG)
@@ -2090,19 +2092,19 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data,
return 0;
}
}
-
+
/* firstly check that we actuallly have some textures, by gathering all textures in a temp list */
for (a = 0; a < MAX_MTEX; a++) {
Tex *tex = (mtex[a]) ? mtex[a]->tex : NULL;
-
+
/* for now, if no texture returned, skip (this shouldn't confuse the user I hope) */
- if (tex == NULL)
+ if (tex == NULL)
continue;
-
+
/* add texture's anim channels */
items += animdata_filter_ds_texture(ac, anim_data, ads, tex, owner_id, filter_mode);
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2113,19 +2115,19 @@ static size_t animdata_filter_ds_material(bAnimContext *ac, ListBase *anim_data,
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
/* add material's animation data to temp collection */
BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma))
{
/* material's animation data */
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode);
-
+
/* nodes */
- if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
+ if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include material-expand widget first */
@@ -2135,13 +2137,13 @@ static size_t animdata_filter_ds_material(bAnimContext *ac, ListBase *anim_data,
ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
return items;
}
@@ -2150,23 +2152,23 @@ static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data
bool has_nested = false;
size_t items = 0;
int a = 0;
-
+
/* first pass: take the materials referenced via the Material slots of the object */
for (a = 1; a <= ob->totcol; a++) {
Material *ma = give_current_material(ob, a);
-
+
/* if material is valid, try to add relevant contents from here */
if (ma) {
/* add channels */
items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
-
+
/* for optimising second pass - check if there's a nested material here to come back for */
if (has_nested == false) {
has_nested = (give_node_material(ma) != NULL);
}
}
}
-
+
/* second pass: go through a second time looking for "nested" materials (material.material references)
*
* NOTE: here we ignore the expanded status of the parent, as it could be too confusing as to why these are
@@ -2176,7 +2178,7 @@ static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data
for (a = 1; a <= ob->totcol; a++) {
Material *base = give_current_material(ob, a);
Material *ma = give_node_material(base);
-
+
/* add channels from the nested material if it exists
* - skip if the same material is referenced in its node tree
* (which is common for BI materials) as that results in
@@ -2187,7 +2189,7 @@ static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data
}
}
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2199,10 +2201,10 @@ static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data
typedef struct tAnimFilterModifiersContext {
bAnimContext *ac; /* anim editor context */
bDopeSheet *ads; /* dopesheet filtering settings */
-
+
ListBase tmp_data; /* list of channels created (but not yet added to the main list) */
size_t items; /* number of channels created */
-
+
int filter_mode; /* flags for stuff we want to filter */
} tAnimFilterModifiersContext;
@@ -2213,31 +2215,31 @@ static void animfilter_modifier_idpoin_cb(void *afm_ptr, Object *ob, ID **idpoin
tAnimFilterModifiersContext *afm = (tAnimFilterModifiersContext *)afm_ptr;
ID *owner_id = &ob->id;
ID *id = *idpoin;
-
- /* NOTE: the walker only guarantees to give us all the ID-ptr *slots*,
+
+ /* NOTE: the walker only guarantees to give us all the ID-ptr *slots*,
* not just the ones which are actually used, so be careful!
*/
if (id == NULL)
return;
-
+
/* check if this is something we're interested in... */
switch (GS(id->name)) {
case ID_TE: /* Textures */
{
Tex *tex = (Tex *)id;
- if (!(afm->ads->filterflag & ADS_FILTER_NOTEX)) {
+ if (!(afm->ads->filterflag & ADS_FILTER_NOTEX)) {
afm->items += animdata_filter_ds_texture(afm->ac, &afm->tmp_data, afm->ads, tex, owner_id, afm->filter_mode);
}
break;
}
-
+
/* TODO: images? */
default:
break;
}
}
-/* animation linked to data used by modifiers
+/* animation linked to data used by modifiers
* NOTE: strictly speaking, modifier animation is already included under Object level
* but for some modifiers (e.g. Displace), there can be linked data that has settings
* which would be nice to animate (i.e. texture parameters) but which are not actually
@@ -2248,8 +2250,8 @@ static size_t animdata_filter_ds_modifiers(bAnimContext *ac, ListBase *anim_data
{
tAnimFilterModifiersContext afm = {NULL};
size_t items = 0;
-
- /* 1) create a temporary "context" containing all the info we have here to pass to the callback
+
+ /* 1) create a temporary "context" containing all the info we have here to pass to the callback
* use to walk through the dependencies of the modifiers
*
* ! Assumes that all other unspecified values (i.e. accumulation buffers) are zero'd out properly
@@ -2257,10 +2259,10 @@ static size_t animdata_filter_ds_modifiers(bAnimContext *ac, ListBase *anim_data
afm.ac = ac;
afm.ads = ads;
afm.filter_mode = filter_mode;
-
+
/* 2) walk over dependencies */
modifiers_foreachIDLink(ob, animfilter_modifier_idpoin_cb, &afm);
-
+
/* 3) extract data from the context, merging it back into the standard list */
if (afm.items) {
/* now add the list of collected channels */
@@ -2268,7 +2270,7 @@ static size_t animdata_filter_ds_modifiers(bAnimContext *ac, ListBase *anim_data
BLI_assert(BLI_listbase_is_empty(&afm.tmp_data));
items += afm.items;
}
-
+
return items;
}
@@ -2283,23 +2285,23 @@ static size_t animdata_filter_ds_particles(bAnimContext *ac, ListBase *anim_data
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
-
+
/* if no material returned, skip - so that we don't get weird blank entries... */
if (ELEM(NULL, psys->part, psys->part->adt))
continue;
-
+
/* add particle-system's animation data to temp collection */
BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_PART_OBJD(psys->part))
{
/* particle system's animation data */
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
-
+
/* textures */
if (!(ads->filterflag & ADS_FILTER_NOTEX))
tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include particle-expand widget first */
@@ -2309,14 +2311,14 @@ static size_t animdata_filter_ds_particles(bAnimContext *ac, ListBase *anim_data
ANIMCHANNEL_NEW_CHANNEL(psys->part, ANIMTYPE_DSPART, psys->part);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2327,19 +2329,19 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
IdAdtTemplate *iat = ob->data;
short type = 0, expanded = 0;
-
+
/* get settings based on data type */
switch (ob->type) {
case OB_CAMERA: /* ------- Camera ------------ */
{
Camera *ca = (Camera *)ob->data;
-
+
if (ads->filterflag & ADS_FILTER_NOCAM)
return 0;
-
+
type = ANIMTYPE_DSCAM;
expanded = FILTER_CAM_OBJD(ca);
break;
@@ -2347,10 +2349,10 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
case OB_LAMP: /* ---------- Lamp ----------- */
{
Lamp *la = (Lamp *)ob->data;
-
+
if (ads->filterflag & ADS_FILTER_NOLAM)
return 0;
-
+
type = ANIMTYPE_DSLAM;
expanded = FILTER_LAM_OBJD(la);
break;
@@ -2360,10 +2362,10 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
case OB_FONT: /* ------- Text Curve ---------- */
{
Curve *cu = (Curve *)ob->data;
-
+
if (ads->filterflag & ADS_FILTER_NOCUR)
return 0;
-
+
type = ANIMTYPE_DSCUR;
expanded = FILTER_CUR_OBJD(cu);
break;
@@ -2371,10 +2373,10 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
case OB_MBALL: /* ------- MetaBall ---------- */
{
MetaBall *mb = (MetaBall *)ob->data;
-
+
if (ads->filterflag & ADS_FILTER_NOMBA)
return 0;
-
+
type = ANIMTYPE_DSMBALL;
expanded = FILTER_MBALL_OBJD(mb);
break;
@@ -2382,10 +2384,10 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
case OB_ARMATURE: /* ------- Armature ---------- */
{
bArmature *arm = (bArmature *)ob->data;
-
+
if (ads->filterflag & ADS_FILTER_NOARM)
return 0;
-
+
type = ANIMTYPE_DSARM;
expanded = FILTER_ARM_OBJD(arm);
break;
@@ -2393,10 +2395,10 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
case OB_MESH: /* ------- Mesh ---------- */
{
Mesh *me = (Mesh *)ob->data;
-
+
if (ads->filterflag & ADS_FILTER_NOMESH)
return 0;
-
+
type = ANIMTYPE_DSMESH;
expanded = FILTER_MESH_OBJD(me);
break;
@@ -2404,10 +2406,10 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
case OB_LATTICE: /* ---- Lattice ---- */
{
Lattice *lt = (Lattice *)ob->data;
-
+
if (ads->filterflag & ADS_FILTER_NOLAT)
return 0;
-
+
type = ANIMTYPE_DSLAT;
expanded = FILTER_LATTICE_OBJD(lt);
break;
@@ -2415,26 +2417,26 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
case OB_SPEAKER: /* ---------- Speaker ----------- */
{
Speaker *spk = (Speaker *)ob->data;
-
+
type = ANIMTYPE_DSSPK;
expanded = FILTER_SPK_OBJD(spk);
break;
}
}
-
+
/* add object data animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
{
/* animation data filtering */
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)iat, filter_mode);
-
+
/* sub-data filtering... */
switch (ob->type) {
case OB_LAMP: /* lamp - textures + nodetree */
{
Lamp *la = ob->data;
bNodeTree *ntree = la->nodetree;
-
+
/* nodetree */
if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE))
tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, &la->id, ntree, filter_mode);
@@ -2443,7 +2445,7 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
}
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include data-expand widget first */
@@ -2453,13 +2455,13 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b
ANIMCHANNEL_NEW_CHANNEL(iat, type, iat);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2470,7 +2472,7 @@ static size_t animdata_filter_ds_keyanim(bAnimContext *ac, ListBase *anim_data,
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
/* add shapekey-level animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_SKE_OBJD(key))
{
@@ -2478,7 +2480,7 @@ static size_t animdata_filter_ds_keyanim(bAnimContext *ac, ListBase *anim_data,
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)key, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include key-expand widget first */
@@ -2487,13 +2489,13 @@ static size_t animdata_filter_ds_keyanim(bAnimContext *ac, ListBase *anim_data,
ANIMCHANNEL_NEW_CHANNEL(key, ANIMTYPE_DSSKEY, ob);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2505,7 +2507,7 @@ static size_t animdata_filter_ds_obanim(bAnimContext *ac, ListBase *anim_data, b
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
AnimData *adt = ob->adt;
short type = 0, expanded = 1;
void *cdata = NULL;
@@ -2526,7 +2528,7 @@ static size_t animdata_filter_ds_obanim(bAnimContext *ac, ListBase *anim_data, b
cdata = adt->action;
expanded = EXPANDED_ACTC(adt->action);
});
-
+
/* add object-level animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
{
@@ -2534,7 +2536,7 @@ static size_t animdata_filter_ds_obanim(bAnimContext *ac, ListBase *anim_data, b
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ob, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include anim-expand widget first */
@@ -2544,13 +2546,13 @@ static size_t animdata_filter_ds_obanim(bAnimContext *ac, ListBase *anim_data, b
ANIMCHANNEL_NEW_CHANNEL(cdata, type, ob);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2562,50 +2564,50 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data
Object *ob = base->object;
size_t tmp_items = 0;
size_t items = 0;
-
+
/* filter data contained under object first */
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_OBJC(ob))
{
Key *key = BKE_key_from_object(ob);
-
+
/* object-level animation */
if ((ob->adt) && !(ads->filterflag & ADS_FILTER_NOOBJ)) {
tmp_items += animdata_filter_ds_obanim(ac, &tmp_data, ads, ob, filter_mode);
}
-
+
/* shape-key */
if ((key && key->adt) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
tmp_items += animdata_filter_ds_keyanim(ac, &tmp_data, ads, ob, key, filter_mode);
}
-
+
/* modifiers */
if ((ob->modifiers.first) && !(ads->filterflag & ADS_FILTER_NOMODIFIERS)) {
tmp_items += animdata_filter_ds_modifiers(ac, &tmp_data, ads, ob, filter_mode);
}
-
+
/* materials */
if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT)) {
tmp_items += animdata_filter_ds_materials(ac, &tmp_data, ads, ob, filter_mode);
}
-
+
/* object data */
if (ob->data) {
tmp_items += animdata_filter_ds_obdata(ac, &tmp_data, ads, ob, filter_mode);
}
-
+
/* particles */
if ((ob->particlesystem.first) && !(ads->filterflag & ADS_FILTER_NOPART)) {
tmp_items += animdata_filter_ds_particles(ac, &tmp_data, ads, ob, filter_mode);
}
-
+
/* grease pencil */
if ((ob->gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) {
tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->gpd, filter_mode);
}
}
END_ANIMFILTER_SUBCHANNELS;
-
-
+
+
/* if we collected some channels, add these to the new list... */
if (tmp_items) {
/* firstly add object expander if required */
@@ -2619,13 +2621,13 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data
}
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added */
return items;
}
@@ -2635,19 +2637,19 @@ static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bD
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
/* add world animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_WOR_SCED(wo))
{
/* animation data filtering */
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)wo, filter_mode);
-
+
/* nodes */
- if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
+ if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)wo, wo->nodetree, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include data-expand widget first */
@@ -2657,13 +2659,13 @@ static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bD
ANIMCHANNEL_NEW_CHANNEL(wo, ANIMTYPE_DSWOR, sce);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2673,11 +2675,11 @@ static size_t animdata_filter_ds_scene(bAnimContext *ac, ListBase *anim_data, bD
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
AnimData *adt = sce->adt;
short type = 0, expanded = 1;
void *cdata = NULL;
-
+
/* determine the type of expander channels to use */
// this is the best way to do this for now...
ANIMDATA_FILTER_CASES(sce,
@@ -2694,7 +2696,7 @@ static size_t animdata_filter_ds_scene(bAnimContext *ac, ListBase *anim_data, bD
cdata = adt->action;
expanded = EXPANDED_ACTC(adt->action);
});
-
+
/* add scene-level animation channels */
BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
{
@@ -2702,7 +2704,7 @@ static size_t animdata_filter_ds_scene(bAnimContext *ac, ListBase *anim_data, bD
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)sce, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
-
+
/* did we find anything? */
if (tmp_items) {
/* include anim-expand widget first */
@@ -2712,13 +2714,13 @@ static size_t animdata_filter_ds_scene(bAnimContext *ac, ListBase *anim_data, bD
ANIMCHANNEL_NEW_CHANNEL(cdata, type, sce);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added to the list */
return items;
}
@@ -2728,39 +2730,39 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d
ListBase tmp_data = {NULL, NULL};
size_t tmp_items = 0;
size_t items = 0;
-
+
/* filter data contained under object first */
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce))
{
bNodeTree *ntree = sce->nodetree;
bGPdata *gpd = sce->gpd;
World *wo = sce->world;
-
+
/* Action, Drivers, or NLA for Scene */
if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
tmp_items += animdata_filter_ds_scene(ac, &tmp_data, ads, sce, filter_mode);
}
-
+
/* world */
if ((wo) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
tmp_items += animdata_filter_ds_world(ac, &tmp_data, ads, sce, wo, filter_mode);
}
-
+
/* nodetree */
if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
}
-
+
/* line styles */
if ((ads->filterflag & ADS_FILTER_NOLINESTYLE) == 0) {
tmp_items += animdata_filter_ds_linestyle(ac, &tmp_data, ads, sce, filter_mode);
}
-
+
/* grease pencil */
if ((gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) {
tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, gpd, filter_mode);
}
-
+
/* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */
}
END_ANIMFILTER_SUBCHANNELS;
@@ -2775,13 +2777,13 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d
ANIMCHANNEL_NEW_CHANNEL(sce, ANIMTYPE_SCENE, sce);
}
}
-
+
/* now add the list of collected channels */
BLI_movelisttolist(anim_data, &tmp_data);
BLI_assert(BLI_listbase_is_empty(&tmp_data));
items += tmp_items;
}
-
+
/* return the number of items added */
return items;
}
@@ -2820,7 +2822,7 @@ static size_t animdata_filter_dopesheet_movieclips(bAnimContext *ac, ListBase *a
{
size_t items = 0;
MovieClip *clip;
- for (clip = G.main->movieclip.first; clip != NULL; clip = clip->id.next) {
+ for (clip = ac->bmain->movieclip.first; clip != NULL; clip = clip->id.next) {
/* only show if gpd is used by something... */
if (ID_REAL_USERS(clip) < 1) {
continue;
@@ -2835,31 +2837,31 @@ static size_t animdata_filter_dopesheet_movieclips(bAnimContext *ac, ListBase *a
static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_mode)
{
Object *ob = base->object;
-
+
if (base->object == NULL)
return false;
-
+
/* firstly, check if object can be included, by the following factors:
* - if only visible, must check for layer and also viewport visibility
* --> while tools may demand only visible, user setting takes priority
* as user option controls whether sets of channels get included while
* tool-flag takes into account collapsed/open channels too
- * - if only selected, must check if object is selected
- * - there must be animation data to edit (this is done recursively as we
+ * - if only selected, must check if object is selected
+ * - there must be animation data to edit (this is done recursively as we
* try to add the channels)
*/
if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
/* layer visibility - we check both object and base, since these may not be in sync yet */
if ((base->flag & BASE_VISIBLED) == 0)
return false;
-
+
/* outliner restrict-flag */
if (ob->restrictflag & OB_RESTRICT_VIEW)
return false;
}
-
- /* if only F-Curves with visible flags set can be shown, check that
- * datablock hasn't been set to invisible
+
+ /* if only F-Curves with visible flags set can be shown, check that
+ * datablock hasn't been set to invisible
*/
if (filter_mode & ANIMFILTER_CURVE_VISIBLE) {
if ((ob->adt) && (ob->adt->flag & ADT_CURVES_NOT_VISIBLE))
@@ -2889,8 +2891,8 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
/* only selected should be shown */
return false;
}
-
- /* check if object belongs to the filtering group if option to filter
+
+ /* check if object belongs to the filtering group if option to filter
* objects by the grouped status is on
* - used to ease the process of doing multiple-character choreographies
*/
@@ -2898,7 +2900,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0)
return false;
}
-
+
/* no reason to exclude this object... */
return true;
}
@@ -2908,7 +2910,7 @@ static int ds_base_sorting_cmp(const void *base1_ptr, const void *base2_ptr)
{
const Base *b1 = *((const Base **)base1_ptr);
const Base *b2 = *((const Base **)base2_ptr);
-
+
return strcmp(b1->object->id.name + 2, b2->object->id.name + 2);
}
@@ -2918,17 +2920,17 @@ static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, ViewLayer *view_l
/* Create an array with space for all the bases, but only containing the usable ones */
size_t tot_bases = BLI_listbase_count(&view_layer->object_bases);
size_t num_bases = 0;
-
+
Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases");
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
if (animdata_filter_base_is_ok(ads, base, filter_mode)) {
sorted_bases[num_bases++] = base;
}
}
-
+
/* Sort this list of pointers (based on the names) */
qsort(sorted_bases, num_bases, sizeof(Base *), ds_base_sorting_cmp);
-
+
/* Return list of sorted bases */
*r_usable_bases = num_bases;
return sorted_bases;
@@ -2949,17 +2951,17 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
printf("\tPointer = %p, Name = '%s'\n", (void *)ads->source, (ads->source) ? ads->source->name : NULL);
return 0;
}
-
- /* augment the filter-flags with settings based on the dopesheet filterflags
+
+ /* augment the filter-flags with settings based on the dopesheet filterflags
* so that some temp settings can get added automagically...
*/
if (ads->filterflag & ADS_FILTER_SELEDIT) {
/* only selected F-Curves should get their keyframes considered for editability */
filter_mode |= ANIMFILTER_SELEDIT;
}
-
+
/* Cache files level animations (frame duration and such). */
- CacheFile *cache_file = G.main->cachefiles.first;
+ CacheFile *cache_file = ac->bmain->cachefiles.first;
for (; cache_file; cache_file = cache_file->id.next) {
items += animdata_filter_ds_cachefile(ac, anim_data, ads, cache_file, filter_mode);
}
@@ -2984,16 +2986,16 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
// TODO: Cache the old sorted order - if the set of bases hasn't changed, don't re-sort...
Base **sorted_bases;
size_t num_bases;
-
+
sorted_bases = animdata_filter_ds_sorted_bases(ads, view_layer, filter_mode, &num_bases);
if (sorted_bases) {
/* Add the necessary channels for these bases... */
for (size_t i = 0; i < num_bases; i++) {
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, sorted_bases[i], filter_mode);
}
-
+
// TODO: store something to validate whether any changes are needed?
-
+
/* free temporary data */
MEM_freeN(sorted_bases);
}
@@ -3009,20 +3011,20 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
}
}
}
-
+
/* return the number of items in the list */
return items;
}
-/* Summary track for DopeSheet/Action Editor
+/* Summary track for DopeSheet/Action Editor
* - return code is whether the summary lets the other channels get drawn
*/
static short animdata_filter_dopesheet_summary(bAnimContext *ac, ListBase *anim_data, int filter_mode, size_t *items)
{
bDopeSheet *ads = NULL;
-
- /* get the DopeSheet information to use
- * - we should only need to deal with the DopeSheet/Action Editor,
+
+ /* get the DopeSheet information to use
+ * - we should only need to deal with the DopeSheet/Action Editor,
* since all the other Animation Editors won't have this concept
* being applicable.
*/
@@ -3034,9 +3036,9 @@ static short animdata_filter_dopesheet_summary(bAnimContext *ac, ListBase *anim_
/* invalid space type - skip this summary channels */
return 1;
}
-
- /* dopesheet summary
- * - only for drawing and/or selecting keyframes in channels, but not for real editing
+
+ /* dopesheet summary
+ * - only for drawing and/or selecting keyframes in channels, but not for real editing
* - only useful for DopeSheet/Action/etc. editors where it is actually useful
*/
if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) {
@@ -3045,17 +3047,17 @@ static short animdata_filter_dopesheet_summary(bAnimContext *ac, ListBase *anim_
BLI_addtail(anim_data, ale);
(*items)++;
}
-
- /* if summary is collapsed, don't show other channels beneath this
+
+ /* if summary is collapsed, don't show other channels beneath this
* - this check is put inside the summary check so that it doesn't interfere with normal operation
- */
+ */
if (ads->flag & ADS_FLAG_SUMMARY_COLLAPSED)
return 0;
}
-
+
/* the other channels beneath this can be shown */
return 1;
-}
+}
/* ......................... */
@@ -3063,18 +3065,18 @@ static short animdata_filter_dopesheet_summary(bAnimContext *ac, ListBase *anim_
static size_t animdata_filter_animchan(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAnimListElem *channel, int filter_mode)
{
size_t items = 0;
-
+
/* data to filter depends on channel type */
/* NOTE: only common channel-types have been handled for now. More can be added as necessary */
switch (channel->type) {
case ANIMTYPE_SUMMARY:
items += animdata_filter_dopesheet(ac, anim_data, ads, filter_mode);
break;
-
+
case ANIMTYPE_SCENE:
items += animdata_filter_dopesheet_scene(ac, anim_data, ads, channel->data, filter_mode);
break;
-
+
case ANIMTYPE_OBJECT:
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode);
break;
@@ -3086,12 +3088,12 @@ static size_t animdata_filter_animchan(bAnimContext *ac, ListBase *anim_data, bD
case ANIMTYPE_ANIMDATA:
items += animfilter_block_data(ac, anim_data, ads, channel->id, filter_mode);
break;
-
+
default:
printf("ERROR: Unsupported channel type (%d) in animdata_filter_animchan()\n", channel->type);
break;
}
-
+
return items;
}
@@ -3102,17 +3104,17 @@ static size_t animdata_filter_remove_invalid(ListBase *anim_data)
{
bAnimListElem *ale, *next;
size_t items = 0;
-
+
/* only keep entries with valid types */
for (ale = anim_data->first; ale; ale = next) {
next = ale->next;
-
+
if (ale->type == ANIMTYPE_NONE)
BLI_freelinkN(anim_data, ale);
else
items++;
}
-
+
return items;
}
@@ -3122,18 +3124,18 @@ static size_t animdata_filter_remove_duplis(ListBase *anim_data)
bAnimListElem *ale, *next;
GSet *gs;
size_t items = 0;
-
- /* build new hashtable to efficiently store and retrieve which entries have been
+
+ /* build new hashtable to efficiently store and retrieve which entries have been
* encountered already while searching
*/
gs = BLI_gset_ptr_new(__func__);
-
+
/* loop through items, removing them from the list if a similar item occurs already */
for (ale = anim_data->first; ale; ale = next) {
next = ale->next;
-
- /* check if hash has any record of an entry like this
- * - just use ale->data for now, though it would be nicer to involve
+
+ /* check if hash has any record of an entry like this
+ * - just use ale->data for now, though it would be nicer to involve
* ale->type in combination too to capture corner cases (where same data performs differently)
*/
if (BLI_gset_add(gs, ale->data)) {
@@ -3145,10 +3147,10 @@ static size_t animdata_filter_remove_duplis(ListBase *anim_data)
BLI_freelinkN(anim_data, ale);
}
}
-
+
/* free the hash... */
BLI_gset_free(gs, NULL);
-
+
/* return the number of items still in the list */
return items;
}
@@ -3165,7 +3167,7 @@ static size_t animdata_filter_remove_duplis(ListBase *anim_data)
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_Flags filter_mode, void *data, eAnimCont_Types datatype)
{
size_t items = 0;
-
+
/* only filter data if there's somewhere to put it */
if (data && anim_data) {
/* firstly filter the data */
@@ -3176,7 +3178,7 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F
Object *obact = ac->obact;
SpaceAction *saction = (SpaceAction *)ac->sl;
bDopeSheet *ads = (saction) ? &saction->ads : NULL;
-
+
/* specially check for AnimData filter... [#36687] */
if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) {
/* all channels here are within the same AnimData block, hence this special case */
@@ -3189,13 +3191,13 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F
if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact);
}
-
+
break;
}
case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */
{
Key *key = (Key *)data;
-
+
/* specially check for AnimData filter... [#36687] */
if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) {
/* all channels here are within the same AnimData block, hence this special case */
@@ -3208,11 +3210,11 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F
if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
items = animdata_filter_shapekey(ac, anim_data, key, filter_mode);
}
-
+
break;
}
-
-
+
+
/* Modes for Specialty Data Types (i.e. not keyframes) */
case ANIMCONT_GPENCIL:
{
@@ -3223,11 +3225,11 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F
case ANIMCONT_MASK:
{
if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
- items = animdata_filter_mask(anim_data, data, filter_mode);
+ items = animdata_filter_mask(ac->bmain, anim_data, data, filter_mode);
break;
}
-
-
+
+
/* DopeSheet Based Modes */
case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */
{
@@ -3244,8 +3246,8 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F
items = animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
break;
}
-
-
+
+
/* Timeline Mode - Basically the same as dopesheet, except we only have the summary for now */
case ANIMCONT_TIMELINE:
{
@@ -3254,17 +3256,17 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F
items += animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
break;
}
-
+
/* Special/Internal Use */
case ANIMCONT_CHANNEL: /* animation channel */
{
bDopeSheet *ads = ac->ads;
-
+
/* based on the channel type, filter relevant data for this */
items = animdata_filter_animchan(ac, anim_data, ads, data, filter_mode);
break;
}
-
+
/* unhandled */
default:
{
@@ -3275,12 +3277,12 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F
/* remove any 'weedy' entries */
items = animdata_filter_remove_invalid(anim_data);
-
+
/* remove duplicates (if required) */
if (filter_mode & ANIMFILTER_NODUPLIS)
items = animdata_filter_remove_duplis(anim_data);
}
-
+
/* return the number of items in the list */
return items;
}
diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h
index dcd8a245fb8..de91ce06c8b 100644
--- a/source/blender/editors/animation/anim_intern.h
+++ b/source/blender/editors/animation/anim_intern.h
@@ -27,7 +27,7 @@
* \ingroup edanimation
*/
-
+
#ifndef __ANIM_INTERN_H__
#define __ANIM_INTERN_H__
@@ -38,14 +38,14 @@ extern ListBase builtin_keyingsets;
/* Operator Define Prototypes ------------------- */
-/* Main Keyframe Management operators:
+/* Main Keyframe Management operators:
* These handle keyframes management from various spaces. They only make use of
* Keying Sets.
*/
void ANIM_OT_keyframe_insert(struct wmOperatorType *ot);
void ANIM_OT_keyframe_delete(struct wmOperatorType *ot);
-/* Main Keyframe Management operators:
+/* Main Keyframe Management operators:
* These handle keyframes management from various spaces. They will handle the menus
* required for each space.
*/
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index 6b219a4f13a..4e0993152f7 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -59,7 +59,7 @@
int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
{
int icon = 0;
-
+
/* sanity checks */
if (name == NULL)
return icon;
@@ -74,17 +74,17 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
else {
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
-
+
/* get RNA pointer, and resolve the path */
RNA_id_pointer_create(id, &id_ptr);
-
+
/* try to resolve the path */
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
const char *structname = NULL, *propname = NULL;
char arrayindbuf[16];
const char *arrayname = NULL;
short free_structname = 0;
-
+
/* For now, name will consist of 3 parts: struct-name, property name, array index
* There are several options possible:
* 1) <struct-name>.<property-name>.<array-index>
@@ -93,12 +93,12 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
* i.e. X Location (Bone1), or X Location (Object)
*
* Currently, option 2 is in use, to try and make it easier to quickly identify F-Curves (it does have
- * problems with looking rather odd though). Option 1 is better in terms of revealing a consistent sense of
+ * problems with looking rather odd though). Option 1 is better in terms of revealing a consistent sense of
* hierarchy though, which isn't so clear with option 2.
*/
-
+
/* for structname
- * - as base, we use a custom name from the structs if one is available
+ * - as base, we use a custom name from the structs if one is available
* - however, if we're showing subdata of bones (probably there will be other exceptions later)
* need to include that info too since it gets confusing otherwise
* - if a pointer just refers to the ID-block, then don't repeat this info
@@ -108,11 +108,11 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
/* perform string 'chopping' to get "Bone Name : Constraint Name" */
char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones[");
char *constName = BLI_str_quoted_substrN(fcu->rna_path, "constraints[");
-
+
/* assemble the string to display in the UI... */
structname = BLI_sprintfN("%s : %s", pchanName, constName);
free_structname = 1;
-
+
/* free the temp names */
if (pchanName) MEM_freeN(pchanName);
if (constName) MEM_freeN(constName);
@@ -127,25 +127,25 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
else
structname = RNA_struct_ui_name(ptr.type);
}
-
+
/* Property Name is straightforward */
propname = RNA_property_ui_name(prop);
-
+
/* Array Index - only if applicable */
if (RNA_property_array_check(prop)) {
char c = RNA_property_array_item_char(prop, fcu->array_index);
-
+
/* we need to write the index to a temp buffer (in py syntax) */
if (c) BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "%c ", c);
else BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "[%d]", fcu->array_index);
-
+
arrayname = &arrayindbuf[0];
}
else {
/* no array index */
arrayname = "";
}
-
+
/* putting this all together into the buffer */
/* XXX we need to check for invalid names...
* XXX the name length limit needs to be passed in or as some define */
@@ -153,17 +153,17 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname);
else
BLI_snprintf(name, 256, "%s%s", arrayname, propname);
-
+
/* free temp name if nameprop is set */
if (free_structname)
MEM_freeN((void *)structname);
-
-
+
+
/* Icon for this property's owner:
* use the struct's icon if it is set
*/
icon = RNA_struct_ui_icon(ptr.type);
-
+
/* valid path - remove the invalid tag since we now know how to use it saving
* users manual effort to reenable using "Revive Disabled FCurves" [#29629]
*/
@@ -172,16 +172,16 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
else {
/* invalid path */
BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
-
+
/* icon for this should be the icon for the base ID */
/* TODO: or should we just use the error icon? */
icon = RNA_struct_ui_icon(id_ptr.type);
-
+
/* tag F-Curve as disabled - as not usable path */
fcu->flag |= FCURVE_DISABLED;
}
}
-
+
/* return the icon that the active data had */
return icon;
}
@@ -197,7 +197,7 @@ void getcolor_fcurve_rainbow(int cur, int tot, float out[3])
{
float hsv[3], fac;
int grouping;
-
+
/* we try to divide the color into groupings of n colors,
* where n is:
* 3 - for 'odd' numbers of curves - there should be a majority of triplets of curves
@@ -206,24 +206,24 @@ void getcolor_fcurve_rainbow(int cur, int tot, float out[3])
*/
grouping = (4 - (tot % 2));
hsv[0] = HSV_BANDWIDTH * (float)(cur % grouping);
-
- /* 'Value' (i.e. darkness) needs to vary so that larger sets of three will be
+
+ /* 'Value' (i.e. darkness) needs to vary so that larger sets of three will be
* 'darker' (i.e. smaller value), so that they don't look that similar to previous ones.
* However, only a range of 0.3 to 1.0 is really usable to avoid clashing
- * with some other stuff
+ * with some other stuff
*/
fac = ((float)cur / (float)tot) * 0.7f;
-
+
/* the base color can get offset a bit so that the colors aren't so identical */
hsv[0] += fac * HSV_BANDWIDTH;
if (hsv[0] > 1.0f) hsv[0] = fmod(hsv[0], 1.0f);
-
+
/* saturation adjustments for more visible range */
hsv[1] = ((hsv[0] > 0.5f) && (hsv[0] < 0.8f)) ? 0.5f : 0.6f;
-
+
/* value is fixed at 1.0f, otherwise we cannot clearly see the curves... */
hsv[2] = 1.0f;
-
+
/* finally, conver this to RGB colors */
hsv_to_rgb_v(hsv, out);
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index c9e96e35149..624c6e9f5de 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -85,8 +85,8 @@ static ListBase *context_get_markers(Scene *scene, ScrArea *sa)
if (sa) {
if (sa->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
- /* local markers can only be shown when there's only a single active action to grab them from
+
+ /* local markers can only be shown when there's only a single active action to grab them from
* - flag only takes effect when there's an action, otherwise it can get too confusing?
*/
if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) && (saction->action)) {
@@ -96,7 +96,7 @@ static ListBase *context_get_markers(Scene *scene, ScrArea *sa)
}
}
}
-
+
/* default to using the scene's markers */
return &scene->markers;
}
@@ -135,7 +135,7 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f
TimeMarker *marker;
float cfra = (float)CFRA;
int changed_tot = 0;
-
+
/* sanity check - no markers, or locked markers */
if ((scene->toolsettings->lock_markers) ||
(markers == NULL))
@@ -170,7 +170,7 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f
}
}
}
-
+
return changed_tot;
}
@@ -182,18 +182,18 @@ TimeMarker *ED_markers_find_nearest_marker(ListBase *markers, float x)
{
TimeMarker *marker, *nearest = NULL;
float dist, min_dist = 1000000;
-
+
if (markers) {
for (marker = markers->first; marker; marker = marker->next) {
dist = fabsf((float)marker->frame - x);
-
+
if (dist < min_dist) {
min_dist = dist;
nearest = marker;
}
}
}
-
+
return nearest;
}
@@ -209,7 +209,7 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la
{
TimeMarker *marker;
float min, max;
-
+
/* sanity check */
//printf("markers = %p - %p, %p\n", markers, markers->first, markers->last);
if (ELEM(NULL, markers, markers->first, markers->last)) {
@@ -228,7 +228,7 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la
max = (float)marker->frame;
}
}
-
+
/* set the min/max values */
*first = min;
*last = max;
@@ -240,16 +240,16 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la
static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel)
{
CfraElem *ce, *cen;
-
+
/* should this one only be considered if it is selected? */
if ((only_sel) && ((marker->flag & SELECT) == 0))
return;
-
+
/* insertion sort - try to find a previous cfra elem */
for (ce = lb->first; ce; ce = ce->next) {
if (ce->cfra == marker->frame) {
/* do because of double keys */
- if (marker->flag & SELECT)
+ if (marker->flag & SELECT)
ce->sel = marker->flag;
return;
}
@@ -257,7 +257,7 @@ static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only
break;
}
}
-
+
cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
if (ce) BLI_insertlinkbefore(lb, ce, cen);
else BLI_addtail(lb, cen);
@@ -273,7 +273,7 @@ static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only
void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short only_sel)
{
TimeMarker *marker;
-
+
if (lb) {
/* Clear the list first, since callers have no way of knowing
* whether this terminated early otherwise. This may lead
@@ -284,11 +284,11 @@ void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short only_sel)
else {
return;
}
-
+
if (markers == NULL) {
return;
}
-
+
for (marker = markers->first; marker; marker = marker->next)
add_marker_to_cfra_elem(lb, marker, only_sel);
}
@@ -299,37 +299,37 @@ void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short only_sel)
TimeMarker *ED_markers_get_first_selected(ListBase *markers)
{
TimeMarker *marker;
-
+
if (markers) {
for (marker = markers->first; marker; marker = marker->next) {
if (marker->flag & SELECT)
return marker;
}
}
-
+
return NULL;
}
/* --------------------------------- */
-/* Print debugging prints of list of markers
+/* Print debugging prints of list of markers
* BSI's: do NOT make static or put in if-defs as "unused code". That's too much trouble when we need to use for quick debugging!
*/
void debug_markers_print_list(ListBase *markers)
{
TimeMarker *marker;
-
+
if (markers == NULL) {
printf("No markers list to print debug for\n");
return;
}
-
+
printf("List of markers follows: -----\n");
-
+
for (marker = markers->first; marker; marker = marker->next) {
printf("\t'%s' on %d at %p with %u\n", marker->name, marker->frame, (void *)marker, marker->flag);
}
-
+
printf("End of list ------------------\n");
}
@@ -344,7 +344,7 @@ static void draw_marker_name(
/* minimal y coordinate which wouldn't be occluded by scroll */
int min_y = 17.0f * UI_DPI_FAC;
-
+
if (marker->flag & SELECT) {
UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
x = xpos + 4.0f * UI_DPI_FAC;
@@ -422,7 +422,7 @@ static void draw_marker(
immUnbindProgram();
}
-
+
/* 5 px to offset icon to align properly, space / pixels corrects for zoom */
if (flag & DRAW_MARKERS_LOCAL) {
icon_id = (marker->flag & ACTIVE) ? ICON_PMARKER_ACT :
@@ -439,11 +439,11 @@ static void draw_marker(
icon_id = (marker->flag & SELECT) ? ICON_MARKER_HLT :
ICON_MARKER;
}
-
+
UI_icon_draw(xpos - 0.45f * UI_DPI_ICON_SIZE, yoffs + UI_DPI_ICON_SIZE, icon_id);
-
+
glDisable(GL_BLEND);
-
+
/* and the marker name too, shifted slightly to the top-right */
#ifdef DURIAN_CAMERA_SWITCH
if (marker->camera) {
@@ -530,7 +530,7 @@ void ED_markers_draw(const bContext *C, int flag)
}
/* ************************ Marker Wrappers API ********************* */
-/* These wrappers allow marker operators to function within the confines
+/* These wrappers allow marker operators to function within the confines
* of standard animation editors, such that they can coexist with the
* primary operations of those editors.
*/
@@ -541,11 +541,11 @@ void ED_markers_draw(const bContext *C, int flag)
static int ed_markers_poll_selected_markers(bContext *C)
{
ListBase *markers = ED_context_get_markers(C);
-
+
/* first things first: markers can only exist in timeline views */
if (ED_operator_animview_active(C) == 0)
return 0;
-
+
/* check if some marker is selected */
return ED_markers_get_first_selected(markers) != NULL;
}
@@ -572,19 +572,19 @@ static int ed_markers_poll_markers_exist(bContext *C)
{
ListBase *markers = ED_context_get_markers(C);
ToolSettings *ts = CTX_data_tool_settings(C);
-
+
if (ts->lock_markers)
return 0;
/* first things first: markers can only exist in timeline views */
if (ED_operator_animview_active(C) == 0)
return 0;
-
+
/* list of markers must exist, as well as some markers in it! */
return (markers && markers->first);
}
-
-/* ------------------------ */
+
+/* ------------------------ */
/**
* Second-tier invoke() callback that performs context validation before running the
@@ -637,30 +637,30 @@ static int ed_marker_add_exec(bContext *C, wmOperator *UNUSED(op))
ListBase *markers = ED_context_get_markers(C);
TimeMarker *marker;
int frame = CTX_data_scene(C)->r.cfra;
-
+
if (markers == NULL)
return OPERATOR_CANCELLED;
-
+
/* prefer not having 2 markers at the same place,
* though the user can move them to overlap once added */
for (marker = markers->first; marker; marker = marker->next) {
- if (marker->frame == frame)
+ if (marker->frame == frame)
return OPERATOR_CANCELLED;
}
-
+
/* deselect all */
for (marker = markers->first; marker; marker = marker->next)
marker->flag &= ~SELECT;
-
+
marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
marker->flag = SELECT;
marker->frame = frame;
BLI_snprintf(marker->name, sizeof(marker->name), "F_%02d", frame); // XXX - temp code only
BLI_addtail(markers, marker);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -670,19 +670,19 @@ static void MARKER_OT_add(wmOperatorType *ot)
ot->name = "Add Time Marker";
ot->description = "Add a new time marker";
ot->idname = "MARKER_OT_add";
-
+
/* api callbacks */
ot->exec = ed_marker_add_exec;
ot->invoke = ed_markers_opwrap_invoke;
ot->poll = ED_operator_animview_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************** transform markers *************************** */
-/* operator state vars used:
+/* operator state vars used:
* frs: delta movement
*
* functions:
@@ -820,12 +820,12 @@ static bool ed_marker_move_init(bContext *C, wmOperator *op)
static void ed_marker_move_exit(bContext *C, wmOperator *op)
{
MarkerMove *mm = op->customdata;
-
+
/* free data */
MEM_freeN(mm->oldframe);
MEM_freeN(op->customdata);
op->customdata = NULL;
-
+
/* clear custom header prints */
ED_area_headerprint(CTX_wm_area(C), NULL);
}
@@ -834,14 +834,14 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *eve
{
if (ed_marker_move_init(C, op)) {
MarkerMove *mm = op->customdata;
-
+
mm->evtx = event->x;
mm->firstx = event->x;
mm->event_type = event->type;
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
-
+
/* reset frs delta */
RNA_int_set(op->ptr, "frames", 0);
@@ -849,7 +849,7 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *eve
return OPERATOR_RUNNING_MODAL;
}
-
+
return OPERATOR_CANCELLED;
}
@@ -869,7 +869,7 @@ static void ed_marker_move_apply(bContext *C, wmOperator *op)
MarkerMove *mm = op->customdata;
TimeMarker *marker;
int a, offs;
-
+
offs = RNA_int_get(op->ptr, "frames");
for (a = 0, marker = mm->markers->first; marker; marker = marker->next) {
if (marker->flag & SELECT) {
@@ -880,7 +880,7 @@ static void ed_marker_move_apply(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
-
+
#ifdef DURIAN_CAMERA_SWITCH
/* so we get view3d redraws */
BKE_scene_camera_switch_update(scene);
@@ -1002,17 +1002,17 @@ static void MARKER_OT_move(wmOperatorType *ot)
ot->name = "Move Time Marker";
ot->description = "Move selected time marker(s)";
ot->idname = "MARKER_OT_move";
-
+
/* api callbacks */
ot->exec = ed_marker_move_exec;
ot->invoke = ed_marker_move_invoke_wrapper;
ot->modal = ed_marker_move_modal;
ot->poll = ed_markers_poll_selected_no_locked_markers;
ot->cancel = ed_marker_move_cancel;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
-
+
/* rna storage */
RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
}
@@ -1040,8 +1040,8 @@ static void ed_marker_duplicate_apply(bContext *C)
{
ListBase *markers = ED_context_get_markers(C);
TimeMarker *marker, *newmarker;
-
- if (markers == NULL)
+
+ if (markers == NULL)
return;
/* go through the list of markers, duplicate selected markers and add duplicated copies
@@ -1051,13 +1051,13 @@ static void ed_marker_duplicate_apply(bContext *C)
if (marker->flag & SELECT) {
/* unselect selected marker */
marker->flag &= ~SELECT;
-
+
/* create and set up new marker */
newmarker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
newmarker->flag = SELECT;
newmarker->frame = marker->frame;
BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
-
+
#ifdef DURIAN_CAMERA_SWITCH
newmarker->camera = marker->camera;
#endif
@@ -1073,9 +1073,9 @@ static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
{
ed_marker_duplicate_apply(C);
ed_marker_move_exec(C, op); /* assumes frs delta set */
-
+
return OPERATOR_FINISHED;
-
+
}
static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -1095,17 +1095,17 @@ static void MARKER_OT_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Time Marker";
ot->description = "Duplicate selected time marker(s)";
ot->idname = "MARKER_OT_duplicate";
-
+
/* api callbacks */
ot->exec = ed_marker_duplicate_exec;
ot->invoke = ed_marker_duplicate_invoke_wrapper;
ot->modal = ed_marker_move_modal;
ot->poll = ed_markers_poll_selected_no_locked_markers;
ot->cancel = ed_marker_move_cancel;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna storage */
RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
}
@@ -1152,18 +1152,18 @@ static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool
View2D *v2d = UI_view2d_fromcontext(C);
float viewx;
int x, cfra;
-
+
if (markers == NULL)
return OPERATOR_PASS_THROUGH;
x = event->x - ar->winrct.xmin;
-
+
viewx = UI_view2d_region_to_view_x(v2d, x);
-
+
cfra = ED_markers_find_nearest_marker_time(markers, viewx);
-
+
select_timeline_marker_frame(markers, cfra, extend);
-
+
#ifdef DURIAN_CAMERA_SWITCH
if (camera) {
@@ -1172,17 +1172,17 @@ static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool
Base *base;
TimeMarker *marker;
int sel = 0;
-
+
if (!extend)
BKE_view_layer_base_deselect_all(view_layer);
-
+
for (marker = markers->first; marker; marker = marker->next) {
if (marker->frame == cfra) {
sel = (marker->flag & SELECT);
break;
}
}
-
+
for (marker = markers->first; marker; marker = marker->next) {
if (marker->camera) {
if (marker->frame == cfra) {
@@ -1195,7 +1195,7 @@ static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool
}
}
}
-
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
#else
@@ -1232,11 +1232,11 @@ static void MARKER_OT_select(wmOperatorType *ot)
ot->name = "Select Time Marker";
ot->description = "Select time marker(s)";
ot->idname = "MARKER_OT_select";
-
+
/* api callbacks */
ot->invoke = ed_marker_select_invoke_wrapper;
ot->poll = ed_markers_poll_markers_exist;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1250,7 +1250,7 @@ static void MARKER_OT_select(wmOperatorType *ot)
/* *************************** border select markers **************** */
-/* operator state vars used: (added by default WM callbacks)
+/* operator state vars used: (added by default WM callbacks)
* xmin, ymin
* xmax, ymax
*
@@ -1277,13 +1277,13 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
bool select = !RNA_boolean_get(op->ptr, "deselect");
bool extend = RNA_boolean_get(op->ptr, "extend");
rctf rect;
-
+
WM_operator_properties_border_to_rctf(op, &rect);
UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
-
+
if (markers == NULL)
return 0;
-
+
/* XXX marker context */
for (marker = markers->first; marker; marker = marker->next) {
if (BLI_rctf_isect_x(&rect, marker->frame)) {
@@ -1298,7 +1298,7 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
marker->flag &= ~SELECT;
}
}
-
+
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
@@ -1316,18 +1316,18 @@ static void MARKER_OT_select_border(wmOperatorType *ot)
ot->name = "Marker Border Select";
ot->description = "Select all time markers using border selection";
ot->idname = "MARKER_OT_select_border";
-
+
/* api callbacks */
ot->exec = ed_marker_border_select_exec;
ot->invoke = ed_marker_select_border_invoke_wrapper;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = ed_markers_poll_markers_exist;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
}
@@ -1346,7 +1346,7 @@ static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
if (action == SEL_TOGGLE) {
action = (ED_markers_get_first_selected(markers) != NULL) ? SEL_DESELECT : SEL_SELECT;
}
-
+
for (marker = markers->first; marker; marker = marker->next) {
switch (action) {
case SEL_SELECT:
@@ -1360,7 +1360,7 @@ static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
break;
}
}
-
+
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
@@ -1373,15 +1373,15 @@ static void MARKER_OT_select_all(wmOperatorType *ot)
ot->name = "(De)select all Markers";
ot->description = "Change selection of all time markers";
ot->idname = "MARKER_OT_select_all";
-
+
/* api callbacks */
ot->exec = ed_marker_select_all_exec;
ot->invoke = ed_markers_opwrap_invoke;
ot->poll = ed_markers_poll_markers_exist;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_select_all(ot);
}
@@ -1394,10 +1394,10 @@ static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op))
ListBase *markers = ED_context_get_markers(C);
TimeMarker *marker, *nmarker;
bool changed = false;
-
+
if (markers == NULL)
return OPERATOR_CANCELLED;
-
+
for (marker = markers->first; marker; marker = nmarker) {
nmarker = marker->next;
if (marker->flag & SELECT) {
@@ -1405,12 +1405,12 @@ static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op))
changed = true;
}
}
-
+
if (changed) {
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -1426,12 +1426,12 @@ static void MARKER_OT_delete(wmOperatorType *ot)
ot->name = "Delete Markers";
ot->description = "Delete selected time marker(s)";
ot->idname = "MARKER_OT_delete";
-
+
/* api callbacks */
ot->invoke = ed_marker_delete_invoke_wrapper;
ot->exec = ed_marker_delete_exec;
ot->poll = ed_markers_poll_selected_no_locked_markers;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1446,10 +1446,10 @@ static int ed_marker_rename_exec(bContext *C, wmOperator *op)
if (marker) {
RNA_string_get(op->ptr, "name", marker->name);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
-
+
return OPERATOR_FINISHED;
}
else {
@@ -1463,7 +1463,7 @@ static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, const wm
TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C));
if (marker)
RNA_string_set(op->ptr, "name", marker->name);
-
+
/* now see if the operator is usable */
return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup_confirm);
}
@@ -1474,15 +1474,15 @@ static void MARKER_OT_rename(wmOperatorType *ot)
ot->name = "Rename Marker";
ot->description = "Rename first selected time marker";
ot->idname = "MARKER_OT_rename";
-
+
/* api callbacks */
ot->invoke = ed_marker_rename_invoke_wrapper;
ot->exec = ed_marker_rename_exec;
ot->poll = ed_markers_poll_selected_no_locked_markers;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_string(ot->srna, "name", "RenamedMarker", sizeof(((TimeMarker *)NULL)->name), "Name", "New name for marker");
//RNA_def_boolean(ot->srna, "ensure_unique", 0, "Ensure Unique", "Ensure that new name is unique within collection of markers");
@@ -1516,7 +1516,7 @@ static int ed_marker_make_links_scene_exec(bContext *C, wmOperator *op)
if (marker->flag & SELECT) {
marker_new = MEM_dupallocN(marker);
marker_new->prev = marker_new->next = NULL;
-
+
BLI_addtail(&scene_to->markers, marker_new);
}
}
@@ -1645,7 +1645,7 @@ void ED_keymap_marker(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Markers", 0, 0);
wmKeyMapItem *kmi;
-
+
WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
@@ -1664,13 +1664,13 @@ void ED_keymap_marker(wmKeyConfig *keyconf)
#else
(void)kmi;
#endif
-
+
WM_keymap_verify_item(keymap, "MARKER_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MARKER_OT_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_rename", MKEY, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
#ifdef DURIAN_CAMERA_SWITCH
WM_keymap_add_item(keymap, "MARKER_OT_camera_bind", BKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 7c96f1a7ccd..23563e7f15f 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -67,10 +67,10 @@
static int change_frame_poll(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
-
+
/* XXX temp? prevent changes during render */
if (G.is_rendering) return false;
-
+
/* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
* this shouldn't show up in 3D editor (or others without 2D timeline view) via search
*/
@@ -85,7 +85,7 @@ static int change_frame_poll(bContext *C)
return false;
}
}
-
+
CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
return false;
}
@@ -139,12 +139,12 @@ static float frame_from_event(bContext *C, const wmEvent *event)
/* convert from region coordinates to View2D 'tot' space */
frame = UI_view2d_region_to_view_x(&region->v2d, event->mval[0]);
-
+
/* respect preview range restrictions (if only allowed to move around within that range) */
if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
CLAMP(frame, PSFRA, PEFRA);
}
-
+
return frame;
}
@@ -195,7 +195,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
change_frame_seq_preview_begin(C, event);
change_frame_apply(C, op);
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
@@ -221,11 +221,11 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
change_frame_apply(C, op);
break;
-
- case LEFTMOUSE:
+
+ case LEFTMOUSE:
case RIGHTMOUSE:
case MIDDLEMOUSE:
- /* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init
+ /* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init
* the modal op) doesn't work for some reason
*/
if (event->val == KM_RELEASE)
@@ -258,14 +258,14 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
ot->name = "Change Frame";
ot->idname = "ANIM_OT_change_frame";
ot->description = "Interactively change the current frame number";
-
+
/* api callbacks */
ot->exec = change_frame_exec;
ot->invoke = change_frame_invoke;
ot->cancel = change_frame_cancel;
ot->modal = change_frame_modal;
ot->poll = change_frame_poll;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR | OPTYPE_UNDO_GROUPED;
ot->undo_group = "FRAME_CHANGE";
@@ -282,10 +282,10 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
static int anim_set_end_frames_poll(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
-
+
/* XXX temp? prevent changes during render */
if (G.is_rendering) return false;
-
+
/* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
* this shouldn't show up in 3D editor (or others without 2D timeline view) via search
*/
@@ -294,7 +294,7 @@ static int anim_set_end_frames_poll(bContext *C)
return true;
}
}
-
+
CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
return false;
}
@@ -314,16 +314,16 @@ static int anim_set_sfra_exec(bContext *C, wmOperator *UNUSED(op))
scene->r.psfra = frame;
else
scene->r.sfra = frame;
-
+
if (PEFRA < frame) {
if (PRVRANGEON)
scene->r.pefra = frame;
else
scene->r.efra = frame;
}
-
+
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -333,14 +333,14 @@ static void ANIM_OT_start_frame_set(wmOperatorType *ot)
ot->name = "Set Start Frame";
ot->idname = "ANIM_OT_start_frame_set";
ot->description = "Set the start frame";
-
+
/* api callbacks */
ot->exec = anim_set_sfra_exec;
ot->poll = anim_set_end_frames_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
+}
static int anim_set_efra_exec(bContext *C, wmOperator *UNUSED(op))
@@ -365,9 +365,9 @@ static int anim_set_efra_exec(bContext *C, wmOperator *UNUSED(op))
else
scene->r.sfra = frame;
}
-
+
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -377,11 +377,11 @@ static void ANIM_OT_end_frame_set(wmOperatorType *ot)
ot->name = "Set End Frame";
ot->idname = "ANIM_OT_end_frame_set";
ot->description = "Set the end frame";
-
+
/* api callbacks */
ot->exec = anim_set_efra_exec;
ot->poll = anim_set_end_frames_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -394,31 +394,31 @@ static int previewrange_define_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
float sfra, efra;
rcti rect;
-
+
/* get min/max values from border select rect (already in region coordinates, not screen) */
WM_operator_properties_border_to_rcti(op, &rect);
-
+
/* convert min/max values to frames (i.e. region to 'tot' rect) */
sfra = UI_view2d_region_to_view_x(&ar->v2d, rect.xmin);
efra = UI_view2d_region_to_view_x(&ar->v2d, rect.xmax);
-
- /* set start/end frames for preview-range
+
+ /* set start/end frames for preview-range
* - must clamp within allowable limits
* - end must not be before start (though this won't occur most of the time)
*/
FRAMENUMBER_MIN_CLAMP(sfra);
FRAMENUMBER_MIN_CLAMP(efra);
if (efra < sfra) efra = sfra;
-
+
scene->r.flag |= SCER_PRV_RANGE;
scene->r.psfra = round_fl_to_int(sfra);
scene->r.pefra = round_fl_to_int(efra);
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
-
+
return OPERATOR_FINISHED;
-}
+}
static void ANIM_OT_previewrange_set(wmOperatorType *ot)
{
@@ -426,18 +426,18 @@ static void ANIM_OT_previewrange_set(wmOperatorType *ot)
ot->name = "Set Preview Range";
ot->idname = "ANIM_OT_previewrange_set";
ot->description = "Interactively define frame range used for playback";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = previewrange_define_exec;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = ED_operator_animview_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
/* used to define frame range.
*
@@ -452,23 +452,23 @@ static int previewrange_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
ScrArea *curarea = CTX_wm_area(C);
-
+
/* sanity checks */
if (ELEM(NULL, scene, curarea))
return OPERATOR_CANCELLED;
-
+
/* simply clear values */
scene->r.flag &= ~SCER_PRV_RANGE;
scene->r.psfra = 0;
scene->r.pefra = 0;
-
+
ED_area_tag_redraw(curarea);
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
-
+
return OPERATOR_FINISHED;
-}
+}
static void ANIM_OT_previewrange_clear(wmOperatorType *ot)
{
@@ -476,12 +476,12 @@ static void ANIM_OT_previewrange_clear(wmOperatorType *ot)
ot->name = "Clear Preview Range";
ot->idname = "ANIM_OT_previewrange_clear";
ot->description = "Clear Preview Range";
-
+
/* api callbacks */
ot->exec = previewrange_clear_exec;
-
+
ot->poll = ED_operator_animview_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -492,13 +492,13 @@ void ED_operatortypes_anim(void)
{
/* Animation Editors only -------------------------- */
WM_operatortype_append(ANIM_OT_change_frame);
-
+
WM_operatortype_append(ANIM_OT_start_frame_set);
WM_operatortype_append(ANIM_OT_end_frame_set);
-
+
WM_operatortype_append(ANIM_OT_previewrange_set);
WM_operatortype_append(ANIM_OT_previewrange_clear);
-
+
/* Entire UI --------------------------------------- */
WM_operatortype_append(ANIM_OT_keyframe_insert);
WM_operatortype_append(ANIM_OT_keyframe_delete);
@@ -508,23 +508,23 @@ void ED_operatortypes_anim(void)
WM_operatortype_append(ANIM_OT_keyframe_insert_button);
WM_operatortype_append(ANIM_OT_keyframe_delete_button);
WM_operatortype_append(ANIM_OT_keyframe_clear_button);
-
-
+
+
WM_operatortype_append(ANIM_OT_driver_button_add);
WM_operatortype_append(ANIM_OT_driver_button_remove);
WM_operatortype_append(ANIM_OT_driver_button_edit);
WM_operatortype_append(ANIM_OT_copy_driver_button);
WM_operatortype_append(ANIM_OT_paste_driver_button);
-
+
WM_operatortype_append(ANIM_OT_keyingset_button_add);
WM_operatortype_append(ANIM_OT_keyingset_button_remove);
-
+
WM_operatortype_append(ANIM_OT_keying_set_add);
WM_operatortype_append(ANIM_OT_keying_set_remove);
WM_operatortype_append(ANIM_OT_keying_set_path_add);
WM_operatortype_append(ANIM_OT_keying_set_path_remove);
-
+
WM_operatortype_append(ANIM_OT_keying_set_active_set);
}
@@ -532,14 +532,14 @@ void ED_keymap_anim(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Animation", 0, 0);
wmKeyMapItem *kmi;
-
+
/* frame management */
/* NOTE: 'ACTIONMOUSE' not 'LEFTMOUSE', as user may have swapped mouse-buttons */
WM_keymap_add_item(keymap, "ANIM_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TKEY, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.show_seconds");
-
+
/* preview range */
WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_set", PKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_clear", PKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 66ed760bf30..03639b0ad77 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -29,7 +29,7 @@
* \ingroup edanimation
*/
-
+
#include <stdio.h>
#include <string.h>
@@ -68,7 +68,7 @@
/* ************************************************** */
/* Animation Data Validation */
-/* Get (or add relevant data to be able to do so) F-Curve from the driver stack,
+/* Get (or add relevant data to be able to do so) F-Curve from the driver stack,
* for the given Animation Data block. This assumes that all the destinations are valid.
*
* - add: 0 - don't add anything if not found,
@@ -80,11 +80,11 @@ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_inde
{
AnimData *adt;
FCurve *fcu;
-
+
/* sanity checks */
if (ELEM(NULL, id, rna_path))
return NULL;
-
+
/* init animdata if none available yet */
adt = BKE_animdata_from_id(id);
if ((adt == NULL) && (add))
@@ -93,32 +93,32 @@ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_inde
/* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
return NULL;
}
-
- /* try to find f-curve matching for this setting
+
+ /* try to find f-curve matching for this setting
* - add if not found and allowed to add one
* TODO: add auto-grouping support? how this works will need to be resolved
*/
fcu = list_find_fcurve(&adt->drivers, rna_path, array_index);
-
+
if ((fcu == NULL) && (add)) {
/* use default settings to make a F-Curve */
fcu = MEM_callocN(sizeof(FCurve), "FCurve");
-
+
fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
-
+
/* store path - make copy, and store that */
fcu->rna_path = BLI_strdup(rna_path);
fcu->array_index = array_index;
-
+
/* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
if (add > 0) {
BezTriple *bezt;
size_t i;
-
+
/* add some new driver data */
fcu->driver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
-
+
/* F-Modifier or Keyframes? */
// FIXME: replace these magic numbers with defines
if (add == 2) {
@@ -129,27 +129,27 @@ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_inde
add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu);
}
else {
- /* add 2 keyframes so that user has something to work with
+ /* add 2 keyframes so that user has something to work with
* - These are configured to 0,0 and 1,1 to give a 1-1 mapping
* which can be easily tweaked from there.
*/
insert_vert_fcurve(fcu, 0.0f, 0.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
insert_vert_fcurve(fcu, 1.0f, 1.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
-
+
/* configure this curve to extrapolate */
for (i = 0, bezt = fcu->bezt; (i < fcu->totvert) && bezt; i++, bezt++) {
bezt->h1 = bezt->h2 = HD_VECT;
}
-
+
fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
calchandles_fcurve(fcu);
}
}
-
+
/* just add F-Curve to end of driver list */
BLI_addtail(&adt->drivers, fcu);
}
-
+
/* return the F-Curve */
return fcu;
}
@@ -169,17 +169,17 @@ static int add_driver_with_target(
FCurve *fcu;
short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
const char *prop_name = RNA_property_identifier(src_prop);
-
+
/* Create F-Curve with Driver */
fcu = verify_driver_fcurve(dst_id, dst_path, dst_index, add_mode);
-
+
if (fcu && fcu->driver) {
ChannelDriver *driver = fcu->driver;
DriverVar *dvar;
-
+
/* Set the type of the driver */
driver->type = driver_type;
-
+
/* Set driver expression, so that the driver works out of the box
*
* The following checks define a bit of "autodetection magic" we use
@@ -187,7 +187,7 @@ static int add_driver_with_target(
* when faced with properties with different units.
*/
/* XXX: if we have N-1 mapping, should we include all those in the expression? */
- if ((RNA_property_unit(dst_prop) == PROP_UNIT_ROTATION) &&
+ if ((RNA_property_unit(dst_prop) == PROP_UNIT_ROTATION) &&
(RNA_property_unit(src_prop) != PROP_UNIT_ROTATION))
{
/* Rotation Destination: normal -> radians, so convert src to radians
@@ -207,7 +207,7 @@ static int add_driver_with_target(
/* Just a normal property without any unit problems */
BLI_strncpy(driver->expression, "var", sizeof(driver->expression));
}
-
+
/* Create a driver variable for the target
* - For transform properties, we want to automatically use "transform channel" instead
* (The only issue is with quat rotations vs euler channels...)
@@ -216,25 +216,25 @@ static int add_driver_with_target(
* when both the source and destinations are in same places.
*/
dvar = driver_add_new_variable(driver);
-
- if (ELEM(src_ptr->type, &RNA_Object, &RNA_PoseBone) &&
+
+ if (ELEM(src_ptr->type, &RNA_Object, &RNA_PoseBone) &&
(STREQ(prop_name, "location") || STREQ(prop_name, "scale") || STRPREFIX(prop_name, "rotation_")) &&
(src_ptr->data != dst_ptr->data))
{
/* Transform Channel */
DriverTarget *dtar;
-
+
driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
dtar = &dvar->targets[0];
-
+
/* Bone or Object target? */
dtar->id = src_id;
dtar->idtype = GS(src_id->name);
-
+
if (src_ptr->type == &RNA_PoseBone) {
RNA_string_get(src_ptr, "name", dtar->pchan_name);
}
-
+
/* Transform channel depends on type */
if (STREQ(prop_name, "location")) {
if (src_index == 2)
@@ -267,11 +267,11 @@ static int add_driver_with_target(
else {
/* Single RNA Property */
DriverTarget *dtar = &dvar->targets[0];
-
+
/* ID is as-is */
dtar->id = src_id;
dtar->idtype = GS(src_id->name);
-
+
/* Need to make a copy of the path (or build one with array index built in) */
if (RNA_property_array_check(src_prop)) {
dtar->rna_path = BLI_sprintfN("%s[%d]", src_path, src_index);
@@ -281,7 +281,7 @@ static int add_driver_with_target(
}
}
}
-
+
/* set the done status */
return (fcu != NULL);
}
@@ -298,35 +298,35 @@ static int add_driver_with_target(
* - mapping_type: eCreateDriver_MappingTypes
*/
int ANIM_add_driver_with_target(
- ReportList *reports,
+ ReportList *reports,
ID *dst_id, const char dst_path[], int dst_index,
ID *src_id, const char src_path[], int src_index,
short flag, int driver_type, short mapping_type)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
-
+
PointerRNA id_ptr2, ptr2;
PropertyRNA *prop2;
int done_tot = 0;
-
+
/* validate pointers first - exit if failure */
RNA_id_pointer_create(dst_id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, dst_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
+ BKE_reportf(reports, RPT_ERROR,
"Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
dst_id->name, dst_path);
return 0;
}
-
+
RNA_id_pointer_create(src_id, &id_ptr2);
- if ((RNA_path_resolve_property(&id_ptr2, src_path, &ptr2, &prop2) == false) ||
+ if ((RNA_path_resolve_property(&id_ptr2, src_path, &ptr2, &prop2) == false) ||
(mapping_type == CREATEDRIVER_MAPPING_NONE))
{
/* No target - So, fall back to default method for adding a "simple" driver normally */
return ANIM_add_driver(reports, dst_id, dst_path, dst_index, flag | CREATEDRIVER_WITH_DEFAULT_DVAR, driver_type);
}
-
+
/* handle curve-property mappings based on mapping_type */
switch (mapping_type) {
case CREATEDRIVER_MAPPING_N_N: /* N-N - Try to match as much as possible, then use the first one */
@@ -334,35 +334,35 @@ int ANIM_add_driver_with_target(
/* Use the shorter of the two (to avoid out of bounds access) */
int dst_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
int src_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr2, prop2) : 1;
-
+
int len = MIN2(dst_len, src_len);
int i;
-
+
for (i = 0; i < len; i++) {
done_tot += add_driver_with_target(reports, dst_id, dst_path, i, src_id, src_path, i, &ptr, prop, &ptr2, prop2, flag, driver_type);
}
break;
}
-
+
case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
default:
{
int len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
int i;
-
+
for (i = 0; i < len; i++) {
done_tot += add_driver_with_target(reports, dst_id, dst_path, i, src_id, src_path, src_index, &ptr, prop, &ptr2, prop2, flag, driver_type);
}
break;
}
-
+
case CREATEDRIVER_MAPPING_1_1: /* 1-1 - Use the specified index (unless -1) */
{
done_tot = add_driver_with_target(reports, dst_id, dst_path, dst_index, src_id, src_path, src_index, &ptr, prop, &ptr2, prop2, flag, driver_type);
break;
}
}
-
+
/* done */
return done_tot;
}
@@ -373,22 +373,22 @@ int ANIM_add_driver_with_target(
* Add a new driver for the specified property on the given ID block
*/
int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
-{
+{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
FCurve *fcu;
int array_index_max;
int done_tot = 0;
-
+
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
+ BKE_reportf(reports, RPT_ERROR,
"Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
id->name, rna_path);
return 0;
}
-
+
/* key entire array convenience method */
if (array_index == -1) {
array_index_max = RNA_property_array_length(&ptr, prop);
@@ -396,25 +396,25 @@ int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int arra
}
else
array_index_max = array_index;
-
+
/* maximum index should be greater than the start index */
if (array_index == array_index_max)
array_index_max += 1;
-
+
/* will only loop once unless the array index was -1 */
for (; array_index < array_index_max; array_index++) {
short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
-
+
/* create F-Curve with Driver */
fcu = verify_driver_fcurve(id, rna_path, array_index, add_mode);
-
+
if (fcu && fcu->driver) {
ChannelDriver *driver = fcu->driver;
-
+
/* set the type of the driver */
driver->type = type;
-
- /* creating drivers for buttons will create the driver(s) with type
+
+ /* creating drivers for buttons will create the driver(s) with type
* "scripted expression" so that their values won't be lost immediately,
* so here we copy those values over to the driver's expression
*/
@@ -424,28 +424,28 @@ int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int arra
char *expression = driver->expression;
int val, maxlen = sizeof(driver->expression);
float fval;
-
+
if (proptype == PROP_BOOLEAN) {
if (!array) val = RNA_property_boolean_get(&ptr, prop);
else val = RNA_property_boolean_get_index(&ptr, prop, array_index);
-
+
BLI_strncpy(expression, (val) ? "True" : "False", maxlen);
}
else if (proptype == PROP_INT) {
if (!array) val = RNA_property_int_get(&ptr, prop);
else val = RNA_property_int_get_index(&ptr, prop, array_index);
-
+
BLI_snprintf(expression, maxlen, "%d", val);
}
else if (proptype == PROP_FLOAT) {
if (!array) fval = RNA_property_float_get(&ptr, prop);
else fval = RNA_property_float_get_index(&ptr, prop, array_index);
-
+
BLI_snprintf(expression, maxlen, "%.3f", fval);
}
}
-
- /* for easier setup of drivers from UI, a driver variable should be
+
+ /* for easier setup of drivers from UI, a driver variable should be
* added if flag is set (UI calls only)
*/
if (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) {
@@ -456,11 +456,11 @@ int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int arra
driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
}
}
-
+
/* set the done status */
done_tot += (fcu != NULL);
}
-
+
/* done */
return done_tot;
}
@@ -473,29 +473,29 @@ bool ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_path
AnimData *adt;
FCurve *fcu;
bool success = false;
-
+
/* we don't check the validity of the path here yet, but it should be ok... */
adt = BKE_animdata_from_id(id);
-
+
if (adt) {
if (array_index == -1) {
/* step through all drivers, removing all of those with the same base path */
FCurve *fcu_iter = adt->drivers.first;
-
+
while ((fcu = iter_step_fcurve(fcu_iter, rna_path)) != NULL) {
/* store the next fcurve for looping */
fcu_iter = fcu->next;
-
+
/* remove F-Curve from driver stack, then free it */
BLI_remlink(&adt->drivers, fcu);
free_fcurve(fcu);
-
+
/* done successfully */
success = true;
}
}
else {
- /* find the matching driver and remove it only
+ /* find the matching driver and remove it only
* Note: here is one of the places where we don't want new F-Curve + Driver added!
* so 'add' var must be 0
*/
@@ -503,7 +503,7 @@ bool ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_path
if (fcu) {
BLI_remlink(&adt->drivers, fcu);
free_fcurve(fcu);
-
+
success = true;
}
}
@@ -543,7 +543,7 @@ bool ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int ar
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
FCurve *fcu;
-
+
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
@@ -552,13 +552,13 @@ bool ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int ar
id->name, rna_path);
return 0;
}
-
+
/* try to get F-Curve with Driver */
fcu = verify_driver_fcurve(id, rna_path, array_index, 0);
-
+
/* clear copy/paste buffer first (for consistency with other copy/paste buffers) */
ANIM_drivers_copybuf_free();
-
+
/* copy this to the copy/paste buf if it exists */
if (fcu && fcu->driver) {
/* make copies of some info such as the rna_path, then clear this info from the F-Curve temporarily
@@ -566,17 +566,17 @@ bool ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int ar
*/
char *tmp_path = fcu->rna_path;
fcu->rna_path = NULL;
-
+
/* make a copy of the F-Curve with */
channeldriver_copypaste_buf = copy_fcurve(fcu);
-
+
/* restore the path */
fcu->rna_path = tmp_path;
-
+
/* copied... */
return 1;
}
-
+
/* done */
return 0;
}
@@ -586,11 +586,11 @@ bool ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int ar
* with the driver + driver-curve data from the buffer
*/
bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
-{
+{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
FCurve *fcu;
-
+
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
@@ -599,35 +599,35 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
id->name, rna_path);
return 0;
}
-
+
/* if the buffer is empty, cannot paste... */
if (channeldriver_copypaste_buf == NULL) {
BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste");
return 0;
}
-
+
/* create Driver F-Curve, but without data which will be copied across... */
fcu = verify_driver_fcurve(id, rna_path, array_index, -1);
-
+
if (fcu) {
- /* copy across the curve data from the buffer curve
+ /* copy across the curve data from the buffer curve
* NOTE: this step needs care to not miss new settings
*/
/* keyframes/samples */
fcu->bezt = MEM_dupallocN(channeldriver_copypaste_buf->bezt);
fcu->fpt = MEM_dupallocN(channeldriver_copypaste_buf->fpt);
fcu->totvert = channeldriver_copypaste_buf->totvert;
-
+
/* modifiers */
copy_fmodifiers(&fcu->modifiers, &channeldriver_copypaste_buf->modifiers);
-
+
/* extrapolation mode */
fcu->extend = channeldriver_copypaste_buf->extend;
-
+
/* the 'juicy' stuff - the driver */
fcu->driver = fcurve_copy_driver(channeldriver_copypaste_buf->driver);
}
-
+
/* done */
return (fcu != NULL);
}
@@ -644,14 +644,14 @@ void ANIM_driver_vars_copybuf_free(void)
/* Free the driver variables kept in the buffer */
if (driver_vars_copybuf.first) {
DriverVar *dvar, *dvarn;
-
+
/* Free variables (and any data they use) */
for (dvar = driver_vars_copybuf.first; dvar; dvar = dvarn) {
dvarn = dvar->next;
driver_free_variable(&driver_vars_copybuf, dvar);
}
}
-
+
BLI_listbase_clear(&driver_vars_copybuf);
}
@@ -671,18 +671,18 @@ bool ANIM_driver_vars_copy(ReportList *reports, FCurve *fcu)
BKE_report(reports, RPT_ERROR, "No driver to copy variables from");
return false;
}
-
+
if (BLI_listbase_is_empty(&fcu->driver->variables)) {
BKE_report(reports, RPT_ERROR, "Driver has no variables to copy");
return false;
}
-
+
/* clear buffer */
ANIM_driver_vars_copybuf_free();
-
+
/* copy over the variables */
driver_variables_copy(&driver_vars_copybuf, &fcu->driver->variables);
-
+
return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
}
@@ -691,55 +691,55 @@ bool ANIM_driver_vars_paste(ReportList *reports, FCurve *fcu, bool replace)
{
ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
ListBase tmp_list = {NULL, NULL};
-
+
/* sanity checks */
if (BLI_listbase_is_empty(&driver_vars_copybuf)) {
BKE_report(reports, RPT_ERROR, "No driver variables in clipboard to paste");
return false;
}
-
+
if (ELEM(NULL, fcu, fcu->driver)) {
BKE_report(reports, RPT_ERROR, "Cannot paste driver variables without a driver");
return false;
}
-
+
/* 1) Make a new copy of the variables in the buffer - these will get pasted later... */
driver_variables_copy(&tmp_list, &driver_vars_copybuf);
-
+
/* 2) Prepare destination array */
if (replace) {
DriverVar *dvar, *dvarn;
-
+
/* Free all existing vars first - We aren't retaining anything */
for (dvar = driver->variables.first; dvar; dvar = dvarn) {
dvarn = dvar->next;
driver_free_variable_ex(driver, dvar);
}
-
+
BLI_listbase_clear(&driver->variables);
}
-
+
/* 3) Add new vars */
if (driver->variables.last) {
DriverVar *last = driver->variables.last;
DriverVar *first = tmp_list.first;
-
+
last->next = first;
first->prev = last;
-
+
driver->variables.last = tmp_list.last;
}
else {
driver->variables.first = tmp_list.first;
driver->variables.last = tmp_list.last;
}
-
+
#ifdef WITH_PYTHON
/* since driver variables are cached, the expression needs re-compiling too */
if (driver->type == DRIVER_TYPE_PYTHON)
driver->flag |= DRIVER_FLAG_RENAMEVAR;
#endif
-
+
return true;
}
@@ -756,10 +756,10 @@ EnumPropertyItem prop_driver_create_mapping_types[] = {
"Drive all components of this property using the target picked"},
{CREATEDRIVER_MAPPING_1_1, "DIRECT", 0, "Single from Target",
"Drive this component of this property using the target picked"},
-
+
{CREATEDRIVER_MAPPING_N_N, "MATCH", ICON_COLOR, "Match Indices",
"Create drivers for each pair of corresponding elements"},
-
+
{CREATEDRIVER_MAPPING_NONE_ALL, "NONE_ALL", ICON_HAND, "Manually Create Later",
"Create drivers for all properties without assigning any targets yet"},
{CREATEDRIVER_MAPPING_NONE, "NONE_SINGLE", 0, "Manually Create Later (Single)",
@@ -772,21 +772,21 @@ static const EnumPropertyItem *driver_mapping_type_itemsf(bContext *C, PointerRN
{
EnumPropertyItem *input = prop_driver_create_mapping_types;
EnumPropertyItem *item = NULL;
-
+
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
int index;
-
+
int totitem = 0;
-
+
if (!C) /* needed for docs */
return prop_driver_create_mapping_types;
-
+
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
+
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
const bool is_array = RNA_property_array_check(prop);
-
+
while (input->identifier) {
if (ELEM(input->value, CREATEDRIVER_MAPPING_1_1, CREATEDRIVER_MAPPING_NONE) || (is_array)) {
RNA_enum_item_add(&item, &totitem, input);
@@ -798,9 +798,9 @@ static const EnumPropertyItem *driver_mapping_type_itemsf(bContext *C, PointerRN
/* We need at least this one! */
RNA_enum_items_add_value(&item, &totitem, input, CREATEDRIVER_MAPPING_NONE);
}
-
+
RNA_enum_item_end(&item, &totitem);
-
+
*r_free = true;
return item;
}
@@ -813,7 +813,7 @@ static int add_driver_button_poll(bContext *C)
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
int index;
-
+
/* this operator can only run if there's a property button active, and it can be animated */
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
return (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop));
@@ -826,28 +826,28 @@ static int add_driver_button_none(bContext *C, wmOperator *op, short mapping_typ
PropertyRNA *prop = NULL;
int index;
int success = 0;
-
+
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
+
if (mapping_type == CREATEDRIVER_MAPPING_NONE_ALL)
index = -1;
-
+
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
-
+
if (path) {
success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
MEM_freeN(path);
}
}
-
+
if (success) {
/* send updates */
UI_context_update_anim_flag(C);
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
-
+
return OPERATOR_FINISHED;
}
else {
@@ -865,10 +865,10 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
else {
/* Create Driver using Eyedropper */
wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
-
+
/* XXX: We assume that it's fine to use the same set of properties, since they're actually the same... */
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, op->ptr);
-
+
return OPERATOR_FINISHED;
}
}
@@ -877,7 +877,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
static int add_driver_button_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
PropertyRNA *prop;
-
+
if ((prop = RNA_struct_find_property(op->ptr, "mapping_type")) && RNA_property_is_set(op->ptr, prop)) {
/* Mapping Type is Set - Directly go into creating drivers */
return add_driver_button_exec(C, op);
@@ -896,18 +896,18 @@ void ANIM_OT_driver_button_add(wmOperatorType *ot)
ot->name = "Add Driver";
ot->idname = "ANIM_OT_driver_button_add";
ot->description = "Add driver(s) for the property(s) represented by the highlighted button";
-
+
/* callbacks */
/* NOTE: No exec, as we need all these to use the current context info
* (especially the eyedropper, which is interactive)
*/
ot->invoke = add_driver_button_invoke;
- ot->exec = add_driver_button_exec;
+ ot->exec = add_driver_button_exec;
ot->poll = add_driver_button_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "mapping_type", prop_driver_create_mapping_types, 0,
"Mapping Type", "Method used to match target and driven properties");
@@ -923,30 +923,30 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
short success = 0;
int index;
const bool all = RNA_boolean_get(op->ptr, "all");
-
+
/* try to find driver using property retrieved from UI */
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
+
if (all)
index = -1;
-
+
if (ptr.id.data && ptr.data && prop) {
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
-
+
if (path) {
success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
MEM_freeN(path);
}
}
-
+
if (success) {
/* send updates */
UI_context_update_anim_flag(C);
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
}
-
+
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -956,11 +956,11 @@ void ANIM_OT_driver_button_remove(wmOperatorType *ot)
ot->name = "Remove Driver";
ot->idname = "ANIM_OT_driver_button_remove";
ot->description = "Remove the driver(s) for the property(s) connected represented by the highlighted button";
-
+
/* callbacks */
- ot->exec = remove_driver_button_exec;
+ ot->exec = remove_driver_button_exec;
//op->poll = ??? // TODO: need to have some driver to be able to do this...
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -996,11 +996,11 @@ void ANIM_OT_driver_button_edit(wmOperatorType *ot)
ot->name = "Edit Driver";
ot->idname = "ANIM_OT_driver_button_edit";
ot->description = "Edit the drivers for the property connected represented by the highlighted button";
-
+
/* callbacks */
ot->exec = edit_driver_button_exec;
//op->poll = ??? // TODO: need to have some driver to be able to do this...
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -1016,23 +1016,23 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
PropertyRNA *prop = NULL;
short success = 0;
int index;
-
+
/* try to create driver using property retrieved from UI */
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
+
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
-
+
if (path) {
/* only copy the driver for the button that this was involved for */
success = ANIM_copy_driver(op->reports, ptr.id.data, path, index, 0);
-
+
UI_context_update_anim_flag(C);
-
+
MEM_freeN(path);
}
}
-
+
/* since we're just copying, we don't really need to do anything else...*/
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1043,11 +1043,11 @@ void ANIM_OT_copy_driver_button(wmOperatorType *ot)
ot->name = "Copy Driver";
ot->idname = "ANIM_OT_copy_driver_button";
ot->description = "Copy the driver for the highlighted button";
-
+
/* callbacks */
- ot->exec = copy_driver_button_exec;
+ ot->exec = copy_driver_button_exec;
//op->poll = ??? // TODO: need to have some driver to be able to do this...
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
@@ -1060,28 +1060,28 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
PropertyRNA *prop = NULL;
short success = 0;
int index;
-
+
/* try to create driver using property retrieved from UI */
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
+
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
-
+
if (path) {
/* only copy the driver for the button that this was involved for */
success = ANIM_paste_driver(op->reports, ptr.id.data, path, index, 0);
-
+
UI_context_update_anim_flag(C);
-
+
DEG_relations_tag_update(CTX_data_main(C));
DEG_id_tag_update(ptr.id.data, OB_RECALC_OB | OB_RECALC_DATA);
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); // XXX
-
+
MEM_freeN(path);
}
}
-
+
/* since we're just copying, we don't really need to do anything else...*/
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1092,11 +1092,11 @@ void ANIM_OT_paste_driver_button(wmOperatorType *ot)
ot->name = "Paste Driver";
ot->idname = "ANIM_OT_paste_driver_button";
ot->description = "Paste the driver in the copy/paste buffer for the highlighted button";
-
+
/* callbacks */
- ot->exec = paste_driver_button_exec;
+ ot->exec = paste_driver_button_exec;
//op->poll = ??? // TODO: need to have some driver to be able to do this...
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index fba18d148c8..951dcc2dddf 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -37,7 +37,7 @@
* Copy/Paste Buffer for F-Modifiers:
* For now, this is also defined in this file so that it can be shared between the
*/
-
+
#include <string.h>
#include "DNA_anim_types.h"
@@ -79,7 +79,7 @@ static void validate_fmodifier_cb(bContext *UNUSED(C), void *fcm_v, void *UNUSED
{
FModifier *fcm = (FModifier *)fcm_v;
const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
-
+
/* call the verify callback on the modifier if applicable */
if (fmi && fmi->verify_data)
fmi->verify_data(fcm);
@@ -90,19 +90,19 @@ static void delete_fmodifier_cb(bContext *C, void *fmods_v, void *fcm_v)
{
ListBase *modifiers = (ListBase *)fmods_v;
FModifier *fcm = (FModifier *)fcm_v;
-
+
/* remove the given F-Modifier from the active modifier-stack */
remove_fmodifier(modifiers, fcm);
ED_undo_push(C, "Delete F-Curve Modifier");
-
+
/* send notifiers */
- // XXX for now, this is the only way to get updates in all the right places... but would be nice to have a special one in this case
+ // XXX for now, this is the only way to get updates in all the right places... but would be nice to have a special one in this case
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
/* --------------- */
-
+
/* draw settings for generator modifier */
static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, short width)
{
@@ -112,20 +112,20 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
uiBut *but;
PointerRNA ptr;
short bwidth = width - 1.5 * UI_UNIT_X; /* max button width */
-
+
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
-
+
/* basic settings (backdrop + mode selector + some padding) */
/* col = uiLayoutColumn(layout, true); */ /* UNUSED */
block = uiLayoutGetBlock(layout);
UI_block_align_begin(block);
but = uiDefButR(block, UI_BTYPE_MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
+
uiDefButR(block, UI_BTYPE_TOGGLE, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL);
UI_block_align_end(block);
-
+
/* now add settings for individual modes */
switch (data->mode) {
case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
@@ -135,7 +135,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
char xval[32];
unsigned int i;
int maxXWidth;
-
+
/* draw polynomial order selector */
row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
@@ -143,8 +143,8 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
&data->poly_order, 1, 100, 0, 0,
TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
-
+
+
/* calculate maximum width of label for "x^n" labels */
if (data->arraysize > 2) {
BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize);
@@ -155,11 +155,11 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
/* basic size (just "x") */
maxXWidth = UI_fontstyle_string_width(fstyle, "x") + 0.5 * UI_UNIT_X;
}
-
+
/* draw controls for each coefficient and a + sign at end of row */
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
-
+
cp = data->coefficients;
for (i = 0; (i < data->arraysize) && (cp); i++, cp++) {
/* To align with first line... */
@@ -167,11 +167,11 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
else
uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
+
/* coefficient */
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Coefficient for polynomial"));
-
+
/* 'x' param (and '+' if necessary) */
if (i == 0)
BLI_strncpy(xval, "", sizeof(xval));
@@ -180,10 +180,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
else
BLI_snprintf(xval, sizeof(xval), "x^%u", i);
uiDefBut(block, UI_BTYPE_LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x"));
-
+
if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) {
uiDefBut(block, UI_BTYPE_LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
+
/* next coefficient on a new row */
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
@@ -195,12 +195,12 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
}
break;
}
-
+
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial expression */
{
float *cp = NULL;
unsigned int i;
-
+
/* draw polynomial order selector */
row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
@@ -208,12 +208,12 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
&data->poly_order, 1, 100, 0, 0,
TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
-
+
+
/* draw controls for each pair of coefficients */
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
-
+
cp = data->coefficients;
for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) {
/* To align with first line */
@@ -223,25 +223,25 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* opening bracket */
uiDefBut(block, UI_BTYPE_LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
+
/* coefficients */
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Coefficient of x"));
-
+
uiDefBut(block, UI_BTYPE_LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
+
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Second coefficient"));
-
+
/* closing bracket and multiplication sign */
if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) {
uiDefBut(block, UI_BTYPE_LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
+
/* set up new row for the next pair of coefficients */
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
}
- else
+ else
uiDefBut(block, UI_BTYPE_LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
break;
@@ -256,10 +256,10 @@ static void draw_modifier__fn_generator(uiLayout *layout, ID *id, FModifier *fcm
{
uiLayout *col;
PointerRNA ptr;
-
+
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
-
+
/* add the settings */
col = uiLayoutColumn(layout, true);
uiItemR(col, &ptr, "function_type", 0, "", ICON_NONE);
@@ -279,21 +279,21 @@ static void draw_modifier__cycles(uiLayout *layout, ID *id, FModifier *fcm, shor
{
uiLayout *split, *col;
PointerRNA ptr;
-
+
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifierCycles, fcm, &ptr);
-
- /* split into 2 columns
+
+ /* split into 2 columns
* NOTE: the mode comboboxes shouldn't get labels, otherwise there isn't enough room
*/
split = uiLayoutSplit(layout, 0.5f, false);
-
+
/* before range */
col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("Before:"), ICON_NONE);
uiItemR(col, &ptr, "mode_before", 0, "", ICON_NONE);
uiItemR(col, &ptr, "cycles_before", 0, NULL, ICON_NONE);
-
+
/* after range */
col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("After:"), ICON_NONE);
@@ -308,22 +308,22 @@ static void draw_modifier__noise(uiLayout *layout, ID *id, FModifier *fcm, short
{
uiLayout *split, *col;
PointerRNA ptr;
-
+
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifierNoise, fcm, &ptr);
-
+
/* blending mode */
uiItemR(layout, &ptr, "blend_type", 0, NULL, ICON_NONE);
-
+
/* split into 2 columns */
split = uiLayoutSplit(layout, 0.5f, false);
-
+
/* col 1 */
col = uiLayoutColumn(split, false);
uiItemR(col, &ptr, "scale", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "strength", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "offset", 0, NULL, ICON_NONE);
-
+
/* col 2 */
col = uiLayoutColumn(split, false);
uiItemR(col, &ptr, "phase", 0, NULL, ICON_NONE);
@@ -337,46 +337,46 @@ static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(ar
FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
FCM_EnvelopeData *fedn;
FCM_EnvelopeData fed;
-
+
/* init template data */
fed.min = -1.0f;
fed.max = 1.0f;
fed.time = (float)scene->r.cfra; // XXX make this int for ease of use?
fed.f1 = fed.f2 = 0;
-
+
/* check that no data exists for the current frame... */
if (env->data) {
bool exists;
int i = BKE_fcm_envelope_find_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
-
+
/* binarysearch_...() will set exists by default to 0, so if it is non-zero, that means that the point exists already */
if (exists)
return;
-
+
/* add new */
fedn = MEM_callocN((env->totvert + 1) * sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
-
+
/* add the points that should occur before the point to be pasted */
if (i > 0)
memcpy(fedn, env->data, i * sizeof(FCM_EnvelopeData));
-
+
/* add point to paste at index i */
*(fedn + i) = fed;
-
+
/* add the points that occur after the point to be pasted */
- if (i < env->totvert)
+ if (i < env->totvert)
memcpy(fedn + i + 1, env->data + i, (env->totvert - i) * sizeof(FCM_EnvelopeData));
-
+
/* replace (+ free) old with new */
MEM_freeN(env->data);
env->data = fedn;
-
+
env->totvert++;
}
else {
env->data = MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
*(env->data) = fed;
-
+
env->totvert = 1;
}
}
@@ -388,7 +388,7 @@ static void fmod_envelope_deletepoint_cb(bContext *UNUSED(C), void *fcm_dv, void
FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
FCM_EnvelopeData *fedn;
int index = GET_INT_FROM_POINTER(ind_v);
-
+
/* check that no data exists for the current frame... */
if (env->totvert > 1) {
/* allocate a new smaller array */
@@ -396,7 +396,7 @@ static void fmod_envelope_deletepoint_cb(bContext *UNUSED(C), void *fcm_dv, void
memcpy(fedn, env->data, sizeof(FCM_EnvelopeData) * (index));
memcpy(fedn + index, env->data + (index + 1), sizeof(FCM_EnvelopeData) * ((env->totvert - index) - 1));
-
+
/* free old array, and set the new */
MEM_freeN(env->data);
env->data = fedn;
@@ -422,10 +422,10 @@ static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, sh
uiBut *but;
PointerRNA ptr;
int i;
-
+
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifierEnvelope, fcm, &ptr);
-
+
/* general settings */
col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Envelope:"), ICON_NONE);
@@ -440,24 +440,24 @@ static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, sh
* the current way is far too cramped */
row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
-
+
uiDefBut(block, UI_BTYPE_LABEL, 1, IFACE_("Control Points:"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
+
but = uiDefBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, IFACE_("Add Point"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Add a new control-point to the envelope on the current frame"));
UI_but_func_set(but, fmod_envelope_addpoint_cb, env, NULL);
-
+
/* control points list */
for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
/* get a new row to operate on */
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
-
+
UI_block_align_begin(block);
but = uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Fra:"), 0, 0, 4.5 * UI_UNIT_X, UI_UNIT_Y,
&fed->time, -MAXFRAMEF, MAXFRAMEF, 10, 1, TIP_("Frame that envelope point occurs"));
UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
+
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Min:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
&fed->min, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Minimum bound of envelope at this point"));
uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Max:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
@@ -477,40 +477,40 @@ static void draw_modifier__limits(uiLayout *layout, ID *id, FModifier *fcm, shor
{
uiLayout *split, *col /* , *row */ /* UNUSED */;
PointerRNA ptr;
-
+
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifierLimits, fcm, &ptr);
-
+
/* row 1: minimum */
{
/* row = uiLayoutRow(layout, false); */ /* UNUSED */
-
+
/* split into 2 columns */
split = uiLayoutSplit(layout, 0.5f, false);
-
+
/* x-minimum */
col = uiLayoutColumn(split, true);
uiItemR(col, &ptr, "use_min_x", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "min_x", 0, NULL, ICON_NONE);
-
+
/* y-minimum*/
col = uiLayoutColumn(split, true);
uiItemR(col, &ptr, "use_min_y", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "min_y", 0, NULL, ICON_NONE);
}
-
+
/* row 2: maximum */
{
/* row = uiLayoutRow(layout, false); */ /* UNUSED */
-
+
/* split into 2 columns */
split = uiLayoutSplit(layout, 0.5f, false);
-
+
/* x-minimum */
col = uiLayoutColumn(split, true);
uiItemR(col, &ptr, "use_max_x", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "max_x", 0, NULL, ICON_NONE);
-
+
/* y-minimum*/
col = uiLayoutColumn(split, true);
uiItemR(col, &ptr, "use_max_y", 0, NULL, ICON_NONE);
@@ -525,27 +525,27 @@ static void draw_modifier__stepped(uiLayout *layout, ID *id, FModifier *fcm, sho
{
uiLayout *col, *sub;
PointerRNA ptr;
-
+
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifierStepped, fcm, &ptr);
-
+
/* block 1: "stepping" settings */
col = uiLayoutColumn(layout, false);
uiItemR(col, &ptr, "frame_step", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "frame_offset", 0, NULL, ICON_NONE);
-
+
/* block 2: start range settings */
col = uiLayoutColumn(layout, true);
uiItemR(col, &ptr, "use_frame_start", 0, NULL, ICON_NONE);
-
+
sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_start"));
uiItemR(sub, &ptr, "frame_start", 0, NULL, ICON_NONE);
-
+
/* block 3: end range settings */
col = uiLayoutColumn(layout, true);
uiItemR(col, &ptr, "use_frame_end", 0, NULL, ICON_NONE);
-
+
sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_end"));
uiItemR(sub, &ptr, "frame_end", 0, NULL, ICON_NONE);
@@ -561,125 +561,125 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier
uiBut *but;
short width = 314;
PointerRNA ptr;
-
+
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifier, fcm, &ptr);
-
+
/* draw header */
{
/* get layout-row + UI-block for this */
box = uiLayoutBox(layout);
-
+
row = uiLayoutRow(box, false);
block = uiLayoutGetBlock(row); // err...
-
+
/* left-align -------------------------------------------- */
sub = uiLayoutRow(row, true);
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
-
+
UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
+
/* expand */
uiItemR(sub, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
+
/* checkbox for 'active' status (for now) */
uiItemR(sub, &ptr, "active", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
+
/* name */
if (fmi)
uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
else
uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
-
+
/* right-align ------------------------------------------- */
sub = uiLayoutRow(row, true);
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
-
-
+
+
/* 'mute' button */
uiItemR(sub, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
+
UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
+
/* delete button */
but = uiDefIconBut(block, UI_BTYPE_BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete F-Curve Modifier"));
UI_but_func_set(but, delete_fmodifier_cb, modifiers, fcm);
-
+
UI_block_emboss_set(block, UI_EMBOSS);
}
-
+
/* when modifier is expanded, draw settings */
if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
/* set up the flexible-box layout which acts as the backdrop for the modifier settings */
box = uiLayoutBox(layout);
-
+
/* draw settings for individual modifiers */
switch (fcm->type) {
case FMODIFIER_TYPE_GENERATOR: /* Generator */
draw_modifier__generator(box, id, fcm, width);
break;
-
+
case FMODIFIER_TYPE_FN_GENERATOR: /* Built-In Function Generator */
draw_modifier__fn_generator(box, id, fcm, width);
break;
-
+
case FMODIFIER_TYPE_CYCLES: /* Cycles */
draw_modifier__cycles(box, id, fcm, width);
break;
-
+
case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
draw_modifier__envelope(box, id, fcm, width);
break;
-
+
case FMODIFIER_TYPE_LIMITS: /* Limits */
draw_modifier__limits(box, id, fcm, width);
break;
-
+
case FMODIFIER_TYPE_NOISE: /* Noise */
draw_modifier__noise(box, id, fcm, width);
break;
-
+
case FMODIFIER_TYPE_STEPPED: /* Stepped */
draw_modifier__stepped(box, id, fcm, width);
break;
-
+
default: /* unknown type */
break;
}
-
+
/* one last panel below this: FModifier range */
// TODO: experiment with placement of this
{
box = uiLayoutBox(layout);
-
+
/* restricted range ----------------------------------------------------- */
col = uiLayoutColumn(box, true);
-
+
/* top row: use restricted range */
row = uiLayoutRow(col, true);
uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
-
+
if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
/* second row: settings */
row = uiLayoutRow(col, true);
-
+
uiItemR(row, &ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
uiItemR(row, &ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
-
+
/* third row: blending influence */
row = uiLayoutRow(col, true);
-
+
uiItemR(row, &ptr, "blend_in", 0, IFACE_("In"), ICON_NONE);
uiItemR(row, &ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
}
-
+
/* influence -------------------------------------------------------------- */
col = uiLayoutColumn(box, true);
-
+
/* top row: use influence */
uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
-
+
if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) {
/* second row: influence value */
uiItemR(col, &ptr, "influence", 0, NULL, ICON_NONE);
@@ -710,15 +710,15 @@ void ANIM_fmodifiers_copybuf_free(void)
bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active)
{
bool ok = true;
-
+
/* sanity checks */
if (ELEM(NULL, modifiers, modifiers->first))
return 0;
-
+
/* copy the whole list, or just the active one? */
if (active) {
FModifier *fcm = find_active_fmodifier(modifiers);
-
+
if (fcm) {
FModifier *fcmN = copy_fmodifier(fcm);
BLI_addtail(&fmodifier_copypaste_buf, fcmN);
@@ -728,44 +728,44 @@ bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active)
}
else
copy_fmodifiers(&fmodifier_copypaste_buf, modifiers);
-
+
/* did we succeed? */
return ok;
}
-/* 'Paste' the F-Modifier(s) from the buffer to the specified list
+/* 'Paste' the F-Modifier(s) from the buffer to the specified list
* - replace: free all the existing modifiers to leave only the pasted ones
*/
bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, FCurve *curve)
{
FModifier *fcm;
bool ok = false;
-
+
/* sanity checks */
if (modifiers == NULL)
return 0;
-
+
bool was_cyclic = curve && BKE_fcurve_is_cyclic(curve);
/* if replacing the list, free the existing modifiers */
if (replace)
free_fmodifiers(modifiers);
-
+
/* now copy over all the modifiers in the buffer to the end of the list */
for (fcm = fmodifier_copypaste_buf.first; fcm; fcm = fcm->next) {
/* make a copy of it */
FModifier *fcmN = copy_fmodifier(fcm);
fcmN->curve = curve;
-
+
/* make sure the new one isn't active, otherwise the list may get several actives */
fcmN->flag &= ~FMODIFIER_FLAG_ACTIVE;
-
+
/* now add it to the end of the list */
BLI_addtail(modifiers, fcmN);
ok = 1;
}
-
+
/* adding or removing the Cycles modifier requires an update to handles */
if (curve && BKE_fcurve_is_cyclic(curve) != was_cyclic)
calchandles_fcurve(curve);
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 98ad2041018..d1377703949 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -72,10 +72,10 @@ short compare_ak_cfraPtr(void *node, void *data)
ActKeyColumn *ak = (ActKeyColumn *)node;
const float *cframe = data;
float val = *cframe;
-
+
if (IS_EQT(val, ak->cfra, BEZT_BINARYSEARCH_THRESH))
return 0;
-
+
if (val < ak->cfra)
return -1;
else if (val > ak->cfra)
@@ -91,7 +91,7 @@ static short compare_ak_bezt(void *node, void *data)
{
ActKeyColumn *ak = (ActKeyColumn *)node;
BezTriple *bezt = (BezTriple *)data;
-
+
if (bezt->vec[1][0] < ak->cfra)
return -1;
else if (bezt->vec[1][0] > ak->cfra)
@@ -105,15 +105,15 @@ static DLRBT_Node *nalloc_ak_bezt(void *data)
{
ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
BezTriple *bezt = (BezTriple *)data;
-
+
/* store settings based on state of BezTriple */
ak->cfra = bezt->vec[1][0];
ak->sel = BEZT_ISSEL_ANY(bezt) ? SELECT : 0;
ak->key_type = BEZKEYTYPE(bezt);
-
+
/* set 'modified', since this is used to identify long keyframes */
ak->modified = 1;
-
+
return (DLRBT_Node *)ak;
}
@@ -122,11 +122,11 @@ static void nupdate_ak_bezt(void *node, void *data)
{
ActKeyColumn *ak = (ActKeyColumn *)node;
BezTriple *bezt = (BezTriple *)data;
-
+
/* set selection status and 'touched' status */
if (BEZT_ISSEL_ANY(bezt)) ak->sel = SELECT;
ak->modified += 1;
-
+
/* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
ak->key_type = BEZT_KEYTYPE_KEYFRAME;
@@ -139,7 +139,7 @@ static short compare_ak_gpframe(void *node, void *data)
{
ActKeyColumn *ak = (ActKeyColumn *)node;
bGPDframe *gpf = (bGPDframe *)data;
-
+
if (gpf->framenum < ak->cfra)
return -1;
else if (gpf->framenum > ak->cfra)
@@ -153,15 +153,15 @@ static DLRBT_Node *nalloc_ak_gpframe(void *data)
{
ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
bGPDframe *gpf = (bGPDframe *)data;
-
+
/* store settings based on state of BezTriple */
ak->cfra = gpf->framenum;
ak->sel = (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
ak->key_type = gpf->key_type;
-
+
/* set 'modified', since this is used to identify long keyframes */
ak->modified = 1;
-
+
return (DLRBT_Node *)ak;
}
@@ -170,11 +170,11 @@ static void nupdate_ak_gpframe(void *node, void *data)
{
ActKeyColumn *ak = (ActKeyColumn *)node;
bGPDframe *gpf = (bGPDframe *)data;
-
+
/* set selection status and 'touched' status */
if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT;
ak->modified += 1;
-
+
/* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
if (gpf->key_type == BEZT_KEYTYPE_KEYFRAME)
ak->key_type = BEZT_KEYTYPE_KEYFRAME;
@@ -262,7 +262,7 @@ short compare_ab_cfraPtr(void *node, void *data)
ActKeyBlock *ab = (ActKeyBlock *)node;
const float *cframe = data;
float val = *cframe;
-
+
if (val < ab->start)
return -1;
else if (val > ab->start)
@@ -277,17 +277,17 @@ short compare_ab_cfraPtr(void *node, void *data)
static ActKeyBlock *bezts_to_new_actkeyblock(BezTriple *prev, BezTriple *beztn)
{
ActKeyBlock *ab = MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock");
-
+
ab->start = prev->vec[1][0];
ab->end = beztn->vec[1][0];
ab->val = beztn->vec[1][1];
-
+
ab->sel = (BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn)) ? SELECT : 0;
ab->modified = 1;
-
+
if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD)
ab->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD;
-
+
return ab;
}
@@ -295,25 +295,25 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt
{
ActKeyBlock *new_ab = NULL;
BezTriple *prev = NULL;
-
+
/* get the BezTriple immediately before the given one which has the same value */
if (beztn != first_bezt) {
- /* XXX: Unless I'm overlooking some details from the past, this should be sufficient?
+ /* XXX: Unless I'm overlooking some details from the past, this should be sufficient?
* The old code did some elaborate stuff trying to find keyframe columns for
* the given BezTriple, then step backwards to the column before that, and find
* an appropriate BezTriple with matching values there. Maybe that was warranted
- * in the past, but now, that list is only ever filled with keyframes from the
+ * in the past, but now, that list is only ever filled with keyframes from the
* current FCurve.
*
* -- Aligorith (20140415)
*/
prev = beztn - 1;
}
-
-
+
+
/* check if block needed */
if (prev == NULL) return;
-
+
if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) {
/* Animator tagged a "moving hold"
* - Previous key must also be tagged as a moving hold, otherwise
@@ -329,11 +329,11 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt
* - Handles which control that section of the curve must be constant
*/
if (IS_EQF(beztn->vec[1][1], prev->vec[1][1]) == 0) return;
-
+
if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) == 0) return;
if (IS_EQF(prev->vec[1][1], prev->vec[2][1]) == 0) return;
}
-
+
/* if there are no blocks already, just add as root */
if (blocks->root == NULL) {
/* just add this as the root, then call the tree-balancing functions to validate */
@@ -342,7 +342,7 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt
}
else {
ActKeyBlock *ab, *abn = NULL;
-
+
/* try to find a keyblock that starts on the previous beztriple, and add a new one if none start there
* Note: we perform a tree traversal here NOT a standard linked-list traversal...
* Note: we can't search from end to try to optimize this as it causes errors there's
@@ -353,32 +353,32 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt
// A|------------------------------------------------|A
// A|----|A|---|A|-----------------------------------|A
for (ab = blocks->root; ab; ab = abn) {
- /* check if this is a match, or whether we go left or right
+ /* check if this is a match, or whether we go left or right
* NOTE: we now use a float threshold to prevent precision errors causing problems with summaries
*/
if (IS_EQT(ab->start, prev->vec[1][0], BEZT_BINARYSEARCH_THRESH)) {
/* set selection status and 'touched' status */
if (BEZT_ISSEL_ANY(beztn))
ab->sel = SELECT;
-
+
/* XXX: only when the first one was a moving hold? */
if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD)
ab->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD;
-
+
ab->modified++;
-
+
/* done... no need to insert */
return;
}
else {
ActKeyBlock **abnp = NULL; /* branch to go down - used to hook new blocks to parents */
-
+
/* check if go left or right, but if not available, add new node */
- if (ab->start < prev->vec[1][0])
+ if (ab->start < prev->vec[1][0])
abnp = &ab->right;
else
abnp = &ab->left;
-
+
/* if this does not exist, add a new node, otherwise continue... */
if (*abnp == NULL) {
/* add a new node representing this, and attach it to the relevant place */
@@ -392,7 +392,7 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt
}
}
}
-
+
/* now, balance the tree taking into account this newly added node */
BLI_dlrbTree_insert(blocks, (DLRBT_Node *)new_ab);
}
@@ -405,13 +405,13 @@ static void set_touched_actkeycolumn(ActKeyColumn *ak)
/* sanity check */
if (ak == NULL)
return;
-
+
/* deal with self first */
if (ak->modified) {
ak->modified = 0;
ak->totcurve++;
}
-
+
/* children */
set_touched_actkeycolumn(ak->left);
set_touched_actkeycolumn(ak->right);
@@ -423,13 +423,13 @@ static void set_touched_actkeyblock(ActKeyBlock *ab)
/* sanity check */
if (ab == NULL)
return;
-
+
/* deal with self first */
if (ab->modified) {
ab->modified = 0;
ab->totcurve++;
}
-
+
/* children */
set_touched_actkeyblock(ab->left);
set_touched_actkeyblock(ab->right);
@@ -442,22 +442,22 @@ bool actkeyblock_is_valid(ActKeyBlock *ab, DLRBT_Tree *keys)
{
ActKeyColumn *ak;
short startCurves, endCurves, totCurves;
-
+
/* check that block is valid */
if (ab == NULL)
return 0;
-
+
/* find out how many curves occur at each keyframe */
ak = (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->start);
startCurves = (ak) ? ak->totcurve : 0;
-
+
ak = (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->end);
endCurves = (ak) ? ak->totcurve : 0;
-
+
/* only draw keyblock if it appears in at all of the keyframes at lowest end */
- if (!startCurves && !endCurves)
+ if (!startCurves && !endCurves)
return 0;
-
+
totCurves = (startCurves > endCurves) ? endCurves : startCurves;
return (ab->totcurve >= totCurves);
}
@@ -478,19 +478,19 @@ void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type,
switch (key_type) {
case BEZT_KEYTYPE_KEYFRAME: /* must be full size */
break;
-
+
case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */
size *= 0.85f;
break;
-
+
case BEZT_KEYTYPE_MOVEHOLD: /* slightly smaller than normal keyframes (but by less than for breakdowns) */
size *= 0.925f;
break;
-
+
case BEZT_KEYTYPE_EXTREME: /* slightly larger */
size *= 1.2f;
break;
-
+
default:
size -= 0.8f * key_type;
}
@@ -521,8 +521,8 @@ void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type,
default:
UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_KEYFRAME_SELECT : TH_KEYTYPE_KEYFRAME, fill_col);
}
-
- /* NOTE: we don't use the straight alpha from the theme, or else effects such as
+
+ /* NOTE: we don't use the straight alpha from the theme, or else effects such as
* graying out protected/muted channels doesn't work correctly!
*/
fill_col[3] *= alpha;
@@ -560,25 +560,25 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
{
const float icon_sz = U.widget_unit * 0.5f * yscale_fac;
const float half_icon_sz = 0.5f * icon_sz;
-
+
glEnable(GL_BLEND);
-
+
/* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
/* TODO: allow this opacity factor to be themed? */
float alpha = channelLocked ? 0.25f : 1.0f;
-
+
/* draw keyblocks */
if (blocks) {
float sel_color[4], unsel_color[4];
float sel_mhcol[4], unsel_mhcol[4];
-
+
/* cache colours first */
UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color);
UI_GetThemeColor4fv(TH_STRIP, unsel_color);
-
+
sel_color[3] *= alpha;
unsel_color[3] *= alpha;
-
+
copy_v4_v4(sel_mhcol, sel_color);
sel_mhcol[3] *= 0.8f;
copy_v4_v4(unsel_mhcol, unsel_color);
@@ -618,7 +618,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
immUnbindProgram();
}
}
-
+
if (keys) {
/* count keys */
unsigned int key_ct = 0;
@@ -662,17 +662,17 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa
void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac)
{
DLRBT_Tree keys, blocks;
-
+
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
-
+
summary_to_keylist(ac, &keys, &blocks);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
-
+
draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, false);
-
+
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
}
@@ -680,17 +680,17 @@ void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos, float yscal
void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac)
{
DLRBT_Tree keys, blocks;
-
+
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
-
+
scene_to_keylist(ads, sce, &keys, &blocks);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
-
+
draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, false);
-
+
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
}
@@ -698,17 +698,17 @@ void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, fl
void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac)
{
DLRBT_Tree keys, blocks;
-
+
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
-
+
ob_to_keylist(ads, ob, &keys, &blocks);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
-
+
draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, false);
-
+
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
}
@@ -716,21 +716,21 @@ void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, f
void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac)
{
DLRBT_Tree keys, blocks;
-
+
bool locked = (fcu->flag & FCURVE_PROTECTED) ||
((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
((adt && adt->action) && ID_IS_LINKED(adt->action));
-
+
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
-
+
fcurve_to_keylist(adt, fcu, &keys, &blocks);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
-
+
draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked);
-
+
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
}
@@ -738,20 +738,20 @@ void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, fl
void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac)
{
DLRBT_Tree keys, blocks;
-
+
bool locked = (agrp->flag & AGRP_PROTECTED) ||
((adt && adt->action) && ID_IS_LINKED(adt->action));
-
+
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
-
+
agroup_to_keylist(adt, agrp, &keys, &blocks);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
-
+
draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked);
-
+
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
}
@@ -759,19 +759,19 @@ void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float y
void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac)
{
DLRBT_Tree keys, blocks;
-
+
bool locked = (act && ID_IS_LINKED(act));
-
+
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
-
+
action_to_keylist(adt, act, &keys, &blocks);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
-
+
draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked);
-
+
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
}
@@ -779,49 +779,49 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, f
void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac)
{
DLRBT_Tree keys;
-
+
BLI_dlrbTree_init(&keys);
-
+
gpencil_to_keylist(ads, gpd, &keys);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
-
+
draw_keylist(v2d, &keys, NULL, ypos, yscale_fac, false);
-
+
BLI_dlrbTree_free(&keys);
}
void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac)
{
DLRBT_Tree keys;
-
+
bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0;
-
+
BLI_dlrbTree_init(&keys);
-
+
gpl_to_keylist(ads, gpl, &keys);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
-
+
draw_keylist(v2d, &keys, NULL, ypos, yscale_fac, locked);
-
+
BLI_dlrbTree_free(&keys);
}
void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac)
{
DLRBT_Tree keys;
-
+
bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0;
-
+
BLI_dlrbTree_init(&keys);
-
+
mask_to_keylist(ads, masklay, &keys);
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
-
+
draw_keylist(v2d, &keys, NULL, ypos, yscale_fac, locked);
-
+
BLI_dlrbTree_free(&keys);
}
@@ -833,11 +833,11 @@ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get F-Curves to take keyframes from */
filter = ANIMFILTER_DATA_VISIBLE;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through each F-Curve, grabbing the keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
/* Why not use all #eAnim_KeyType here?
@@ -860,7 +860,7 @@ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks)
break;
}
}
-
+
ANIM_animdata_freelist(&anim_data);
}
}
@@ -871,66 +871,66 @@ void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
bAnimListElem dummychan = {NULL};
-
+
if (sce == NULL)
return;
-
+
/* create a dummy wrapper data to work with */
dummychan.type = ANIMTYPE_SCENE;
dummychan.data = sce;
dummychan.id = &sce->id;
dummychan.adt = sce->adt;
-
+
ac.ads = ads;
ac.data = &dummychan;
ac.datatype = ANIMCONT_CHANNEL;
-
+
/* get F-Curves to take keyframes from */
filter = ANIMFILTER_DATA_VISIBLE; // curves only
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* loop through each F-Curve, grabbing the keyframes */
for (ale = anim_data.first; ale; ale = ale->next)
fcurve_to_keylist(ale->adt, ale->data, keys, blocks);
-
+
ANIM_animdata_freelist(&anim_data);
}
void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *blocks)
-{
+{
bAnimContext ac = {NULL};
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
bAnimListElem dummychan = {NULL};
Base dummybase = {NULL};
-
+
if (ob == NULL)
return;
-
+
/* create a dummy wrapper data to work with */
dummybase.object = ob;
-
+
dummychan.type = ANIMTYPE_OBJECT;
dummychan.data = &dummybase;
dummychan.id = &ob->id;
dummychan.adt = ob->adt;
-
+
ac.ads = ads;
ac.data = &dummychan;
ac.datatype = ANIMCONT_CHANNEL;
-
+
/* get F-Curves to take keyframes from */
filter = ANIMFILTER_DATA_VISIBLE; // curves only
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* loop through each F-Curve, grabbing the keyframes */
for (ale = anim_data.first; ale; ale = ale->next)
fcurve_to_keylist(ale->adt, ale->data, keys, blocks);
-
+
ANIM_animdata_freelist(&anim_data);
}
@@ -974,19 +974,19 @@ void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree
/* apply NLA-mapping (if applicable) */
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
-
+
/* loop through beztriples, making ActKeysColumns and ActKeyBlocks */
for (v = 0, bezt = fcu->bezt; v < fcu->totvert; v++, bezt++) {
add_bezt_to_keycolumns_list(keys, bezt);
if (blocks) add_bezt_to_keyblocks_list(blocks, fcu->bezt, bezt);
}
-
+
/* update the number of curves that elements have appeared in */
if (keys)
set_touched_actkeycolumn(keys->root);
if (blocks)
set_touched_actkeyblock(blocks->root);
-
+
/* unapply NLA-mapping if applicable */
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
@@ -1021,7 +1021,7 @@ void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree
void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys)
{
bGPDlayer *gpl;
-
+
if (gpd && keys) {
/* for now, just aggregate out all the frames, but only for visible layers */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
@@ -1035,7 +1035,7 @@ void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys)
void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
{
bGPDframe *gpf;
-
+
if (gpl && keys) {
/* although the frames should already be in an ordered list, they are not suitable for displaying yet */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next)
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 4e42229e50d..6b24008c4d8 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -73,11 +73,11 @@
/* --------------------------- Base Functions ------------------------------------ */
-/* This function is used to loop over BezTriples in the given F-Curve, applying a given
+/* This function is used to loop over BezTriples in the given F-Curve, applying a given
* operation on them, and optionally applies an F-Curve validation function afterwards.
*/
// TODO: make this function work on samples too...
-short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
+short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
{
BezTriple *bezt;
short ok = 0;
@@ -96,7 +96,7 @@ short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEdi
/* if function to apply to bezier curves is set, then loop through executing it on beztriples */
if (key_cb) {
- /* if there's a validation func, include that check in the loop
+ /* if there's a validation func, include that check in the loop
* (this is should be more efficient than checking for it in every loop)
*/
if (key_ok) {
@@ -106,11 +106,11 @@ short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEdi
ked->curIndex = i;
ked->curflags = 0;
}
-
+
/* Only operate on this BezTriple if it fullfills the criteria of the validation func */
if ((ok = key_ok(ked, bezt))) {
if (ked) ked->curflags = ok;
-
+
/* Exit with return-code '1' if function returns positive
* This is useful if finding if some BezTriple satisfies a condition.
*/
@@ -121,7 +121,7 @@ short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEdi
else {
for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
if (ked) ked->curIndex = i;
-
+
/* Exit with return-code '1' if function returns positive
* This is useful if finding if some BezTriple satisfies a condition.
*/
@@ -129,7 +129,7 @@ short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEdi
}
}
}
-
+
/* unset the F-Curve from the editdata now that it's done */
if (ked) {
ked->fcu = NULL;
@@ -140,7 +140,7 @@ short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEdi
/* if fcu_cb (F-Curve post-editing callback) has been specified then execute it */
if (fcu_cb)
fcu_cb(fcu);
-
+
/* done */
return 0;
}
@@ -151,17 +151,17 @@ short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEdi
static short agrp_keyframes_loop(KeyframeEditData *ked, bActionGroup *agrp, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
{
FCurve *fcu;
-
+
/* sanity check */
if (agrp == NULL)
return 0;
-
+
/* only iterate over the F-Curves that are in this group */
for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) {
if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
return 1;
}
-
+
return 0;
}
@@ -169,17 +169,17 @@ static short agrp_keyframes_loop(KeyframeEditData *ked, bActionGroup *agrp, Keyf
static short act_keyframes_loop(KeyframeEditData *ked, bAction *act, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
{
FCurve *fcu;
-
+
/* sanity check */
if (act == NULL)
return 0;
-
+
/* just loop through all F-Curves */
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
return 1;
}
-
+
return 0;
}
@@ -191,29 +191,29 @@ static short ob_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, Object *o
bAnimListElem *ale;
int filter;
int ret = 0;
-
+
bAnimListElem dummychan = {NULL};
Base dummybase = {NULL};
-
+
if (ob == NULL)
return 0;
-
+
/* create a dummy wrapper data to work with */
dummybase.object = ob;
-
+
dummychan.type = ANIMTYPE_OBJECT;
dummychan.data = &dummybase;
dummychan.id = &ob->id;
dummychan.adt = ob->adt;
-
+
ac.ads = ads;
ac.data = &dummychan;
ac.datatype = ANIMCONT_CHANNEL;
-
+
/* get F-Curves to take keyframes from */
filter = ANIMFILTER_DATA_VISIBLE; // curves only
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* loop through each F-Curve, applying the operation as required, but stopping on the first one */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ANIM_fcurve_keyframes_loop(ked, (FCurve *)ale->data, key_ok, key_cb, fcu_cb)) {
@@ -221,9 +221,9 @@ static short ob_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, Object *o
break;
}
}
-
+
ANIM_animdata_freelist(&anim_data);
-
+
/* return return code - defaults to zero if nothing happened */
return ret;
}
@@ -236,26 +236,26 @@ static short scene_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, Scene
bAnimListElem *ale;
int filter;
int ret = 0;
-
+
bAnimListElem dummychan = {NULL};
-
+
if (sce == NULL)
return 0;
-
+
/* create a dummy wrapper data to work with */
dummychan.type = ANIMTYPE_SCENE;
dummychan.data = sce;
dummychan.id = &sce->id;
dummychan.adt = sce->adt;
-
+
ac.ads = ads;
ac.data = &dummychan;
ac.datatype = ANIMCONT_CHANNEL;
-
+
/* get F-Curves to take keyframes from */
filter = ANIMFILTER_DATA_VISIBLE; // curves only
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* loop through each F-Curve, applying the operation as required, but stopping on the first one */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ANIM_fcurve_keyframes_loop(ked, (FCurve *)ale->data, key_ok, key_cb, fcu_cb)) {
@@ -263,9 +263,9 @@ static short scene_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, Scene
break;
}
}
-
+
ANIM_animdata_freelist(&anim_data);
-
+
/* return return code - defaults to zero if nothing happened */
return ret;
}
@@ -276,22 +276,22 @@ static short summary_keyframes_loop(KeyframeEditData *ked, bAnimContext *ac, Key
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter, ret_code = 0;
-
+
/* sanity check */
if (ac == NULL)
return 0;
-
+
/* get F-Curves to take keyframes from */
filter = ANIMFILTER_DATA_VISIBLE;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through each F-Curve, working on the keyframes until the first curve aborts */
for (ale = anim_data.first; ale; ale = ale->next) {
switch (ale->datatype) {
case ALE_MASKLAY:
case ALE_GPFRAME:
break;
-
+
case ALE_FCURVE:
default:
{
@@ -301,19 +301,19 @@ static short summary_keyframes_loop(KeyframeEditData *ked, bAnimContext *ac, Key
*/
float f1 = ked->f1;
float f2 = ked->f2;
-
+
if (ked->iterflags & (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP)) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
if (ked->iterflags & KED_F1_NLA_UNMAP)
ked->f1 = BKE_nla_tweakedit_remap(adt, f1, NLATIME_CONVERT_UNMAP);
if (ked->iterflags & KED_F2_NLA_UNMAP)
ked->f2 = BKE_nla_tweakedit_remap(adt, f2, NLATIME_CONVERT_UNMAP);
}
-
+
/* now operate on the channel as per normal */
ret_code = ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb);
-
+
/* reset */
ked->f1 = f1;
ked->f2 = f2;
@@ -325,13 +325,13 @@ static short summary_keyframes_loop(KeyframeEditData *ked, bAnimContext *ac, Key
break;
}
}
-
+
if (ret_code)
break;
}
-
+
ANIM_animdata_freelist(&anim_data);
-
+
return ret_code;
}
@@ -343,21 +343,21 @@ short ANIM_animchannel_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, bA
/* sanity checks */
if (ale == NULL)
return 0;
-
+
/* method to use depends on the type of keyframe data */
switch (ale->datatype) {
/* direct keyframe data (these loops are exposed) */
case ALE_FCURVE: /* F-Curve */
return ANIM_fcurve_keyframes_loop(ked, ale->key_data, key_ok, key_cb, fcu_cb);
-
- /* indirect 'summaries' (these are not exposed directly)
+
+ /* indirect 'summaries' (these are not exposed directly)
* NOTE: must keep this code in sync with the drawing code and also the filtering code!
*/
case ALE_GROUP: /* action group */
return agrp_keyframes_loop(ked, (bActionGroup *)ale->data, key_ok, key_cb, fcu_cb);
case ALE_ACT: /* action */
return act_keyframes_loop(ked, (bAction *)ale->key_data, key_ok, key_cb, fcu_cb);
-
+
case ALE_OB: /* object */
return ob_keyframes_loop(ked, ads, (Object *)ale->key_data, key_ok, key_cb, fcu_cb);
case ALE_SCE: /* scene */
@@ -365,7 +365,7 @@ short ANIM_animchannel_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, bA
case ALE_ALL: /* 'all' (DopeSheet summary) */
return summary_keyframes_loop(ked, (bAnimContext *)ale->data, key_ok, key_cb, fcu_cb);
}
-
+
return 0;
}
@@ -375,21 +375,21 @@ short ANIM_animchanneldata_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads
/* sanity checks */
if (data == NULL)
return 0;
-
+
/* method to use depends on the type of keyframe data */
switch (keytype) {
/* direct keyframe data (these loops are exposed) */
case ALE_FCURVE: /* F-Curve */
return ANIM_fcurve_keyframes_loop(ked, data, key_ok, key_cb, fcu_cb);
-
- /* indirect 'summaries' (these are not exposed directly)
+
+ /* indirect 'summaries' (these are not exposed directly)
* NOTE: must keep this code in sync with the drawing code and also the filtering code!
*/
case ALE_GROUP: /* action group */
return agrp_keyframes_loop(ked, (bActionGroup *)data, key_ok, key_cb, fcu_cb);
case ALE_ACT: /* action */
return act_keyframes_loop(ked, (bAction *)data, key_ok, key_cb, fcu_cb);
-
+
case ALE_OB: /* object */
return ob_keyframes_loop(ked, ads, (Object *)data, key_ok, key_cb, fcu_cb);
case ALE_SCE: /* scene */
@@ -397,7 +397,7 @@ short ANIM_animchanneldata_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads
case ALE_ALL: /* 'all' (DopeSheet summary) */
return summary_keyframes_loop(ked, (bAnimContext *)data, key_ok, key_cb, fcu_cb);
}
-
+
return 0;
}
@@ -411,20 +411,20 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter animation data */
filter = ANIMFILTER_DATA_VISIBLE;
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop over F-Curves that are likely to have been edited, and check them */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = ale->key_data;
-
+
/* make sure keyframes in F-Curve are all in order, and handles are in valid positions */
sort_time_fcurve(fcu);
calchandles_fcurve(fcu);
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
}
@@ -435,7 +435,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
/* ------------------------ */
/* Some macros to make this easier... */
-/* run the given check on the 3 handles
+/* run the given check on the 3 handles
* - check should be a macro, which takes the handle index as its single arg, which it substitutes later
* - requires that a var, of type short, is named 'ok', and has been initialized to 0
*/
@@ -454,16 +454,16 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
} (void)0
/* ------------------------ */
-
+
static short ok_bezier_frame(KeyframeEditData *ked, BezTriple *bezt)
{
short ok = 0;
-
+
/* frame is stored in f1 property (this float accuracy check may need to be dropped?) */
#define KEY_CHECK_OK(_index) IS_EQF(bezt->vec[_index][0], ked->f1)
KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
-
+
/* return ok flags */
return ok;
}
@@ -471,19 +471,19 @@ static short ok_bezier_frame(KeyframeEditData *ked, BezTriple *bezt)
static short ok_bezier_framerange(KeyframeEditData *ked, BezTriple *bezt)
{
short ok = 0;
-
+
/* frame range is stored in float properties */
#define KEY_CHECK_OK(_index) ((bezt->vec[_index][0] > ked->f1) && (bezt->vec[_index][0] < ked->f2))
KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
-
+
/* return ok flags */
return ok;
}
static short ok_bezier_selected(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- /* this macro checks all beztriple handles for selection...
+ /* this macro checks all beztriple handles for selection...
* only one of the verts has to be selected for this to be ok...
*/
if (BEZT_ISSEL_ANY(bezt))
@@ -493,17 +493,17 @@ static short ok_bezier_selected(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
}
static short ok_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
-{
+{
short ok = 0;
-
- /* value is stored in f1 property
+
+ /* value is stored in f1 property
* - this float accuracy check may need to be dropped?
* - should value be stored in f2 instead so that we won't have conflicts when using f1 for frames too?
*/
#define KEY_CHECK_OK(_index) IS_EQF(bezt->vec[_index][1], ked->f1)
KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
-
+
/* return ok flags */
return ok;
}
@@ -511,12 +511,12 @@ static short ok_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
static short ok_bezier_valuerange(KeyframeEditData *ked, BezTriple *bezt)
{
short ok = 0;
-
+
/* value range is stored in float properties */
#define KEY_CHECK_OK(_index) ((bezt->vec[_index][1] > ked->f1) && (bezt->vec[_index][1] < ked->f2))
KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
-
+
/* return ok flags */
return ok;
}
@@ -526,15 +526,15 @@ static short ok_bezier_region(KeyframeEditData *ked, BezTriple *bezt)
/* rect is stored in data property (it's of type rectf, but may not be set) */
if (ked->data) {
short ok = 0;
-
+
#define KEY_CHECK_OK(_index) BLI_rctf_isect_pt_v(ked->data, bezt->vec[_index])
KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
-
+
/* return ok flags */
return ok;
}
- else
+ else
return 0;
}
@@ -547,9 +547,9 @@ bool keyframe_region_lasso_test(
{
if (BLI_rctf_isect_pt_v(data_lasso->rectf_scaled, xy)) {
float xy_view[2];
-
+
BLI_rctf_transform_pt_v(data_lasso->rectf_view, data_lasso->rectf_scaled, xy_view, xy);
-
+
if (BLI_lasso_is_point_inside(data_lasso->mcords, data_lasso->mcords_tot, xy_view[0], xy_view[1], INT_MAX)) {
return true;
}
@@ -563,11 +563,11 @@ static short ok_bezier_region_lasso(KeyframeEditData *ked, BezTriple *bezt)
/* check for lasso customdata (KeyframeEdit_LassoData) */
if (ked->data) {
short ok = 0;
-
+
#define KEY_CHECK_OK(_index) keyframe_region_lasso_test(ked->data, bezt->vec[_index])
KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
-
+
/* return ok flags */
return ok;
}
@@ -581,7 +581,7 @@ static short ok_bezier_channel_lasso(KeyframeEditData *ked, BezTriple *bezt)
if (ked->data) {
KeyframeEdit_LassoData *data = ked->data;
float pt[2];
-
+
/* late-binding remap of the x values (for summary channels) */
/* XXX: Ideally we reset, but it should be fine just leaving it as-is
* as the next channel will reset it properly, while the next summary-channel
@@ -591,11 +591,11 @@ static short ok_bezier_channel_lasso(KeyframeEditData *ked, BezTriple *bezt)
data->rectf_scaled->xmin = ked->f1;
data->rectf_scaled->xmax = ked->f2;
}
-
+
/* only use the x-coordinate of the point; the y is the channel range... */
pt[0] = bezt->vec[1][0];
pt[1] = ked->channel_y;
-
+
if (keyframe_region_lasso_test(data, pt))
return KEYFRAME_OK_KEY;
}
@@ -611,14 +611,14 @@ bool keyframe_region_circle_test(
{
if (BLI_rctf_isect_pt_v(data_circle->rectf_scaled, xy)) {
float xy_view[2];
-
+
BLI_rctf_transform_pt_v(data_circle->rectf_view, data_circle->rectf_scaled, xy_view, xy);
-
+
xy_view[0] = xy_view[0] - data_circle->mval[0];
xy_view[1] = xy_view[1] - data_circle->mval[1];
return len_squared_v2(xy_view) < data_circle->radius_squared;
}
-
+
return false;
}
@@ -628,11 +628,11 @@ static short ok_bezier_region_circle(KeyframeEditData *ked, BezTriple *bezt)
/* check for circle select customdata (KeyframeEdit_CircleData) */
if (ked->data) {
short ok = 0;
-
+
#define KEY_CHECK_OK(_index) keyframe_region_circle_test(ked->data, bezt->vec[_index])
KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
-
+
/* return ok flags */
return ok;
}
@@ -646,7 +646,7 @@ static short ok_bezier_channel_circle(KeyframeEditData *ked, BezTriple *bezt)
if (ked->data) {
KeyframeEdit_CircleData *data = ked->data;
float pt[2];
-
+
/* late-binding remap of the x values (for summary channels) */
/* XXX: Ideally we reset, but it should be fine just leaving it as-is
* as the next channel will reset it properly, while the next summary-channel
@@ -656,11 +656,11 @@ static short ok_bezier_channel_circle(KeyframeEditData *ked, BezTriple *bezt)
data->rectf_scaled->xmin = ked->f1;
data->rectf_scaled->xmax = ked->f2;
}
-
+
/* only use the x-coordinate of the point; the y is the channel range... */
pt[0] = bezt->vec[1][0];
pt[1] = ked->channel_y;
-
+
if (keyframe_region_circle_test(data, pt))
return KEYFRAME_OK_KEY;
}
@@ -707,16 +707,16 @@ short bezt_calc_average(KeyframeEditData *ked, BezTriple *bezt)
if (bezt->f2 & SELECT) {
/* store average time in float 1 (only do rounding at last step) */
ked->f1 += bezt->vec[1][0];
-
- /* store average value in float 2 (only do rounding at last step)
+
+ /* store average value in float 2 (only do rounding at last step)
* - this isn't always needed, but some operators may also require this
*/
ked->f2 += bezt->vec[1][1];
-
+
/* increment number of items */
ked->i1++;
}
-
+
return 0;
}
@@ -727,10 +727,10 @@ short bezt_to_cfraelem(KeyframeEditData *ked, BezTriple *bezt)
if (bezt->f2 & SELECT) {
CfraElem *ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
BLI_addtail(&ked->list, ce);
-
+
ce->cfra = bezt->vec[1][0];
}
-
+
return 0;
}
@@ -741,10 +741,10 @@ void bezt_remap_times(KeyframeEditData *ked, BezTriple *bezt)
{
KeyframeEditCD_Remap *rmap = (KeyframeEditCD_Remap *)ked->data;
const float scale = (rmap->newMax - rmap->newMin) / (rmap->oldMax - rmap->oldMin);
-
+
/* perform transform on all three handles unless indicated otherwise */
// TODO: need to include some checks for that
-
+
bezt->vec[0][0] = scale * (bezt->vec[0][0] - rmap->oldMin) + rmap->newMin;
bezt->vec[1][0] = scale * (bezt->vec[1][0] - rmap->oldMin) + rmap->newMin;
bezt->vec[2][0] = scale * (bezt->vec[2][0] - rmap->oldMin) + rmap->newMin;
@@ -766,7 +766,7 @@ static short snap_bezier_nearestsec(KeyframeEditData *ked, BezTriple *bezt)
{
const Scene *scene = ked->scene;
const float secf = (float)FPS;
-
+
if (bezt->f2 & SELECT)
bezt->vec[1][0] = (floorf(bezt->vec[1][0] / secf + 0.5f) * secf);
return 0;
@@ -794,7 +794,7 @@ static short snap_bezier_horizontal(KeyframeEditData *UNUSED(ked), BezTriple *be
{
if (bezt->f2 & SELECT) {
bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1];
-
+
if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM, HD_VECT)) bezt->h1 = HD_ALIGN;
if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM, HD_VECT)) bezt->h2 = HD_ALIGN;
}
@@ -871,11 +871,11 @@ static void mirror_bezier_yaxis_ex(BezTriple *bezt, const float center)
static short mirror_bezier_cframe(KeyframeEditData *ked, BezTriple *bezt)
{
const Scene *scene = ked->scene;
-
+
if (bezt->f2 & SELECT) {
mirror_bezier_xaxis_ex(bezt, CFRA);
}
-
+
return 0;
}
@@ -885,7 +885,7 @@ static short mirror_bezier_yaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
/* Yes, names are inverted, we are mirroring accross y axis, hence along x axis... */
mirror_bezier_xaxis_ex(bezt, 0.0f);
}
-
+
return 0;
}
@@ -895,7 +895,7 @@ static short mirror_bezier_xaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
/* Yes, names are inverted, we are mirroring accross x axis, hence along y axis... */
mirror_bezier_yaxis_ex(bezt, 0.0f);
}
-
+
return 0;
}
@@ -905,7 +905,7 @@ static short mirror_bezier_marker(KeyframeEditData *ked, BezTriple *bezt)
if (bezt->f2 & SELECT) {
mirror_bezier_xaxis_ex(bezt, ked->f1);
}
-
+
return 0;
}
@@ -915,7 +915,7 @@ static short mirror_bezier_time(KeyframeEditData *ked, BezTriple *bezt)
if (bezt->f2 & SELECT) {
mirror_bezier_xaxis_ex(bezt, ked->f1);
}
-
+
return 0;
}
@@ -925,7 +925,7 @@ static short mirror_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
if (bezt->f2 & SELECT) {
mirror_bezier_yaxis_ex(bezt, ked->f1);
}
-
+
return 0;
}
@@ -941,7 +941,7 @@ KeyframeEditFunc ANIM_editkeyframes_mirror(short type)
case MIRROR_KEYS_XAXIS: /* mirror over value 0 */
return mirror_bezier_xaxis;
case MIRROR_KEYS_MARKER: /* mirror over marker */
- return mirror_bezier_marker;
+ return mirror_bezier_marker;
case MIRROR_KEYS_TIME: /* mirror over frame/time */
return mirror_bezier_time;
case MIRROR_KEYS_VALUE: /* mirror over given value */
@@ -966,12 +966,12 @@ KeyframeEditFunc ANIM_editkeyframes_mirror(short type)
} (void)0
/* Sets the selected bezier handles to type 'auto' */
-static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
if (bezt->f1 & SELECT) bezt->h1 = HD_AUTO;
if (bezt->f3 & SELECT) bezt->h2 = HD_AUTO;
-
+
ENSURE_HANDLES_MATCH(bezt);
}
return 0;
@@ -980,19 +980,19 @@ static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
/* Sets the selected bezier handles to type 'auto-clamped'
* NOTE: this is like auto above, but they're handled a bit different
*/
-static short set_bezier_auto_clamped(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_bezier_auto_clamped(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
if (bezt->f1 & SELECT) bezt->h1 = HD_AUTO_ANIM;
if (bezt->f3 & SELECT) bezt->h2 = HD_AUTO_ANIM;
-
+
ENSURE_HANDLES_MATCH(bezt);
}
return 0;
}
/* Sets the selected bezier handles to type 'vector' */
-static short set_bezier_vector(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_bezier_vector(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
if (bezt->f1 & SELECT) bezt->h1 = HD_VECT;
if (bezt->f3 & SELECT) bezt->h2 = HD_VECT;
@@ -1002,7 +1002,7 @@ static short set_bezier_vector(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
/* Queries if the handle should be set to 'free' or 'align' */
// NOTE: this was used for the 'toggle free/align' option
// currently this isn't used, but may be restored later
-static short bezier_isfree(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short bezier_isfree(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
if ((bezt->f1 & SELECT) && (bezt->h1)) return 1;
if ((bezt->f3 & SELECT) && (bezt->h2)) return 1;
@@ -1010,15 +1010,15 @@ static short bezier_isfree(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
}
/* Sets selected bezier handles to type 'align' */
-static short set_bezier_align(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
-{
+static short set_bezier_align(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
if (bezt->f1 & SELECT) bezt->h1 = HD_ALIGN;
if (bezt->f3 & SELECT) bezt->h2 = HD_ALIGN;
return 0;
}
/* Sets selected bezier handles to type 'free' */
-static short set_bezier_free(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_bezier_free(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
if (bezt->f1 & SELECT) bezt->h1 = HD_FREE;
if (bezt->f3 & SELECT) bezt->h2 = HD_FREE;
@@ -1034,14 +1034,14 @@ KeyframeEditFunc ANIM_editkeyframes_handles(short code)
return set_bezier_auto;
case HD_AUTO_ANIM: /* auto clamped */
return set_bezier_auto_clamped;
-
+
case HD_VECT: /* vector */
return set_bezier_vector;
case HD_FREE: /* free */
return set_bezier_free;
case HD_ALIGN: /* align */
return set_bezier_align;
-
+
default: /* check for toggle free or align? */
return bezier_isfree;
}
@@ -1049,23 +1049,23 @@ KeyframeEditFunc ANIM_editkeyframes_handles(short code)
/* ------- */
-static short set_bezt_constant(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_bezt_constant(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
+ if (bezt->f2 & SELECT)
bezt->ipo = BEZT_IPO_CONST;
return 0;
}
-static short set_bezt_linear(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_bezt_linear(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
+ if (bezt->f2 & SELECT)
bezt->ipo = BEZT_IPO_LIN;
return 0;
}
-static short set_bezt_bezier(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_bezt_bezier(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
+ if (bezt->f2 & SELECT)
bezt->ipo = BEZT_IPO_BEZ;
return 0;
}
@@ -1150,7 +1150,7 @@ KeyframeEditFunc ANIM_editkeyframes_ipo(short code)
return set_bezt_constant;
case BEZT_IPO_LIN: /* linear */
return set_bezt_linear;
-
+
/* easing */
case BEZT_IPO_BACK:
return set_bezt_back;
@@ -1172,7 +1172,7 @@ KeyframeEditFunc ANIM_editkeyframes_ipo(short code)
return set_bezt_quint;
case BEZT_IPO_SINE:
return set_bezt_sine;
-
+
default: /* bezier */
return set_bezt_bezier;
}
@@ -1180,37 +1180,37 @@ KeyframeEditFunc ANIM_editkeyframes_ipo(short code)
/* ------- */
-static short set_keytype_keyframe(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_keytype_keyframe(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
+ if (bezt->f2 & SELECT)
BEZKEYTYPE(bezt) = BEZT_KEYTYPE_KEYFRAME;
return 0;
}
-static short set_keytype_breakdown(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_keytype_breakdown(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
+ if (bezt->f2 & SELECT)
BEZKEYTYPE(bezt) = BEZT_KEYTYPE_BREAKDOWN;
return 0;
}
-static short set_keytype_extreme(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_keytype_extreme(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
+ if (bezt->f2 & SELECT)
BEZKEYTYPE(bezt) = BEZT_KEYTYPE_EXTREME;
return 0;
}
-static short set_keytype_jitter(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_keytype_jitter(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
+ if (bezt->f2 & SELECT)
BEZKEYTYPE(bezt) = BEZT_KEYTYPE_JITTER;
return 0;
}
-static short set_keytype_moving_hold(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short set_keytype_moving_hold(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
+ if (bezt->f2 & SELECT)
BEZKEYTYPE(bezt) = BEZT_KEYTYPE_MOVEHOLD;
return 0;
}
@@ -1221,16 +1221,16 @@ KeyframeEditFunc ANIM_editkeyframes_keytype(short code)
switch (code) {
case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */
return set_keytype_breakdown;
-
+
case BEZT_KEYTYPE_EXTREME: /* extreme keyframe */
return set_keytype_extreme;
-
+
case BEZT_KEYTYPE_JITTER: /* jitter keyframe */
return set_keytype_jitter;
-
+
case BEZT_KEYTYPE_MOVEHOLD: /* moving hold */
return set_keytype_moving_hold;
-
+
case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */
default:
return set_keytype_keyframe;
@@ -1273,13 +1273,13 @@ KeyframeEditFunc ANIM_editkeyframes_easing(short mode)
switch (mode) {
case BEZT_IPO_EASE_IN: /* ease in */
return set_easingtype_easein;
-
+
case BEZT_IPO_EASE_OUT: /* ease out */
return set_easingtype_easeout;
-
+
case BEZT_IPO_EASE_IN_OUT: /* both */
return set_easingtype_easeinout;
-
+
default: /* auto */
return set_easingtype_easeauto;
}
@@ -1288,7 +1288,7 @@ KeyframeEditFunc ANIM_editkeyframes_easing(short mode)
/* ******************************************* */
/* Selection */
-static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt)
+static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt)
{
/* if we've got info on what to select, use it, otherwise select all */
if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
@@ -1302,11 +1302,11 @@ static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt)
else {
BEZT_SEL_ALL(bezt);
}
-
+
return 0;
}
-static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt)
+static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt)
{
/* if we've got info on what to deselect, use it, otherwise deselect all */
if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
@@ -1320,11 +1320,11 @@ static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt)
else {
BEZT_DESEL_ALL(bezt);
}
-
+
return 0;
}
-static short select_bezier_invert(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+static short select_bezier_invert(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
/* Invert the selection for the whole bezier triple */
bezt->f2 ^= SELECT;
@@ -1369,33 +1369,33 @@ static short selmap_build_bezier_more(KeyframeEditData *ked, BezTriple *bezt)
FCurve *fcu = ked->fcu;
char *map = ked->data;
int i = ked->curIndex;
-
+
/* if current is selected, just make sure it stays this way */
if (BEZT_ISSEL_ANY(bezt)) {
map[i] = 1;
return 0;
}
-
+
/* if previous is selected, that means that selection should extend across */
if (i > 0) {
BezTriple *prev = bezt - 1;
-
+
if (BEZT_ISSEL_ANY(prev)) {
map[i] = 1;
return 0;
}
}
-
+
/* if next is selected, that means that selection should extend across */
if (i < (fcu->totvert - 1)) {
BezTriple *next = bezt + 1;
-
+
if (BEZT_ISSEL_ANY(next)) {
map[i] = 1;
return 0;
}
}
-
+
return 0;
}
@@ -1404,7 +1404,7 @@ static short selmap_build_bezier_less(KeyframeEditData *ked, BezTriple *bezt)
FCurve *fcu = ked->fcu;
char *map = ked->data;
int i = ked->curIndex;
-
+
/* if current is selected, check the left/right keyframes
* since it might need to be deselected (but otherwise no)
*/
@@ -1412,7 +1412,7 @@ static short selmap_build_bezier_less(KeyframeEditData *ked, BezTriple *bezt)
/* if previous is not selected, we're on the tip of an iceberg */
if (i > 0) {
BezTriple *prev = bezt - 1;
-
+
if (BEZT_ISSEL_ANY(prev) == 0)
return 0;
}
@@ -1420,11 +1420,11 @@ static short selmap_build_bezier_less(KeyframeEditData *ked, BezTriple *bezt)
/* current keyframe is selected at an endpoint, so should get deselected */
return 0;
}
-
+
/* if next is not selected, we're on the tip of an iceberg */
if (i < (fcu->totvert - 1)) {
BezTriple *next = bezt + 1;
-
+
if (BEZT_ISSEL_ANY(next) == 0)
return 0;
}
@@ -1432,11 +1432,11 @@ static short selmap_build_bezier_less(KeyframeEditData *ked, BezTriple *bezt)
/* current keyframe is selected at an endpoint, so should get deselected */
return 0;
}
-
+
/* if we're still here, that means that keyframe should remain untouched */
map[i] = 1;
}
-
+
return 0;
}
@@ -1446,7 +1446,7 @@ KeyframeEditFunc ANIM_editkeyframes_buildselmap(short mode)
switch (mode) {
case SELMAP_LESS: /* less */
return selmap_build_bezier_less;
-
+
case SELMAP_MORE: /* more */
default:
return selmap_build_bezier_more;
@@ -1460,7 +1460,7 @@ short bezt_selmap_flush(KeyframeEditData *ked, BezTriple *bezt)
{
const char *map = ked->data;
short on = map[ked->curIndex];
-
+
/* select or deselect based on whether the map allows it or not */
if (on) {
BEZT_SEL_ALL(bezt);
@@ -1468,7 +1468,7 @@ short bezt_selmap_flush(KeyframeEditData *ked, BezTriple *bezt)
else {
BEZT_DESEL_ALL(bezt);
}
-
+
return 0;
}
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 7d5fbeb7e3b..a6ed6643257 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -48,6 +48,7 @@
#include "BKE_fcurve.h"
#include "BKE_report.h"
#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_deform.h"
@@ -68,19 +69,19 @@
*
* - Joshua Leung, Dec 2008
*/
-
+
/* **************************************************** */
-/* Only delete the nominated keyframe from provided F-Curve.
+/* Only delete the nominated keyframe from provided F-Curve.
* Not recommended to be used many times successively. For that
* there is delete_fcurve_keys().
*/
void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc)
{
/* sanity check */
- if (fcu == NULL)
+ if (fcu == NULL)
return;
-
+
/* verify the index:
* 1) cannot be greater than the number of available keyframes
* 2) negative indices are for specifying a value from the end of the array
@@ -89,7 +90,7 @@ void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc)
return;
else if (index < 0)
index += fcu->totvert;
-
+
/* Delete this keyframe */
memmove(&fcu->bezt[index], &fcu->bezt[index + 1], sizeof(BezTriple) * (fcu->totvert - index - 1));
fcu->totvert--;
@@ -99,7 +100,7 @@ void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc)
MEM_freeN(fcu->bezt);
fcu->bezt = NULL;
}
-
+
/* recalc handles - only if it won't cause problems */
if (do_recalc)
calchandles_fcurve(fcu);
@@ -110,7 +111,7 @@ bool delete_fcurve_keys(FCurve *fcu)
{
int i;
bool changed = false;
-
+
if (fcu->bezt == NULL) /* ignore baked curves */
return false;
@@ -123,7 +124,7 @@ bool delete_fcurve_keys(FCurve *fcu)
changed = true;
}
}
-
+
/* Free the array of BezTriples if there are not keyframes */
if (fcu->totvert == 0)
clear_fcurve_keys(fcu);
@@ -148,30 +149,30 @@ void duplicate_fcurve_keys(FCurve *fcu)
{
BezTriple *newbezt;
int i;
-
+
/* this can only work when there is an F-Curve, and also when there are some BezTriples */
if (ELEM(NULL, fcu, fcu->bezt))
return;
-
+
for (i = 0; i < fcu->totvert; i++) {
/* If a key is selected */
if (fcu->bezt[i].f2 & SELECT) {
/* Expand the list */
newbezt = MEM_callocN(sizeof(BezTriple) * (fcu->totvert + 1), "beztriple");
-
+
memcpy(newbezt, fcu->bezt, sizeof(BezTriple) * (i + 1));
memcpy(newbezt + i + 1, fcu->bezt + i, sizeof(BezTriple));
memcpy(newbezt + i + 2, fcu->bezt + i + 1, sizeof(BezTriple) * (fcu->totvert - (i + 1)));
fcu->totvert++;
-
+
/* reassign pointers... (free old, and add new) */
MEM_freeN(fcu->bezt);
fcu->bezt = newbezt;
-
+
/* Unselect the current key */
BEZT_DESEL_ALL(&fcu->bezt[i]);
i++;
-
+
/* Select the copied key */
BEZT_SEL_ALL(&fcu->bezt[i]);
}
@@ -189,7 +190,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
BezTriple *old_bezts, *bezt, *beztn;
BezTriple *lastb;
int totCount, i;
-
+
/* check if any points */
if ((fcu == NULL) || (fcu->bezt == NULL) || (fcu->totvert == 0) ||
(!cleardefault && fcu->totvert == 1))
@@ -202,7 +203,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
totCount = fcu->totvert;
fcu->bezt = NULL;
fcu->totvert = 0;
-
+
/* now insert first keyframe, as it should be ok */
bezt = old_bezts;
insert_vert_fcurve(fcu, bezt->vec[1][0], bezt->vec[1][1], BEZKEYTYPE(bezt), 0);
@@ -210,8 +211,8 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
lastb = fcu->bezt;
lastb->f1 = lastb->f2 = lastb->f3 = 0;
}
-
- /* Loop through BezTriples, comparing them. Skip any that do
+
+ /* Loop through BezTriples, comparing them. Skip any that do
* not fit the criteria for "ok" points.
*/
for (i = 1; i < totCount; i++) {
@@ -228,22 +229,22 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
}
lastb = (fcu->bezt + (fcu->totvert - 1));
bezt = (old_bezts + i);
-
+
/* get references for quicker access */
prev[0] = lastb->vec[1][0]; prev[1] = lastb->vec[1][1];
cur[0] = bezt->vec[1][0]; cur[1] = bezt->vec[1][1];
-
+
if (!(bezt->f2 & SELECT)) {
insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0);
lastb = (fcu->bezt + (fcu->totvert - 1));
lastb->f1 = lastb->f2 = lastb->f3 = 0;
continue;
}
-
+
/* check if current bezt occurs at same time as last ok */
if (IS_EQT(cur[0], prev[0], thresh)) {
- /* If there is a next beztriple, and if occurs at the same time, only insert
- * if there is a considerable distance between the points, and also if the
+ /* If there is a next beztriple, and if occurs at the same time, only insert
+ * if there is a considerable distance between the points, and also if the
* current is further away than the next one is to the previous.
*/
if (beztn && (IS_EQT(cur[0], next[0], thresh)) &&
@@ -287,7 +288,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo
}
}
}
-
+
/* now free the memory used by the old BezTriples */
if (old_bezts)
MEM_freeN(old_bezts);
@@ -346,14 +347,14 @@ void smooth_fcurve(FCurve *fcu)
if (BEZT_ISSEL_ANY(bezt))
totSel++;
}
-
+
/* if any points were selected, allocate tSmooth_Bezt points to work on */
if (totSel >= 3) {
tSmooth_Bezt *tarray, *tsb;
-
+
/* allocate memory in one go */
tsb = tarray = MEM_callocN(totSel * sizeof(tSmooth_Bezt), "tSmooth_Bezt Array");
-
+
/* populate tarray with data of selected points */
bezt = fcu->bezt;
for (i = 0, x = 0; (i < fcu->totvert) && (x < totSel); i++, bezt++) {
@@ -362,7 +363,7 @@ void smooth_fcurve(FCurve *fcu)
tsb->h1 = &bezt->vec[0][1];
tsb->h2 = &bezt->vec[1][1];
tsb->h3 = &bezt->vec[2][1];
-
+
/* advance to the next tsb to populate */
if (x < totSel - 1)
tsb++;
@@ -370,15 +371,15 @@ void smooth_fcurve(FCurve *fcu)
break;
}
}
-
+
/* calculate the new smoothed F-Curve's with weighted averages:
* - this is done with two passes to avoid progressive corruption errors
* - uses 5 points for each operation (which stores in the relevant handles)
* - previous: w/a ratio = 3:5:2:1:1
* - next: w/a ratio = 1:1:2:5:3
*/
-
- /* round 1: calculate smoothing deltas and new values */
+
+ /* round 1: calculate smoothing deltas and new values */
tsb = tarray;
for (i = 0; i < totSel; i++, tsb++) {
/* don't touch end points (otherwise, curves slowly explode, as we don't have enough data there) */
@@ -387,21 +388,21 @@ void smooth_fcurve(FCurve *fcu)
const tSmooth_Bezt *tP2 = (i - 2 > 0) ? (tsb - 2) : (NULL);
const tSmooth_Bezt *tN1 = tsb + 1;
const tSmooth_Bezt *tN2 = (i + 2 < totSel) ? (tsb + 2) : (NULL);
-
+
const float p1 = *tP1->h2;
const float p2 = (tP2) ? (*tP2->h2) : (*tP1->h2);
const float c1 = *tsb->h2;
const float n1 = *tN1->h2;
const float n2 = (tN2) ? (*tN2->h2) : (*tN1->h2);
-
+
/* calculate previous and next, then new position by averaging these */
tsb->y1 = (3 * p2 + 5 * p1 + 2 * c1 + n1 + n2) / 12;
tsb->y3 = (p2 + p1 + 2 * c1 + 5 * n1 + 3 * n2) / 12;
-
+
tsb->y2 = (tsb->y1 + tsb->y3) / 2;
}
}
-
+
/* round 2: apply new values */
tsb = tarray;
for (i = 0; i < totSel; i++, tsb++) {
@@ -409,17 +410,17 @@ void smooth_fcurve(FCurve *fcu)
if (ELEM(i, 0, (totSel - 1)) == 0) {
/* y2 takes the average of the 2 points */
*tsb->h2 = tsb->y2;
-
+
/* handles are weighted between their original values and the averaged values */
- *tsb->h1 = ((*tsb->h1) * 0.7f) + (tsb->y1 * 0.3f);
+ *tsb->h1 = ((*tsb->h1) * 0.7f) + (tsb->y1 * 0.3f);
*tsb->h3 = ((*tsb->h3) * 0.7f) + (tsb->y3 * 0.3f);
}
}
-
+
/* free memory required for tarray */
MEM_freeN(tarray);
}
-
+
/* recalculate handles */
calchandles_fcurve(fcu);
}
@@ -442,7 +443,7 @@ void sample_fcurve(FCurve *fcu)
if (fcu->bezt == NULL) /* ignore baked */
return;
-
+
/* find selected keyframes... once pair has been found, add keyframes */
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
/* check if selected, and which end this is */
@@ -459,39 +460,39 @@ void sample_fcurve(FCurve *fcu)
continue;
}
}
-
+
/* set end */
end = bezt;
-
+
/* cache values then add keyframes using these values, as adding
* keyframes while sampling will affect the outcome...
* - only start sampling+adding from index=1, so that we don't overwrite original keyframe
*/
range = (int)(ceil(end->vec[1][0] - start->vec[1][0]));
sfra = (int)(floor(start->vec[1][0]));
-
+
if (range) {
value_cache = MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache");
-
+
/* sample values */
for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
fp->frame = (float)(sfra + n);
fp->val = evaluate_fcurve(fcu, fp->frame);
}
-
+
/* add keyframes with these, tagging as 'breakdowns' */
for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
insert_vert_fcurve(fcu, fp->frame, fp->val, BEZT_KEYTYPE_BREAKDOWN, 1);
}
-
+
/* free temp cache */
MEM_freeN(value_cache);
-
+
/* as we added keyframes, we need to compensate so that bezt is at the right place */
bezt = fcu->bezt + i + range - 1;
i += (range - 1);
}
-
+
/* the current selection island has ended, so start again from scratch */
start = NULL;
end = NULL;
@@ -503,14 +504,14 @@ void sample_fcurve(FCurve *fcu)
}
}
}
-
+
/* recalculate channel's handles? */
calchandles_fcurve(fcu);
}
/* **************************************************** */
/* Copy/Paste Tools */
-/* - The copy/paste buffer currently stores a set of temporary F-Curves containing only the keyframes
+/* - The copy/paste buffer currently stores a set of temporary F-Curves containing only the keyframes
* that were selected in each of the original F-Curves
* - All pasted frames are offset by the same amount. This is calculated as the difference in the times of
* the current frame and the 'first keyframe' (i.e. the earliest one in all channels).
@@ -526,12 +527,12 @@ static float animcopy_cfra = 0.0;
/* datatype for use in copy/paste buffer */
typedef struct tAnimCopybufItem {
struct tAnimCopybufItem *next, *prev;
-
+
ID *id; /* ID which owns the curve */
bActionGroup *grp; /* Action Group */
char *rna_path; /* RNA-Path */
int array_index; /* array index */
-
+
int totvert; /* number of keyframes stored for this channel */
BezTriple *bezt; /* keyframes in buffer */
@@ -544,23 +545,23 @@ typedef struct tAnimCopybufItem {
void ANIM_fcurves_copybuf_free(void)
{
tAnimCopybufItem *aci, *acn;
-
+
/* free each buffer element */
for (aci = animcopybuf.first; aci; aci = acn) {
acn = aci->next;
-
+
/* free keyframes */
- if (aci->bezt)
+ if (aci->bezt)
MEM_freeN(aci->bezt);
-
+
/* free RNA-path */
if (aci->rna_path)
MEM_freeN(aci->rna_path);
-
+
/* free ourself */
BLI_freelinkN(&animcopybuf, aci);
}
-
+
/* restore initial state */
BLI_listbase_clear(&animcopybuf);
animcopy_firstframe = 999999999.0f;
@@ -571,27 +572,27 @@ void ANIM_fcurves_copybuf_free(void)
/* This function adds data to the keyframes copy/paste buffer, freeing existing data first */
short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
-{
+{
bAnimListElem *ale;
Scene *scene = ac->scene;
-
+
/* clear buffer first */
ANIM_fcurves_copybuf_free();
-
+
/* assume that each of these is an F-Curve */
for (ale = anim_data->first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
tAnimCopybufItem *aci;
BezTriple *bezt, *nbezt, *newbuf;
int i;
-
+
/* firstly, check if F-Curve has any selected keyframes
* - skip if no selected keyframes found (so no need to create unnecessary copy-buffer data)
* - this check should also eliminate any problems associated with using sample-data
*/
if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ANIM_editkeyframes_ok(BEZT_OK_SELECTED), NULL) == 0)
continue;
-
+
/* init copybuf item info */
aci = MEM_callocN(sizeof(tAnimCopybufItem), "AnimCopybufItem");
aci->id = ale->id;
@@ -599,7 +600,7 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
aci->grp = fcu->grp;
aci->rna_path = MEM_dupallocN(fcu->rna_path);
aci->array_index = fcu->array_index;
-
+
/* detect if this is a bone. We do that here rather than during pasting because ID pointers will get invalidated if we undo.
* storing the relevant information here helps avoiding crashes if we undo-repaste */
if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) {
@@ -614,9 +615,9 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
}
if (bone_name) MEM_freeN(bone_name);
}
-
+
BLI_addtail(&animcopybuf, aci);
-
+
/* add selected keyframes to buffer */
/* TODO: currently, we resize array every time we add a new vert -
* this works ok as long as it is assumed only a few keys are copied */
@@ -624,23 +625,23 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
if (BEZT_ISSEL_ANY(bezt)) {
/* add to buffer */
newbuf = MEM_callocN(sizeof(BezTriple) * (aci->totvert + 1), "copybuf beztriple");
-
+
/* assume that since we are just re-sizing the array, just copy all existing data across */
if (aci->bezt)
memcpy(newbuf, aci->bezt, sizeof(BezTriple) * (aci->totvert));
-
+
/* copy current beztriple across too */
nbezt = &newbuf[aci->totvert];
*nbezt = *bezt;
-
+
/* ensure copy buffer is selected so pasted keys are selected */
BEZT_SEL_ALL(nbezt);
-
+
/* free old array and set the new */
if (aci->bezt) MEM_freeN(aci->bezt);
aci->bezt = newbuf;
aci->totvert++;
-
+
/* check if this is the earliest frame encountered so far */
if (bezt->vec[1][0] < animcopy_firstframe)
animcopy_firstframe = bezt->vec[1][0];
@@ -648,9 +649,9 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
animcopy_lastframe = bezt->vec[1][0];
}
}
-
+
}
-
+
/* check if anything ended up in the buffer */
if (ELEM(NULL, animcopybuf.first, animcopybuf.last))
return -1;
@@ -729,7 +730,8 @@ static tAnimCopybufItem *pastebuf_match_path_full(FCurve *fcu, const short from_
}
/* medium match strictness: path match only (i.e. ignore ID) */
-static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short from_single, const short UNUSED(to_simple))
+static tAnimCopybufItem *pastebuf_match_path_property(
+ Main *bmain, FCurve *fcu, const short from_single, const short UNUSED(to_simple))
{
tAnimCopybufItem *aci;
@@ -740,18 +742,18 @@ static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short f
* more involved since it needs to to path lookups.
* This is not 100% reliable since the user could be editing the curves on a path that wont
* resolve, or a bone could be renamed after copying for eg. but in normal copy & paste
- * this should work out ok.
+ * this should work out ok.
*/
- if (BLI_findindex(which_libbase(G.main, aci->id_type), aci->id) == -1) {
+ if (BLI_findindex(which_libbase(bmain, aci->id_type), aci->id) == -1) {
/* pedantic but the ID could have been removed, and beats crashing! */
printf("paste_animedit_keys: error ID has been removed!\n");
}
else {
PointerRNA id_ptr, rptr;
PropertyRNA *prop;
-
+
RNA_id_pointer_create(aci->id, &id_ptr);
-
+
if (RNA_path_resolve_property(&id_ptr, aci->rna_path, &rptr, &prop)) {
const char *identifier = RNA_property_identifier(prop);
int len_id = strlen(identifier);
@@ -804,7 +806,7 @@ static void do_curve_mirror_flippping(tAnimCopybufItem *aci, BezTriple *bezt)
flip = true;
else if (BLI_strn_endswith(aci->rna_path, "rotation_axis_angle", slength) && ELEM(aci->array_index, 2, 3))
flip = true;
-
+
if (flip) {
bezt->vec[0][1] = -bezt->vec[0][1];
bezt->vec[1][1] = -bezt->vec[1][1];
@@ -829,18 +831,18 @@ static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float
case KEYFRAME_PASTE_MERGE_MIX:
/* do-nothing */
break;
-
+
case KEYFRAME_PASTE_MERGE_OVER:
/* remove all keys */
clear_fcurve_keys(fcu);
break;
-
+
case KEYFRAME_PASTE_MERGE_OVER_RANGE:
case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL:
{
float f_min;
float f_max;
-
+
if (merge_mode == KEYFRAME_PASTE_MERGE_OVER_RANGE) {
f_min = aci->bezt[0].vec[1][0] + offset;
f_max = aci->bezt[aci->totvert - 1].vec[1][0] + offset;
@@ -849,7 +851,7 @@ static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float
f_min = animcopy_firstframe + offset;
f_max = animcopy_lastframe + offset;
}
-
+
/* remove keys in range */
if (f_min < f_max) {
/* select verts in range for removal */
@@ -858,39 +860,39 @@ static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float
bezt->f2 |= SELECT;
}
}
-
+
/* remove frames in the range */
delete_fcurve_keys(fcu);
}
break;
}
}
-
+
/* just start pasting, with the first keyframe on the current frame, and so on */
for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) {
/* temporarily apply offset to src beztriple while copying */
if (flip)
do_curve_mirror_flippping(aci, bezt);
-
+
bezt->vec[0][0] += offset;
bezt->vec[1][0] += offset;
bezt->vec[2][0] += offset;
-
+
/* insert the keyframe
* NOTE: we do not want to inherit handles from existing keyframes in this case!
*/
-
+
insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL);
-
+
/* un-apply offset from src beztriple after copying */
bezt->vec[0][0] -= offset;
bezt->vec[1][0] -= offset;
bezt->vec[2][0] -= offset;
-
+
if (flip)
do_curve_mirror_flippping(aci, bezt);
}
-
+
/* recalculate F-Curve's handles? */
calchandles_fcurve(fcu);
}
@@ -921,12 +923,12 @@ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
{
bAnimListElem *ale;
-
+
const Scene *scene = (ac->scene);
-
+
const bool from_single = BLI_listbase_is_single(&animcopybuf);
const bool to_simple = BLI_listbase_is_single(anim_data);
-
+
float offset = 0.0f;
int pass;
@@ -940,7 +942,7 @@ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
BKE_report(ac->reports, RPT_ERROR, "No selected F-Curves to paste into");
return -1;
}
-
+
/* methods of offset */
switch (offset_mode) {
case KEYFRAME_PASTE_OFFSET_CFRA_START:
@@ -961,25 +963,25 @@ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
/* 1:1 match, no tricky checking, just paste */
FCurve *fcu;
tAnimCopybufItem *aci;
-
+
ale = anim_data->first;
fcu = (FCurve *)ale->data; /* destination F-Curve */
aci = animcopybuf.first;
-
+
paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, false);
ale->update |= ANIM_UPDATE_DEFAULT;
}
else {
- /* from selected channels
+ /* from selected channels
* This "passes" system aims to try to find "matching" channels to paste keyframes
* into with increasingly loose matching heuristics. The process finishes when at least
* one F-Curve has been pasted into.
*/
for (pass = 0; pass < 3; pass++) {
unsigned int totmatch = 0;
-
+
for (ale = anim_data->first; ale; ale = ale->next) {
- /* find buffer item to paste from
+ /* find buffer item to paste from
* - if names don't matter (i.e. only 1 channel in buffer), don't check id/group
* - if names do matter, only check if id-type is ok for now (group check is not that important)
* - most importantly, rna-paths should match (array indices are unimportant for now)
@@ -987,28 +989,28 @@ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->data; /* destination F-Curve */
tAnimCopybufItem *aci = NULL;
-
+
switch (pass) {
case 0:
/* most strict, must be exact path match data_path & index */
aci = pastebuf_match_path_full(fcu, from_single, to_simple, flip);
break;
-
+
case 1:
/* less strict, just compare property names */
- aci = pastebuf_match_path_property(fcu, from_single, to_simple);
+ aci = pastebuf_match_path_property(ac->bmain, fcu, from_single, to_simple);
break;
-
+
case 2:
/* Comparing properties gave no results, so just do index comparisons */
aci = pastebuf_match_index_only(fcu, from_single, to_simple);
break;
}
-
+
/* copy the relevant data from the matching buffer curve */
if (aci) {
totmatch++;
-
+
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
@@ -1018,16 +1020,16 @@ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
}
}
-
+
ale->update |= ANIM_UPDATE_DEFAULT;
}
-
+
/* don't continue if some fcurves were pasted */
if (totmatch)
break;
}
}
-
+
ANIM_animdata_update(ac, anim_data);
return 0;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 979e6dffe5c..1913eb944d9 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -29,7 +29,7 @@
* \ingroup edanimation
*/
-
+
#include <stdio.h>
#include <stddef.h>
#include <string.h>
@@ -53,17 +53,18 @@
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
-#include "BKE_animsys.h"
#include "BKE_action.h"
+#include "BKE_animsys.h"
#include "BKE_armature.h"
+#include "BKE_context.h"
#include "BKE_fcurve.h"
-#include "BKE_idcode.h"
-#include "BKE_nla.h"
#include "BKE_global.h"
-#include "BKE_context.h"
-#include "BKE_report.h"
+#include "BKE_idcode.h"
#include "BKE_key.h"
+#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_nla.h"
+#include "BKE_report.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@@ -94,42 +95,42 @@
short ANIM_get_keyframing_flags(Scene *scene, short incl_mode)
{
eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
-
+
/* standard flags */
{
/* visual keying */
- if (IS_AUTOKEY_FLAG(scene, AUTOMATKEY))
+ if (IS_AUTOKEY_FLAG(scene, AUTOMATKEY))
flag |= INSERTKEY_MATRIX;
-
+
/* only needed */
- if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED))
+ if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED))
flag |= INSERTKEY_NEEDED;
-
+
/* default F-Curve color mode - RGB from XYZ indices */
- if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
+ if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
flag |= INSERTKEY_XYZ2RGB;
}
-
+
/* only if including settings from the autokeying mode... */
if (incl_mode) {
/* keyframing mode - only replace existing keyframes */
- if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+ if (IS_AUTOKEY_MODE(scene, EDITKEYS))
flag |= INSERTKEY_REPLACE;
}
-
+
return flag;
}
/* ******************************************* */
/* Animation Data Validation */
-/* Get (or add relevant data to be able to do so) the Active Action for the given
+/* Get (or add relevant data to be able to do so) the Active Action for the given
* Animation Data block, given an ID block where the Animation Data should reside.
*/
-bAction *verify_adt_action(ID *id, short add)
+bAction *verify_adt_action(Main *bmain, ID *id, short add)
{
AnimData *adt;
-
+
/* init animdata if none available yet */
adt = BKE_animdata_from_id(id);
if ((adt == NULL) && (add))
@@ -146,10 +147,10 @@ bAction *verify_adt_action(ID *id, short add)
/* init action name from name of ID block */
char actname[sizeof(id->name) - 2];
BLI_snprintf(actname, sizeof(actname), "%sAction", id->name + 2);
-
+
/* create action */
- adt->action = BKE_action_add(G.main, actname);
-
+ adt->action = BKE_action_add(bmain, actname);
+
/* set ID-type from ID-block that this is going to be assigned to
* so that users can't accidentally break actions by assigning them
* to the wrong places
@@ -158,7 +159,7 @@ bAction *verify_adt_action(ID *id, short add)
/* tag depsgraph to be rebuilt to include time dependency */
/* XXX: we probably should have bmain passed down, but that involves altering too many API's */
- DEG_relations_tag_update(G.main);
+ DEG_relations_tag_update(bmain);
}
DEG_id_tag_update(&adt->action->id, DEG_TAG_COPY_ON_WRITE);
@@ -167,54 +168,54 @@ bAction *verify_adt_action(ID *id, short add)
return adt->action;
}
-/* Get (or add relevant data to be able to do so) F-Curve from the Active Action,
+/* Get (or add relevant data to be able to do so) F-Curve from the Active Action,
* for the given Animation Data block. This assumes that all the destinations are valid.
*/
-FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr,
+FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr,
const char rna_path[], const int array_index, short add)
{
bActionGroup *agrp;
FCurve *fcu;
-
+
/* sanity checks */
if (ELEM(NULL, act, rna_path))
return NULL;
-
- /* try to find f-curve matching for this setting
+
+ /* try to find f-curve matching for this setting
* - add if not found and allowed to add one
* TODO: add auto-grouping support? how this works will need to be resolved
*/
fcu = list_find_fcurve(&act->curves, rna_path, array_index);
-
+
if ((fcu == NULL) && (add)) {
/* use default settings to make a F-Curve */
fcu = MEM_callocN(sizeof(FCurve), "FCurve");
-
+
fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
if (BLI_listbase_is_empty(&act->curves))
fcu->flag |= FCURVE_ACTIVE; /* first one added active */
-
+
/* store path - make copy, and store that */
fcu->rna_path = BLI_strdup(rna_path);
fcu->array_index = array_index;
-
+
/* if a group name has been provided, try to add or find a group, then add F-Curve to it */
if (group) {
/* try to find group */
agrp = BKE_action_group_find_name(act, group);
-
+
/* no matching groups, so add one */
if (agrp == NULL) {
agrp = action_groups_add_new(act, group);
-
+
/* sync bone group colors if applicable */
if (ptr && (ptr->type == &RNA_PoseBone)) {
Object *ob = (Object *)ptr->id.data;
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
bPose *pose = ob->pose;
bActionGroup *grp;
-
+
/* find bone group (if present), and use the color from that */
grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
if (grp) {
@@ -223,7 +224,7 @@ FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr,
}
}
}
-
+
/* add F-Curve to group */
action_groups_add_channel(act, agrp, fcu);
}
@@ -232,7 +233,7 @@ FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr,
BLI_addtail(&act->curves, fcu);
}
}
-
+
/* return the F-Curve */
return fcu;
}
@@ -285,10 +286,10 @@ void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, Poin
idname, fcu->rna_path);
return;
}
-
+
/* update F-Curve flags */
update_autoflags_fcurve_direct(fcu, prop);
-
+
if (old_flag != fcu->flag) {
/* Same as if keyframes had been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
@@ -300,7 +301,7 @@ void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, Poin
/* -------------- BezTriple Insertion -------------------- */
-/* This function adds a given BezTriple to an F-Curve. It will allocate
+/* This function adds a given BezTriple to an F-Curve. It will allocate
* memory for the array if needed, and will insert the BezTriple into a
* suitable place in chronological order.
*
@@ -310,12 +311,12 @@ void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, Poin
int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
{
int i = 0;
-
+
/* are there already keyframes? */
if (fcu->bezt) {
bool replace;
i = binarysearch_bezt_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace);
-
+
/* replace an existing keyframe? */
if (replace) {
/* sanity check: 'i' may in rare cases exceed arraylen */
@@ -327,16 +328,16 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
/* just change the values when replacing, so as to not overwrite handles */
BezTriple *dst = (fcu->bezt + i);
float dy = bezt->vec[1][1] - dst->vec[1][1];
-
+
/* just apply delta value change to the handle values */
dst->vec[0][1] += dy;
dst->vec[1][1] += dy;
dst->vec[2][1] += dy;
-
+
dst->f1 = bezt->f1;
dst->f2 = bezt->f2;
dst->f3 = bezt->f3;
-
+
/* TODO: perform some other operations? */
}
}
@@ -345,29 +346,29 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
else if ((flag & INSERTKEY_REPLACE) == 0) {
/* insert new - if we're not restricted to replacing keyframes only */
BezTriple *newb = MEM_callocN((fcu->totvert + 1) * sizeof(BezTriple), "beztriple");
-
+
/* add the beztriples that should occur before the beztriple to be pasted (originally in fcu) */
if (i > 0)
memcpy(newb, fcu->bezt, i * sizeof(BezTriple));
-
+
/* add beztriple to paste at index i */
*(newb + i) = *bezt;
-
+
/* add the beztriples that occur after the beztriple to be pasted (originally in fcu) */
- if (i < fcu->totvert)
+ if (i < fcu->totvert)
memcpy(newb + i + 1, fcu->bezt + i, (fcu->totvert - i) * sizeof(BezTriple));
-
+
/* replace (+ free) old with new, only if necessary to do so */
MEM_freeN(fcu->bezt);
fcu->bezt = newb;
-
+
fcu->totvert++;
}
}
/* no keyframes already, but can only add if...
* 1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know
* 2) there are no samples on the curve
- * // NOTE: maybe we may want to allow this later when doing samples -> bezt conversions,
+ * // NOTE: maybe we may want to allow this later when doing samples -> bezt conversions,
* // but for now, having both is asking for trouble
*/
else if ((flag & INSERTKEY_REPLACE) == 0 && (fcu->fpt == NULL)) {
@@ -381,9 +382,9 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
/* return error code -1 to prevent any misunderstandings */
return -1;
}
-
-
- /* we need to return the index, so that some tools which do post-processing can
+
+
+ /* we need to return the index, so that some tools which do post-processing can
* detect where we added the BezTriple in the array
*/
return i;
@@ -403,8 +404,8 @@ int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType ke
BezTriple beztr = {{{0}}};
unsigned int oldTot = fcu->totvert;
int a;
-
- /* set all three points, for nicer start position
+
+ /* set all three points, for nicer start position
* NOTE: +/- 1 on vec.x for left and right handles is so that 'free' handles work ok...
*/
beztr.vec[0][0] = x - 1.0f;
@@ -414,7 +415,7 @@ int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType ke
beztr.vec[2][0] = x + 1.0f;
beztr.vec[2][1] = y;
beztr.f1 = beztr.f2 = beztr.f3 = SELECT;
-
+
/* set default handle types and interpolation mode */
if (flag & INSERTKEY_NO_USERPREF) {
/* for Py-API, we want scripts to have predictable behaviour,
@@ -426,11 +427,11 @@ int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType ke
else {
/* for UI usage - defaults should come from the userprefs and/or toolsettings */
beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */
-
+
/* use default interpolation mode, with exceptions for int/discrete values */
beztr.ipo = U.ipo_new;
}
-
+
/* interpolation type used is constrained by the type of values the curve can take */
if (fcu->flag & FCURVE_DISCRETE_VALUES) {
beztr.ipo = BEZT_IPO_CONST;
@@ -438,10 +439,10 @@ int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType ke
else if ((beztr.ipo == BEZT_IPO_BEZ) && (fcu->flag & FCURVE_INT_VALUES)) {
beztr.ipo = BEZT_IPO_LIN;
}
-
+
/* set keyframe type value (supplied), which should come from the scene settings in most cases */
BEZKEYTYPE(&beztr) = keyframe_type;
-
+
/* set default values for "easing" interpolation mode settings
* NOTE: Even if these modes aren't currently used, if users switch
* to these later, we want these to work in a sane way out of
@@ -449,48 +450,48 @@ int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType ke
*/
beztr.back = 1.70158f; /* "back" easing - this value used to be used when overshoot=0, but that */
/* introduced discontinuities in how the param worked */
-
+
beztr.amplitude = 0.8f; /* "elastic" easing - values here were hand-optimised for a default duration of */
beztr.period = 4.1f; /* ~10 frames (typical mograph motion length) */
-
+
/* add temp beztriple to keyframes */
a = insert_bezt_fcurve(fcu, &beztr, flag);
-
- /* what if 'a' is a negative index?
+
+ /* what if 'a' is a negative index?
* for now, just exit to prevent any segfaults
*/
if (a < 0) return -1;
-
+
/* don't recalculate handles if fast is set
* - this is a hack to make importers faster
* - we may calculate twice (due to autohandle needing to be calculated twice)
*/
- if ((flag & INSERTKEY_FAST) == 0)
+ if ((flag & INSERTKEY_FAST) == 0)
calchandles_fcurve(fcu);
-
+
/* set handletype and interpolation */
if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) {
BezTriple *bezt = (fcu->bezt + a);
-
- /* set interpolation from previous (if available), but only if we didn't just replace some keyframe
+
+ /* set interpolation from previous (if available), but only if we didn't just replace some keyframe
* - replacement is indicated by no-change in number of verts
* - when replacing, the user may have specified some interpolation that should be kept
*/
if (fcu->totvert > oldTot) {
- if (a > 0)
+ if (a > 0)
bezt->ipo = (bezt - 1)->ipo;
else if (a < fcu->totvert - 1)
bezt->ipo = (bezt + 1)->ipo;
}
-
+
/* don't recalculate handles if fast is set
* - this is a hack to make importers faster
* - we may calculate twice (due to autohandle needing to be calculated twice)
*/
- if ((flag & INSERTKEY_FAST) == 0)
+ if ((flag & INSERTKEY_FAST) == 0)
calchandles_fcurve(fcu);
}
-
+
/* return the index at which the keyframe was added */
return a;
}
@@ -515,34 +516,34 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
BezTriple *bezt = NULL, *prev = NULL;
int totCount, i;
float valA = 0.0f, valB = 0.0f;
-
+
/* safety checking */
if (fcu == NULL) return KEYNEEDED_JUSTADD;
totCount = fcu->totvert;
if (totCount == 0) return KEYNEEDED_JUSTADD;
-
+
/* loop through checking if any are the same */
bezt = fcu->bezt;
for (i = 0; i < totCount; i++) {
float prevPosi = 0.0f, prevVal = 0.0f;
float beztPosi = 0.0f, beztVal = 0.0f;
-
+
/* get current time+value */
beztPosi = bezt->vec[1][0];
beztVal = bezt->vec[1][1];
-
+
if (prev) {
/* there is a keyframe before the one currently being examined */
-
+
/* get previous time+value */
prevPosi = prev->vec[1][0];
prevVal = prev->vec[1][1];
-
+
/* keyframe to be added at point where there are already two similar points? */
if (IS_EQF(prevPosi, cFrame) && IS_EQF(beztPosi, cFrame) && IS_EQF(beztPosi, prevPosi)) {
return KEYNEEDED_DONTADD;
}
-
+
/* keyframe between prev+current points ? */
if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
/* is the value of keyframe to be added the same as keyframes on either side ? */
@@ -551,18 +552,18 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
}
else {
float realVal;
-
+
/* get real value of curve at that point */
realVal = evaluate_fcurve(fcu, cFrame);
-
+
/* compare whether it's the same as proposed */
if (IS_EQF(realVal, nValue))
return KEYNEEDED_DONTADD;
- else
+ else
return KEYNEEDED_JUSTADD;
}
}
-
+
/* new keyframe before prev beztriple? */
if (cFrame < prevPosi) {
/* A new keyframe will be added. However, whether the previous beztriple
@@ -571,18 +572,18 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
*/
if (IS_EQF(prevVal, nValue) && IS_EQF(beztVal, nValue) && IS_EQF(prevVal, beztVal))
return KEYNEEDED_DELNEXT;
- else
+ else
return KEYNEEDED_JUSTADD;
}
}
else {
- /* just add a keyframe if there's only one keyframe
+ /* just add a keyframe if there's only one keyframe
* and the new one occurs before the existing one does.
*/
if ((cFrame < beztPosi) && (totCount == 1))
return KEYNEEDED_JUSTADD;
}
-
+
/* continue. frame to do not yet passed (or other conditions not met) */
if (i < (totCount - 1)) {
prev = bezt;
@@ -591,7 +592,7 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
else
break;
}
-
+
/* Frame in which to add a new-keyframe occurs after all other keys
* -> If there are at least two existing keyframes, then if the values of the
* last two keyframes and the new-keyframe match, the last existing keyframe
@@ -601,28 +602,30 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
*/
bezt = (fcu->bezt + (fcu->totvert - 1));
valA = bezt->vec[1][1];
-
+
if (prev)
valB = prev->vec[1][1];
- else
+ else
valB = bezt->vec[1][1] + 1.0f;
-
+
if (IS_EQF(valA, nValue) && IS_EQF(valA, valB))
return KEYNEEDED_DELPREV;
- else
+ else
return KEYNEEDED_JUSTADD;
}
/* ------------------ RNA Data-Access Functions ------------------ */
/* Try to read value using RNA-properties obtained already */
-static float setting_get_rna_value(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, int index)
+static float setting_get_rna_value(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, int index, const bool get_evaluated)
{
- PointerRNA ptr_eval;
+ PointerRNA ptr_eval = *ptr;
float value = 0.0f;
-
- DEG_get_evaluated_rna_pointer(depsgraph, ptr, &ptr_eval);
-
+
+ if (get_evaluated) {
+ DEG_get_evaluated_rna_pointer(depsgraph, ptr, &ptr_eval);
+ }
+
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
if (RNA_property_array_check(prop))
@@ -648,7 +651,7 @@ static float setting_get_rna_value(Depsgraph *depsgraph, PointerRNA *ptr, Proper
default:
break;
}
-
+
return value;
}
@@ -662,7 +665,7 @@ enum {
VISUALKEY_SCA,
};
-/* This helper function determines if visual-keyframing should be used when
+/* This helper function determines if visual-keyframing should be used when
* inserting keyframes for the given channel. As visual-keyframing only works
* on Object and Pose-Channel blocks, this should only get called for those
* blocktypes, when using "standard" keying but 'Visual Keying' option in Auto-Keying
@@ -675,12 +678,12 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
bool has_rigidbody = false;
bool has_parent = false;
const char *identifier = NULL;
-
+
/* validate data */
if (ELEM(NULL, ptr, ptr->data, prop))
return false;
-
- /* get first constraint and determine type of keyframe constraints to check for
+
+ /* get first constraint and determine type of keyframe constraints to check for
* - constraints can be on either Objects or PoseChannels, so we only check if the
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
* those structs, allowing us to identify the owner of the data
@@ -689,27 +692,27 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
/* Object */
Object *ob = (Object *)ptr->data;
RigidBodyOb *rbo = ob->rigidbody_object;
-
+
con = ob->constraints.first;
identifier = RNA_property_identifier(prop);
has_parent = (ob->parent != NULL);
-
+
/* active rigidbody objects only, as only those are affected by sim */
has_rigidbody = ((rbo) && (rbo->type == RBO_TYPE_ACTIVE));
}
else if (ptr->type == &RNA_PoseBone) {
/* Pose Channel */
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
+
con = pchan->constraints.first;
identifier = RNA_property_identifier(prop);
has_parent = (pchan->parent != NULL);
}
-
+
/* check if any data to search using */
if (ELEM(NULL, con, identifier) && (has_parent == false) && (has_rigidbody == false))
return false;
-
+
/* location or rotation identifiers only... */
if (identifier == NULL) {
printf("%s failed: NULL identifier\n", __func__);
@@ -728,20 +731,20 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
printf("%s failed: identifier - '%s'\n", __func__, identifier);
return false;
}
-
-
+
+
/* only search if a searchtype and initial constraint are available */
if (searchtype) {
/* parent or rigidbody are always matching */
if (has_parent || has_rigidbody)
return true;
-
+
/* constraints */
for (; con; con = con->next) {
/* only consider constraint if it is not disabled, and has influence */
if (con->flag & CONSTRAINT_DISABLE) continue;
if (con->enforce == 0.0f) continue;
-
+
/* some constraints may alter these transforms */
switch (con->type) {
/* multi-transform constraints */
@@ -754,7 +757,7 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
return true;
case CONSTRAINT_TYPE_KINEMATIC:
return true;
-
+
/* single-transform constraits */
case CONSTRAINT_TYPE_TRACKTO:
if (searchtype == VISUALKEY_ROT) return true;
@@ -789,18 +792,18 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
case CONSTRAINT_TYPE_MINMAX:
if (searchtype == VISUALKEY_LOC) return true;
break;
-
+
default:
break;
}
}
}
-
+
/* when some condition is met, this function returns, so that means we've got nothing */
return false;
}
-/* This helper function extracts the value to use for visual-keyframing
+/* This helper function extracts the value to use for visual-keyframing
* In the event that it is not possible to perform visual keying, try to fall-back
* to using the default method. Assumes that all data it has been passed is valid.
*/
@@ -809,8 +812,8 @@ static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, Property
const char *identifier = RNA_property_identifier(prop);
float tmat[4][4];
int rotmode;
-
- /* handle for Objects or PoseChannels only
+
+ /* handle for Objects or PoseChannels only
* - only Location, Rotation or Scale keyframes are supported currently
* - constraints can be on either Objects or PoseChannels, so we only check if the
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
@@ -820,25 +823,25 @@ static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, Property
if (ptr->type == &RNA_Object) {
Object *ob = (Object *)ptr->data;
const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
-
+
/* Loc code is specific... */
if (strstr(identifier, "location")) {
return ob_eval->obmat[3][array_index];
}
-
+
copy_m4_m4(tmat, ob_eval->obmat);
rotmode = ob_eval->rotmode;
}
else if (ptr->type == &RNA_PoseBone) {
Object *ob = (Object *)ptr->id.data;
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
+
const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
-
+
BKE_armature_mat_pose_to_bone(pchan_eval, pchan_eval->pose_mat, tmat);
rotmode = pchan_eval->rotmode;
-
+
/* Loc code is specific... */
if (strstr(identifier, "location")) {
/* only use for non-connected bones */
@@ -847,29 +850,29 @@ static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, Property
}
}
else {
- return setting_get_rna_value(depsgraph, ptr, prop, array_index);
+ return setting_get_rna_value(depsgraph, ptr, prop, array_index, true);
}
-
+
/* Rot/Scale code are common! */
if (strstr(identifier, "rotation_euler")) {
float eul[3];
-
+
mat4_to_eulO(eul, rotmode, tmat);
return eul[array_index];
}
else if (strstr(identifier, "rotation_quaternion")) {
float mat3[3][3], quat[4];
-
+
copy_m3_m4(mat3, tmat);
mat3_to_quat_is_ok(quat, mat3);
-
+
return quat[array_index];
}
else if (strstr(identifier, "rotation_axis_angle")) {
float axis[3], angle;
-
+
mat4_to_axis_angle(axis, &angle, tmat);
-
+
/* w = 0, x,y,z = 1,2,3 */
if (array_index == 0)
return angle;
@@ -878,19 +881,19 @@ static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, Property
}
else if (strstr(identifier, "scale")) {
float scale[3];
-
+
mat4_to_size(scale, tmat);
-
+
return scale[array_index];
}
-
+
/* as the function hasn't returned yet, read value from system in the default way */
- return setting_get_rna_value(depsgraph, ptr, prop, array_index);
+ return setting_get_rna_value(depsgraph, ptr, prop, array_index, true);
}
/* ------------------------- Insert Key API ------------------------- */
-/* Secondary Keyframing API call:
+/* Secondary Keyframing API call:
* Use this when validation of necessary animation data is not necessary, since an RNA-pointer to the necessary
* data being keyframed, and a pointer to the F-Curve to use have both been provided.
*
@@ -903,7 +906,7 @@ static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, Property
bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag)
{
float curval = 0.0f;
-
+
/* no F-Curve to add keyframe to? */
if (fcu == NULL) {
BKE_report(reports, RPT_ERROR, "No F-Curve to add keyframes to");
@@ -911,13 +914,13 @@ bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRN
}
/* F-Curve not editable? */
if (fcurve_is_keyframable(fcu) == 0) {
- BKE_reportf(reports, RPT_ERROR,
+ BKE_reportf(reports, RPT_ERROR,
"F-Curve with path '%s[%d]' cannot be keyframed, ensure that it is not locked or sampled, "
"and try removing F-Modifiers",
fcu->rna_path, fcu->array_index);
return false;
}
-
+
/* if no property given yet, try to validate from F-Curve info */
if ((ptr.id.data == NULL) && (ptr.data == NULL)) {
BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from");
@@ -925,12 +928,12 @@ bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRN
}
if (prop == NULL) {
PointerRNA tmp_ptr;
-
+
/* try to get property we should be affecting */
if (RNA_path_resolve_property(&ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
/* property not found... */
const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : TIP_("<No ID pointer>");
-
+
BKE_reportf(reports, RPT_ERROR,
"Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
idname, fcu->rna_path);
@@ -941,7 +944,7 @@ bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRN
ptr = tmp_ptr;
}
}
-
+
/* update F-Curve flags to ensure proper behaviour for property type */
update_autoflags_fcurve_direct(fcu, prop);
@@ -957,33 +960,33 @@ bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRN
cfra = 0.0f;
}
}
-
+
/* obtain value to give keyframe */
- if ( (flag & INSERTKEY_MATRIX) &&
+ if ( (flag & INSERTKEY_MATRIX) &&
(visualkey_can_use(&ptr, prop)) )
{
- /* visual-keying is only available for object and pchan datablocks, as
- * it works by keyframing using a value extracted from the final matrix
+ /* visual-keying is only available for object and pchan datablocks, as
+ * it works by keyframing using a value extracted from the final matrix
* instead of using the kt system to extract a value.
*/
curval = visualkey_get_value(depsgraph, &ptr, prop, fcu->array_index);
}
else {
/* read value from system */
- curval = setting_get_rna_value(depsgraph, &ptr, prop, fcu->array_index);
+ curval = setting_get_rna_value(depsgraph, &ptr, prop, fcu->array_index, false);
}
-
+
/* only insert keyframes where they are needed */
if (flag & INSERTKEY_NEEDED) {
short insert_mode;
-
+
/* check whether this curve really needs a new keyframe */
insert_mode = new_key_needed(fcu, cfra, curval);
-
+
/* insert new keyframe at current frame */
if (insert_mode)
insert_vert_fcurve(fcu, cfra, curval, keytype, flag);
-
+
/* delete keyframe immediately before/after newly added */
switch (insert_mode) {
case KEYNEEDED_DELPREV:
@@ -993,7 +996,7 @@ bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRN
delete_fcurve_key(fcu, 1, 1);
break;
}
-
+
/* only return success if keyframe added */
if (insert_mode)
return true;
@@ -1001,11 +1004,11 @@ bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRN
else {
/* just insert keyframe */
insert_vert_fcurve(fcu, cfra, curval, keytype, flag);
-
+
/* return success */
return true;
}
-
+
/* failed */
return false;
}
@@ -1019,21 +1022,23 @@ bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRN
*
* index of -1 keys all array indices
*/
-short insert_keyframe(Depsgraph *depsgraph, ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag)
-{
+short insert_keyframe(
+ Main *bmain, Depsgraph *depsgraph, ReportList *reports, ID *id, bAction *act,
+ const char group[], const char rna_path[], int array_index, float cfra, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag)
+{
PointerRNA id_ptr, ptr;
PropertyRNA *prop = NULL;
AnimData *adt;
FCurve *fcu;
int array_index_max = array_index + 1;
int ret = 0;
-
+
/* validate pointer first - exit if failure */
if (id == NULL) {
BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path);
return 0;
}
-
+
RNA_id_pointer_create(id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
BKE_reportf(reports, RPT_ERROR,
@@ -1041,45 +1046,45 @@ short insert_keyframe(Depsgraph *depsgraph, ReportList *reports, ID *id, bAction
(id) ? id->name : TIP_("<Missing ID block>"), rna_path);
return 0;
}
-
+
/* if no action is provided, keyframe to the default one attached to this ID-block */
if (act == NULL) {
/* get action to add F-Curve+keyframe to */
- act = verify_adt_action(id, 1);
-
+ act = verify_adt_action(bmain, id, 1);
+
if (act == NULL) {
- BKE_reportf(reports, RPT_ERROR,
+ BKE_reportf(reports, RPT_ERROR,
"Could not insert keyframe, as this type does not support animation data (ID = %s, path = %s)",
id->name, rna_path);
return 0;
}
}
-
+
/* apply NLA-mapping to frame to use (if applicable) */
adt = BKE_animdata_from_id(id);
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
-
+
/* key entire array convenience method */
if (array_index == -1) {
array_index = 0;
array_index_max = RNA_property_array_length(&ptr, prop);
-
+
/* for single properties, increase max_index so that the property itself gets included,
- * but don't do this for standard arrays since that can cause corruption issues
+ * but don't do this for standard arrays since that can cause corruption issues
* (extra unused curves)
*/
if (array_index_max == array_index)
array_index_max++;
}
-
+
/* will only loop once unless the array index was -1 */
for (; array_index < array_index_max; array_index++) {
- /* make sure the F-Curve exists
+ /* make sure the F-Curve exists
* - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
* but still try to get the F-Curve if it exists...
*/
fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, (flag & INSERTKEY_REPLACE) == 0);
-
+
/* we may not have a F-Curve when we're replacing only... */
if (fcu) {
/* set color mode if the F-Curve is new (i.e. without any keyframes) */
@@ -1095,12 +1100,16 @@ short insert_keyframe(Depsgraph *depsgraph, ReportList *reports, ID *id, bAction
fcu->color_mode = FCURVE_COLOR_AUTO_YRGB;
}
}
-
+
/* insert keyframe */
ret += insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, keytype, flag);
}
}
-
+
+ if (ret) {
+ DEG_id_tag_update(&adt->action->id, DEG_TAG_COPY_ON_WRITE);
+ }
+
return ret;
}
@@ -1149,13 +1158,13 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
PropertyRNA *prop;
int array_index_max = array_index + 1;
int ret = 0;
-
+
/* sanity checks */
if (ELEM(NULL, id, adt)) {
BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
return 0;
}
-
+
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
@@ -1164,18 +1173,18 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
id->name, rna_path);
return 0;
}
-
+
/* get F-Curve
* Note: here is one of the places where we don't want new Action + F-Curve added!
* so 'add' var must be 0
*/
if (act == NULL) {
- /* if no action is provided, use the default one attached to this ID-block
+ /* if no action is provided, use the default one attached to this ID-block
* - if it doesn't exist, then we're out of options...
*/
if (adt->action) {
act = adt->action;
-
+
/* apply NLA-mapping to frame to use (if applicable) */
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
}
@@ -1184,20 +1193,20 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
return 0;
}
}
-
+
/* key entire array convenience method */
if (array_index == -1) {
array_index = 0;
array_index_max = RNA_property_array_length(&ptr, prop);
-
+
/* for single properties, increase max_index so that the property itself gets included,
- * but don't do this for standard arrays since that can cause corruption issues
+ * but don't do this for standard arrays since that can cause corruption issues
* (extra unused curves)
*/
if (array_index_max == array_index)
array_index_max++;
}
-
+
/* will only loop once unless the array index was -1 */
for (; array_index < array_index_max; array_index++) {
FCurve *fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, 0);
@@ -1216,7 +1225,7 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
ret += delete_keyframe_fcurve(adt, fcu, cfra);
}
-
+
/* return success/failure */
return ret;
}
@@ -1326,11 +1335,11 @@ static int modify_key_op_poll(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
Scene *scene = CTX_data_scene(C);
-
+
/* if no area or active scene */
- if (ELEM(NULL, sa, scene))
+ if (ELEM(NULL, sa, scene))
return false;
-
+
/* should be fine */
return true;
}
@@ -1346,19 +1355,19 @@ static int insert_key_exec(bContext *C, wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
short success;
-
+
/* type is the Keying Set the user specified to use when calling the operator:
* - type == 0: use scene's active Keying Set
* - type > 0: use a user-defined Keying Set from the active scene
* - type < 0: use a builtin Keying Set
*/
- if (type == 0)
+ if (type == 0)
type = scene->active_keyingset;
if (type > 0)
ks = BLI_findlink(&scene->keyingsets, type - 1);
else
ks = BLI_findlink(&builtin_keyingsets, -type - 1);
-
+
/* report failures */
if (ks == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active keying set");
@@ -1372,12 +1381,12 @@ static int insert_key_exec(bContext *C, wmOperator *op)
ED_object_mode_toggle(C, OB_MODE_EDIT);
ob_edit_mode = true;
}
-
+
/* try to insert keyframes for the channels specified by KeyingSet */
success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
if (G.debug & G_DEBUG)
BKE_reportf(op->reports, RPT_INFO, "Keying set '%s' - successfully added %d keyframes", ks->name, success);
-
+
/* restore the edit mode if necessary */
if (ob_edit_mode) {
ED_object_mode_toggle(C, OB_MODE_EDIT);
@@ -1392,39 +1401,39 @@ static int insert_key_exec(bContext *C, wmOperator *op)
/* if the appropriate properties have been set, make a note that we've inserted something */
if (RNA_boolean_get(op->ptr, "confirm_success"))
BKE_reportf(op->reports, RPT_INFO, "Successfully added %d keyframes for keying set '%s'", success, ks->name);
-
+
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
}
else
BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes");
-
+
return OPERATOR_FINISHED;
}
void ANIM_OT_keyframe_insert(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Insert Keyframe";
ot->idname = "ANIM_OT_keyframe_insert";
ot->description = "Insert keyframes on the current frame for all properties in the specified Keying Set";
-
+
/* callbacks */
- ot->exec = insert_key_exec;
+ ot->exec = insert_key_exec;
ot->poll = modify_key_op_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* keyingset to use (dynamic enum) */
prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
RNA_def_property_flag(prop, PROP_HIDDEN);
ot->prop = prop;
-
- /* confirm whether a keyframe was added by showing a popup
+
+ /* confirm whether a keyframe was added by showing a popup
* - by default, this is enabled, since this operator is assumed to be called independently
*/
prop = RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Insert",
@@ -1433,68 +1442,68 @@ void ANIM_OT_keyframe_insert(wmOperatorType *ot)
}
/* Insert Key Operator (With Menu) ------------------------ */
-/* This operator checks if a menu should be shown for choosing the KeyingSet to use,
+/* This operator checks if a menu should be shown for choosing the KeyingSet to use,
* then calls the menu if necessary before
*/
static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
-
+
/* if prompting or no active Keying Set, show the menu */
if ((scene->active_keyingset == 0) || RNA_boolean_get(op->ptr, "always_prompt")) {
uiPopupMenu *pup;
uiLayout *layout;
-
+
/* call the menu, which will call this operator again, hence the canceled */
pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type");
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
else {
/* just call the exec() on the active keyingset */
RNA_enum_set(op->ptr, "type", 0);
RNA_boolean_set(op->ptr, "confirm_success", true);
-
+
return op->type->exec(C, op);
}
}
-
+
void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Insert Keyframe Menu";
ot->idname = "ANIM_OT_keyframe_insert_menu";
ot->description = "Insert Keyframes for specified Keying Set, with menu of available Keying Sets if undefined";
-
+
/* callbacks */
ot->invoke = insert_key_menu_invoke;
- ot->exec = insert_key_exec;
+ ot->exec = insert_key_exec;
ot->poll = ED_operator_areaactive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* keyingset to use (dynamic enum) */
prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
RNA_def_property_flag(prop, PROP_HIDDEN);
ot->prop = prop;
-
- /* confirm whether a keyframe was added by showing a popup
+
+ /* confirm whether a keyframe was added by showing a popup
* - by default, this is disabled so that if a menu is shown, this doesn't come up too
*/
// XXX should this just be always on?
prop = RNA_def_boolean(ot->srna, "confirm_success", 0, "Confirm Successful Insert",
"Show a popup when the keyframes get successfully added");
RNA_def_property_flag(prop, PROP_HIDDEN);
-
- /* whether the menu should always be shown
+
+ /* whether the menu should always be shown
* - by default, the menu should only be shown when there is no active Keying Set (2.5 behavior),
* although in some cases it might be useful to always shown (pre 2.5 behavior)
*/
@@ -1511,30 +1520,30 @@ static int delete_key_exec(bContext *C, wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
short success;
-
+
/* type is the Keying Set the user specified to use when calling the operator:
* - type == 0: use scene's active Keying Set
* - type > 0: use a user-defined Keying Set from the active scene
* - type < 0: use a builtin Keying Set
*/
- if (type == 0)
+ if (type == 0)
type = scene->active_keyingset;
if (type > 0)
ks = BLI_findlink(&scene->keyingsets, type - 1);
else
ks = BLI_findlink(&builtin_keyingsets, -type - 1);
-
+
/* report failure */
if (ks == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
return OPERATOR_CANCELLED;
}
-
+
/* try to delete keyframes for the channels specified by KeyingSet */
success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
if (G.debug & G_DEBUG)
printf("KeyingSet '%s' - Successfully removed %d Keyframes\n", ks->name, success);
-
+
/* report failure or do updates? */
if (success == MODIFYKEY_INVALID_CONTEXT) {
BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
@@ -1544,39 +1553,39 @@ static int delete_key_exec(bContext *C, wmOperator *op)
/* if the appropriate properties have been set, make a note that we've inserted something */
if (RNA_boolean_get(op->ptr, "confirm_success"))
BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", success, ks->name);
-
+
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
}
else
BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes");
-
+
return OPERATOR_FINISHED;
}
void ANIM_OT_keyframe_delete(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Delete Keying-Set Keyframe";
ot->idname = "ANIM_OT_keyframe_delete";
ot->description = "Delete keyframes on the current frame for all properties in the specified Keying Set";
-
+
/* callbacks */
- ot->exec = delete_key_exec;
+ ot->exec = delete_key_exec;
ot->poll = modify_key_op_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* keyingset to use (dynamic enum) */
prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
RNA_def_property_flag(prop, PROP_HIDDEN);
ot->prop = prop;
-
- /* confirm whether a keyframe was added by showing a popup
+
+ /* confirm whether a keyframe was added by showing a popup
* - by default, this is enabled, since this operator is assumed to be called independently
*/
RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Delete",
@@ -1587,7 +1596,7 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot)
/* NOTE: Although this version is simpler than the more generic version for KeyingSets,
* it is more useful for animators working in the 3D view.
*/
-
+
static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
{
bool changed = false;
@@ -1599,23 +1608,23 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
AnimData *adt = ob->adt;
bAction *act = adt->action;
FCurve *fcu, *fcn;
-
+
for (fcu = act->curves.first; fcu; fcu = fcn) {
bool can_delete = false;
-
+
fcn = fcu->next;
-
+
/* in pose mode, only delete the F-Curve if it belongs to a selected bone */
if (ob->mode & OB_MODE_POSE) {
if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) {
bPoseChannel *pchan;
char *bone_name;
-
+
/* get bone-name, and check if this bone is selected */
bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
if (bone_name) MEM_freeN(bone_name);
-
+
/* delete if bone is selected*/
if ((pchan) && (pchan->bone)) {
if (pchan->bone->flag & BONE_SELECTED)
@@ -1627,7 +1636,7 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
/* object mode - all of Object's F-Curves are affected */
can_delete = true;
}
-
+
/* delete F-Curve completely */
if (can_delete) {
ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
@@ -1645,7 +1654,7 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
/* send updates */
WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1655,13 +1664,13 @@ void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot)
ot->name = "Remove Animation";
ot->description = "Remove all keyframe animation for selected objects";
ot->idname = "ANIM_OT_keyframe_clear_v3d";
-
+
/* callbacks */
ot->invoke = WM_operator_confirm;
- ot->exec = clear_anim_v3d_exec;
-
+ ot->exec = clear_anim_v3d_exec;
+
ot->poll = ED_operator_areaactive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1671,22 +1680,22 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
float cfra = (float)CFRA;
-
+
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
ID *id = &ob->id;
int success = 0;
-
+
/* just those in active action... */
if ((ob->adt) && (ob->adt->action)) {
AnimData *adt = ob->adt;
bAction *act = adt->action;
FCurve *fcu, *fcn;
const float cfra_unmap = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
-
+
for (fcu = act->curves.first; fcu; fcu = fcn) {
fcn = fcu->next;
-
+
/* don't touch protected F-Curves */
if (BKE_fcurve_is_protected(fcu)) {
BKE_reportf(op->reports, RPT_WARNING,
@@ -1694,57 +1703,57 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op)
fcu->rna_path, id->name + 2);
continue;
}
-
+
/* special exception for bones, as this makes this operator more convenient to use
* NOTE: This is only done in pose mode. In object mode, we're dealign with the entire object.
*/
if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) {
bPoseChannel *pchan;
char *bone_name;
-
+
/* get bone-name, and check if this bone is selected */
bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
if (bone_name) MEM_freeN(bone_name);
-
+
/* skip if bone is not selected */
if ((pchan) && (pchan->bone)) {
/* bones are only selected/editable if visible... */
bArmature *arm = (bArmature *)ob->data;
-
+
/* skipping - not visible on currently visible layers */
if ((arm->layer & pchan->bone->layer) == 0)
continue;
/* skipping - is currently hidden */
if (pchan->bone->flag & BONE_HIDDEN_P)
continue;
-
+
/* selection flag... */
if ((pchan->bone->flag & BONE_SELECTED) == 0)
continue;
}
}
-
- /* delete keyframes on current frame
+
+ /* delete keyframes on current frame
* WARNING: this can delete the next F-Curve, hence the "fcn" copying
*/
success += delete_keyframe_fcurve(adt, fcu, cfra_unmap);
}
}
-
+
/* report success (or failure) */
if (success)
BKE_reportf(op->reports, RPT_INFO, "Object '%s' successfully had %d keyframes removed", id->name + 2, success);
else
BKE_reportf(op->reports, RPT_ERROR, "No keyframes removed from Object '%s'", id->name + 2);
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
}
CTX_DATA_END;
-
+
/* send updates */
WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1754,13 +1763,13 @@ void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot)
ot->name = "Delete Keyframe";
ot->description = "Remove keyframes on current frame for selected objects and bones";
ot->idname = "ANIM_OT_keyframe_delete_v3d";
-
+
/* callbacks */
ot->invoke = WM_operator_confirm;
- ot->exec = delete_key_v3d_exec;
-
+ ot->exec = delete_key_v3d_exec;
+
ot->poll = ED_operator_areaactive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1771,6 +1780,7 @@ void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot)
static int insert_key_button_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
PointerRNA ptr = {{NULL}};
@@ -1783,16 +1793,16 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
const bool all = RNA_boolean_get(op->ptr, "all");
eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
-
+
/* flags for inserting keyframes */
flag = ANIM_get_keyframing_flags(scene, 1);
-
+
/* try to insert keyframe using property retrieved from UI */
if (!(but = UI_context_active_but_prop_get(C, &ptr, &prop, &index))) {
/* pass event on if no active button found */
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
-
+
if ((ptr.id.data && ptr.data && prop) && RNA_property_animateable(&ptr, prop)) {
if (ptr.type == &RNA_NlaStrip) {
/* Handle special properties for NLA Strips, whose F-Curves are stored on the
@@ -1801,7 +1811,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
*/
NlaStrip *strip = (NlaStrip *)ptr.data;
FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
-
+
if (fcu) {
success = insert_keyframe_direct(depsgraph, op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, 0);
}
@@ -1814,9 +1824,9 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
/* Driven property - Find driver */
FCurve *fcu;
bool driven, special;
-
+
fcu = rna_get_fcurve_context_ui(C, &ptr, prop, index, NULL, NULL, &driven, &special);
-
+
if (fcu && driven) {
success = insert_keyframe_direct(depsgraph, op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, INSERTKEY_DRIVER);
}
@@ -1824,11 +1834,11 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
else {
/* standard properties */
path = RNA_path_from_ID_to_property(&ptr, prop);
-
+
if (path) {
const char *identifier = RNA_property_identifier(prop);
const char *group = NULL;
-
+
/* Special exception for keyframing transforms:
* Set "group" for this manually, instead of having them appearing at the bottom (ungrouped)
* part of the channels list. Leaving these ungrouped is not a nice user behaviour in this case.
@@ -1847,19 +1857,19 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
*/
group = "Object Transforms";
}
-
-
+
+
if (all) {
/* -1 indicates operating on the entire array (or the property itself otherwise) */
index = -1;
}
-
- success = insert_keyframe(depsgraph, op->reports, ptr.id.data, NULL, group, path, index, cfra, ts->keyframe_type, flag);
-
+
+ success = insert_keyframe(bmain, depsgraph, op->reports, ptr.id.data, NULL, group, path, index, cfra, ts->keyframe_type, flag);
+
MEM_freeN(path);
}
else {
- BKE_report(op->reports, RPT_WARNING,
+ BKE_report(op->reports, RPT_WARNING,
"Failed to resolve path to property, "
"try manually specifying this using a Keying Set instead");
}
@@ -1867,7 +1877,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
}
else {
if (prop && !RNA_property_animateable(&ptr, prop)) {
- BKE_reportf(op->reports, RPT_WARNING,
+ BKE_reportf(op->reports, RPT_WARNING,
"\"%s\" property cannot be animated",
RNA_property_identifier(prop));
}
@@ -1877,15 +1887,15 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
(void *)ptr.data, (void *)prop);
}
}
-
+
if (success) {
/* send updates */
UI_context_update_anim_flag(C);
-
+
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
}
-
+
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1895,11 +1905,11 @@ void ANIM_OT_keyframe_insert_button(wmOperatorType *ot)
ot->name = "Insert Keyframe (Buttons)";
ot->idname = "ANIM_OT_keyframe_insert_button";
ot->description = "Insert a keyframe for current UI-active property";
-
+
/* callbacks */
- ot->exec = insert_key_button_exec;
+ ot->exec = insert_key_button_exec;
ot->poll = modify_key_op_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -1919,7 +1929,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
short success = 0;
int index;
const bool all = RNA_boolean_get(op->ptr, "all");
-
+
/* try to insert keyframe using property retrieved from UI */
if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
/* pass event on if no active button found */
@@ -1935,7 +1945,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
ID *id = ptr.id.data;
NlaStrip *strip = (NlaStrip *)ptr.data;
FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), 0);
-
+
if (fcu) {
if (BKE_fcurve_is_protected(fcu)) {
BKE_reportf(op->reports, RPT_WARNING,
@@ -1949,7 +1959,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
*/
bool found = false;
int i;
-
+
/* try to find index of beztriple to get rid of */
i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
if (found) {
@@ -1963,13 +1973,13 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
else {
/* standard properties */
path = RNA_path_from_ID_to_property(&ptr, prop);
-
+
if (path) {
if (all) {
/* -1 indicates operating on the entire array (or the property itself otherwise) */
index = -1;
}
-
+
success = delete_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index, cfra, 0);
MEM_freeN(path);
}
@@ -1980,16 +1990,16 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
else if (G.debug & G_DEBUG) {
printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
}
-
-
+
+
if (success) {
/* send updates */
UI_context_update_anim_flag(C);
-
+
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
}
-
+
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -1999,11 +2009,11 @@ void ANIM_OT_keyframe_delete_button(wmOperatorType *ot)
ot->name = "Delete Keyframe (Buttons)";
ot->idname = "ANIM_OT_keyframe_delete_button";
ot->description = "Delete current keyframe of current UI-active property";
-
+
/* callbacks */
- ot->exec = delete_key_button_exec;
+ ot->exec = delete_key_button_exec;
ot->poll = modify_key_op_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -2031,13 +2041,13 @@ static int clear_key_button_exec(bContext *C, wmOperator *op)
if (ptr.id.data && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
-
+
if (path) {
if (all) {
/* -1 indicates operating on the entire array (or the property itself otherwise) */
index = -1;
}
-
+
success += clear_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index, 0);
MEM_freeN(path);
}
@@ -2052,7 +2062,7 @@ static int clear_key_button_exec(bContext *C, wmOperator *op)
if (success) {
/* send updates */
UI_context_update_anim_flag(C);
-
+
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
}
@@ -2084,11 +2094,11 @@ void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
bool autokeyframe_cfra_can_key(Scene *scene, ID *id)
{
float cfra = (float)CFRA; // XXX for now, this will do
-
+
/* only filter if auto-key mode requires this */
if (IS_AUTOKEY_ON(scene) == 0)
return false;
-
+
if (IS_AUTOKEY_MODE(scene, EDITKEYS)) {
/* Replace Mode:
* For whole block, only key if there's a keyframe on that frame already
@@ -2103,7 +2113,7 @@ bool autokeyframe_cfra_can_key(Scene *scene, ID *id)
* let's set the "normal" flag too, so that it will all be sane everywhere...
*/
scene->toolsettings->autokey_mode = AUTOKEY_MODE_NORMAL;
-
+
/* Can insert anytime we like... */
return true;
}
@@ -2120,12 +2130,12 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
/* quick sanity check */
if (ELEM(NULL, fcu, fcu->bezt))
return false;
-
+
/* we either include all regardless of muting, or only non-muted */
if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) {
bool replace;
int i = binarysearch_bezt_index(fcu->bezt, frame, fcu->totvert, &replace);
-
+
/* binarysearch_bezt_index will set replace to be 0 or 1
* - obviously, 1 represents a match
*/
@@ -2135,26 +2145,26 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
return true;
}
}
-
+
return false;
}
-/* Checks whether an Action has a keyframe for a given frame
+/* Checks whether an Action has a keyframe for a given frame
* Since we're only concerned whether a keyframe exists, we can simply loop until a match is found...
*/
static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
{
FCurve *fcu;
-
+
/* can only find if there is data */
if (act == NULL)
return false;
-
+
/* if only check non-muted, check if muted */
if ((filter & ANIMFILTER_KEYS_MUTED) || (act->flag & ACT_MUTED))
return false;
-
- /* loop over F-Curves, using binary-search to try to find matches
+
+ /* loop over F-Curves, using binary-search to try to find matches
* - this assumes that keyframes are only beztriples
*/
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
@@ -2164,7 +2174,7 @@ static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
return true;
}
}
-
+
/* nothing found */
return false;
}
@@ -2175,27 +2185,27 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
/* error checking */
if (ob == NULL)
return false;
-
+
/* check own animation data - specifically, the action it contains */
if ((ob->adt) && (ob->adt->action)) {
- /* T41525 - When the active action is a NLA strip being edited,
+ /* T41525 - When the active action is a NLA strip being edited,
* we need to correct the frame number to "look inside" the
* remapped action
*/
float ob_frame = BKE_nla_tweakedit_remap(ob->adt, frame, NLATIME_CONVERT_UNMAP);
-
+
if (action_frame_has_keyframe(ob->adt->action, ob_frame, filter))
return true;
}
-
+
/* try shapekey keyframes (if available, and allowed by filter) */
if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOSKEY)) {
Key *key = BKE_key_from_object(ob);
-
- /* shapekeys can have keyframes ('Relative Shape Keys')
- * or depend on time (old 'Absolute Shape Keys')
+
+ /* shapekeys can have keyframes ('Relative Shape Keys')
+ * or depend on time (old 'Absolute Shape Keys')
*/
-
+
/* 1. test for relative (with keyframes) */
if (id_frame_has_keyframe((ID *)key, frame, filter))
return true;
@@ -2209,24 +2219,24 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
/* if only active, then we can skip a lot of looping */
if (filter & ANIMFILTER_KEYS_ACTIVE) {
Material *ma = give_current_material(ob, (ob->actcol + 1));
-
+
/* we only retrieve the active material... */
if (id_frame_has_keyframe((ID *)ma, frame, filter))
return true;
}
else {
int a;
-
+
/* loop over materials */
for (a = 0; a < ob->totcol; a++) {
Material *ma = give_current_material(ob, a + 1);
-
+
if (id_frame_has_keyframe((ID *)ma, frame, filter))
return true;
}
}
}
-
+
/* nothing found */
return false;
}
@@ -2239,7 +2249,7 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter)
/* sanity checks */
if (id == NULL)
return false;
-
+
/* perform special checks for 'macro' types */
switch (GS(id->name)) {
case ID_OB: /* object */
@@ -2252,15 +2262,15 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter)
default: /* 'normal type' */
{
AnimData *adt = BKE_animdata_from_id(id);
-
+
/* only check keyframes in active action */
if (adt)
return action_frame_has_keyframe(adt->action, frame, filter);
break;
}
}
-
-
+
+
/* no keyframe found */
return false;
}
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 17a527d2cda..5bf23a53819 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -29,7 +29,7 @@
* \ingroup edanimation
*/
-
+
#include <stdio.h>
#include <stddef.h>
#include <string.h>
@@ -84,10 +84,10 @@ static int keyingset_poll_default_add(bContext *C)
static int keyingset_poll_active_edit(bContext *C)
{
Scene *scene = CTX_data_scene(C);
-
+
if (scene == NULL)
return 0;
-
+
/* there must be an active KeyingSet (and KeyingSets) */
return ((scene->active_keyingset > 0) && (scene->keyingsets.first));
}
@@ -97,42 +97,42 @@ static int keyingset_poll_activePath_edit(bContext *C)
{
Scene *scene = CTX_data_scene(C);
KeyingSet *ks;
-
+
if (scene == NULL)
return 0;
if (scene->active_keyingset <= 0)
return 0;
else
ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
+
/* there must be an active KeyingSet and an active path */
return ((ks) && (ks->paths.first) && (ks->active_path > 0));
}
-
+
/* Add a Default (Empty) Keying Set ------------------------- */
static int add_default_keyingset_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
short flag = 0, keyingflag = 0;
-
- /* validate flags
+
+ /* validate flags
* - absolute KeyingSets should be created by default
*/
flag |= KEYINGSET_ABSOLUTE;
-
+
/* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
keyingflag = ANIM_get_keyframing_flags(scene, 0);
-
+
/* call the API func, and set the active keyingset index */
BKE_keyingset_add(&scene->keyingsets, NULL, NULL, flag, keyingflag);
-
+
scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -142,7 +142,7 @@ void ANIM_OT_keying_set_add(wmOperatorType *ot)
ot->name = "Add Empty Keying Set";
ot->idname = "ANIM_OT_keying_set_add";
ot->description = "Add a new (empty) Keying Set to the active Scene";
-
+
/* callbacks */
ot->exec = add_default_keyingset_exec;
ot->poll = keyingset_poll_default_add;
@@ -154,7 +154,7 @@ static int remove_active_keyingset_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
KeyingSet *ks;
-
+
/* verify the Keying Set to use:
* - use the active one
* - return error if it doesn't exist
@@ -169,17 +169,17 @@ static int remove_active_keyingset_exec(bContext *C, wmOperator *op)
}
else
ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
+
/* free KeyingSet's data, then remove it from the scene */
BKE_keyingset_free(ks);
BLI_freelinkN(&scene->keyingsets, ks);
-
+
/* the active one should now be the previously second-to-last one */
scene->active_keyingset--;
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -189,7 +189,7 @@ void ANIM_OT_keying_set_remove(wmOperatorType *ot)
ot->name = "Remove Active Keying Set";
ot->idname = "ANIM_OT_keying_set_remove";
ot->description = "Remove the active Keying Set";
-
+
/* callbacks */
ot->exec = remove_active_keyingset_exec;
ot->poll = keyingset_poll_active_edit;
@@ -202,7 +202,7 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
KeyingSet *ks;
KS_Path *ksp;
-
+
/* verify the Keying Set to use:
* - use the active one
* - return error if it doesn't exist
@@ -213,16 +213,16 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op)
}
else
ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
+
/* don't use the API method for this, since that checks on values... */
ksp = MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
BLI_addtail(&ks->paths, ksp);
ks->active_path = BLI_listbase_count(&ks->paths);
-
+
ksp->groupmode = KSP_GROUP_KSNAME; // XXX?
ksp->idtype = ID_OB;
ksp->flag = KSP_FLAG_WHOLE_ARRAY;
-
+
return OPERATOR_FINISHED;
}
@@ -232,7 +232,7 @@ void ANIM_OT_keying_set_path_add(wmOperatorType *ot)
ot->name = "Add Empty Keying Set Path";
ot->idname = "ANIM_OT_keying_set_path_add";
ot->description = "Add empty path to active Keying Set";
-
+
/* callbacks */
ot->exec = add_empty_ks_path_exec;
ot->poll = keyingset_poll_active_edit;
@@ -244,15 +244,15 @@ static int remove_active_ks_path_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
KeyingSet *ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
+
/* if there is a KeyingSet, find the nominated path to remove */
if (ks) {
KS_Path *ksp = BLI_findlink(&ks->paths, ks->active_path - 1);
-
+
if (ksp) {
/* remove the active path from the KeyingSet */
BKE_keyingset_free_path(ks, ksp);
-
+
/* the active path should now be the previously second-to-last active one */
ks->active_path--;
}
@@ -265,7 +265,7 @@ static int remove_active_ks_path_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active keying set to remove a path from");
return OPERATOR_CANCELLED;
}
-
+
return OPERATOR_FINISHED;
}
@@ -275,7 +275,7 @@ void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
ot->name = "Remove Active Keying Set Path";
ot->idname = "ANIM_OT_keying_set_path_remove";
ot->description = "Remove active Path from active Keying Set";
-
+
/* callbacks */
ot->exec = remove_active_ks_path_exec;
ot->poll = keyingset_poll_activePath_edit;
@@ -296,33 +296,33 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
short success = 0;
int index = 0, pflag = 0;
const bool all = RNA_boolean_get(op->ptr, "all");
-
+
/* try to add to keyingset using property retrieved from UI */
if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
/* pass event on if no active button found */
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
-
+
/* verify the Keying Set to use:
* - use the active one for now (more control over this can be added later)
- * - add a new one if it doesn't exist
+ * - add a new one if it doesn't exist
*/
if (scene->active_keyingset == 0) {
short flag = 0, keyingflag = 0;
-
- /* validate flags
+
+ /* validate flags
* - absolute KeyingSets should be created by default
*/
flag |= KEYINGSET_ABSOLUTE;
-
+
keyingflag |= ANIM_get_keyframing_flags(scene, 0);
-
- if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
+
+ if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
keyingflag |= INSERTKEY_XYZ2RGB;
-
+
/* call the API func, and set the active keyingset index */
ks = BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", "Button Keying Set", flag, keyingflag);
-
+
scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
}
else if (scene->active_keyingset < 0) {
@@ -332,41 +332,41 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
else {
ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
}
-
+
/* check if property is able to be added */
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
path = RNA_path_from_ID_to_property(&ptr, prop);
-
+
if (path) {
/* set flags */
if (all) {
pflag |= KSP_FLAG_WHOLE_ARRAY;
-
- /* we need to set the index for this to 0, even though it may break in some cases, this is
+
+ /* we need to set the index for this to 0, even though it may break in some cases, this is
* necessary if we want the entire array for most cases to get included without the user
* having to worry about where they clicked
*/
index = 0;
}
-
+
/* add path to this setting */
BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
ks->active_path = BLI_listbase_count(&ks->paths);
success = 1;
-
+
/* free the temp path created */
MEM_freeN(path);
}
}
-
+
if (success) {
/* send updates */
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
+
/* show notification/report header, so that users notice that something changed */
BKE_reportf(op->reports, RPT_INFO, "Property added to Keying Set: '%s'", ks->name);
}
-
+
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -376,11 +376,11 @@ void ANIM_OT_keyingset_button_add(wmOperatorType *ot)
ot->name = "Add to Keying Set";
ot->idname = "ANIM_OT_keyingset_button_add";
ot->description = "Add current UI-active property to current keying set";
-
+
/* callbacks */
- ot->exec = add_keyingset_button_exec;
+ ot->exec = add_keyingset_button_exec;
//op->poll = ???
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -399,13 +399,13 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
char *path = NULL;
short success = 0;
int index = 0;
-
+
/* try to add to keyingset using property retrieved from UI */
if (UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
/* pass event on if no active button found */
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
-
+
/* verify the Keying Set to use:
* - use the active one for now (more control over this can be added later)
* - return error if it doesn't exist
@@ -421,35 +421,35 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
else {
ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
}
-
+
if (ptr.id.data && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
-
+
if (path) {
KS_Path *ksp;
-
+
/* try to find a path matching this description */
ksp = BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
-
+
if (ksp) {
BKE_keyingset_free_path(ks, ksp);
success = 1;
}
-
+
/* free temp path used */
MEM_freeN(path);
}
}
-
-
+
+
if (success) {
/* send updates */
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
+
/* show warning */
BKE_report(op->reports, RPT_INFO, "Property removed from Keying Set");
}
-
+
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
@@ -459,11 +459,11 @@ void ANIM_OT_keyingset_button_remove(wmOperatorType *ot)
ot->name = "Remove from Keying Set";
ot->idname = "ANIM_OT_keyingset_button_remove";
ot->description = "Remove current UI-active property from current keying set";
-
+
/* callbacks */
- ot->exec = remove_keyingset_button_exec;
+ ot->exec = remove_keyingset_button_exec;
//op->poll = ???
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -477,13 +477,13 @@ static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, const wmEve
{
uiPopupMenu *pup;
uiLayout *layout;
-
+
/* call the menu, which will call this operator again, hence the canceled */
pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, "ANIM_OT_keying_set_active_set", "type");
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -491,33 +491,33 @@ static int keyingset_active_menu_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
int type = RNA_enum_get(op->ptr, "type");
-
+
/* If type == 0, it will deselect any active keying set. */
scene->active_keyingset = type;
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ANIM_OT_keying_set_active_set(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Set Active Keying Set";
ot->idname = "ANIM_OT_keying_set_active_set";
ot->description = "Select a new keying set as the active one";
-
+
/* callbacks */
ot->invoke = keyingset_active_menu_invoke;
- ot->exec = keyingset_active_menu_exec;
+ ot->exec = keyingset_active_menu_exec;
ot->poll = ED_operator_areaactive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* keyingset to use (dynamic enum) */
prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
@@ -541,7 +541,7 @@ KeyingSetInfo *ANIM_keyingset_info_find_name(const char name[])
/* sanity checks */
if ((name == NULL) || (name[0] == 0))
return NULL;
-
+
/* search by comparing names */
return BLI_findstring(&keyingset_type_infos, name, offsetof(KeyingSetInfo, idname));
}
@@ -550,17 +550,17 @@ KeyingSetInfo *ANIM_keyingset_info_find_name(const char name[])
KeyingSet *ANIM_builtin_keyingset_get_named(KeyingSet *prevKS, const char name[])
{
KeyingSet *ks, *first = NULL;
-
+
/* sanity checks any name to check? */
if (name[0] == 0)
return NULL;
-
+
/* get first KeyingSet to use */
if (prevKS && prevKS->next)
first = prevKS->next;
else
first = builtin_keyingsets.first;
-
+
/* loop over KeyingSets checking names */
for (ks = first; ks; ks = ks->next) {
if (STREQ(name, ks->idname))
@@ -582,18 +582,18 @@ KeyingSet *ANIM_builtin_keyingset_get_named(KeyingSet *prevKS, const char name[]
void ANIM_keyingset_info_register(KeyingSetInfo *ksi)
{
KeyingSet *ks;
-
- /* create a new KeyingSet
+
+ /* create a new KeyingSet
* - inherit name and keyframing settings from the typeinfo
*/
ks = BKE_keyingset_add(&builtin_keyingsets, ksi->idname, ksi->name, 1, ksi->keyingflag);
-
+
/* link this KeyingSet with its typeinfo */
memcpy(&ks->typeinfo, ksi->idname, sizeof(ks->typeinfo));
-
+
/* Copy description... */
BLI_strncpy(ks->description, ksi->description, sizeof(ks->description));
-
+
/* add type-info to the list */
BLI_addtail(&keyingset_type_infos, ksi);
}
@@ -621,7 +621,7 @@ void ANIM_keyingset_info_unregister(Main *bmain, KeyingSetInfo *ksi)
MEM_freeN(ks);
}
}
-
+
/* free the type info */
BLI_freelinkN(&keyingset_type_infos, ksi);
}
@@ -631,17 +631,17 @@ void ANIM_keyingset_info_unregister(Main *bmain, KeyingSetInfo *ksi)
void ANIM_keyingset_infos_exit(void)
{
KeyingSetInfo *ksi, *next;
-
+
/* free type infos */
for (ksi = keyingset_type_infos.first; ksi; ksi = next) {
next = ksi->next;
-
+
/* free extra RNA data, and remove from list */
if (ksi->ext.free)
ksi->ext.free(ksi->ext.data);
BLI_freelinkN(&keyingset_type_infos, ksi);
}
-
+
/* free builtin sets */
BKE_keyingsets_free(&builtin_keyingsets);
}
@@ -667,7 +667,7 @@ KeyingSet *ANIM_scene_get_active_keyingset(Scene *scene)
/* if no scene, we've got no hope of finding the Keying Set */
if (scene == NULL)
return NULL;
-
+
/* currently, there are several possibilities here:
* - 0: no active keying set
* - > 0: one of the user-defined Keying Sets, but indices start from 0 (hence the -1)
@@ -683,22 +683,22 @@ KeyingSet *ANIM_scene_get_active_keyingset(Scene *scene)
int ANIM_scene_get_keyingset_index(Scene *scene, KeyingSet *ks)
{
int index;
-
+
/* if no KeyingSet provided, have none */
if (ks == NULL)
return 0;
-
+
/* check if the KeyingSet exists in scene list */
if (scene) {
- /* get index and if valid, return
+ /* get index and if valid, return
* - (absolute) Scene KeyingSets are from (>= 1)
*/
index = BLI_findindex(&scene->keyingsets, ks);
if (index != -1)
return (index + 1);
}
-
- /* still here, so try builtins list too
+
+ /* still here, so try builtins list too
* - builtins are from (<= -1)
* - none/invalid is (= 0)
*/
@@ -712,15 +712,15 @@ int ANIM_scene_get_keyingset_index(Scene *scene, KeyingSet *ks)
/* Get Keying Set to use for Auto-Keyframing some transforms */
KeyingSet *ANIM_get_keyingset_for_autokeying(Scene *scene, const char *tranformKSName)
{
- /* get KeyingSet to use
- * - use the active KeyingSet if defined (and user wants to use it for all autokeying),
+ /* get KeyingSet to use
+ * - use the active KeyingSet if defined (and user wants to use it for all autokeying),
* or otherwise key transforms only
*/
if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (scene->active_keyingset))
return ANIM_scene_get_active_keyingset(scene);
else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL))
return ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_AVAILABLE_ID);
- else
+ else
return ANIM_builtin_keyingset_get_named(NULL, tranformKSName);
}
@@ -738,8 +738,8 @@ const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *UNU
if (C == NULL) {
return DummyRNA_DEFAULT_items;
}
-
- /* active Keying Set
+
+ /* active Keying Set
* - only include entry if it exists
*/
if (scene->active_keyingset) {
@@ -748,14 +748,14 @@ const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *UNU
item_tmp.name = "Active Keying Set";
item_tmp.value = i;
RNA_enum_item_add(&item, &totitem, &item_tmp);
-
+
/* separator */
RNA_enum_item_add_separator(&item, &totitem);
}
-
+
i++;
-
- /* user-defined Keying Sets
+
+ /* user-defined Keying Sets
* - these are listed in the order in which they were defined for the active scene
*/
if (scene->keyingsets.first) {
@@ -768,11 +768,11 @@ const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *UNU
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
}
-
+
/* separator */
RNA_enum_item_add_separator(&item, &totitem);
}
-
+
/* builtin Keying Sets */
i = -1;
for (ks = builtin_keyingsets.first; ks; ks = ks->next, i--) {
@@ -802,7 +802,7 @@ bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
{
if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
-
+
/* get the associated 'type info' for this KeyingSet */
if (ksi == NULL)
return 0;
@@ -811,13 +811,13 @@ bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
/* check if it can be used in the current context */
return (ksi->poll(ksi, C));
}
-
+
return true;
}
/* Special 'Overrides' Iterator for Relative KeyingSets ------ */
-/* 'Data Sources' for relative Keying Set 'overrides'
+/* 'Data Sources' for relative Keying Set 'overrides'
* - this is basically a wrapper for PointerRNA's in a linked list
* - do not allow this to be accessed from outside for now
*/
@@ -827,14 +827,14 @@ typedef struct tRKS_DSource {
} tRKS_DSource;
-/* Iterator used for overriding the behavior of iterators defined for
+/* Iterator used for overriding the behavior of iterators defined for
* relative Keying Sets, with the main usage of this being operators
* requiring Auto Keyframing. Internal Use Only!
*/
static void RKS_ITER_overrides_list(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks, ListBase *dsources)
{
tRKS_DSource *ds;
-
+
for (ds = dsources->first; ds; ds = ds->next) {
/* run generate callback on this data */
ksi->generate(ksi, C, ks, &ds->ptr);
@@ -845,8 +845,8 @@ static void RKS_ITER_overrides_list(KeyingSetInfo *ksi, bContext *C, KeyingSet *
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
{
tRKS_DSource *ds;
-
- /* sanity checks
+
+ /* sanity checks
* - we must have somewhere to output the data
* - we must have both srna+data (and with id too optionally), or id by itself only
*/
@@ -854,11 +854,11 @@ void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *s
return;
if (ELEM(NULL, srna, data) && (id == NULL))
return;
-
+
/* allocate new elem, and add to the list */
ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
BLI_addtail(dsources, ds);
-
+
/* depending on what data we have, create using ID or full pointer call */
if (srna && data)
RNA_pointer_create(id, srna, data, &ds->ptr);
@@ -880,31 +880,31 @@ short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
/* sanity check */
if (ks == NULL)
return 0;
-
+
/* if relative Keying Sets, poll and build up the paths */
if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
-
- /* clear all existing paths
+
+ /* clear all existing paths
* NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
*/
BKE_keyingset_free(ks);
-
+
/* get the associated 'type info' for this KeyingSet */
if (ksi == NULL)
return MODIFYKEY_MISSING_TYPEINFO;
/* TODO: check for missing callbacks! */
-
+
/* check if it can be used in the current context */
if (ksi->poll(ksi, C)) {
/* if a list of data sources are provided, run a special iterator over them,
* otherwise, just continue per normal
*/
- if (dsources)
+ if (dsources)
RKS_ITER_overrides_list(ksi, C, ks, dsources);
else
ksi->iter(ksi, C, ks);
-
+
/* if we don't have any paths now, then this still qualifies as invalid context */
// FIXME: we need some error conditions (to be retrieved from the iterator why this failed!)
if (BLI_listbase_is_empty(&ks->paths))
@@ -916,16 +916,16 @@ short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
return MODIFYKEY_INVALID_CONTEXT;
}
}
-
+
/* succeeded; return 0 to tag error free */
return 0;
-}
+}
/* Determine which keying flags apply based on the override flags */
static short keyingset_apply_keying_flags(const short base_flags, const short overrides, const short own_flags)
{
short result = 0;
-
+
/* The logic for whether a keying flag applies is as follows:
* - If the flag in question is set in "overrides", that means that the
* status of that flag in "own_flags" is used
@@ -939,14 +939,14 @@ static short keyingset_apply_keying_flags(const short base_flags, const short ov
else { \
result |= (base_flags & kflag); \
}
-
- /* Apply the flags one by one...
+
+ /* Apply the flags one by one...
* (See rna_def_common_keying_flags() for the supported flags)
*/
APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_NEEDED)
APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_MATRIX)
APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_XYZ2RGB)
-
+
#undef APPLY_KEYINGFLAG_OVERRIDE
return result;
@@ -959,6 +959,7 @@ static short keyingset_apply_keying_flags(const short base_flags, const short ov
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ReportList *reports = CTX_wm_reports(C);
KS_Path *ksp;
@@ -966,11 +967,11 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
const char *groupname = NULL;
short kflag = 0, success = 0;
char keytype = scene->toolsettings->keyframe_type;
-
+
/* sanity checks */
if (ks == NULL)
return 0;
-
+
/* get flags to use */
if (mode == MODIFYKEY_MODE_INSERT) {
/* use context settings as base */
@@ -978,20 +979,20 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
}
else if (mode == MODIFYKEY_MODE_DELETE)
kflag = 0;
-
+
/* if relative Keying Sets, poll and build up the paths */
success = ANIM_validate_keyingset(C, dsources, ks);
-
+
if (success != 0) {
/* return error code if failed */
return success;
}
-
+
/* apply the paths as specified in the KeyingSet now */
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
int arraylen, i;
short kflag2;
-
+
/* skip path if no ID pointer is specified */
if (ksp->id == NULL) {
BKE_reportf(reports, RPT_WARNING,
@@ -999,10 +1000,10 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
ks->name, ksp->rna_path, ksp->array_index);
continue;
}
-
+
/* since keying settings can be defined on the paths too, apply the settings for this path first */
kflag2 = keyingset_apply_keying_flags(kflag, ksp->keyingoverride, ksp->keyingflag);
-
+
/* get pointer to name of group to add channels to */
if (ksp->groupmode == KSP_GROUP_NONE)
groupname = NULL;
@@ -1010,59 +1011,59 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
groupname = ks->name;
else
groupname = ksp->group;
-
+
/* init arraylen and i - arraylen should be greater than i so that
* normal non-array entries get keyframed correctly
*/
i = ksp->array_index;
arraylen = i;
-
+
/* get length of array if whole array option is enabled */
if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
-
+
RNA_id_pointer_create(ksp->id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, ksp->rna_path, &ptr, &prop)) {
arraylen = RNA_property_array_length(&ptr, prop);
i = 0; /* start from start of array, instead of the previously specified index - T48020 */
}
}
-
+
/* we should do at least one step */
if (arraylen == i)
arraylen++;
-
- /* for each possible index, perform operation
+
+ /* for each possible index, perform operation
* - assume that arraylen is greater than index
*/
for (; i < arraylen; i++) {
/* action to take depends on mode */
if (mode == MODIFYKEY_MODE_INSERT)
- success += insert_keyframe(depsgraph, reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, keytype, kflag2);
+ success += insert_keyframe(bmain, depsgraph, reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, keytype, kflag2);
else if (mode == MODIFYKEY_MODE_DELETE)
success += delete_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
}
-
+
/* set recalc-flags */
switch (GS(ksp->id->name)) {
case ID_OB: /* Object (or Object-Related) Keyframes */
{
Object *ob = (Object *)ksp->id;
-
+
// XXX: only object transforms?
- DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
break;
}
default:
DEG_id_tag_update(ksp->id, DEG_TAG_COPY_ON_WRITE);
break;
}
-
+
/* send notifiers for updates (this doesn't require context to work!) */
WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
}
-
+
/* return the number of channels successfully affected */
return success;
}
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index d80d3d6964c..c1fb1dcf82f 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -66,12 +66,12 @@
EditBone *ED_armature_ebone_add(bArmature *arm, const char *name)
{
EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone");
-
+
BLI_strncpy(bone->name, name, sizeof(bone->name));
ED_armature_ebone_unique_name(arm->edbo, bone->name, NULL);
-
+
BLI_addtail(arm->edbo, bone);
-
+
bone->flag |= BONE_TIPSEL;
bone->weight = 1.0f;
bone->dist = 0.25f;
@@ -81,7 +81,7 @@ EditBone *ED_armature_ebone_add(bArmature *arm, const char *name)
bone->rad_tail = 0.05f;
bone->segments = 1;
bone->layer = arm->layer;
-
+
/* Bendy-Bone parameters */
bone->roll1 = 0.0f;
bone->roll2 = 0.0f;
@@ -103,7 +103,7 @@ EditBone *ED_armature_ebone_add_primitive(Object *obedit_arm, float length, bool
EditBone *bone;
ED_armature_edit_deselect_all(obedit_arm);
-
+
/* Create a bone */
bone = ED_armature_ebone_add(arm, "Bone");
@@ -134,7 +134,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
v3d = CTX_wm_view3d(C);
obedit = CTX_data_edit_object(C);
arm = obedit->data;
-
+
/* find the active or selected bone */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone)) {
@@ -142,7 +142,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
if (ebone == NULL) {
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone)) {
@@ -150,14 +150,14 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
- if (ebone == NULL)
+ if (ebone == NULL)
return OPERATOR_CANCELLED;
-
+
to_root = 1;
}
-
+
ED_armature_edit_deselect_all(obedit);
-
+
/* we re-use code for mirror editing... */
flipbone = NULL;
if (arm->flag & ARM_MIRROR_EDIT)
@@ -171,10 +171,10 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
SWAP(EditBone *, flipbone, ebone);
}
}
-
+
newbone = ED_armature_ebone_add(arm, ebone->name);
arm->act_edbone = newbone;
-
+
if (to_root) {
copy_v3_v3(newbone->head, ebone->head);
newbone->rad_head = ebone->rad_tail;
@@ -186,28 +186,28 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
newbone->parent = ebone;
newbone->flag |= BONE_CONNECTED;
}
-
+
const View3DCursor *curs = ED_view3d_cursor3d_get(scene, v3d);
copy_v3_v3(newbone->tail, curs->location);
sub_v3_v3v3(newbone->tail, newbone->tail, obedit->obmat[3]);
-
+
if (a == 1)
newbone->tail[0] = -newbone->tail[0];
-
+
copy_m3_m4(mat, obedit->obmat);
invert_m3_m3(imat, mat);
mul_m3_v3(imat, newbone->tail);
-
+
newbone->length = len_v3v3(newbone->head, newbone->tail);
newbone->rad_tail = newbone->length * 0.05f;
newbone->dist = newbone->length * 0.25f;
-
+
}
-
+
ED_armature_edit_sync_selection(arm->edbo);
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
-
+
return OPERATOR_FINISHED;
}
@@ -226,9 +226,9 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEv
scene = CTX_data_scene(C);
ar = CTX_wm_region(C);
v3d = CTX_wm_view3d(C);
-
+
View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d);
-
+
copy_v3_v3(oldcurs, cursor->location);
VECCOPY2D(mval_f, event->mval);
@@ -250,12 +250,12 @@ void ARMATURE_OT_click_extrude(wmOperatorType *ot)
ot->name = "Click-Extrude";
ot->idname = "ARMATURE_OT_click_extrude";
ot->description = "Create a new bone going from the last selected joint to the mouse position";
-
+
/* api callbacks */
ot->invoke = armature_click_extrude_invoke;
ot->exec = armature_click_extrude_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -266,12 +266,12 @@ void ARMATURE_OT_click_extrude(wmOperatorType *ot)
EditBone *add_points_bone(Object *obedit, float head[3], float tail[3])
{
EditBone *ebo;
-
+
ebo = ED_armature_ebone_add(obedit->data, "Bone");
-
+
copy_v3_v3(ebo->head, head);
copy_v3_v3(ebo->tail, tail);
-
+
return ebo;
}
@@ -377,7 +377,7 @@ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Obj
bPoseChannel *pchan;
bConstraint *curcon;
ListBase *conlist;
-
+
if ((pchan = BKE_pose_channel_verify(dst_ob->pose, dupBone->name))) {
if ((conlist = &pchan->constraints)) {
for (curcon = conlist->first; curcon; curcon = curcon->next) {
@@ -387,17 +387,17 @@ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Obj
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
-
+
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(curcon, &targets);
-
+
for (ct = targets.first; ct; ct = ct->next) {
if ((ct->tar == src_ob) && (ct->subtarget[0])) {
- ct->tar = dst_ob; /* update target */
+ ct->tar = dst_ob; /* update target */
oldtarget = get_named_editbone(editbones, ct->subtarget);
if (oldtarget) {
/* was the subtarget bone duplicated too? If
- * so, update the constraint to point at the
+ * so, update the constraint to point at the
* duplicate of the old subtarget.
*/
if (oldtarget->temp.ebone) {
@@ -407,7 +407,7 @@ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Obj
}
}
}
-
+
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(curcon, &targets, 0);
}
@@ -426,20 +426,20 @@ EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase
Object *src_ob, Object *dst_ob)
{
EditBone *eBone = MEM_mallocN(sizeof(EditBone), "addup_editbone");
-
+
/* Copy data from old bone to new bone */
memcpy(eBone, curBone, sizeof(EditBone));
-
+
curBone->temp.ebone = eBone;
eBone->temp.ebone = curBone;
-
+
if (name != NULL) {
BLI_strncpy(eBone->name, name, sizeof(eBone->name));
}
ED_armature_ebone_unique_name(editbones, eBone->name, NULL);
BLI_addtail(editbones, eBone);
-
+
/* copy the ID property */
if (curBone->prop)
eBone->prop = IDP_CopyProperty(curBone->prop);
@@ -449,7 +449,7 @@ EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase
*/
if (src_ob->pose) {
bPoseChannel *chanold, *channew;
-
+
chanold = BKE_pose_channel_verify(src_ob->pose, curBone->name);
if (chanold) {
/* WARNING: this creates a new posechannel, but there will not be an attached bone
@@ -462,7 +462,7 @@ EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase
}
}
}
-
+
return eBone;
}
@@ -506,7 +506,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
}
}
-
+
/* Find the selected bones and duplicate them as needed */
for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe; ebone_iter = ebone_iter->next) {
if (EBONE_VISIBLE(arm, ebone_iter) &&
@@ -567,7 +567,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
updateDuplicateSubtarget(ebone, arm->edbo, obedit);
}
}
-
+
/* correct the active bone */
if (arm->act_edbone && arm->act_edbone->temp.ebone) {
arm->act_edbone = arm->act_edbone->temp.ebone;
@@ -585,7 +585,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
ED_armature_edit_validate_active(arm);
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
-
+
return OPERATOR_FINISHED;
}
@@ -596,11 +596,11 @@ void ARMATURE_OT_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Selected Bone(s)";
ot->idname = "ARMATURE_OT_duplicate";
ot->description = "Make copies of the selected bones within the same armature";
-
+
/* api callbacks */
ot->exec = armature_duplicate_selected_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -846,7 +846,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* Duplicate the necessary bones */
for (ebone = arm->edbo->first; ((ebone) && (ebone != first)); ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone)) {
@@ -864,7 +864,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
do_extrude = 2;
}
}
-
+
if (do_extrude) {
/* we re-use code for mirror editing... */
flipbone = NULL;
@@ -879,7 +879,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
if ((flipbone == NULL) && (forked))
flipbone = ebone;
}
-
+
for (a = 0; a < 2; a++) {
if (a == 1) {
if (flipbone == NULL)
@@ -888,31 +888,31 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
SWAP(EditBone *, flipbone, ebone);
}
}
-
+
totbone++;
newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
-
+
if (do_extrude == true) {
copy_v3_v3(newbone->head, ebone->tail);
copy_v3_v3(newbone->tail, newbone->head);
newbone->parent = ebone;
-
+
newbone->flag = ebone->flag & (BONE_TIPSEL | BONE_RELATIVE_PARENTING); // copies it, in case mirrored bone
-
+
if (newbone->parent) newbone->flag |= BONE_CONNECTED;
}
else {
copy_v3_v3(newbone->head, ebone->head);
copy_v3_v3(newbone->tail, ebone->head);
newbone->parent = ebone->parent;
-
+
newbone->flag = BONE_TIPSEL;
-
+
if (newbone->parent && (ebone->flag & BONE_CONNECTED)) {
newbone->flag |= BONE_CONNECTED;
}
}
-
+
newbone->weight = ebone->weight;
newbone->dist = ebone->dist;
newbone->xwidth = ebone->xwidth;
@@ -921,7 +921,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
newbone->rad_tail = ebone->rad_tail;
newbone->segments = 1;
newbone->layer = ebone->layer;
-
+
/* Bendy-Bone parameters */
newbone->roll1 = ebone->roll1;
newbone->roll2 = ebone->roll2;
@@ -936,7 +936,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
BLI_strncpy(newbone->name, ebone->name, sizeof(newbone->name));
-
+
if (flipbone && forked) { // only set if mirror edit
if (strlen(newbone->name) < (MAXBONENAME - 2)) {
if (a == 0) strcat(newbone->name, "_L");
@@ -944,18 +944,18 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
}
}
ED_armature_ebone_unique_name(arm->edbo, newbone->name, NULL);
-
+
/* Add the new bone to the list */
BLI_addtail(arm->edbo, newbone);
if (!first)
first = newbone;
-
+
/* restore ebone if we were flipping */
if (a == 1 && flipbone)
SWAP(EditBone *, flipbone, ebone);
}
}
-
+
/* Deselect the old bone */
ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
}
@@ -986,14 +986,14 @@ void ARMATURE_OT_extrude(wmOperatorType *ot)
ot->name = "Extrude";
ot->idname = "ARMATURE_OT_extrude";
ot->description = "Create new bones from the selected joints";
-
+
/* api callbacks */
ot->exec = armature_extrude_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_boolean(ot->srna, "forked", 0, "Forked", "");
}
@@ -1002,16 +1002,16 @@ void ARMATURE_OT_extrude(wmOperatorType *ot)
/*op makes a new bone and returns it with its tip selected */
-static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
+static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
Object *obedit = CTX_data_edit_object(C);
EditBone *bone;
float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3];
char name[MAXBONENAME];
-
+
RNA_string_get(op->ptr, "name", name);
-
+
copy_v3_v3(curs, ED_view3d_cursor3d_get(CTX_data_scene(C), CTX_wm_view3d(C))->location);
/* Get inverse point for head and orientation for tail */
@@ -1021,18 +1021,18 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
if (rv3d && (U.flag & USER_ADD_VIEWALIGNED))
copy_m3_m4(obmat, rv3d->viewmat);
else unit_m3(obmat);
-
+
copy_m3_m4(viewmat, obedit->obmat);
mul_m3_m3m3(totmat, obmat, viewmat);
invert_m3_m3(imat, totmat);
-
+
ED_armature_edit_deselect_all(obedit);
-
+
/* Create a bone */
bone = ED_armature_ebone_add(obedit->data, name);
copy_v3_v3(bone->head, curs);
-
+
if (rv3d && (U.flag & USER_ADD_VIEWALIGNED))
add_v3_v3v3(bone->tail, bone->head, imat[1]); // bone with unit length 1
else
@@ -1050,16 +1050,16 @@ void ARMATURE_OT_bone_primitive_add(wmOperatorType *ot)
ot->name = "Add Bone";
ot->idname = "ARMATURE_OT_bone_primitive_add";
ot->description = "Add a new bone located at the 3D-Cursor";
-
+
/* api callbacks */
ot->exec = armature_bone_primitive_add_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_string(ot->srna, "name", "Bone", MAXBONENAME, "Name", "Name of the newly created bone");
-
+
}
/* ********************** Subdivide *******************************/
@@ -1075,10 +1075,10 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
EditBone *newbone, *tbone;
int cuts, i;
-
+
/* there may not be a number_cuts property defined (for 'simple' subdivide) */
cuts = RNA_int_get(op->ptr, "number_cuts");
-
+
/* loop over all editable bones */
// XXX the old code did this in reverse order though!
CTX_DATA_BEGIN_WITH_ID(C, EditBone *, ebone, selected_editable_bones, bArmature *, arm)
@@ -1087,37 +1087,37 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op)
/* compute cut ratio first */
float cutratio = 1.0f / (float)i;
float cutratioI = 1.0f - cutratio;
-
+
float val1[3];
float val2[3];
float val3[3];
-
+
newbone = MEM_mallocN(sizeof(EditBone), "ebone subdiv");
*newbone = *ebone;
BLI_addtail(arm->edbo, newbone);
-
+
/* calculate location of newbone->head */
copy_v3_v3(val1, ebone->head);
copy_v3_v3(val2, ebone->tail);
copy_v3_v3(val3, newbone->head);
-
+
val3[0] = val1[0] * cutratio + val2[0] * cutratioI;
val3[1] = val1[1] * cutratio + val2[1] * cutratioI;
val3[2] = val1[2] * cutratio + val2[2] * cutratioI;
-
+
copy_v3_v3(newbone->head, val3);
copy_v3_v3(newbone->tail, ebone->tail);
copy_v3_v3(ebone->tail, newbone->head);
-
+
newbone->rad_head = ((ebone->rad_head * cutratio) + (ebone->rad_tail * cutratioI));
ebone->rad_tail = newbone->rad_head;
-
+
newbone->flag |= BONE_CONNECTED;
newbone->prop = NULL;
ED_armature_ebone_unique_name(arm->edbo, newbone->name, NULL);
-
+
/* correct parent bones */
for (tbone = arm->edbo->first; tbone; tbone = tbone->next) {
if (tbone->parent == ebone)
@@ -1127,10 +1127,10 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
-
+
return OPERATOR_FINISHED;
}
@@ -1142,14 +1142,14 @@ void ARMATURE_OT_subdivide(wmOperatorType *ot)
ot->name = "Subdivide Multi";
ot->idname = "ARMATURE_OT_subdivide";
ot->description = "Break selected bones into chains of smaller bones";
-
+
/* api callbacks */
ot->exec = armature_subdivide_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* Properties */
prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 1000, "Number of Cuts", "", 1, 10);
/* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index fe0722470cd..ccc1eefd9dc 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -29,7 +29,7 @@
* \ingroup edarmature
*/
-#include <assert.h>
+#include <assert.h>
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
@@ -50,6 +50,7 @@
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_object.h"
@@ -68,7 +69,7 @@
/* ************************** Object Tools Exports ******************************* */
/* NOTE: these functions are exported to the Object module to be called from the tools there */
-void ED_armature_transform_apply(Object *ob, float mat[4][4], const bool do_props)
+void ED_armature_transform_apply(Main *bmain, Object *ob, float mat[4][4], const bool do_props)
{
bArmature *arm = ob->data;
@@ -79,7 +80,7 @@ void ED_armature_transform_apply(Object *ob, float mat[4][4], const bool do_prop
ED_armature_transform_bones(arm, mat, do_props);
/* Turn the list into an armature */
- ED_armature_from_edit(arm);
+ ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
}
@@ -94,20 +95,20 @@ void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const b
/* Do the rotations */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
float tmat[3][3];
-
+
/* find the current bone's roll matrix */
ED_armature_ebone_to_mat3(ebone, tmat);
-
+
/* transform the roll matrix */
mul_m3_m3m3(tmat, mat3, tmat);
-
+
/* transform the bone */
mul_m4_v3(mat, ebone->head);
mul_m4_v3(mat, ebone->tail);
/* apply the transformed roll back */
mat3_to_vec_roll(tmat, NULL, &ebone->roll);
-
+
if (do_props) {
ebone->rad_head *= scale;
ebone->rad_tail *= scale;
@@ -120,7 +121,7 @@ void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const b
}
}
-void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do_props)
+void ED_armature_transform(Main *bmain, bArmature *arm, float mat[4][4], const bool do_props)
{
if (arm->edbo) {
ED_armature_transform_bones(arm, mat, do_props);
@@ -133,14 +134,14 @@ void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do
ED_armature_transform_bones(arm, mat, do_props);
/* Go back to object mode*/
- ED_armature_from_edit(arm);
+ ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
}
}
/* exported for use in editors/object/ */
/* 0 == do center, 1 == center new, 2 == center cursor */
-void ED_armature_origin_set(Object *ob, float cursor[3], int centermode, int around)
+void ED_armature_origin_set(Main *bmain, Object *ob, float cursor[3], int centermode, int around)
{
const bool is_editmode = BKE_object_is_in_editmode(ob);
EditBone *ebone;
@@ -181,16 +182,16 @@ void ED_armature_origin_set(Object *ob, float cursor[3], int centermode, int aro
mid_v3_v3v3(cent, min, max);
}
}
-
+
/* Do the adjustments */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
sub_v3_v3(ebone->head, cent);
sub_v3_v3(ebone->tail, cent);
}
-
+
/* Turn the list into an armature */
if (is_editmode == false) {
- ED_armature_from_edit(arm);
+ ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
}
@@ -292,7 +293,7 @@ static const EnumPropertyItem prop_calc_roll_types[] = {
};
-static int armature_calc_roll_exec(bContext *C, wmOperator *op)
+static int armature_calc_roll_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
eCalcRollTypes type = RNA_enum_get(op->ptr, "type");
@@ -319,12 +320,12 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
float cursor_local[3];
const View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d);
-
+
invert_m4_m4(ob->imat, ob->obmat);
copy_v3_v3(cursor_local, cursor->location);
mul_m4_v3(ob->imat, cursor_local);
-
+
/* cursor */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
@@ -393,7 +394,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No region view3d available");
return OPERATOR_CANCELLED;
}
-
+
copy_v3_v3(vec, rv3d->viewinv[2]);
mul_m3_v3(imat, vec);
}
@@ -404,7 +405,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active bone set");
return OPERATOR_CANCELLED;
}
-
+
ED_armature_ebone_to_mat3(ebone, mat);
copy_v3_v3(vec, mat[2]);
}
@@ -415,9 +416,9 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
mul_m3_v3(imat, vec);
normalize_v3(vec);
}
-
+
if (axis_flip) negate_v3(vec);
-
+
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
/* roll func is a callback which assumes that all is well */
@@ -425,7 +426,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
}
}
}
-
+
if (arm->flag & ARM_MIRROR_EDIT) {
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
@@ -436,10 +437,10 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -449,12 +450,12 @@ void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
ot->name = "Recalculate Roll";
ot->idname = "ARMATURE_OT_calculate_roll";
ot->description = "Automatically fix alignment of select bones' axes";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = armature_calc_roll_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -521,10 +522,10 @@ void ARMATURE_OT_roll_clear(wmOperatorType *ot)
/* temporary data-structure for merge/fill bones */
typedef struct EditBonePoint {
struct EditBonePoint *next, *prev;
-
+
EditBone *head_owner; /* EditBone which uses this point as a 'head' point */
EditBone *tail_owner; /* EditBone which uses this point as a 'tail' point */
-
+
float vec[3]; /* the actual location of the point in local/EditMode space */
} EditBonePoint;
@@ -533,11 +534,11 @@ static void chains_find_tips(ListBase *edbo, ListBase *list)
{
EditBone *curBone, *ebo;
LinkData *ld;
-
+
/* note: this is potentially very slow ... there's got to be a better way */
for (curBone = edbo->first; curBone; curBone = curBone->next) {
short stop = 0;
-
+
/* is this bone contained within any existing chain? (skip if so) */
for (ld = list->first; ld; ld = ld->next) {
for (ebo = ld->data; ebo; ebo = ebo->parent) {
@@ -546,12 +547,12 @@ static void chains_find_tips(ListBase *edbo, ListBase *list)
break;
}
}
-
+
if (stop) break;
}
/* skip current bone if it is part of an existing chain */
if (stop) continue;
-
+
/* is any existing chain part of the chain formed by this bone? */
stop = 0;
for (ebo = curBone->parent; ebo; ebo = ebo->parent) {
@@ -562,12 +563,12 @@ static void chains_find_tips(ListBase *edbo, ListBase *list)
break;
}
}
-
+
if (stop) break;
}
/* current bone has already been added to a chain? */
if (stop) continue;
-
+
/* add current bone to a new chain */
ld = MEM_callocN(sizeof(LinkData), "BoneChain");
ld->data = curBone;
@@ -582,14 +583,14 @@ static void fill_add_joint(EditBone *ebo, short eb_tail, ListBase *points)
EditBonePoint *ebp;
float vec[3];
short found = 0;
-
+
if (eb_tail) {
copy_v3_v3(vec, ebo->tail);
}
else {
copy_v3_v3(vec, ebo->head);
}
-
+
for (ebp = points->first; ebp; ebp = ebp->next) {
if (equals_v3v3(ebp->vec, vec)) {
if (eb_tail) {
@@ -610,11 +611,11 @@ static void fill_add_joint(EditBone *ebo, short eb_tail, ListBase *points)
}
}
}
-
+
/* allocate a new point if no existing point was related */
if (found == 0) {
ebp = MEM_callocN(sizeof(EditBonePoint), "EditBonePoint");
-
+
if (eb_tail) {
copy_v3_v3(ebp->vec, ebo->tail);
ebp->tail_owner = ebo;
@@ -623,7 +624,7 @@ static void fill_add_joint(EditBone *ebo, short eb_tail, ListBase *points)
copy_v3_v3(ebp->vec, ebo->head);
ebp->head_owner = ebo;
}
-
+
BLI_addtail(points, ebp);
}
}
@@ -666,7 +667,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
/* the number of joints determines how we fill:
* 1) between joint and cursor (joint=head, cursor=tail)
* 2) between the two joints (order is dependent on active-bone/hierarchy)
@@ -699,14 +700,14 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
if (count == 1) {
EditBonePoint *ebp;
float curs[3];
-
+
/* Get Points - selected joint */
ebp = points.first;
-
+
/* Get points - cursor (tail) */
invert_m4_m4(obedit->imat, obedit->obmat);
mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)->location);
-
+
/* Create a bone */
newbone = add_points_bone(obedit, ebp->vec, curs);
}
@@ -714,11 +715,11 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
EditBonePoint *ebp_a, *ebp_b;
float head[3], tail[3];
short headtail = 0;
-
+
/* check that the points don't belong to the same bone */
ebp_a = (EditBonePoint *)points.first;
ebp_b = ebp_a->next;
-
+
if (((ebp_a->head_owner == ebp_b->tail_owner) && (ebp_a->head_owner != NULL)) ||
((ebp_a->tail_owner == ebp_b->head_owner) && (ebp_a->tail_owner != NULL)))
{
@@ -726,7 +727,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
BLI_freelistN(&points);
return OPERATOR_CANCELLED;
}
-
+
/* find which one should be the 'head' */
if ((ebp_a->head_owner && ebp_b->head_owner) || (ebp_a->tail_owner && ebp_b->tail_owner)) {
/* use active, nice predictable */
@@ -759,7 +760,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
else if (ebp_b->head_owner) {
headtail = 2;
}
-
+
/* assign head/tail combinations */
if (headtail == 2) {
copy_v3_v3(head, ebp_a->vec);
@@ -769,11 +770,11 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
copy_v3_v3(head, ebp_b->vec);
copy_v3_v3(tail, ebp_a->vec);
}
-
+
/* add new bone and parent it to the appropriate end */
if (headtail) {
newbone = add_points_bone(obedit, head, tail);
-
+
/* do parenting (will need to set connected flag too) */
if (headtail == 2) {
/* ebp tail or head - tail gets priority */
@@ -808,13 +809,13 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
arm->act_edbone = newbone;
newbone->flag |= BONE_TIPSEL;
}
-
+
/* updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
-
+
/* free points */
BLI_freelistN(&points);
-
+
return OPERATOR_FINISHED;
}
@@ -824,18 +825,18 @@ void ARMATURE_OT_fill(wmOperatorType *ot)
ot->name = "Fill Between Joints";
ot->idname = "ARMATURE_OT_fill";
ot->description = "Add bone between selected joint(s) and/or 3D-Cursor";
-
+
/* callbacks */
ot->exec = armature_fill_bones_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* --------------------- */
-/* this function merges between two bones, removes them and those in-between,
+/* this function merges between two bones, removes them and those in-between,
* and adjusts the parent relationships for those in-between
*/
static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone *endchild, ListBase *chains)
@@ -844,7 +845,7 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
EditBone *ebo, *ebone, *newbone;
LinkData *chain;
float head[3], tail[3];
-
+
/* check if same bone */
if (start == end) {
if (G.debug & G_DEBUG) {
@@ -852,7 +853,7 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
printf("\tstart = %s, end = %s\n", start->name, end->name);
}
}
-
+
/* step 1: add a new bone
* - head = head/tail of start (default head)
* - tail = head/tail of end (default tail)
@@ -876,17 +877,17 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
/* TODO, copy more things to the new bone */
newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE |
BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE);
-
- /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge
+
+ /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge
* - potentially several tips for side chains leading to some tree exist...
*/
for (chain = chains->first; chain; chain = chain->next) {
- /* traverse down chain until we hit the bottom or if we run into the tip of the chain of bones we're
- * merging (need to stop in this case to avoid corrupting this chain too!)
+ /* traverse down chain until we hit the bottom or if we run into the tip of the chain of bones we're
+ * merging (need to stop in this case to avoid corrupting this chain too!)
*/
for (ebone = chain->data; (ebone) && (ebone != end); ebone = ebone->parent) {
short found = 0;
-
+
/* check if this bone is parented to one in the merging chain
* ! WATCHIT: must only go check until end of checking chain
*/
@@ -898,23 +899,23 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
break;
}
}
-
+
/* carry on to the next tip now */
- if (found)
+ if (found)
break;
}
}
-
+
/* step 2b: parent child of end to newbone (child from this chain) */
if (endchild)
endchild->parent = newbone;
-
+
/* step 3: delete all bones between and including start and end */
for (ebo = end; ebo; ebo = ebone) {
ebone = (ebo == start) ? (NULL) : (ebo->parent);
bone_free(arm, ebo);
}
-
+
newbone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED);
ED_armature_edit_sync_selection(arm->edbo);
}
@@ -925,33 +926,33 @@ static int armature_merge_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
bArmature *arm = (obedit) ? obedit->data : NULL;
short type = RNA_enum_get(op->ptr, "type");
-
+
/* sanity checks */
if (ELEM(NULL, obedit, arm))
return OPERATOR_CANCELLED;
-
+
/* for now, there's only really one type of merging that's performed... */
if (type == 1) {
/* go down chains, merging bones */
ListBase chains = {NULL, NULL};
LinkData *chain, *nchain;
EditBone *ebo;
-
+
armature_tag_select_mirrored(arm);
-
+
/* get chains (ends on chains) */
chains_find_tips(arm->edbo, &chains);
if (BLI_listbase_is_empty(&chains)) return OPERATOR_CANCELLED;
-
+
/* each 'chain' is the last bone in the chain (with no children) */
for (chain = chains.first; chain; chain = nchain) {
EditBone *bstart = NULL, *bend = NULL;
EditBone *bchild = NULL, *child = NULL;
-
+
/* temporarily remove chain from list of chains */
nchain = chain->next;
BLI_remlink(&chains, chain);
-
+
/* only consider bones that are visible and selected */
for (ebo = chain->data; ebo; child = ebo, ebo = ebo->parent) {
/* check if visible + selected */
@@ -964,37 +965,37 @@ static int armature_merge_exec(bContext *C, wmOperator *op)
bend = ebo;
bchild = child;
}
- else
+ else
bstart = ebo;
}
else {
/* chain is broken... merge any continous segments then clear */
if (bstart && bend)
bones_merge(obedit, bstart, bend, bchild, &chains);
-
+
bstart = NULL;
bend = NULL;
bchild = NULL;
}
}
-
+
/* merge from bstart to bend if something not merged */
if (bstart && bend)
bones_merge(obedit, bstart, bend, bchild, &chains);
-
+
/* put back link */
BLI_insertlinkbefore(&chains, nchain, chain);
}
-
+
armature_tag_unselect(arm);
-
+
BLI_freelistN(&chains);
}
-
+
/* updates */
ED_armature_edit_sync_selection(arm->edbo);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
-
+
return OPERATOR_FINISHED;
}
@@ -1009,15 +1010,15 @@ void ARMATURE_OT_merge(wmOperatorType *ot)
ot->name = "Merge Bones";
ot->idname = "ARMATURE_OT_merge";
ot->description = "Merge continuous chains of selected bones";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = armature_merge_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", merge_types, 0, "Type", "");
}
@@ -1029,41 +1030,41 @@ void ARMATURE_OT_merge(wmOperatorType *ot)
* easy to retrieve any hierarchical/chain relationships which are necessary for
* this to be done easily.
*/
-
+
/* helper to clear BONE_TRANSFORM flags */
static void armature_clear_swap_done_flags(bArmature *arm)
{
EditBone *ebone;
-
+
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
ebone->flag &= ~BONE_TRANSFORM;
}
}
-static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
+static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = CTX_data_edit_object(C);
bArmature *arm = (bArmature *)ob->data;
ListBase chains = {NULL, NULL};
LinkData *chain;
-
+
/* get chains of bones (ends on chains) */
chains_find_tips(arm->edbo, &chains);
if (BLI_listbase_is_empty(&chains)) return OPERATOR_CANCELLED;
-
+
/* ensure that mirror bones will also be operated on */
armature_tag_select_mirrored(arm);
-
- /* clear BONE_TRANSFORM flags
+
+ /* clear BONE_TRANSFORM flags
* - used to prevent duplicate/canceling operations from occurring [#34123]
* - BONE_DONE cannot be used here as that's already used for mirroring
*/
armature_clear_swap_done_flags(arm);
-
+
/* loop over chains, only considering selected and visible bones */
for (chain = chains.first; chain; chain = chain->next) {
EditBone *ebo, *child = NULL, *parent = NULL;
-
+
/* loop over bones in chain */
for (ebo = chain->data; ebo; ebo = parent) {
/* parent is this bone's original parent
@@ -1071,14 +1072,14 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
* but the value of ebo->parent may change here...
*/
parent = ebo->parent;
-
+
/* skip bone if already handled... [#34123] */
if ((ebo->flag & BONE_TRANSFORM) == 0) {
/* only if selected and editable */
if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {
/* swap head and tail coordinates */
swap_v3_v3(ebo->head, ebo->tail);
-
+
/* do parent swapping:
* - use 'child' as new parent
* - connected flag is only set if points are coincidental
@@ -1088,44 +1089,44 @@ static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
ebo->flag |= BONE_CONNECTED;
else
ebo->flag &= ~BONE_CONNECTED;
-
- /* get next bones
+
+ /* get next bones
* - child will become the new parent of next bone
*/
child = ebo;
}
else {
- /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it
+ /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it
* as it will be facing in opposite direction
*/
if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
ebo->parent = NULL;
ebo->flag &= ~BONE_CONNECTED;
}
-
+
/* get next bones
- * - child will become new parent of next bone (not swapping occurred,
+ * - child will become new parent of next bone (not swapping occurred,
* so set to NULL to prevent infinite-loop)
*/
child = NULL;
}
-
+
/* tag as done (to prevent double-swaps) */
ebo->flag |= BONE_TRANSFORM;
}
}
}
-
+
/* free chains */
BLI_freelistN(&chains);
-
+
/* clear temp flags */
armature_clear_swap_done_flags(arm);
armature_tag_unselect(arm);
-
+
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1135,11 +1136,11 @@ void ARMATURE_OT_switch_direction(wmOperatorType *ot)
ot->name = "Switch Direction";
ot->idname = "ARMATURE_OT_switch_direction";
ot->description = "Change the direction that a chain of bones points in (head <-> tail swap)";
-
+
/* api callbacks */
ot->exec = armature_switch_direction_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1150,10 +1151,10 @@ void ARMATURE_OT_switch_direction(wmOperatorType *ot)
static void fix_connected_bone(EditBone *ebone)
{
float diff[3];
-
+
if (!(ebone->parent) || !(ebone->flag & BONE_CONNECTED) || equals_v3v3(ebone->parent->tail, ebone->head))
return;
-
+
/* if the parent has moved we translate child's head and tail accordingly */
sub_v3_v3v3(diff, ebone->parent->tail, ebone->head);
add_v3_v3(ebone->head, diff);
@@ -1164,14 +1165,14 @@ static void fix_connected_bone(EditBone *ebone)
static void fix_editbone_connected_children(ListBase *edbo, EditBone *ebone)
{
EditBone *selbone;
-
+
for (selbone = edbo->first; selbone; selbone = selbone->next) {
if ((selbone->parent) && (selbone->parent == ebone) && (selbone->flag & BONE_CONNECTED)) {
fix_connected_bone(selbone);
fix_editbone_connected_children(edbo, selbone);
}
}
-}
+}
static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actbone)
{
@@ -1186,21 +1187,21 @@ static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actb
mul_v3_fl(actboneaxis, length);
add_v3_v3v3(selbone->tail, selbone->head, actboneaxis);
selbone->roll = actbone->roll;
-
+
/* if the bone being aligned has connected descendants they must be moved
* according to their parent new position, otherwise they would be left
* in an inconsistent state: connected but away from the parent*/
fix_editbone_connected_children(edbo, selbone);
}
-static int armature_align_bones_exec(bContext *C, wmOperator *op)
+static int armature_align_bones_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
bArmature *arm = (bArmature *)ob->data;
EditBone *actbone = CTX_data_active_bone(C);
EditBone *actmirb = NULL;
int num_selected_bones;
-
+
/* there must be an active bone */
if (actbone == NULL) {
BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
@@ -1208,28 +1209,28 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
}
else if (arm->flag & ARM_MIRROR_EDIT) {
/* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
- * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
+ * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
* (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
* This is useful for arm-chains, for example parenting lower arm to upper arm
* - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
* then just use actbone. Useful when doing upper arm to spine.
*/
actmirb = ED_armature_ebone_get_mirrored(arm->edbo, actbone);
- if (actmirb == NULL)
+ if (actmirb == NULL)
actmirb = actbone;
}
-
- /* if there is only 1 selected bone, we assume that that is the active bone,
+
+ /* if there is only 1 selected bone, we assume that that is the active bone,
* since a user will need to have clicked on a bone (thus selecting it) to make it active
*/
num_selected_bones = CTX_DATA_COUNT(C, selected_editable_bones);
if (num_selected_bones <= 1) {
/* When only the active bone is selected, and it has a parent,
- * align it to the parent, as that is the only possible outcome.
+ * align it to the parent, as that is the only possible outcome.
*/
if (actbone->parent) {
bone_align_to_bone(arm->edbo, actbone, actbone->parent);
-
+
if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
bone_align_to_bone(arm->edbo, actmirb, actmirb->parent);
@@ -1240,11 +1241,11 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
/* Align 'selected' bones to the active one
* - the context iterator contains both selected bones and their mirrored copies,
* so we assume that unselected bones are mirrored copies of some selected bone
- * - since the active one (and/or its mirror) will also be selected, we also need
+ * - since the active one (and/or its mirror) will also be selected, we also need
* to check that we are not trying to operate on them, since such an operation
* would cause errors
*/
-
+
/* align selected bones to the active one */
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
{
@@ -1262,7 +1263,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1272,11 +1273,11 @@ void ARMATURE_OT_align(wmOperatorType *ot)
ot->name = "Align Bones";
ot->idname = "ARMATURE_OT_align";
ot->description = "Align selected bones to the active bone (or to their parent)";
-
+
/* api callbacks */
ot->exec = armature_align_bones_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1388,12 +1389,12 @@ void ARMATURE_OT_delete(wmOperatorType *ot)
ot->name = "Delete Selected Bone(s)";
ot->idname = "ARMATURE_OT_delete";
ot->description = "Remove selected bones from the armature";
-
+
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = armature_delete_selected_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1597,11 +1598,11 @@ void ARMATURE_OT_hide(wmOperatorType *ot)
ot->name = "Hide Selected Bones";
ot->idname = "ARMATURE_OT_hide";
ot->description = "Tag selected bones to not be visible in Edit Mode";
-
+
/* api callbacks */
ot->exec = armature_hide_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1615,7 +1616,7 @@ static int armature_reveal_exec(bContext *C, wmOperator *op)
bArmature *arm = obedit->data;
EditBone *ebone;
const bool select = RNA_boolean_get(op->ptr, "select");
-
+
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (arm->layer & ebone->layer) {
if (ebone->flag & BONE_HIDDEN_A) {
@@ -1640,11 +1641,11 @@ void ARMATURE_OT_reveal(wmOperatorType *ot)
ot->name = "Reveal Bones";
ot->idname = "ARMATURE_OT_reveal";
ot->description = "Reveal all bones hidden in Edit Mode";
-
+
/* api callbacks */
ot->exec = armature_reveal_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index fff85b773e2..1fe729b7c4b 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -146,25 +146,25 @@ void POSE_OT_toggle_bone_selection_overlay(struct wmOperatorType *ot);
/* Temporary data linking PoseChannels with the F-Curves they affect */
typedef struct tPChanFCurveLink {
struct tPChanFCurveLink *next, *prev;
-
+
ListBase fcurves; /* F-Curves for this PoseChannel (wrapped with LinkData) */
struct bPoseChannel *pchan; /* Pose Channel which data is attached to */
-
+
char *pchan_path; /* RNA Path to this Pose Channel (needs to be freed when we're done) */
-
+
float oldloc[3]; /* transform values at start of operator (to be restored before each modal step) */
float oldrot[3];
float oldscale[3];
float oldquat[4];
float oldangle;
float oldaxis[3];
-
+
float roll1, roll2; /* old bbone values (to be restored along with the transform properties) */
float curveInX, curveInY; /* (NOTE: we haven't renamed these this time, as their names are already long enough) */
float curveOutX, curveOutY;
float ease1, ease2;
float scaleIn, scaleOut;
-
+
struct IDProperty *oldprops; /* copy of custom properties at start of operator (to be restored before each modal step) */
} tPChanFCurveLink;
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index e8d45f72f89..a73e64af0ee 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -105,15 +105,15 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char *
{
bConstraint *curcon;
bConstraintTarget *ct;
-
+
for (curcon = conlist->first; curcon; curcon = curcon->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
ListBase targets = {NULL, NULL};
-
+
/* constraint targets */
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(curcon, &targets);
-
+
for (ct = targets.first; ct; ct = ct->next) {
if (ct->tar == ob) {
if (STREQ(ct->subtarget, oldname)) {
@@ -121,11 +121,11 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char *
}
}
}
-
+
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(curcon, &targets, 0);
}
-
+
/* action constraints */
if (curcon->type == CONSTRAINT_TYPE_ACTION) {
bActionConstraint *actcon = (bActionConstraint *)curcon->data;
@@ -137,24 +137,24 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char *
/* called by UI for renaming a bone */
/* warning: make sure the original bone was not renamed yet! */
/* seems messy, but thats what you get with not using pointers but channel names :) */
-void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *newnamep)
+void ED_armature_bone_rename(Main *bmain, bArmature *arm, const char *oldnamep, const char *newnamep)
{
Object *ob;
char newname[MAXBONENAME];
char oldname[MAXBONENAME];
-
+
/* names better differ! */
if (!STREQLEN(oldnamep, newnamep, MAXBONENAME)) {
-
+
/* we alter newname string... so make copy */
BLI_strncpy(newname, newnamep, MAXBONENAME);
/* we use oldname for search... so make copy */
BLI_strncpy(oldname, oldnamep, MAXBONENAME);
-
+
/* now check if we're in editmode, we need to find the unique name */
if (arm->edbo) {
EditBone *eBone = ED_armature_ebone_find_name(arm->edbo, oldname);
-
+
if (eBone) {
ED_armature_ebone_unique_name(arm->edbo, newname, NULL);
BLI_strncpy(eBone->name, newname, MAXBONENAME);
@@ -165,7 +165,7 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
}
else {
Bone *bone = BKE_armature_find_bone_name(arm, oldname);
-
+
if (bone) {
unique_bone_name(arm, newname);
BLI_strncpy(bone->name, newname, MAXBONENAME);
@@ -174,15 +174,15 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
return;
}
}
-
+
/* do entire dbase - objects */
- for (ob = G.main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
ModifierData *md;
-
+
/* we have the object using the armature */
if (arm == ob->data) {
Object *cob;
-
+
/* Rename the pose channel, if it exists */
if (ob->pose) {
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, oldname);
@@ -204,9 +204,9 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
BLI_assert(BKE_pose_channels_is_valid(ob->pose) == true);
}
-
+
/* Update any object constraints to use the new bone name */
- for (cob = G.main->object.first; cob; cob = cob->id.next) {
+ for (cob = bmain->object.first; cob; cob = cob->id.next) {
if (cob->constraints.first)
constraint_bone_name_fix(ob, &cob->constraints, oldname, newname);
if (cob->pose) {
@@ -217,7 +217,7 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
}
}
}
-
+
/* See if an object is parented to this armature */
if (ob->parent && (ob->parent->data == arm)) {
if (ob->partype == PARBONE) {
@@ -226,14 +226,14 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
BLI_strncpy(ob->parsubstr, newname, MAXBONENAME);
}
}
-
+
if (modifiers_usesArmature(ob, arm)) {
bDeformGroup *dg = defgroup_find_name(ob, oldname);
if (dg) {
BLI_strncpy(dg->name, newname, MAXBONENAME);
}
}
-
+
/* fix modifiers that might be using this name */
for (md = ob->modifiers.first; md; md = md->next) {
switch (md->type) {
@@ -266,20 +266,20 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
}
}
}
-
+
/* Fix all animdata that may refer to this bone - we can't just do the ones attached to objects, since
* other ID-blocks may have drivers referring to this bone [#29822]
*/
// XXX: the ID here is for armatures, but most bone drivers are actually on the object instead...
{
-
+
BKE_animdata_fix_paths_rename_all(&arm->id, "pose.bones", oldname, newname);
}
-
+
/* correct view locking */
{
bScreen *screen;
- for (screen = G.main->screen.first; screen; screen = screen->id.next) {
+ for (screen = bmain->screen.first; screen; screen = screen->id.next) {
ScrArea *sa;
/* add regions */
for (sa = screen->areabase.first; sa; sa = sa->next) {
@@ -316,7 +316,7 @@ typedef struct BoneFlipNameData {
* \param bones_names: List of BoneConflict elems.
* \param do_strip_numbers: if set, try to get rid of dot-numbers at end of bone names.
*/
-void ED_armature_bones_flip_names(bArmature *arm, ListBase *bones_names, const bool do_strip_numbers)
+void ED_armature_bones_flip_names(Main *bmain, bArmature *arm, ListBase *bones_names, const bool do_strip_numbers)
{
ListBase bones_names_conflicts = {NULL};
BoneFlipNameData *bfn;
@@ -332,7 +332,7 @@ void ED_armature_bones_flip_names(bArmature *arm, ListBase *bones_names, const b
* Bone.R, Bone.R.001, Bone.R.002, etc. */
BLI_string_flip_side_name(name_flip, name, do_strip_numbers, sizeof(name_flip));
- ED_armature_bone_rename(arm, name, name_flip);
+ ED_armature_bone_rename(bmain, arm, name, name_flip);
if (!STREQ(name, name_flip)) {
bfn = alloca(sizeof(BoneFlipNameData));
@@ -346,7 +346,7 @@ void ED_armature_bones_flip_names(bArmature *arm, ListBase *bones_names, const b
* Note that if the other bone was not selected, its name was not flipped, so conflict remains and that second
* rename simply generates a new numbered alternative name. */
for (bfn = bones_names_conflicts.first; bfn; bfn = bfn->next) {
- ED_armature_bone_rename(arm, bfn->name, bfn->name_flip);
+ ED_armature_bone_rename(bmain, arm, bfn->name, bfn->name_flip);
}
}
@@ -355,6 +355,7 @@ void ED_armature_bones_flip_names(bArmature *arm, ListBase *bones_names, const b
static int armature_flip_names_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_edit_object(C);
bArmature *arm;
@@ -374,10 +375,10 @@ static int armature_flip_names_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- ED_armature_bones_flip_names(arm, &bones_names, do_strip_numbers);
+ ED_armature_bones_flip_names(bmain, arm, &bones_names, do_strip_numbers);
BLI_freelistN(&bones_names);
-
+
/* since we renamed stuff... */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -397,11 +398,11 @@ void ARMATURE_OT_flip_names(wmOperatorType *ot)
ot->name = "Flip Names";
ot->idname = "ARMATURE_OT_flip_names";
ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones";
-
+
/* api callbacks */
ot->exec = armature_flip_names_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -413,31 +414,32 @@ void ARMATURE_OT_flip_names(wmOperatorType *ot)
static int armature_autoside_names_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_edit_object(C);
bArmature *arm;
char newname[MAXBONENAME];
short axis = RNA_enum_get(op->ptr, "type");
-
+
/* paranoia checks */
- if (ELEM(NULL, ob, ob->pose))
+ if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
arm = ob->data;
-
+
/* loop through selected bones, auto-naming them */
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
{
BLI_strncpy(newname, ebone->name, sizeof(newname));
if (bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]))
- ED_armature_bone_rename(arm, ebone->name, newname);
+ ED_armature_bone_rename(bmain, arm, ebone->name, newname);
}
CTX_DATA_END;
-
+
/* since we renamed stuff... */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -449,20 +451,20 @@ void ARMATURE_OT_autoside_names(wmOperatorType *ot)
{2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "AutoName by Axis";
ot->idname = "ARMATURE_OT_autoside_names";
ot->description = "Automatically renames the selected bones according to which side of the target axis they fall on";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = armature_autoside_names_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* settings */
ot->prop = RNA_def_enum(ot->srna, "type", axis_items, 0, "Axis", "Axis tag names with");
}
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index ed79c2c4ab6..cee99c3b8f8 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -46,16 +46,16 @@ void ED_operatortypes_armature(void)
{
/* EDIT ARMATURE */
WM_operatortype_append(ARMATURE_OT_bone_primitive_add);
-
+
WM_operatortype_append(ARMATURE_OT_align);
WM_operatortype_append(ARMATURE_OT_calculate_roll);
WM_operatortype_append(ARMATURE_OT_roll_clear);
WM_operatortype_append(ARMATURE_OT_switch_direction);
WM_operatortype_append(ARMATURE_OT_subdivide);
-
+
WM_operatortype_append(ARMATURE_OT_parent_set);
WM_operatortype_append(ARMATURE_OT_parent_clear);
-
+
WM_operatortype_append(ARMATURE_OT_select_all);
WM_operatortype_append(ARMATURE_OT_select_mirror);
WM_operatortype_append(ARMATURE_OT_select_more);
@@ -77,10 +77,10 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(ARMATURE_OT_merge);
WM_operatortype_append(ARMATURE_OT_separate);
WM_operatortype_append(ARMATURE_OT_split);
-
+
WM_operatortype_append(ARMATURE_OT_autoside_names);
WM_operatortype_append(ARMATURE_OT_flip_names);
-
+
WM_operatortype_append(ARMATURE_OT_layers_show_all);
WM_operatortype_append(ARMATURE_OT_armature_layers);
WM_operatortype_append(ARMATURE_OT_bone_layers);
@@ -88,19 +88,19 @@ void ED_operatortypes_armature(void)
/* POSE */
WM_operatortype_append(POSE_OT_hide);
WM_operatortype_append(POSE_OT_reveal);
-
+
WM_operatortype_append(POSE_OT_armature_apply);
WM_operatortype_append(POSE_OT_visual_transform_apply);
-
+
WM_operatortype_append(POSE_OT_rot_clear);
WM_operatortype_append(POSE_OT_loc_clear);
WM_operatortype_append(POSE_OT_scale_clear);
WM_operatortype_append(POSE_OT_transforms_clear);
WM_operatortype_append(POSE_OT_user_transforms_clear);
-
+
WM_operatortype_append(POSE_OT_copy);
WM_operatortype_append(POSE_OT_paste);
-
+
WM_operatortype_append(POSE_OT_select_all);
WM_operatortype_append(POSE_OT_select_parent);
@@ -109,7 +109,7 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(POSE_OT_select_constraint_target);
WM_operatortype_append(POSE_OT_select_grouped);
WM_operatortype_append(POSE_OT_select_mirror);
-
+
WM_operatortype_append(POSE_OT_group_add);
WM_operatortype_append(POSE_OT_group_remove);
WM_operatortype_append(POSE_OT_group_move);
@@ -118,38 +118,38 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(POSE_OT_group_unassign);
WM_operatortype_append(POSE_OT_group_select);
WM_operatortype_append(POSE_OT_group_deselect);
-
+
WM_operatortype_append(POSE_OT_paths_calculate);
WM_operatortype_append(POSE_OT_paths_update);
WM_operatortype_append(POSE_OT_paths_clear);
-
+
WM_operatortype_append(POSE_OT_autoside_names);
WM_operatortype_append(POSE_OT_flip_names);
-
+
WM_operatortype_append(POSE_OT_rotation_mode_set);
WM_operatortype_append(POSE_OT_quaternions_flip);
-
+
WM_operatortype_append(POSE_OT_bone_layers);
WM_operatortype_append(POSE_OT_toggle_bone_selection_overlay);
-
+
WM_operatortype_append(POSE_OT_propagate);
-
+
/* POSELIB */
WM_operatortype_append(POSELIB_OT_browse_interactive);
WM_operatortype_append(POSELIB_OT_apply_pose);
-
+
WM_operatortype_append(POSELIB_OT_pose_add);
WM_operatortype_append(POSELIB_OT_pose_remove);
WM_operatortype_append(POSELIB_OT_pose_rename);
WM_operatortype_append(POSELIB_OT_pose_move);
-
+
WM_operatortype_append(POSELIB_OT_new);
WM_operatortype_append(POSELIB_OT_unlink);
-
+
WM_operatortype_append(POSELIB_OT_action_sanitize);
-
+
/* POSE SLIDING */
WM_operatortype_append(POSE_OT_push);
WM_operatortype_append(POSE_OT_relax);
@@ -191,7 +191,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
/* Armature ------------------------ */
keymap = WM_keymap_find(keyconf, "Armature", 0, 0);
keymap->poll = ED_operator_editarmature;
@@ -206,14 +206,14 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "ARMATURE_OT_align", AKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_calculate_roll", NKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_roll_clear", RKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "ARMATURE_OT_switch_direction", FKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "ARMATURE_OT_bone_primitive_add", AKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "ARMATURE_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
-
+
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_all", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
@@ -221,14 +221,14 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
-
+
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
RNA_boolean_set(kmi->ptr, "extend", true);
-
+
kmi = WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
RNA_boolean_set(kmi->ptr, "extend", false);
@@ -244,7 +244,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "ARMATURE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_shortest_path_pick", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_armature_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_armature_delete", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_dissolve", XKEY, KM_PRESS, KM_CTRL, 0);
@@ -255,19 +255,19 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "ARMATURE_OT_fill", FKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_merge", MKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_split", YKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "ARMATURE_OT_separate", PKEY, KM_PRESS, 0, 0);
-
+
/* set flags */
WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_enable", WKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_disable", WKEY, KM_PRESS, KM_ALT, 0);
-
+
/* armature/bone layers */
WM_keymap_add_item(keymap, "ARMATURE_OT_layers_show_all", ACCENTGRAVEKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_armature_layers", MKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_bone_layers", MKEY, KM_PRESS, 0, 0);
-
+
/* special transforms: */
/* 1) envelope/b-bone size */
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
@@ -278,7 +278,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
/* 3) set roll */
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", RKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_BONE_ROLL);
-
+
/* menus */
WM_keymap_add_menu(keymap, "VIEW3D_MT_armature_specials", WKEY, KM_PRESS, 0, 0);
@@ -286,36 +286,36 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
/* only set in posemode, by space_view3d listener */
keymap = WM_keymap_find(keyconf, "Pose", 0, 0);
keymap->poll = ED_operator_posemode;
-
+
/* set parent and add object are object-based operators, but we make them
* available here because it's useful to do in pose mode too */
WM_keymap_add_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0);
-
+
kmi = WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "POSE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_menu(keymap, "VIEW3D_MT_pose_apply", AKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* TODO: clear pose */
WM_keymap_add_item(keymap, "POSE_OT_rot_clear", RKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "POSE_OT_loc_clear", GKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "POSE_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "POSE_OT_quaternions_flip", FKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "POSE_OT_rotation_mode_set", RKEY, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "POSE_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "flipped", false);
kmi = WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "flipped", true);
-
+
#ifdef __APPLE__
WM_keymap_add_item(keymap, "POSE_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
kmi = WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
@@ -337,7 +337,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
RNA_boolean_set(kmi->ptr, "extend", true);
-
+
kmi = WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
RNA_boolean_set(kmi->ptr, "extend", false);
@@ -348,14 +348,14 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "POSE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "POSE_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "POSE_OT_select_mirror", FKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "POSE_OT_constraint_add_with_targets", CKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "POSE_OT_constraints_clear", CKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_item(keymap, "POSE_OT_ik_add", IKEY, KM_PRESS, /*KM_CTRL|*/ KM_SHIFT, 0);
WM_keymap_add_item(keymap, "POSE_OT_ik_clear", IKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
-
+
WM_keymap_add_menu(keymap, "VIEW3D_MT_pose_group", GKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* set flags */
WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_bone_options_enable", WKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
@@ -366,25 +366,25 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "ARMATURE_OT_armature_layers", MKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "POSE_OT_bone_layers", MKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "POSE_OT_toggle_bone_selection_overlay", ZKEY, KM_PRESS, 0, 0);
-
+
/* special transforms: */
/* 1) envelope/b-bone size */
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_BONESIZE);
-
+
/* keyframes management */
WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_insert_menu", IKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_delete_v3d", IKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_keying_set_active_set", IKEY, KM_PRESS, KM_CTRL | KM_SHIFT | KM_ALT, 0);
-
+
/* Pose -> PoseLib ------------- */
/* only set in posemode, by space_view3d listener */
WM_keymap_add_item(keymap, "POSELIB_OT_browse_interactive", LKEY, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "POSELIB_OT_pose_add", LKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "POSELIB_OT_pose_remove", LKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "POSELIB_OT_pose_rename", LKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
-
+
/* Pose -> Pose Sliding ------------- */
/* only set in posemode, by space_view3d listener */
WM_keymap_add_item(keymap, "POSE_OT_push", EKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 91f8a8713bc..9282148e857 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -110,7 +110,7 @@ static void joined_armature_fix_links_constraints(
bActionConstraint *data = con->data;
if (data->act) {
- BKE_action_fix_paths_rename(&tarArm->id, data->act, "pose.bones[",
+ BKE_action_fix_paths_rename(&tarArm->id, data->act, "pose.bones[",
pchan->name, curbone->name, 0, 0, false);
}
}
@@ -122,7 +122,7 @@ static void joined_armature_fix_links_constraints(
typedef struct tJoinArmature_AdtFixData {
Object *srcArm;
Object *tarArm;
-
+
GHash *names_map;
} tJoinArmature_AdtFixData;
@@ -135,34 +135,34 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
tJoinArmature_AdtFixData *afd = (tJoinArmature_AdtFixData *)user_data;
ID *src_id = &afd->srcArm->id;
ID *dst_id = &afd->tarArm->id;
-
+
GHashIterator gh_iter;
-
+
/* Fix paths - If this is the target object, it will have some "dirty" paths */
if ((id == src_id) && strstr(fcu->rna_path, "pose.bones[")) {
GHASH_ITER(gh_iter, afd->names_map) {
const char *old_name = BLI_ghashIterator_getKey(&gh_iter);
const char *new_name = BLI_ghashIterator_getValue(&gh_iter);
-
+
/* only remap if changed; this still means there will be some waste if there aren't many drivers/keys */
if (!STREQ(old_name, new_name) && strstr(fcu->rna_path, old_name)) {
fcu->rna_path = BKE_animsys_fix_rna_path_rename(id, fcu->rna_path, "pose.bones",
old_name, new_name, 0, 0, false);
-
- /* we don't want to apply a second remapping on this driver now,
+
+ /* we don't want to apply a second remapping on this driver now,
* so stop trying names, but keep fixing drivers
*/
break;
}
}
}
-
-
+
+
/* Driver targets */
if (fcu->driver) {
ChannelDriver *driver = fcu->driver;
DriverVar *dvar;
-
+
/* Fix driver references to invalid ID's */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
/* only change the used targets, since the others will need fixing manually anyway */
@@ -171,7 +171,7 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
/* change the ID's used... */
if (dtar->id == src_id) {
dtar->id = dst_id;
-
+
/* also check on the subtarget...
* XXX: We duplicate the logic from drivers_path_rename_fix() here, with our own
* little twists so that we know that it isn't going to clobber the wrong data
@@ -180,7 +180,7 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
GHASH_ITER(gh_iter, afd->names_map) {
const char *old_name = BLI_ghashIterator_getKey(&gh_iter);
const char *new_name = BLI_ghashIterator_getValue(&gh_iter);
-
+
/* only remap if changed */
if (!STREQ(old_name, new_name)) {
if ((dtar->rna_path) && strstr(dtar->rna_path, old_name)) {
@@ -210,7 +210,7 @@ static void joined_armature_fix_links(Main *bmain, Object *tarArm, Object *srcAr
Object *ob;
bPose *pose;
bPoseChannel *pchant;
-
+
/* let's go through all objects in database */
for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* do some object-type specific things */
@@ -220,12 +220,12 @@ static void joined_armature_fix_links(Main *bmain, Object *tarArm, Object *srcAr
joined_armature_fix_links_constraints(tarArm, srcArm, pchan, curbone, &pchant->constraints);
}
}
-
+
/* fix object-level constraints */
if (ob != srcArm) {
joined_armature_fix_links_constraints(tarArm, srcArm, pchan, curbone, &ob->constraints);
}
-
+
/* See if an object is parented to this armature */
if (ob->parent && (ob->parent == srcArm)) {
/* Is object parented to a bone of this src armature? */
@@ -235,7 +235,7 @@ static void joined_armature_fix_links(Main *bmain, Object *tarArm, Object *srcAr
BLI_strncpy(ob->parsubstr, curbone->name, sizeof(ob->parsubstr));
}
}
-
+
/* make tar armature be new parent */
ob->parent = tarArm;
}
@@ -254,13 +254,13 @@ int join_armature_exec(bContext *C, wmOperator *op)
EditBone *curbone;
float mat[4][4], oimat[4][4];
bool ok = false;
-
+
/* Ensure we're not in editmode and that the active object is an armature*/
if (!ob || ob->type != OB_ARMATURE)
return OPERATOR_CANCELLED;
if (!arm || arm->edbo)
return OPERATOR_CANCELLED;
-
+
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
{
if (base->object == ob) {
@@ -278,7 +278,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
/* Get editbones of active armature to add editbones to */
ED_armature_to_edit(arm);
-
+
/* get pose of active object and move it out of posemode */
pose = ob->pose;
ob->mode &= ~OB_MODE_POSE;
@@ -288,36 +288,36 @@ int join_armature_exec(bContext *C, wmOperator *op)
if ((base->object->type == OB_ARMATURE) && (base->object != ob)) {
tJoinArmature_AdtFixData afd = {NULL};
bArmature *curarm = base->object->data;
-
+
/* we assume that each armature datablock is only used in a single place */
BLI_assert(ob->data != base->object->data);
-
+
/* init callback data for fixing up AnimData links later */
afd.srcArm = base->object;
afd.tarArm = ob;
afd.names_map = BLI_ghash_str_new("join_armature_adt_fix");
-
+
/* Make a list of editbones in current armature */
ED_armature_to_edit(base->object->data);
-
+
/* Get Pose of current armature */
opose = base->object->pose;
base->object->mode &= ~OB_MODE_POSE;
//BASACT->flag &= ~OB_MODE_POSE;
-
+
/* Find the difference matrix */
invert_m4_m4(oimat, ob->obmat);
mul_m4_m4m4(mat, oimat, base->object->obmat);
-
+
/* Copy bones and posechannels from the object to the edit armature */
for (pchan = opose->chanbase.first; pchan; pchan = pchann) {
pchann = pchan->next;
curbone = ED_armature_ebone_find_name(curarm->edbo, pchan->name);
-
+
/* Get new name */
ED_armature_ebone_unique_name(arm->edbo, curbone->name, NULL);
BLI_ghash_insert(afd.names_map, BLI_strdup(pchan->name), curbone->name);
-
+
/* Transform the bone */
{
float premat[4][4];
@@ -325,48 +325,48 @@ int join_armature_exec(bContext *C, wmOperator *op)
float difmat[4][4];
float imat[4][4];
float temp[3][3];
-
+
/* Get the premat */
ED_armature_ebone_to_mat3(curbone, temp);
-
+
unit_m4(premat); /* mul_m4_m3m4 only sets 3x3 part */
mul_m4_m3m4(premat, temp, mat);
-
+
mul_m4_v3(mat, curbone->head);
mul_m4_v3(mat, curbone->tail);
-
+
/* Get the postmat */
ED_armature_ebone_to_mat3(curbone, temp);
copy_m4_m3(postmat, temp);
-
+
/* Find the roll */
invert_m4_m4(imat, premat);
mul_m4_m4m4(difmat, imat, postmat);
-
+
curbone->roll -= atan2f(difmat[2][0], difmat[2][2]);
}
-
+
/* Fix Constraints and Other Links to this Bone and Armature */
joined_armature_fix_links(bmain, ob, base->object, pchan, curbone);
-
+
/* Rename pchan */
BLI_strncpy(pchan->name, curbone->name, sizeof(pchan->name));
-
+
/* Jump Ship! */
BLI_remlink(curarm->edbo, curbone);
BLI_addtail(arm->edbo, curbone);
-
+
BLI_remlink(&opose->chanbase, pchan);
BLI_addtail(&pose->chanbase, pchan);
BKE_pose_channels_hash_free(opose);
BKE_pose_channels_hash_free(pose);
}
-
+
/* Fix all the drivers (and animation data) */
BKE_fcurves_main_cb(bmain, joined_armature_fix_animdata_cb, &afd);
BLI_ghash_free(afd.names_map, MEM_freeN, NULL);
-
- /* Only copy over animdata now, after all the remapping has been done,
+
+ /* Only copy over animdata now, after all the remapping has been done,
* so that we don't have to worry about ambiguities re which armature
* a bone came from!
*/
@@ -380,7 +380,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
BKE_animdata_merge_copy(&ob->id, &base->object->id, ADT_MERGECOPY_KEEP_DST, false);
}
}
-
+
if (curarm->adt) {
if (arm->adt == NULL) {
/* no animdata, so just use a copy of the whole thing */
@@ -391,39 +391,39 @@ int join_armature_exec(bContext *C, wmOperator *op)
BKE_animdata_merge_copy(&arm->id, &curarm->id, ADT_MERGECOPY_KEEP_DST, false);
}
}
-
+
/* Free the old object data */
ED_object_base_free_and_unlink(bmain, scene, base->object);
}
}
CTX_DATA_END;
-
+
DEG_relations_tag_update(bmain); /* because we removed object(s) */
- ED_armature_from_edit(arm);
+ ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
-
+
return OPERATOR_FINISHED;
}
/* *********************************** Separate *********************************************** */
/* Helper function for armature separating - link fixing */
-static void separated_armature_fix_links(Object *origArm, Object *newArm)
+static void separated_armature_fix_links(Main *bmain, Object *origArm, Object *newArm)
{
Object *ob;
bPoseChannel *pchan;
bConstraint *con;
ListBase *opchans, *npchans;
-
+
/* get reference to list of bones in original and new armatures */
opchans = &origArm->pose->chanbase;
npchans = &newArm->pose->chanbase;
-
+
/* let's go through all objects in database */
- for (ob = G.main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* do some object-type specific things */
if (ob->type == OB_ARMATURE) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -431,11 +431,11 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
-
+
/* constraint targets */
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
-
+
for (ct = targets.first; ct; ct = ct->next) {
/* any targets which point to original armature are redirected to the new one only if:
* - the target isn't origArm/newArm itself
@@ -462,18 +462,18 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
}
}
}
-
+
/* fix object-level constraints */
if (ob != origArm) {
for (con = ob->constraints.first; con; con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
-
+
/* constraint targets */
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
-
+
for (ct = targets.first; ct; ct = ct->next) {
/* any targets which point to original armature are redirected to the new one only if:
* - the target isn't origArm/newArm itself
@@ -492,14 +492,14 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
}
}
}
-
+
if (cti->flush_constraint_targets) {
cti->flush_constraint_targets(con, &targets, 0);
}
}
}
}
-
+
/* See if an object is parented to this armature */
if (ob->parent && (ob->parent == origArm)) {
/* Is object parented to a bone of this src armature? */
@@ -512,31 +512,31 @@ static void separated_armature_fix_links(Object *origArm, Object *newArm)
}
}
-/* Helper function for armature separating - remove certain bones from the given armature
+/* Helper function for armature separating - remove certain bones from the given armature
* sel: remove selected bones from the armature, otherwise the unselected bones are removed
* (ob is not in editmode)
*/
-static void separate_armature_bones(Object *ob, short sel)
+static void separate_armature_bones(Main *bmain, Object *ob, short sel)
{
bArmature *arm = (bArmature *)ob->data;
bPoseChannel *pchan, *pchann;
EditBone *curbone;
-
+
/* make local set of editbones to manipulate here */
ED_armature_to_edit(arm);
-
+
/* go through pose-channels, checking if a bone should be removed */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchann) {
pchann = pchan->next;
curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
-
+
/* check if bone needs to be removed */
if ( (sel && (curbone->flag & BONE_SELECTED)) ||
(!sel && !(curbone->flag & BONE_SELECTED)) )
{
EditBone *ebo;
bPoseChannel *pchn;
-
+
/* clear the bone->parent var of any bone that had this as its parent */
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
if (ebo->parent == curbone) {
@@ -545,25 +545,25 @@ static void separate_armature_bones(Object *ob, short sel)
ebo->flag &= ~BONE_CONNECTED;
}
}
-
+
/* clear the pchan->parent var of any pchan that had this as its parent */
for (pchn = ob->pose->chanbase.first; pchn; pchn = pchn->next) {
if (pchn->parent == pchan)
pchn->parent = NULL;
}
-
+
/* free any of the extra-data this pchan might have */
BKE_pose_channel_free(pchan);
BKE_pose_channels_hash_free(ob->pose);
-
+
/* get rid of unneeded bone */
bone_free(arm, curbone);
BLI_freelinkN(&ob->pose->chanbase, pchan);
}
}
-
+
/* exit editmode (recalculates pchans too) */
- ED_armature_from_edit(ob->data);
+ ED_armature_from_edit(bmain, ob->data);
ED_armature_edit_free(ob->data);
}
@@ -576,14 +576,14 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
Object *oldob, *newob;
Base *oldbase, *newbase;
-
+
/* sanity checks */
if (obedit == NULL)
return OPERATOR_CANCELLED;
-
+
/* set wait cursor in case this takes a while */
WM_cursor_wait(1);
-
+
/* we are going to do this as follows (unlike every other instance of separate):
* 1. exit editmode +posemode for active armature/base. Take note of what this is.
* 2. duplicate base - BASACT is the new one now
@@ -604,16 +604,16 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
/* 1) store starting settings and exit editmode */
oldob = obedit;
oldbase = view_layer->basact;
oldob->mode &= ~OB_MODE_POSE;
//oldbase->flag &= ~OB_POSEMODE;
-
- ED_armature_from_edit(obedit->data);
+
+ ED_armature_from_edit(bmain, obedit->data);
ED_armature_edit_free(obedit->data);
-
+
/* 2) duplicate base */
newbase = ED_object_add_duplicate(bmain, scene, view_layer, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
DEG_relations_tag_update(bmain);
@@ -623,22 +623,22 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
/* 3) remove bones that shouldn't still be around on both armatures */
- separate_armature_bones(oldob, 1);
- separate_armature_bones(newob, 0);
-
-
+ separate_armature_bones(bmain, oldob, 1);
+ separate_armature_bones(bmain, newob, 0);
+
+
/* 4) fix links before depsgraph flushes */ // err... or after?
- separated_armature_fix_links(oldob, newob);
-
+ separated_armature_fix_links(bmain, oldob, newob);
+
DEG_id_tag_update(&oldob->id, OB_RECALC_DATA); /* this is the original one */
DEG_id_tag_update(&newob->id, OB_RECALC_DATA); /* this is the separated one */
-
-
+
+
/* 5) restore original conditions */
obedit = oldob;
-
+
ED_armature_to_edit(obedit->data);
-
+
/* parents tips remain selected when connected children are removed. */
ED_armature_edit_deselect_all(obedit);
@@ -646,10 +646,10 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
-
+
/* recalc/redraw + cleanup */
WM_cursor_wait(0);
-
+
return OPERATOR_FINISHED;
}
@@ -659,12 +659,12 @@ void ARMATURE_OT_separate(wmOperatorType *ot)
ot->name = "Separate Bones";
ot->idname = "ARMATURE_OT_separate";
ot->description = "Isolate selected bones into a separate armature";
-
+
/* callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = separate_armature_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -688,13 +688,13 @@ static void bone_connect_to_new_parent(ListBase *edbo, EditBone *selbone, EditBo
{
EditBone *ebone;
float offset[3];
-
+
if ((selbone->parent) && (selbone->flag & BONE_CONNECTED))
selbone->parent->flag &= ~(BONE_TIPSEL);
-
+
/* make actbone the parent of selbone */
selbone->parent = actbone;
-
+
/* in actbone tree we cannot have a loop */
for (ebone = actbone->parent; ebone; ebone = ebone->parent) {
if (ebone->parent == selbone) {
@@ -702,21 +702,21 @@ static void bone_connect_to_new_parent(ListBase *edbo, EditBone *selbone, EditBo
ebone->flag &= ~BONE_CONNECTED;
}
}
-
+
if (mode == ARM_PAR_CONNECT) {
/* Connected: Child bones will be moved to the parent tip */
selbone->flag |= BONE_CONNECTED;
sub_v3_v3v3(offset, actbone->tail, selbone->head);
-
+
copy_v3_v3(selbone->head, actbone->tail);
selbone->rad_head = actbone->rad_tail;
-
+
add_v3_v3(selbone->tail, offset);
-
+
/* offset for all its children */
for (ebone = edbo->first; ebone; ebone = ebone->next) {
EditBone *par;
-
+
for (par = ebone->parent; par; par = par->parent) {
if (par == selbone) {
add_v3_v3(ebone->head, offset);
@@ -739,14 +739,14 @@ static const EnumPropertyItem prop_editarm_make_parent_types[] = {
{0, NULL, 0, NULL, NULL}
};
-static int armature_parent_set_exec(bContext *C, wmOperator *op)
+static int armature_parent_set_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
bArmature *arm = (bArmature *)ob->data;
EditBone *actbone = CTX_data_active_bone(C);
EditBone *actmirb = NULL;
short val = RNA_enum_get(op->ptr, "type");
-
+
/* there must be an active bone */
if (actbone == NULL) {
BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
@@ -754,27 +754,27 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
}
else if (arm->flag & ARM_MIRROR_EDIT) {
/* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
- * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
+ * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
* (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
* This is useful for arm-chains, for example parenting lower arm to upper arm
* - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
* then just use actbone. Useful when doing upper arm to spine.
*/
actmirb = ED_armature_ebone_get_mirrored(arm->edbo, actbone);
- if (actmirb == NULL)
+ if (actmirb == NULL)
actmirb = actbone;
}
-
- /* if there is only 1 selected bone, we assume that that is the active bone,
+
+ /* if there is only 1 selected bone, we assume that that is the active bone,
* since a user will need to have clicked on a bone (thus selecting it) to make it active
*/
if (CTX_DATA_COUNT(C, selected_editable_bones) <= 1) {
/* When only the active bone is selected, and it has a parent,
- * connect it to the parent, as that is the only possible outcome.
+ * connect it to the parent, as that is the only possible outcome.
*/
if (actbone->parent) {
bone_connect_to_existing_parent(actbone);
-
+
if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
bone_connect_to_existing_parent(actmirb);
}
@@ -783,16 +783,16 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
/* Parent 'selected' bones to the active one
* - the context iterator contains both selected bones and their mirrored copies,
* so we assume that unselected bones are mirrored copies of some selected bone
- * - since the active one (and/or its mirror) will also be selected, we also need
+ * - since the active one (and/or its mirror) will also be selected, we also need
* to check that we are not trying to operate on them, since such an operation
* would cause errors
*/
-
+
/* parent selected bones to the active one */
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
{
if (ELEM(ebone, actbone, actmirb) == 0) {
- if (ebone->flag & BONE_SELECTED)
+ if (ebone->flag & BONE_SELECTED)
bone_connect_to_new_parent(arm->edbo, ebone, actbone, val);
else
bone_connect_to_new_parent(arm->edbo, ebone, actmirb, val);
@@ -800,11 +800,11 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
-
+
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -814,7 +814,7 @@ static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const
uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE);
uiLayout *layout = UI_popup_menu_layout(pup);
int allchildbones = 0;
-
+
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
{
if (ebone != actbone) {
@@ -824,13 +824,13 @@ static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const
CTX_DATA_END;
uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_CONNECT);
-
+
/* ob becomes parent, make the associated menus */
if (allchildbones)
uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_OFFSET);
-
+
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -840,15 +840,15 @@ void ARMATURE_OT_parent_set(wmOperatorType *ot)
ot->name = "Make Parent";
ot->idname = "ARMATURE_OT_parent_set";
ot->description = "Set the active bone as the parent of the selected bones";
-
+
/* api callbacks */
ot->invoke = armature_parent_set_invoke;
ot->exec = armature_parent_set_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_enum(ot->srna, "type", prop_editarm_make_parent_types, 0, "ParentType", "Type of parenting");
}
@@ -866,28 +866,28 @@ static void editbone_clear_parent(EditBone *ebone, int mode)
/* for nice selection */
ebone->parent->flag &= ~(BONE_TIPSEL);
}
-
+
if (mode == 1) ebone->parent = NULL;
ebone->flag &= ~BONE_CONNECTED;
}
-static int armature_parent_clear_exec(bContext *C, wmOperator *op)
+static int armature_parent_clear_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
bArmature *arm = (bArmature *)ob->data;
int val = RNA_enum_get(op->ptr, "type");
-
+
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
{
editbone_clear_parent(ebone, val);
}
CTX_DATA_END;
-
+
ED_armature_edit_sync_selection(arm->edbo);
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -897,15 +897,15 @@ void ARMATURE_OT_parent_clear(wmOperatorType *ot)
ot->name = "Clear Parent";
ot->idname = "ARMATURE_OT_parent_clear";
ot->description = "Remove the parent-child relationship between selected bones and their parents";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = armature_parent_clear_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
ot->prop = RNA_def_enum(ot->srna, "type", prop_editarm_clear_parent_types, 0, "ClearType", "What way to clear parenting");
}
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 65f845ce34c..95acc8ab6ba 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -149,10 +149,10 @@ void *get_bone_from_selectbuffer(
short i;
bool takeNext = false;
int minsel = 0xffffffff, minunsel = 0xffffffff;
-
+
for (i = 0; i < hits; i++) {
hitresult = buffer[3 + (i * 4)];
-
+
if (!(hitresult & BONESEL_NOSEL)) {
if (hitresult & BONESEL_ANY) { /* to avoid including objects in selection */
Base *base = NULL;
@@ -184,7 +184,7 @@ void *get_bone_from_selectbuffer(
data = ebone;
}
-
+
if (data) {
if (sel) {
if (do_nearest) {
@@ -225,7 +225,7 @@ void *get_bone_from_selectbuffer(
}
}
}
-
+
if (firstunSel) {
*r_base = firstunSel_base;
return firstunSel;
@@ -249,11 +249,11 @@ void *get_nearest_bone(
short hits;
ED_view3d_viewcontext_init(C, &vc);
-
+
// rect.xmin = ... mouseco!
rect.xmin = rect.xmax = xy[0];
rect.ymin = rect.ymax = xy[1];
-
+
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
*r_base = NULL;
@@ -310,7 +310,7 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv
curBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
}
}
-
+
if (curBone->flag & BONE_CONNECTED)
next = curBone->parent;
else
@@ -339,11 +339,11 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv
if (!curBone)
bone = NULL;
}
-
+
ED_armature_edit_sync_selection(arm->edbo);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object);
-
+
return OPERATOR_FINISHED;
}
@@ -358,15 +358,15 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot)
ot->name = "Select Connected";
ot->idname = "ARMATURE_OT_select_linked";
ot->description = "Select bones related to selected ones by parent/child relationships";
-
+
/* api callbacks */
/* leave 'exec' unset */
ot->invoke = armature_select_linked_invoke;
ot->poll = armature_select_linked_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
}
@@ -505,7 +505,7 @@ cache_end:
dep = 1;
else if ( (hitresult & BONESEL_TIP) && (ebone->flag & BONE_TIPSEL) == 0)
dep = 1;
- else
+ else
dep = 2;
}
else {
@@ -638,10 +638,10 @@ bool ED_armature_edit_select_pick(bContext *C, const int mval[2], bool extend, b
ED_armature_edit_deselect_all_multi(objects, objects_len);
MEM_freeN(objects);
}
-
+
/* by definition the non-root connected bones have no root point drawn,
* so a root selection needs to be delivered to the parent tip */
-
+
if (selmask & BONE_SELECTED) {
if (nearBone->parent && (nearBone->flag & BONE_CONNECTED)) {
/* click in a chain */
@@ -706,9 +706,9 @@ bool ED_armature_edit_select_pick(bContext *C, const int mval[2], bool extend, b
else
nearBone->flag |= selmask;
}
-
+
ED_armature_edit_sync_selection(arm->edbo);
-
+
if (nearBone) {
/* then now check for active status */
if (ebone_select_flag(nearBone)) {
@@ -748,7 +748,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
-
+
/* Set the flags */
CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones)
{
@@ -783,7 +783,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -793,14 +793,14 @@ void ARMATURE_OT_select_all(wmOperatorType *ot)
ot->name = "(De)select All";
ot->idname = "ARMATURE_OT_select_all";
ot->description = "Toggle selection status of all bones";
-
+
/* api callbacks */
ot->exec = armature_de_select_all_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
WM_operator_properties_select_all(ot);
}
@@ -1228,7 +1228,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
int direction = RNA_enum_get(op->ptr, "direction");
const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
bool changed = false;
-
+
ob = obedit;
arm = (bArmature *)ob->data;
@@ -1286,15 +1286,15 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
changed = true;
}
}
-
+
if (changed == false) {
return OPERATOR_CANCELLED;
}
ED_armature_edit_sync_selection(arm->edbo);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1305,16 +1305,16 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
{BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Select Hierarchy";
ot->idname = "ARMATURE_OT_select_hierarchy";
ot->description = "Select immediate parent/children of selected bones";
-
+
/* api callbacks */
ot->exec = armature_select_hierarchy_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 1722cbd5c5c..87a66514417 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -45,6 +45,7 @@
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_deform.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_object_deform.h"
#include "BKE_report.h"
#include "BKE_subsurf.h"
@@ -71,7 +72,7 @@ static int bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap)
* This function performs 2 functions:
*
* a) It returns 1 if the bone is skinnable.
- * If we loop over all bones with this
+ * If we loop over all bones with this
* function, we can count the number of
* skinnable bones.
* b) If the pointer data is non null,
@@ -96,10 +97,10 @@ static int bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap)
segments = bone->segments;
else
segments = 1;
-
+
if (data->list != NULL) {
hbone = (Bone ***) &data->list;
-
+
for (a = 0; a < segments; a++) {
**hbone = bone;
++*hbone;
@@ -111,10 +112,10 @@ static int bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap)
return 0;
}
-static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
+static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
{
/* This group creates a vertex group to ob that has the
- * same name as bone (provided the bone is skinnable).
+ * same name as bone (provided the bone is skinnable).
* If such a vertex group already exist the routine exits.
*/
if (!(bone->flag & BONE_NO_DEFORM)) {
@@ -126,7 +127,7 @@ static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
return 0;
}
-static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
+static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
{
/* Bones that are deforming
* are regarded to be "skinnable" and are eligible for
@@ -134,16 +135,16 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
*
* This function performs 2 functions:
*
- * a) If the bone is skinnable, it creates
+ * a) If the bone is skinnable, it creates
* a vertex group for ob that has
* the name of the skinnable bone
* (if one doesn't exist already).
* b) If the pointer data is non null,
* it is treated like a handle to a
- * bDeformGroup pointer -- the
+ * bDeformGroup pointer -- the
* bDeformGroup pointer is set to point
* to the deform group with the bone's
- * name, and the pointer the handle
+ * name, and the pointer the handle
* points to is incremented to point to the
* next member of an array of pointers
* to bDeformGroups. This way we can loop using
@@ -162,7 +163,7 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
segments = bone->segments;
else
segments = 1;
-
+
if (!data->is_weight_paint || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) {
if (!(defgroup = defgroup_find_name(ob, bone->name))) {
defgroup = BKE_object_defgroup_add_name(ob, bone->name);
@@ -172,10 +173,10 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
defgroup = NULL;
}
}
-
+
if (data->list != NULL) {
hgroup = (bDeformGroup ***) &data->list;
-
+
for (a = 0; a < segments; a++) {
**hgroup = defgroup;
++*hgroup;
@@ -215,25 +216,25 @@ static void envelope_bone_weighting(
}
iflip = (dgroupflip) ? mesh_get_x_mirror_vert(ob, NULL, i, use_topology) : -1;
-
+
/* for each skinnable bone */
for (j = 0; j < numbones; ++j) {
if (!selected[j])
continue;
-
+
bone = bonelist[j];
dgroup = dgrouplist[j];
-
+
/* store the distance-factor from the vertex to the bone */
distance = distfactor_to_bone(verts[i], root[j], tip[j],
bone->rad_head * scale, bone->rad_tail * scale, bone->dist * scale);
-
+
/* add the vert to the deform group if (weight != 0.0) */
if (distance != 0.0f)
ED_vgroup_vert_add(ob, dgroup, i, distance, WEIGHT_REPLACE);
else
ED_vgroup_vert_remove(ob, dgroup, i);
-
+
/* do same for mirror */
if (dgroupflip && dgroupflip[j] && iflip != -1) {
if (distance != 0.0f)
@@ -282,10 +283,10 @@ static void add_verts_to_dgroups(
/* count the number of skinnable bones */
numbones = bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable_cb);
-
+
if (numbones == 0)
return;
-
+
if (BKE_object_defgroup_data_create(ob->data) == NULL)
return;
@@ -313,13 +314,13 @@ static void add_verts_to_dgroups(
for (j = 0; j < numbones; ++j) {
bone = bonelist[j];
dgroup = dgrouplist[j];
-
+
/* handle bbone */
if (heat) {
if (segments == 0) {
segments = 1;
bbone = NULL;
-
+
if ((par->pose) && (pchan = BKE_pose_channel_find_name(par->pose, bone->name))) {
if (bone->segments > 1) {
segments = bone->segments;
@@ -328,10 +329,10 @@ static void add_verts_to_dgroups(
}
}
}
-
+
segments--;
}
-
+
/* compute root and tip */
if (bbone) {
mul_v3_m4v3(root[j], bone->arm_mat, bbone[segments].mat[3]);
@@ -346,10 +347,10 @@ static void add_verts_to_dgroups(
copy_v3_v3(root[j], bone->arm_head);
copy_v3_v3(tip[j], bone->arm_tail);
}
-
+
mul_m4_v3(par->obmat, root[j]);
mul_m4_v3(par->obmat, tip[j]);
-
+
/* set selected */
if (wpmode) {
if ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))
@@ -357,7 +358,7 @@ static void add_verts_to_dgroups(
}
else
selected[j] = 1;
-
+
/* find flipped group */
if (dgroup && mirror) {
char name_flip[MAXBONENAME];
@@ -374,12 +375,12 @@ static void add_verts_to_dgroups(
if (wpmode) {
/* if in weight paint mode, use final verts from derivedmesh */
DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH);
-
+
if (dm->foreachMappedVert) {
mesh_get_mapped_verts_coords(dm, verts, mesh->totvert);
vertsfilled = 1;
}
-
+
dm->release(dm);
}
else if (modifiers_findByType(ob, eModifierType_Subsurf)) {
@@ -431,7 +432,7 @@ void ED_object_vgroup_calc_from_armature(
ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, Object *par,
const int mode, const bool mirror)
{
- /* Lets try to create some vertex groups
+ /* Lets try to create some vertex groups
* based on the bones of the parent armature.
*/
bArmature *arm = par->data;
@@ -439,7 +440,7 @@ void ED_object_vgroup_calc_from_armature(
if (mode == ARM_GROUPS_NAME) {
const int defbase_tot = BLI_listbase_count(&ob->defbase);
int defbase_add;
- /* Traverse the bone list, trying to create empty vertex
+ /* Traverse the bone list, trying to create empty vertex
* groups corresponding to the bone.
*/
defbase_add = bone_looper(ob, arm->bonebase.first, NULL, vgroup_add_unique_bone_cb);
@@ -451,7 +452,7 @@ void ED_object_vgroup_calc_from_armature(
}
}
else if (ELEM(mode, ARM_GROUPS_ENVELOPE, ARM_GROUPS_AUTO)) {
- /* Traverse the bone list, trying to create vertex groups
+ /* Traverse the bone list, trying to create vertex groups
* that are populated with the vertices for which the
* bone is closest.
*/
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index ffa8b9f5007..02d45a4e041 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -57,7 +57,7 @@
void ED_armature_edit_sync_selection(ListBase *edbo)
{
EditBone *ebo;
-
+
for (ebo = edbo->first; ebo; ebo = ebo->next) {
/* if bone is not selectable, we shouldn't alter this setting... */
if ((ebo->flag & BONE_UNSELECTABLE) == 0) {
@@ -67,7 +67,7 @@ void ED_armature_edit_sync_selection(ListBase *edbo)
else
ebo->flag &= ~BONE_ROOTSEL;
}
-
+
if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL))
ebo->flag |= BONE_SELECTED;
else
@@ -94,27 +94,27 @@ void ED_armature_edit_validate_active(struct bArmature *arm)
int bone_looper(Object *ob, Bone *bone, void *data,
int (*bone_func)(Object *, Bone *, void *))
{
- /* We want to apply the function bone_func to every bone
- * in an armature -- feed bone_looper the first bone and
- * a pointer to the bone_func and watch it go!. The int count
+ /* We want to apply the function bone_func to every bone
+ * in an armature -- feed bone_looper the first bone and
+ * a pointer to the bone_func and watch it go!. The int count
* can be useful for counting bones with a certain property
* (e.g. skinnable)
*/
int count = 0;
-
+
if (bone) {
/* only do bone_func if the bone is non null */
count += bone_func(ob, bone, data);
-
+
/* try to execute bone_func for the first child */
count += bone_looper(ob, bone->childbase.first, data, bone_func);
-
+
/* try to execute bone_func for the next bone at this
* depth of the recursion.
*/
count += bone_looper(ob, bone->next, data, bone_func);
}
-
+
return count;
}
@@ -273,13 +273,13 @@ EditBone *ED_armature_ebone_get_mirrored(const ListBase *edbo, EditBone *ebo)
if (ebo == NULL)
return NULL;
-
+
BLI_string_flip_side_name(name_flip, ebo->name, false, sizeof(name_flip));
-
+
if (!STREQ(name_flip, ebo->name)) {
return ED_armature_ebone_find_name(edbo, name_flip);
}
-
+
return NULL;
}
@@ -293,7 +293,7 @@ void armature_select_mirrored_ex(bArmature *arm, const int flag)
/* Select mirrored bones */
if (arm->flag & ARM_MIRROR_EDIT) {
EditBone *curBone, *ebone_mirr;
-
+
for (curBone = arm->edbo->first; curBone; curBone = curBone->next) {
if (arm->layer & curBone->layer) {
if (curBone->flag & flag) {
@@ -304,7 +304,7 @@ void armature_select_mirrored_ex(bArmature *arm, const int flag)
}
}
}
-
+
}
void armature_select_mirrored(bArmature *arm)
@@ -333,7 +333,7 @@ void armature_tag_select_mirrored(bArmature *arm)
}
}
}
-
+
for (curBone = arm->edbo->first; curBone; curBone = curBone->next) {
if (curBone->flag & BONE_DONE) {
EditBone *ebone_mirr = ED_armature_ebone_get_mirrored(arm->edbo, curBone);
@@ -363,17 +363,17 @@ void ED_armature_edit_transform_mirror_update(Object *obedit)
{
bArmature *arm = obedit->data;
EditBone *ebo, *eboflip;
-
+
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
/* no layer check, correct mirror is more important */
if (ebo->flag & (BONE_TIPSEL | BONE_ROOTSEL)) {
eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
-
+
if (eboflip) {
/* we assume X-axis flipping for now */
if (ebo->flag & BONE_TIPSEL) {
EditBone *children;
-
+
eboflip->tail[0] = -ebo->tail[0];
eboflip->tail[1] = ebo->tail[1];
eboflip->tail[2] = ebo->tail[2];
@@ -381,7 +381,7 @@ void ED_armature_edit_transform_mirror_update(Object *obedit)
eboflip->roll = -ebo->roll;
eboflip->curveOutX = -ebo->curveOutX;
eboflip->roll2 = -ebo->roll2;
-
+
/* Also move connected children, in case children's name aren't mirrored properly */
for (children = arm->edbo->first; children; children = children->next) {
if (children->parent == eboflip && children->flag & BONE_CONNECTED) {
@@ -398,7 +398,7 @@ void ED_armature_edit_transform_mirror_update(Object *obedit)
eboflip->roll = -ebo->roll;
eboflip->curveInX = -ebo->curveInX;
eboflip->roll1 = -ebo->roll1;
-
+
/* Also move connected parent, in case parent's name isn't mirrored properly */
if (eboflip->parent && eboflip->flag & BONE_CONNECTED) {
EditBone *parent = eboflip->parent;
@@ -411,7 +411,7 @@ void ED_armature_edit_transform_mirror_update(Object *obedit)
eboflip->roll = -ebo->roll;
eboflip->xwidth = ebo->xwidth;
eboflip->zwidth = ebo->zwidth;
-
+
eboflip->curveInX = -ebo->curveInX;
eboflip->curveOutX = -ebo->curveOutX;
eboflip->roll1 = -ebo->roll1;
@@ -432,17 +432,17 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone
EditBone *eBoneAct = NULL;
EditBone *eBoneTest = NULL;
Bone *curBone;
-
+
for (curBone = bones->first; curBone; curBone = curBone->next) {
eBone = MEM_callocN(sizeof(EditBone), "make_editbone");
-
+
/* Copy relevant data from bone to eBone
* Keep selection logic in sync with ED_armature_edit_sync_selection.
*/
eBone->parent = parent;
BLI_strncpy(eBone->name, curBone->name, sizeof(eBone->name));
eBone->flag = curBone->flag;
-
+
/* fix selection flags */
if (eBone->flag & BONE_SELECTED) {
/* if the bone is selected the copy its root selection to the parents tip */
@@ -462,11 +462,11 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone
eBone->flag &= ~BONE_ROOTSEL;
}
}
-
+
copy_v3_v3(eBone->head, curBone->arm_head);
copy_v3_v3(eBone->tail, curBone->arm_tail);
eBone->roll = curBone->arm_roll;
-
+
/* rest of stuff copy */
eBone->length = curBone->length;
eBone->dist = curBone->dist;
@@ -492,20 +492,20 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone
if (curBone->prop)
eBone->prop = IDP_CopyProperty(curBone->prop);
-
+
BLI_addtail(edbo, eBone);
-
+
/* Add children if necessary */
if (curBone->childbase.first) {
eBoneTest = make_boneList(edbo, &curBone->childbase, eBone, actBone);
if (eBoneTest)
eBoneAct = eBoneTest;
}
-
+
if (curBone == actBone)
eBoneAct = eBone;
}
-
+
return eBoneAct;
}
@@ -585,23 +585,23 @@ static void armature_finalize_restpose(ListBase *bonelist, ListBase *editbonelis
}
/* put EditMode back in Object */
-void ED_armature_from_edit(bArmature *arm)
+void ED_armature_from_edit(Main *bmain, bArmature *arm)
{
EditBone *eBone, *neBone;
Bone *newBone;
Object *obt;
-
+
/* armature bones */
BKE_armature_bonelist_free(&arm->bonebase);
arm->act_bone = NULL;
-
+
/* remove zero sized bones, this gives unstable restposes */
for (eBone = arm->edbo->first; eBone; eBone = neBone) {
float len_sq = len_squared_v3v3(eBone->head, eBone->tail);
neBone = eBone->next;
if (len_sq <= SQUARE(0.000001f)) { /* FLT_EPSILON is too large? */
EditBone *fBone;
-
+
/* Find any bones that refer to this bone */
for (fBone = arm->edbo->first; fBone; fBone = fBone->next) {
if (fBone->parent == eBone)
@@ -612,19 +612,19 @@ void ED_armature_from_edit(bArmature *arm)
bone_free(arm, eBone);
}
}
-
+
/* Copy the bones from the editData into the armature */
for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
newBone = MEM_callocN(sizeof(Bone), "bone");
eBone->temp.bone = newBone; /* Associate the real Bones with the EditBones */
-
+
BLI_strncpy(newBone->name, eBone->name, sizeof(newBone->name));
copy_v3_v3(newBone->arm_head, eBone->head);
copy_v3_v3(newBone->arm_tail, eBone->tail);
newBone->arm_roll = eBone->roll;
-
+
newBone->flag = eBone->flag;
-
+
if (eBone == arm->act_edbone) {
/* don't change active selection, this messes up separate which uses
* editmode toggle and can separate active bone which is de-selected originally */
@@ -632,10 +632,10 @@ void ED_armature_from_edit(bArmature *arm)
arm->act_bone = newBone;
}
newBone->roll = 0.0f;
-
+
newBone->weight = eBone->weight;
newBone->dist = eBone->dist;
-
+
newBone->xwidth = eBone->xwidth;
newBone->zwidth = eBone->zwidth;
newBone->rad_head = eBone->rad_head;
@@ -659,7 +659,7 @@ void ED_armature_from_edit(bArmature *arm)
if (eBone->prop)
newBone->prop = IDP_CopyProperty(eBone->prop);
}
-
+
/* Fix parenting in a separate pass to ensure ebone->bone connections are valid at this point.
* Do not set bone->head/tail here anymore, using EditBone data for that is not OK since our later fiddling
* with parent's arm_mat (for roll conversion) may have some small but visible impact on locations (T46010). */
@@ -674,24 +674,24 @@ void ED_armature_from_edit(bArmature *arm)
BLI_addtail(&arm->bonebase, newBone);
}
}
-
+
/* Finalize definition of restpose data (roll, bone_mat, arm_mat, head/tail...). */
armature_finalize_restpose(&arm->bonebase, arm->edbo);
-
+
/* so all users of this armature should get rebuilt */
- for (obt = G.main->object.first; obt; obt = obt->id.next) {
+ for (obt = bmain->object.first; obt; obt = obt->id.next) {
if (obt->data == arm) {
BKE_pose_rebuild(obt, arm);
}
}
-
+
DEG_id_tag_update(&arm->id, 0);
}
void ED_armature_edit_free(struct bArmature *arm)
{
EditBone *eBone;
-
+
/* Clear the editbones list */
if (arm->edbo) {
if (arm->edbo->first) {
@@ -701,7 +701,7 @@ void ED_armature_edit_free(struct bArmature *arm)
MEM_freeN(eBone->prop);
}
}
-
+
BLI_freelistN(arm->edbo);
}
MEM_freeN(arm->edbo);
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
new file mode 100644
index 00000000000..b74b515b37f
--- /dev/null
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -0,0 +1,2644 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Martin Poirier
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * autoarmature.c: Interface for automagically manipulating armature (retarget, created, ...)
+ */
+
+/** \file blender/editors/armature/editarmature_retarget.c
+ * \ingroup edarmature
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "PIL_time.h"
+
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+
+#include "BKE_constraint.h"
+#include "BKE_armature.h"
+#include "BKE_context.h"
+#include "BKE_main.h"
+
+#include "ED_armature.h"
+#include "ED_undo.h"
+
+#include "BIF_retarget.h"
+
+#include "armature_intern.h"
+
+/************ RIG RETARGET DATA STRUCTURES ***************/
+
+typedef struct MemoNode {
+ float weight;
+ int next;
+} MemoNode;
+
+typedef struct RetargetParam {
+ RigGraph *rigg;
+ RigArc *iarc;
+ RigNode *inode_start;
+ bContext *context;
+} RetargetParam;
+
+typedef enum {
+ RETARGET_LENGTH,
+ RETARGET_AGGRESSIVE
+} RetargetMode;
+
+typedef enum {
+ METHOD_BRUTE_FORCE = 0,
+ METHOD_MEMOIZE = 1
+} RetargetMethod;
+
+typedef enum {
+ ARC_FREE = 0,
+ ARC_TAKEN = 1,
+ ARC_USED = 2
+} ArcUsageFlags;
+
+static RigGraph *GLOBAL_RIGG = NULL;
+
+/*******************************************************************************************************/
+
+void exec_retargetArctoArc(TaskPool * __restrict pool, void *taskdata, int threadid);
+
+static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second);
+float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]);
+
+/* two levels */
+#define SHAPE_LEVELS (SHAPE_RADIX * SHAPE_RADIX)
+
+/*********************************** EDITBONE UTILS ****************************************************/
+
+static int countEditBoneChildren(ListBase *list, EditBone *parent)
+{
+ EditBone *ebone;
+ int count = 0;
+
+ for (ebone = list->first; ebone; ebone = ebone->next) {
+ if (ebone->parent == parent) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+static EditBone *nextEditBoneChild(ListBase *list, EditBone *parent, int n)
+{
+ EditBone *ebone;
+
+ for (ebone = list->first; ebone; ebone = ebone->next) {
+ if (ebone->parent == parent) {
+ if (n == 0) {
+ return ebone;
+ }
+ n--;
+ }
+ }
+
+ return NULL;
+}
+
+static void getEditBoneRollUpAxis(EditBone *bone, float roll, float up_axis[3])
+{
+ float mat[3][3], nor[3];
+
+ sub_v3_v3v3(nor, bone->tail, bone->head);
+
+ vec_roll_to_mat3(nor, roll, mat);
+ copy_v3_v3(up_axis, mat[2]);
+}
+
+static float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4], float qroll[4], float aligned_axis[3])
+{
+ float nor[3], new_up_axis[3], x_axis[3], z_axis[3];
+
+ copy_v3_v3(new_up_axis, old_up_axis);
+ mul_qt_v3(qrot, new_up_axis);
+
+ sub_v3_v3v3(nor, bone->tail, bone->head);
+
+ cross_v3_v3v3(x_axis, nor, aligned_axis);
+ cross_v3_v3v3(z_axis, x_axis, nor);
+
+ normalize_v3(new_up_axis);
+ normalize_v3(x_axis);
+ normalize_v3(z_axis);
+
+ if (dot_v3v3(new_up_axis, x_axis) < 0) {
+ negate_v3(x_axis);
+ }
+
+ if (dot_v3v3(new_up_axis, z_axis) < 0) {
+ negate_v3(z_axis);
+ }
+
+ if (angle_normalized_v3v3(x_axis, new_up_axis) < angle_normalized_v3v3(z_axis, new_up_axis)) {
+ rotation_between_vecs_to_quat(qroll, new_up_axis, x_axis); /* set roll rotation quat */
+ return ED_armature_ebone_roll_to_vector(bone, x_axis, false);
+ }
+ else {
+ rotation_between_vecs_to_quat(qroll, new_up_axis, z_axis); /* set roll rotation quat */
+ return ED_armature_ebone_roll_to_vector(bone, z_axis, false);
+ }
+}
+
+static float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4], float up_axis[3])
+{
+ if (previous == NULL) {
+ /* default to up_axis if no previous */
+ return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis);
+ }
+ else {
+ float new_up_axis[3];
+ float vec_first[3], vec_second[3], normal[3];
+
+ if (previous->bone) {
+ sub_v3_v3v3(vec_first, previous->bone->tail, previous->bone->head);
+ }
+ else if (previous->prev->bone) {
+ sub_v3_v3v3(vec_first, edge->bone->head, previous->prev->bone->tail);
+ }
+ else {
+ /* default to up_axis if first bone in the chain is an offset */
+ return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis);
+ }
+
+ sub_v3_v3v3(vec_second, edge->bone->tail, edge->bone->head);
+
+ normalize_v3(vec_first);
+ normalize_v3(vec_second);
+
+ cross_v3_v3v3(normal, vec_first, vec_second);
+ normalize_v3(normal);
+
+ axis_angle_to_quat(qroll, vec_second, edge->up_angle);
+
+ mul_qt_v3(qroll, normal);
+
+ copy_v3_v3(new_up_axis, edge->up_axis);
+ mul_qt_v3(qrot, new_up_axis);
+
+ normalize_v3(new_up_axis);
+
+ /* real qroll between normal and up_axis */
+ rotation_between_vecs_to_quat(qroll, new_up_axis, normal);
+
+ return ED_armature_ebone_roll_to_vector(edge->bone, normal, false);
+ }
+}
+
+float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4])
+{
+ float new_up_axis[3];
+
+ copy_v3_v3(new_up_axis, old_up_axis);
+ mul_qt_v3(qrot, new_up_axis);
+
+ return ED_armature_ebone_roll_to_vector(bone, new_up_axis, false);
+}
+
+/************************************ DESTRUCTORS ******************************************************/
+
+static void RIG_freeRigArc(BArc *arc)
+{
+ BLI_freelistN(&((RigArc *)arc)->edges);
+}
+
+void RIG_freeRigGraph(BGraph *rg)
+{
+ RigGraph *rigg = (RigGraph *)rg;
+ BNode *node;
+ BArc *arc;
+
+ BLI_task_pool_free(rigg->task_pool);
+ BLI_task_scheduler_free(rigg->task_scheduler);
+
+ if (rigg->link_mesh) {
+ REEB_freeGraph(rigg->link_mesh);
+ }
+
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ RIG_freeRigArc(arc);
+ }
+ BLI_freelistN(&rg->arcs);
+
+ for (node = rg->nodes.first; node; node = node->next) {
+ BLI_freeNode(rg, (BNode *)node);
+ }
+ BLI_freelistN(&rg->nodes);
+
+ BLI_freelistN(&rigg->controls);
+
+ BLI_ghash_free(rigg->bones_map, NULL, NULL);
+ BLI_ghash_free(rigg->controls_map, NULL, NULL);
+
+ if (rigg->flag & RIG_FREE_BONELIST) {
+ BLI_freelistN(rigg->editbones);
+ MEM_freeN(rigg->editbones);
+ }
+
+ MEM_freeN(rg);
+}
+
+/************************************* ALLOCATORS ******************************************************/
+
+static RigGraph *newRigGraph(void)
+{
+ RigGraph *rg;
+ int totthread;
+
+ rg = MEM_callocN(sizeof(RigGraph), "rig graph");
+
+ rg->head = NULL;
+
+ rg->bones_map = BLI_ghash_str_new("newRigGraph bones gh");
+ rg->controls_map = BLI_ghash_str_new("newRigGraph cont gh");
+
+ rg->free_arc = RIG_freeRigArc;
+ rg->free_node = NULL;
+
+#ifdef USE_THREADS
+ totthread = TASK_SCHEDULER_AUTO_THREADS;
+#else
+ totthread = TASK_SCHEDULER_SINGLE_THREAD;
+#endif
+
+ rg->task_scheduler = BLI_task_scheduler_create(totthread);
+ rg->task_pool = BLI_task_pool_create(rg->task_scheduler, NULL);
+
+ return rg;
+}
+
+static RigArc *newRigArc(RigGraph *rg)
+{
+ RigArc *arc;
+
+ arc = MEM_callocN(sizeof(RigArc), "rig arc");
+ arc->count = 0;
+ BLI_addtail(&rg->arcs, arc);
+
+ return arc;
+}
+
+static RigControl *newRigControl(RigGraph *rg)
+{
+ RigControl *ctrl;
+
+ ctrl = MEM_callocN(sizeof(RigControl), "rig control");
+
+ BLI_addtail(&rg->controls, ctrl);
+
+ return ctrl;
+}
+
+static RigNode *newRigNodeHead(RigGraph *rg, RigArc *arc, float p[3])
+{
+ RigNode *node;
+ node = MEM_callocN(sizeof(RigNode), "rig node");
+ BLI_addtail(&rg->nodes, node);
+
+ copy_v3_v3(node->p, p);
+ node->degree = 1;
+ node->arcs = NULL;
+
+ arc->head = node;
+
+ return node;
+}
+
+static void addRigNodeHead(RigGraph *UNUSED(rg), RigArc *arc, RigNode *node)
+{
+ node->degree++;
+
+ arc->head = node;
+}
+
+static RigNode *newRigNode(RigGraph *rg, float p[3])
+{
+ RigNode *node;
+ node = MEM_callocN(sizeof(RigNode), "rig node");
+ BLI_addtail(&rg->nodes, node);
+
+ copy_v3_v3(node->p, p);
+ node->degree = 0;
+ node->arcs = NULL;
+
+ return node;
+}
+
+static RigNode *newRigNodeTail(RigGraph *rg, RigArc *arc, float p[3])
+{
+ RigNode *node = newRigNode(rg, p);
+
+ node->degree = 1;
+ arc->tail = node;
+
+ return node;
+}
+
+static void RIG_appendEdgeToArc(RigArc *arc, RigEdge *edge)
+{
+ BLI_addtail(&arc->edges, edge);
+
+ if (edge->prev == NULL) {
+ copy_v3_v3(edge->head, arc->head->p);
+ }
+ else {
+ RigEdge *last_edge = edge->prev;
+ copy_v3_v3(edge->head, last_edge->tail);
+ RIG_calculateEdgeAngles(last_edge, edge);
+ }
+
+ edge->length = len_v3v3(edge->head, edge->tail);
+
+ arc->length += edge->length;
+
+ arc->count += 1;
+}
+
+static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone)
+{
+ RigEdge *edge;
+
+ edge = MEM_callocN(sizeof(RigEdge), "rig edge");
+
+ copy_v3_v3(edge->tail, tail);
+ edge->bone = bone;
+
+ if (bone) {
+ getEditBoneRollUpAxis(bone, bone->roll, edge->up_axis);
+ }
+
+ RIG_appendEdgeToArc(arc, edge);
+}
+/************************************** CLONING TEMPLATES **********************************************/
+
+static void renameTemplateBone(char *name, char *template_name, ListBase *editbones, char *side_string, char *num_string)
+{
+ int i, j;
+
+ for (i = 0, j = 0; i < (MAXBONENAME - 1) && j < (MAXBONENAME - 1) && template_name[i] != '\0'; i++) {
+ if (template_name[i] == '&') {
+ if (template_name[i + 1] == 'S' || template_name[i + 1] == 's') {
+ j += BLI_strncpy_rlen(name + j, side_string, MAXBONENAME);
+ i++;
+ }
+ else if (template_name[i + 1] == 'N' || template_name[i + 1] == 'n') {
+ j += BLI_strncpy_rlen(name + j, num_string, MAXBONENAME);
+ i++;
+ }
+ else {
+ name[j] = template_name[i];
+ j++;
+ }
+ }
+ else {
+ name[j] = template_name[i];
+ j++;
+ }
+ }
+
+ name[j] = '\0';
+
+ ED_armature_ebone_unique_name(editbones, name, NULL);
+}
+
+static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash, char *side_string, char *num_string)
+{
+ RigControl *ctrl;
+ char name[MAXBONENAME];
+
+ ctrl = newRigControl(rg);
+
+ copy_v3_v3(ctrl->head, src_ctrl->head);
+ copy_v3_v3(ctrl->tail, src_ctrl->tail);
+ copy_v3_v3(ctrl->up_axis, src_ctrl->up_axis);
+ copy_v3_v3(ctrl->offset, src_ctrl->offset);
+
+ ctrl->tail_mode = src_ctrl->tail_mode;
+ ctrl->flag = src_ctrl->flag;
+
+ renameTemplateBone(name, src_ctrl->bone->name, rg->editbones, side_string, num_string);
+ ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, name, rg->editbones, src_rg->ob, rg->ob);
+ ctrl->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone);
+
+ ctrl->link = src_ctrl->link;
+ ctrl->link_tail = src_ctrl->link_tail;
+
+ return ctrl;
+}
+
+static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *ptr_hash, char *side_string, char *num_string)
+{
+ RigEdge *src_edge;
+ RigArc *arc;
+
+ arc = newRigArc(rg);
+
+ arc->head = BLI_ghash_lookup(ptr_hash, src_arc->head);
+ arc->tail = BLI_ghash_lookup(ptr_hash, src_arc->tail);
+
+ arc->head->degree++;
+ arc->tail->degree++;
+
+ arc->length = src_arc->length;
+
+ arc->count = src_arc->count;
+
+ for (src_edge = src_arc->edges.first; src_edge; src_edge = src_edge->next) {
+ RigEdge *edge;
+
+ edge = MEM_callocN(sizeof(RigEdge), "rig edge");
+
+ copy_v3_v3(edge->head, src_edge->head);
+ copy_v3_v3(edge->tail, src_edge->tail);
+ copy_v3_v3(edge->up_axis, src_edge->up_axis);
+
+ edge->length = src_edge->length;
+ edge->angle = src_edge->angle;
+ edge->up_angle = src_edge->up_angle;
+
+ if (src_edge->bone != NULL) {
+ char name[MAXBONENAME];
+ renameTemplateBone(name, src_edge->bone->name, rg->editbones, side_string, num_string);
+ edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob);
+ edge->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone);
+ }
+
+ BLI_addtail(&arc->edges, edge);
+ }
+
+ return arc;
+}
+
+static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob, char *side_string, char *num_string)
+{
+ GHash *ptr_hash;
+ RigNode *node;
+ RigArc *arc;
+ RigControl *ctrl;
+ RigGraph *rg;
+
+ ptr_hash = BLI_ghash_ptr_new("cloneRigGraph gh");
+
+ rg = newRigGraph();
+
+ rg->ob = ob;
+ rg->editbones = editbones;
+
+ preEditBoneDuplicate(rg->editbones); /* prime bones for duplication */
+ preEditBoneDuplicate(src->editbones); /* prime bones for duplication */
+
+ /* Clone nodes */
+ for (node = src->nodes.first; node; node = node->next) {
+ RigNode *cloned_node = newRigNode(rg, node->p);
+ BLI_ghash_insert(ptr_hash, node, cloned_node);
+ }
+
+ rg->head = BLI_ghash_lookup(ptr_hash, src->head);
+
+ /* Clone arcs */
+ for (arc = src->arcs.first; arc; arc = arc->next) {
+ cloneArc(rg, src, arc, ptr_hash, side_string, num_string);
+ }
+
+ /* Clone controls */
+ for (ctrl = src->controls.first; ctrl; ctrl = ctrl->next) {
+ cloneControl(rg, src, ctrl, ptr_hash, side_string, num_string);
+ }
+
+ /* Relink bones properly */
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ RigEdge *edge;
+
+ for (edge = arc->edges.first; edge; edge = edge->next) {
+ if (edge->bone != NULL) {
+ EditBone *bone;
+
+ updateDuplicateSubtargetObjects(edge->bone, src->editbones, src->ob, rg->ob);
+
+ if (edge->bone->parent) {
+ bone = BLI_ghash_lookup(ptr_hash, edge->bone->parent);
+
+ if (bone != NULL) {
+ edge->bone->parent = bone;
+ }
+ else {
+ /* disconnect since parent isn't cloned
+ * this will only happen when cloning from selected bones
+ * */
+ edge->bone->flag &= ~BONE_CONNECTED;
+ }
+ }
+ }
+ }
+ }
+
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
+ EditBone *bone;
+
+ updateDuplicateSubtargetObjects(ctrl->bone, src->editbones, src->ob, rg->ob);
+
+ if (ctrl->bone->parent) {
+ bone = BLI_ghash_lookup(ptr_hash, ctrl->bone->parent);
+
+ if (bone != NULL) {
+ ctrl->bone->parent = bone;
+ }
+ else {
+ /* disconnect since parent isn't cloned
+ * this will only happen when cloning from selected bones
+ * */
+ ctrl->bone->flag &= ~BONE_CONNECTED;
+ }
+ }
+
+ ctrl->link = BLI_ghash_lookup(ptr_hash, ctrl->link);
+ ctrl->link_tail = BLI_ghash_lookup(ptr_hash, ctrl->link_tail);
+ }
+
+ BLI_ghash_free(ptr_hash, NULL, NULL);
+
+ return rg;
+}
+
+
+/*******************************************************************************************************/
+
+static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second)
+{
+ float vec_first[3], vec_second[3];
+
+ sub_v3_v3v3(vec_first, edge_first->tail, edge_first->head);
+ sub_v3_v3v3(vec_second, edge_second->tail, edge_second->head);
+
+ normalize_v3(vec_first);
+ normalize_v3(vec_second);
+
+ edge_first->angle = angle_normalized_v3v3(vec_first, vec_second);
+
+ if (edge_second->bone != NULL) {
+ float normal[3];
+
+ cross_v3_v3v3(normal, vec_first, vec_second);
+ normalize_v3(normal);
+
+ edge_second->up_angle = angle_normalized_v3v3(normal, edge_second->up_axis);
+ }
+}
+
+/************************************ CONTROL BONES ****************************************************/
+
+static void RIG_addControlBone(RigGraph *rg, EditBone *bone)
+{
+ RigControl *ctrl = newRigControl(rg);
+ ctrl->bone = bone;
+ copy_v3_v3(ctrl->head, bone->head);
+ copy_v3_v3(ctrl->tail, bone->tail);
+ getEditBoneRollUpAxis(bone, bone->roll, ctrl->up_axis);
+ ctrl->tail_mode = TL_NONE;
+
+ BLI_ghash_insert(rg->controls_map, bone->name, ctrl);
+}
+
+static int RIG_parentControl(RigControl *ctrl, EditBone *link)
+{
+ if (link) {
+ float offset[3];
+ int flag = 0;
+
+ sub_v3_v3v3(offset, ctrl->bone->head, link->head);
+
+ /* if root matches, check for direction too */
+ if (dot_v3v3(offset, offset) < 0.0001f) {
+ float vbone[3], vparent[3];
+
+ flag |= RIG_CTRL_FIT_ROOT;
+
+ sub_v3_v3v3(vbone, ctrl->bone->tail, ctrl->bone->head);
+ sub_v3_v3v3(vparent, link->tail, link->head);
+
+ /* test for opposite direction */
+ if (dot_v3v3(vbone, vparent) > 0) {
+ float nor[3];
+ float len;
+
+ cross_v3_v3v3(nor, vbone, vparent);
+
+ len = dot_v3v3(nor, nor);
+ if (len < 0.0001f) {
+ flag |= RIG_CTRL_FIT_BONE;
+ }
+ }
+ }
+
+ /* Bail out if old one is automatically better */
+ if (flag < ctrl->flag) {
+ return 0;
+ }
+
+ /* if there's already a link
+ * overwrite only if new link is higher in the chain */
+ if (ctrl->link && flag == ctrl->flag) {
+ EditBone *bone = NULL;
+
+ for (bone = ctrl->link; bone; bone = bone->parent) {
+ /* if link is in the chain, break and use that one */
+ if (bone == link) {
+ break;
+ }
+ }
+
+ /* not in chain, don't update link */
+ if (bone == NULL) {
+ return 0;
+ }
+ }
+
+
+ ctrl->link = link;
+ ctrl->flag = flag;
+
+ copy_v3_v3(ctrl->offset, offset);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void RIG_reconnectControlBones(RigGraph *rg)
+{
+ RigControl *ctrl;
+ bool changed = true;
+
+ /* first pass, link to deform bones */
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
+ bPoseChannel *pchan;
+ bConstraint *con;
+ int found = 0;
+
+ /* DO SOME MAGIC HERE */
+ for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ for (con = pchan->constraints.first; con; con = con->next) {
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ /* constraint targets */
+ if (cti && cti->get_constraint_targets) {
+ int target_index;
+
+ cti->get_constraint_targets(con, &targets);
+
+ for (target_index = 0, ct = targets.first; ct; target_index++, ct = ct->next) {
+ if ((ct->tar == rg->ob) && STREQ(ct->subtarget, ctrl->bone->name)) {
+ /* SET bone link to bone corresponding to pchan */
+ EditBone *link = BLI_ghash_lookup(rg->bones_map, pchan->name);
+
+ /* Making sure bone is in this armature */
+ if (link != NULL) {
+ /* for pole targets, link to parent bone instead, if possible */
+ if (con->type == CONSTRAINT_TYPE_KINEMATIC && target_index == 1) {
+ if (link->parent && BLI_ghash_haskey(rg->bones_map, link->parent->name)) {
+ link = link->parent;
+ }
+ }
+
+ found = RIG_parentControl(ctrl, link);
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
+ }
+ }
+
+ /* if not found yet, check parent */
+ if (found == 0) {
+ if (ctrl->bone->parent) {
+ /* make sure parent is a deforming bone
+ * NULL if not
+ * */
+ EditBone *link = BLI_ghash_lookup(rg->bones_map, ctrl->bone->parent->name);
+
+ found = RIG_parentControl(ctrl, link);
+ }
+
+ /* check if bone is not superposed on another one */
+ {
+ RigArc *arc;
+ RigArc *best_arc = NULL;
+ EditBone *link = NULL;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ RigEdge *edge;
+ for (edge = arc->edges.first; edge; edge = edge->next) {
+ if (edge->bone) {
+ int fit = 0;
+
+ fit = len_v3v3(ctrl->bone->head, edge->bone->head) < 0.0001f;
+ fit = fit || len_v3v3(ctrl->bone->tail, edge->bone->tail) < 0.0001f;
+
+ if (fit) {
+ /* pick the bone on the arc with the lowest symmetry level
+ * means you connect control to the trunk of the skeleton */
+ if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level) {
+ best_arc = arc;
+ link = edge->bone;
+ }
+ }
+ }
+ }
+ }
+
+ found = RIG_parentControl(ctrl, link);
+ }
+ }
+
+ /* if not found yet, check child */
+ if (found == 0) {
+ RigArc *arc;
+ RigArc *best_arc = NULL;
+ EditBone *link = NULL;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ RigEdge *edge;
+ for (edge = arc->edges.first; edge; edge = edge->next) {
+ if (edge->bone && edge->bone->parent == ctrl->bone) {
+ /* pick the bone on the arc with the lowest symmetry level
+ * means you connect control to the trunk of the skeleton */
+ if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level) {
+ best_arc = arc;
+ link = edge->bone;
+ }
+ }
+ }
+ }
+
+ found = RIG_parentControl(ctrl, link);
+ }
+
+ }
+
+
+ /* second pass, make chains in control bones */
+ while (changed) {
+ changed = false;
+
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
+ /* if control is not linked yet */
+ if (ctrl->link == NULL) {
+ bPoseChannel *pchan;
+ bConstraint *con;
+ RigControl *ctrl_parent = NULL;
+ RigControl *ctrl_child;
+ int found = 0;
+
+ if (ctrl->bone->parent) {
+ ctrl_parent = BLI_ghash_lookup(rg->controls_map, ctrl->bone->parent->name);
+ }
+
+ /* check constraints first */
+
+ /* DO SOME MAGIC HERE */
+ for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ for (con = pchan->constraints.first; con; con = con->next) {
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ /* constraint targets */
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct = targets.first; ct; ct = ct->next) {
+ if ((ct->tar == rg->ob) && STREQ(ct->subtarget, ctrl->bone->name)) {
+ /* SET bone link to ctrl corresponding to pchan */
+ RigControl *link = BLI_ghash_lookup(rg->controls_map, pchan->name);
+
+ /* if owner is a control bone, link with it */
+ if (link && link->link) {
+ RIG_parentControl(ctrl, link->bone);
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
+ }
+ }
+
+ if (found == 0) {
+ /* check if parent is already linked */
+ if (ctrl_parent && ctrl_parent->link) {
+ RIG_parentControl(ctrl, ctrl_parent->bone);
+ changed = true;
+ }
+ else {
+ /* check childs */
+ for (ctrl_child = rg->controls.first; ctrl_child; ctrl_child = ctrl_child->next) {
+ /* if a child is linked, link to that one */
+ if (ctrl_child->link && ctrl_child->bone->parent == ctrl->bone) {
+ RIG_parentControl(ctrl, ctrl_child->bone);
+ changed = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* third pass, link control tails */
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
+ /* fit bone already means full match, so skip those */
+ if ((ctrl->flag & RIG_CTRL_FIT_BONE) == 0) {
+ GHashIterator ghi;
+
+ /* look on deform bones first */
+ BLI_ghashIterator_init(&ghi, rg->bones_map);
+
+ for (; !BLI_ghashIterator_done(&ghi); BLI_ghashIterator_step(&ghi)) {
+ EditBone *bone = (EditBone *)BLI_ghashIterator_getValue(&ghi);
+
+ /* don't link with parent */
+ if (bone->parent != ctrl->bone) {
+ if (len_v3v3(ctrl->bone->tail, bone->head) < 0.01f) {
+ ctrl->tail_mode = TL_HEAD;
+ ctrl->link_tail = bone;
+ break;
+ }
+ else if (len_v3v3(ctrl->bone->tail, bone->tail) < 0.01f) {
+ ctrl->tail_mode = TL_TAIL;
+ ctrl->link_tail = bone;
+ break;
+ }
+ }
+ }
+
+ /* if we haven't found one yet, look in control bones */
+ if (ctrl->tail_mode == TL_NONE) {
+ /* pass */
+ }
+ }
+ }
+
+}
+
+/*******************************************************************************************************/
+
+static void RIG_joinArcs(RigGraph *rg, RigNode *node, RigArc *joined_arc1, RigArc *joined_arc2)
+{
+ RigEdge *edge, *next_edge;
+
+ /* ignore cases where joint is at start or end */
+ if (joined_arc1->head == joined_arc2->head || joined_arc1->tail == joined_arc2->tail) {
+ return;
+ }
+
+ /* swap arcs to make sure arc1 is before arc2 */
+ if (joined_arc1->head == joined_arc2->tail) {
+ RigArc *tmp = joined_arc1;
+ joined_arc1 = joined_arc2;
+ joined_arc2 = tmp;
+ }
+
+ for (edge = joined_arc2->edges.first; edge; edge = next_edge) {
+ next_edge = edge->next;
+
+ RIG_appendEdgeToArc(joined_arc1, edge);
+ }
+
+ joined_arc1->tail = joined_arc2->tail;
+
+ BLI_listbase_clear(&joined_arc2->edges);
+
+ BLI_removeArc((BGraph *)rg, (BArc *)joined_arc2);
+
+ BLI_removeNode((BGraph *)rg, (BNode *)node);
+}
+
+static void RIG_removeNormalNodes(RigGraph *rg)
+{
+ RigNode *node, *next_node;
+
+ for (node = rg->nodes.first; node; node = next_node) {
+ next_node = node->next;
+
+ if (node->degree == 2) {
+ RigArc *arc, *joined_arc1 = NULL, *joined_arc2 = NULL;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ if (arc->head == node || arc->tail == node) {
+ if (joined_arc1 == NULL) {
+ joined_arc1 = arc;
+ }
+ else {
+ joined_arc2 = arc;
+ break;
+ }
+ }
+ }
+
+ RIG_joinArcs(rg, node, joined_arc1, joined_arc2);
+ }
+ }
+}
+
+static void RIG_removeUneededOffsets(RigGraph *rg)
+{
+ RigArc *arc;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ RigEdge *first_edge, *last_edge;
+
+ first_edge = arc->edges.first;
+ last_edge = arc->edges.last;
+
+ if (first_edge->bone == NULL) {
+ if (first_edge->bone == NULL && len_v3v3(first_edge->tail, arc->head->p) <= 0.001f) {
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+ }
+ else if (arc->head->degree == 1) {
+ RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, first_edge->tail, 0.001f);
+
+ if (new_node) {
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+ BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->head);
+ }
+ else {
+ RigEdge *next_edge = first_edge->next;
+
+ if (next_edge) {
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+
+ copy_v3_v3(arc->head->p, next_edge->head);
+ }
+ }
+ }
+ else {
+ /* check if all arc connected start with a null edge */
+ RigArc *other_arc;
+ for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) {
+ if (other_arc != arc) {
+ RigEdge *test_edge;
+ if (other_arc->head == arc->head) {
+ test_edge = other_arc->edges.first;
+
+ if (test_edge->bone != NULL) {
+ break;
+ }
+ }
+ else if (other_arc->tail == arc->head) {
+ test_edge = other_arc->edges.last;
+
+ if (test_edge->bone != NULL) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (other_arc == NULL) {
+ RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, first_edge->tail, 0.001);
+
+ if (new_node) {
+ /* remove null edge in other arcs too */
+ for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) {
+ if (other_arc != arc) {
+ RigEdge *test_edge;
+ if (other_arc->head == arc->head) {
+ BLI_replaceNodeInArc((BGraph *)rg, (BArc *)other_arc, (BNode *)new_node, (BNode *)other_arc->head);
+ test_edge = other_arc->edges.first;
+ BLI_remlink(&other_arc->edges, test_edge);
+ MEM_freeN(test_edge);
+ }
+ else if (other_arc->tail == arc->head) {
+ BLI_replaceNodeInArc((BGraph *)rg, (BArc *)other_arc, (BNode *)new_node, (BNode *)other_arc->tail);
+ test_edge = other_arc->edges.last;
+ BLI_remlink(&other_arc->edges, test_edge);
+ MEM_freeN(test_edge);
+ }
+ }
+ }
+
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+ BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->head);
+ }
+ else {
+ RigEdge *next_edge = first_edge->next;
+
+ if (next_edge) {
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+
+ copy_v3_v3(arc->head->p, next_edge->head);
+
+ /* remove null edge in other arcs too */
+ for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) {
+ if (other_arc != arc) {
+ RigEdge *test_edge;
+ if (other_arc->head == arc->head) {
+ test_edge = other_arc->edges.first;
+ BLI_remlink(&other_arc->edges, test_edge);
+ MEM_freeN(test_edge);
+ }
+ else if (other_arc->tail == arc->head) {
+ test_edge = other_arc->edges.last;
+ BLI_remlink(&other_arc->edges, test_edge);
+ MEM_freeN(test_edge);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (last_edge->bone == NULL) {
+ if (len_v3v3(last_edge->head, arc->tail->p) <= 0.001f) {
+ BLI_remlink(&arc->edges, last_edge);
+ MEM_freeN(last_edge);
+ }
+ else if (arc->tail->degree == 1) {
+ RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, last_edge->head, 0.001f);
+
+ if (new_node) {
+ RigEdge *previous_edge = last_edge->prev;
+
+ BLI_remlink(&arc->edges, last_edge);
+ MEM_freeN(last_edge);
+ BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->tail);
+
+ /* set previous angle to 0, since there's no following edges */
+ if (previous_edge) {
+ previous_edge->angle = 0;
+ }
+ }
+ else {
+ RigEdge *previous_edge = last_edge->prev;
+
+ if (previous_edge) {
+ BLI_remlink(&arc->edges, last_edge);
+ MEM_freeN(last_edge);
+
+ copy_v3_v3(arc->tail->p, previous_edge->tail);
+ previous_edge->angle = 0;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node, bool selected)
+{
+ EditBone *bone, *last_bone = root_bone;
+ RigArc *arc = NULL;
+ int contain_head = 0;
+
+ for (bone = root_bone; bone; bone = nextEditBoneChild(list, bone, 0)) {
+ int nb_children;
+
+ if (selected == 0 || (bone->flag & BONE_SELECTED)) {
+ if ((bone->flag & BONE_NO_DEFORM) == 0) {
+ BLI_ghash_insert(rg->bones_map, bone->name, bone);
+
+ if (arc == NULL) {
+ arc = newRigArc(rg);
+
+ if (starting_node == NULL) {
+ starting_node = newRigNodeHead(rg, arc, root_bone->head);
+ }
+ else {
+ addRigNodeHead(rg, arc, starting_node);
+ }
+ }
+
+ if (bone->parent && (bone->flag & BONE_CONNECTED) == 0) {
+ RIG_addEdgeToArc(arc, bone->head, NULL);
+ }
+
+ RIG_addEdgeToArc(arc, bone->tail, bone);
+
+ last_bone = bone;
+
+ if (STREQ(bone->name, "head")) {
+ contain_head = 1;
+ }
+ }
+ else if ((bone->flag & BONE_EDITMODE_LOCKED) == 0) { /* ignore locked bones */
+ RIG_addControlBone(rg, bone);
+ }
+ }
+
+ nb_children = countEditBoneChildren(list, bone);
+ if (nb_children > 1) {
+ RigNode *end_node = NULL;
+ int i;
+
+ if (arc != NULL) {
+ end_node = newRigNodeTail(rg, arc, bone->tail);
+ }
+ else {
+ end_node = newRigNode(rg, bone->tail);
+ }
+
+ for (i = 0; i < nb_children; i++) {
+ root_bone = nextEditBoneChild(list, bone, i);
+ RIG_arcFromBoneChain(rg, list, root_bone, end_node, selected);
+ }
+
+ /* arc ends here, break */
+ break;
+ }
+ }
+
+ /* If the loop exited without forking */
+ if (arc != NULL && bone == NULL) {
+ newRigNodeTail(rg, arc, last_bone->tail);
+ }
+
+ if (contain_head) {
+ rg->head = arc->tail;
+ }
+}
+
+/*******************************************************************************************************/
+static void RIG_findHead(RigGraph *rg)
+{
+ if (rg->head == NULL) {
+ if (BLI_listbase_is_single(&rg->arcs)) {
+ RigArc *arc = rg->arcs.first;
+
+ rg->head = (RigNode *)arc->head;
+ }
+ else {
+ RigArc *arc;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ RigEdge *edge = arc->edges.last;
+
+ if (edge->bone->flag & (BONE_TIPSEL | BONE_SELECTED)) {
+ rg->head = arc->tail;
+ break;
+ }
+ }
+ }
+
+ if (rg->head == NULL) {
+ rg->head = rg->nodes.first;
+ }
+ }
+}
+
+/*******************************************************************************************************/
+
+static void RIG_printNode(RigNode *node, const char name[])
+{
+ printf("%s %p %i <%0.3f, %0.3f, %0.3f>\n", name, (void *)node, node->degree, node->p[0], node->p[1], node->p[2]);
+
+ if (node->symmetry_flag & SYM_TOPOLOGICAL) {
+ if (node->symmetry_flag & SYM_AXIAL)
+ printf("Symmetry AXIAL\n");
+ else if (node->symmetry_flag & SYM_RADIAL)
+ printf("Symmetry RADIAL\n");
+
+ print_v3("symmetry axis", node->symmetry_axis);
+ }
+}
+
+void RIG_printArcBones(RigArc *arc)
+{
+ RigEdge *edge;
+
+ for (edge = arc->edges.first; edge; edge = edge->next) {
+ if (edge->bone)
+ printf("%s ", edge->bone->name);
+ else
+ printf("---- ");
+ }
+ printf("\n");
+}
+
+static void RIG_printCtrl(RigControl *ctrl, char *indent)
+{
+ char text[128];
+
+ printf("%sBone: %s\n", indent, ctrl->bone->name);
+ printf("%sLink: %s\n", indent, ctrl->link ? ctrl->link->name : "!NONE!");
+
+ BLI_snprintf(text, sizeof(text), "%soffset", indent);
+ print_v3(text, ctrl->offset);
+
+ printf("%sFlag: %i\n", indent, ctrl->flag);
+}
+
+static void RIG_printLinkedCtrl(RigGraph *rg, EditBone *bone, int tabs)
+{
+ RigControl *ctrl;
+ char indent[64];
+ char *s = indent;
+ int i;
+
+ for (i = 0; i < tabs; i++) {
+ s[0] = '\t';
+ s++;
+ }
+ s[0] = 0;
+
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) {
+ if (ctrl->link == bone) {
+ RIG_printCtrl(ctrl, indent);
+ RIG_printLinkedCtrl(rg, ctrl->bone, tabs + 1);
+ }
+ }
+}
+
+void RIG_printArc(RigGraph *rg, RigArc *arc)
+{
+ RigEdge *edge;
+
+ RIG_printNode((RigNode *)arc->head, "head");
+
+ for (edge = arc->edges.first; edge; edge = edge->next) {
+ printf("\tinner joints %0.3f %0.3f %0.3f\n", edge->tail[0], edge->tail[1], edge->tail[2]);
+ printf("\t\tlength %f\n", edge->length);
+ printf("\t\tangle %f\n", edge->angle * (float)(180 / M_PI));
+ if (edge->bone) {
+ printf("\t\t%s\n", edge->bone->name);
+ RIG_printLinkedCtrl(rg, edge->bone, 3);
+ }
+ }
+ printf("symmetry level: %i flag: %i group %i\n", arc->symmetry_level, arc->symmetry_flag, arc->symmetry_group);
+
+ RIG_printNode((RigNode *)arc->tail, "tail");
+}
+
+void RIG_printGraph(RigGraph *rg)
+{
+ RigArc *arc;
+
+ printf("---- ARCS ----\n");
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ RIG_printArc(rg, arc);
+ printf("\n");
+ }
+
+ if (rg->head) {
+ RIG_printNode(rg->head, "HEAD NODE:");
+ }
+ else {
+ printf("HEAD NODE: NONE\n");
+ }
+}
+
+/*******************************************************************************************************/
+
+RigGraph *RIG_graphFromArmature(const bContext *C, Object *ob, bArmature *arm)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ EditBone *ebone;
+ RigGraph *rg;
+
+ rg = newRigGraph();
+
+ if (obedit == ob) {
+ rg->editbones = ((bArmature *)obedit->data)->edbo;
+ }
+ else {
+ rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
+ make_boneList(rg->editbones, &arm->bonebase, NULL, NULL);
+ rg->flag |= RIG_FREE_BONELIST;
+ }
+
+ rg->ob = ob;
+
+ /* Do the rotations */
+ for (ebone = rg->editbones->first; ebone; ebone = ebone->next) {
+ if (ebone->parent == NULL) {
+ RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 0);
+ }
+ }
+
+ BLI_removeDoubleNodes((BGraph *)rg, 0.001);
+
+ RIG_removeNormalNodes(rg);
+
+ RIG_removeUneededOffsets(rg);
+
+ BLI_buildAdjacencyList((BGraph *)rg);
+
+ RIG_findHead(rg);
+
+ BLI_markdownSymmetry((BGraph *)rg, (BNode *)rg->head, scene->toolsettings->skgen_symmetry_limit);
+
+ RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
+
+ if (BLI_isGraphCyclic((BGraph *)rg)) {
+ printf("armature cyclic\n");
+ }
+
+ return rg;
+}
+
+static RigGraph *armatureSelectedToGraph(bContext *C, Object *ob, bArmature *arm)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ EditBone *ebone;
+ RigGraph *rg;
+
+ rg = newRigGraph();
+
+ if (obedit == ob) {
+ rg->editbones = arm->edbo;
+ }
+ else {
+ rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
+ make_boneList(rg->editbones, &arm->bonebase, NULL, NULL);
+ rg->flag |= RIG_FREE_BONELIST;
+ }
+
+ rg->ob = ob;
+
+ /* Do the rotations */
+ for (ebone = rg->editbones->first; ebone; ebone = ebone->next) {
+ if (ebone->parent == NULL) {
+ RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 1);
+ }
+ }
+
+ BLI_removeDoubleNodes((BGraph *)rg, 0.001);
+
+ RIG_removeNormalNodes(rg);
+
+ RIG_removeUneededOffsets(rg);
+
+ BLI_buildAdjacencyList((BGraph *)rg);
+
+ RIG_findHead(rg);
+
+ BLI_markdownSymmetry((BGraph *)rg, (BNode *)rg->head, scene->toolsettings->skgen_symmetry_limit);
+
+ RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
+
+ if (BLI_isGraphCyclic((BGraph *)rg)) {
+ printf("armature cyclic\n");
+ }
+
+ return rg;
+}
+/************************************ GENERATING *****************************************************/
+
+#if 0
+static EditBone *add_editbonetolist(char *name, ListBase *list)
+{
+ EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone");
+
+ BLI_strncpy(bone->name, name, sizeof(bone->name));
+ ED_armature_ebone_unique_name(list, bone->name, NULL);
+
+ BLI_addtail(list, bone);
+
+ bone->flag |= BONE_TIPSEL;
+ bone->weight = 1.0F;
+ bone->dist = 0.25F;
+ bone->xwidth = 0.1;
+ bone->zwidth = 0.1;
+ bone->rad_head = 0.10;
+ bone->rad_tail = 0.05;
+ bone->segments = 1;
+ bone->layer = 1; //arm->layer;
+
+ /* Bendy-Bone parameters */
+ bone->roll1 = 0.0f;
+ bone->roll2 = 0.0f;
+ bone->curveInX = 0.0f;
+ bone->curveInY = 0.0f;
+ bone->curveOutX = 0.0f;
+ bone->curveOutY = 0.0f;
+ bone->ease1 = 1.0f;
+ bone->ease2 = 1.0f;
+ bone->scaleIn = 1.0f;
+ bone->scaleOut = 1.0f;
+
+ return bone;
+}
+#endif
+
+#if 0 /* UNUSED */
+static void generateMissingArcsFromNode(RigGraph *rigg, ReebNode *node, int multi_level_limit)
+{
+ while (node->multi_level > multi_level_limit && node->link_up)
+ {
+ node = node->link_up;
+ }
+
+ while (node->multi_level < multi_level_limit && node->link_down)
+ {
+ node = node->link_down;
+ }
+
+ if (node->multi_level == multi_level_limit)
+ {
+ int i;
+
+ for (i = 0; i < node->degree; i++)
+ {
+ ReebArc *earc = node->arcs[i];
+
+ if (earc->flag == ARC_FREE && earc->head == node)
+ {
+ ReebNode *other = BIF_otherNodeFromIndex(earc, node);
+
+ earc->flag = ARC_USED;
+
+ //generateBonesForArc(rigg, earc, node, other);
+ generateMissingArcsFromNode(rigg, other, multi_level_limit);
+ }
+ }
+ }
+}
+
+static void generateMissingArcs(RigGraph *rigg)
+{
+ ReebGraph *reebg;
+ int multi_level_limit = 5;
+
+ for (reebg = rigg->link_mesh; reebg; reebg = reebg->link_up)
+ {
+ ReebArc *earc;
+
+ for (earc = reebg->arcs.first; earc; earc = earc->next)
+ {
+ if (earc->flag == ARC_USED)
+ {
+ generateMissingArcsFromNode(rigg, earc->head, multi_level_limit);
+ generateMissingArcsFromNode(rigg, earc->tail, multi_level_limit);
+ }
+ }
+ }
+}
+#endif
+
+/************************************ RETARGETTING *****************************************************/
+
+static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize);
+
+static void repositionTailControl(RigGraph *rigg, RigControl *ctrl);
+
+static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float resize)
+{
+ if ((ctrl->flag & RIG_CTRL_DONE) == RIG_CTRL_DONE) {
+ RigControl *ctrl_child;
+
+#if 0
+ printf("CTRL: %s LINK: %s", ctrl->bone->name, ctrl->link->name);
+
+ if (ctrl->link_tail)
+ {
+ printf(" TAIL: %s", ctrl->link_tail->name);
+ }
+
+ printf("\n");
+#endif
+
+ /* if there was a tail link: apply link, recalc resize factor and qrot */
+ if (ctrl->tail_mode != TL_NONE) {
+ float *tail_vec = NULL;
+ float v1[3], v2[3], qtail[4];
+
+ if (ctrl->tail_mode == TL_TAIL) {
+ tail_vec = ctrl->link_tail->tail;
+ }
+ else if (ctrl->tail_mode == TL_HEAD) {
+ tail_vec = ctrl->link_tail->head;
+ }
+
+ sub_v3_v3v3(v1, ctrl->bone->tail, ctrl->bone->head);
+ sub_v3_v3v3(v2, tail_vec, ctrl->bone->head);
+
+ copy_v3_v3(ctrl->bone->tail, tail_vec);
+
+ rotation_between_vecs_to_quat(qtail, v1, v2);
+ mul_qt_qtqt(ctrl->qrot, qtail, ctrl->qrot);
+
+ resize = len_v3(v2) / len_v3v3(ctrl->head, ctrl->tail);
+ }
+
+ ctrl->bone->roll = rollBoneByQuat(ctrl->bone, ctrl->up_axis, ctrl->qrot);
+
+ /* Cascade to connected control bones */
+ for (ctrl_child = rigg->controls.first; ctrl_child; ctrl_child = ctrl_child->next) {
+ if (ctrl_child->link == ctrl->bone) {
+ repositionControl(rigg, ctrl_child, ctrl->bone->head, ctrl->bone->tail, ctrl->qrot, resize);
+ }
+ if (ctrl_child->link_tail == ctrl->bone) {
+ repositionTailControl(rigg, ctrl_child);
+ }
+ }
+ }
+}
+
+static void repositionTailControl(RigGraph *rigg, RigControl *ctrl)
+{
+ ctrl->flag |= RIG_CTRL_TAIL_DONE;
+
+ finalizeControl(rigg, ctrl, 1); /* resize will be recalculated anyway so we don't need it */
+}
+
+static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float UNUSED(tail[3]), float qrot[4], float resize)
+{
+ float parent_offset[3], tail_offset[3];
+
+ copy_v3_v3(parent_offset, ctrl->offset);
+ mul_v3_fl(parent_offset, resize);
+ mul_qt_v3(qrot, parent_offset);
+
+ add_v3_v3v3(ctrl->bone->head, head, parent_offset);
+
+ ctrl->flag |= RIG_CTRL_HEAD_DONE;
+
+ copy_qt_qt(ctrl->qrot, qrot);
+
+ if (ctrl->tail_mode == TL_NONE) {
+ sub_v3_v3v3(tail_offset, ctrl->tail, ctrl->head);
+ mul_v3_fl(tail_offset, resize);
+ mul_qt_v3(qrot, tail_offset);
+
+ add_v3_v3v3(ctrl->bone->tail, ctrl->bone->head, tail_offset);
+
+ ctrl->flag |= RIG_CTRL_TAIL_DONE;
+ }
+
+ finalizeControl(rigg, ctrl, resize);
+}
+
+static void repositionBone(bContext *C, RigGraph *rigg, RigEdge *edge, float vec0[3], float vec1[3], float up_axis[3])
+{
+ Scene *scene = CTX_data_scene(C);
+ EditBone *bone;
+ RigControl *ctrl;
+ float qrot[4], resize;
+ float v1[3], v2[3];
+ float l1, l2;
+
+ bone = edge->bone;
+
+ sub_v3_v3v3(v1, edge->tail, edge->head);
+ sub_v3_v3v3(v2, vec1, vec0);
+
+ l1 = normalize_v3(v1);
+ l2 = normalize_v3(v2);
+
+ resize = l2 / l1;
+
+ rotation_between_vecs_to_quat(qrot, v1, v2);
+
+ copy_v3_v3(bone->head, vec0);
+ copy_v3_v3(bone->tail, vec1);
+
+ if (!is_zero_v3(up_axis)) {
+ float qroll[4];
+
+ if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_VIEW) {
+ bone->roll = rollBoneByQuatAligned(bone, edge->up_axis, qrot, qroll, up_axis);
+ }
+ else if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_JOINT) {
+ bone->roll = rollBoneByQuatJoint(edge, edge->prev, qrot, qroll, up_axis);
+ }
+ else {
+ unit_qt(qroll);
+ }
+
+ mul_qt_qtqt(qrot, qroll, qrot);
+ }
+ else {
+ bone->roll = rollBoneByQuat(bone, edge->up_axis, qrot);
+ }
+
+ for (ctrl = rigg->controls.first; ctrl; ctrl = ctrl->next) {
+ if (ctrl->link == bone) {
+ repositionControl(rigg, ctrl, vec0, vec1, qrot, resize);
+ }
+ if (ctrl->link_tail == bone) {
+ repositionTailControl(rigg, ctrl);
+ }
+ }
+}
+
+static RetargetMode detectArcRetargetMode(RigArc *arc);
+static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start);
+
+
+static RetargetMode detectArcRetargetMode(RigArc *iarc)
+{
+ RetargetMode mode = RETARGET_AGGRESSIVE;
+ ReebArc *earc = iarc->link_mesh;
+ RigEdge *edge;
+ int large_angle = 0;
+ float avg_angle = 0;
+ /* float avg_length = 0; */ /* UNUSED */
+ int nb_edges = 0;
+
+
+ for (edge = iarc->edges.first; edge; edge = edge->next) {
+ avg_angle += edge->angle;
+ nb_edges++;
+ }
+
+ avg_angle /= nb_edges - 1; /* -1 because last edge doesn't have an angle */
+
+ /* avg_length = iarc->length / nb_edges; */ /* UNUSED */
+
+
+ if (nb_edges > 2) {
+ for (edge = iarc->edges.first; edge; edge = edge->next) {
+ if (fabsf(edge->angle - avg_angle) > (float)(M_PI / 6)) {
+ large_angle = 1;
+ }
+ }
+ }
+ else if (nb_edges == 2 && avg_angle > 0) {
+ large_angle = 1;
+ }
+
+
+ if (large_angle == 0) {
+ mode = RETARGET_LENGTH;
+ }
+
+ if (earc->bcount <= (iarc->count - 1)) {
+ mode = RETARGET_LENGTH;
+ }
+
+ return mode;
+}
+
+#ifndef USE_THREADS
+static void printMovesNeeded(int *positions, int nb_positions)
+{
+ int moves = 0;
+ int i;
+
+ for (i = 0; i < nb_positions; i++) {
+ moves += positions[i] - (i + 1);
+ }
+
+ printf("%i moves needed\n", moves);
+}
+
+static void printPositions(int *positions, int nb_positions)
+{
+ int i;
+
+ for (i = 0; i < nb_positions; i++) {
+ printf("%i ", positions[i]);
+ }
+ printf("\n");
+}
+#endif
+
+#define MAX_COST FLT_MAX /* FIX ME */
+
+static float costDistance(BArcIterator *iter, float *vec0, float *vec1, int i0, int i1, float distance_weight)
+{
+ EmbedBucket *bucket = NULL;
+ float max_dist = 0;
+ float v1[3], v2[3], c[3];
+ float v1_inpf;
+
+ if (distance_weight > 0) {
+ sub_v3_v3v3(v1, vec0, vec1);
+
+ v1_inpf = dot_v3v3(v1, v1);
+
+ if (v1_inpf > 0) {
+ int j;
+ for (j = i0 + 1; j < i1 - 1; j++) {
+ float dist;
+
+ bucket = IT_peek(iter, j);
+
+ sub_v3_v3v3(v2, bucket->p, vec1);
+
+ cross_v3_v3v3(c, v1, v2);
+
+ dist = dot_v3v3(c, c) / v1_inpf;
+
+ max_dist = dist > max_dist ? dist : max_dist;
+ }
+
+ return distance_weight * max_dist;
+ }
+ else {
+ return MAX_COST;
+ }
+ }
+ else {
+ return 0;
+ }
+}
+
+static float costAngle(float original_angle, float vec_first[3], float vec_second[3], float angle_weight)
+{
+ if (angle_weight > 0) {
+ float current_angle;
+
+ if (!is_zero_v3(vec_first) && !is_zero_v3(vec_second)) {
+ current_angle = saacos(dot_v3v3(vec_first, vec_second));
+
+ return angle_weight * fabsf(current_angle - original_angle);
+ }
+ else {
+ return angle_weight * (float)M_PI;
+ }
+ }
+ else {
+ return 0;
+ }
+}
+
+static float costLength(float original_length, float current_length, float length_weight)
+{
+ if (current_length == 0) {
+ return MAX_COST;
+ }
+ else {
+ float length_ratio = fabsf((current_length - original_length) / original_length);
+ return length_weight * length_ratio * length_ratio;
+ }
+}
+
+#if 0
+static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec1, float *vec2, int i1, int i2)
+{
+ float vec[3];
+ float length;
+
+ sub_v3_v3v3(vec, vec2, vec1);
+ length = normalize_v3(vec);
+
+ return costLength(edge->length, length) + costDistance(iter, vec1, vec2, i1, i2);
+}
+#endif
+
+static float calcCostAngleLengthDistance(BArcIterator *iter, float **UNUSED(vec_cache), RigEdge *edge,
+ float *vec0, float *vec1, float *vec2, int i1, int i2,
+ float angle_weight, float length_weight, float distance_weight)
+{
+ float vec_second[3], vec_first[3];
+ float length2;
+ float new_cost = 0;
+
+ sub_v3_v3v3(vec_second, vec2, vec1);
+ length2 = normalize_v3(vec_second);
+
+
+ /* Angle cost */
+ if (edge->prev) {
+ sub_v3_v3v3(vec_first, vec1, vec0);
+ normalize_v3(vec_first);
+
+ new_cost += costAngle(edge->prev->angle, vec_first, vec_second, angle_weight);
+ }
+
+ /* Length cost */
+ new_cost += costLength(edge->length, length2, length_weight);
+
+ /* Distance cost */
+ new_cost += costDistance(iter, vec1, vec2, i1, i2, distance_weight);
+
+ return new_cost;
+}
+
+static int indexMemoNode(int nb_positions, int previous, int current, int joints_left)
+{
+ return joints_left * nb_positions * nb_positions + current * nb_positions + previous;
+}
+
+static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions, int joints_left)
+{
+ int previous = 0, current = 0;
+ int i = 0;
+
+ for (i = 0; joints_left > 0; joints_left--, i++) {
+ MemoNode *node;
+ node = table + indexMemoNode(nb_positions, previous, current, joints_left);
+
+ positions[i] = node->next;
+
+ previous = current;
+ current = node->next;
+ }
+}
+
+static MemoNode *solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache,
+ int nb_joints, int nb_positions, int previous, int current, RigEdge *edge,
+ int joints_left, float angle_weight, float length_weight, float distance_weight)
+{
+ MemoNode *node;
+ int index = indexMemoNode(nb_positions, previous, current, joints_left);
+
+ node = table + index;
+
+ if (node->weight != 0) {
+ return node;
+ }
+ else if (joints_left == 0) {
+ float *vec0 = vec_cache[previous];
+ float *vec1 = vec_cache[current];
+ float *vec2 = vec_cache[nb_positions + 1];
+
+ node->weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, iter->length, angle_weight, length_weight, distance_weight);
+
+ return node;
+ }
+ else {
+ MemoNode *min_node = NULL;
+ float *vec0 = vec_cache[previous];
+ float *vec1 = vec_cache[current];
+ float min_weight = 0.0f;
+ int min_next = 0;
+ int next;
+
+ for (next = current + 1; next <= nb_positions - (joints_left - 1); next++) {
+ MemoNode *next_node;
+ float *vec2 = vec_cache[next];
+ float weight = 0.0f;
+
+ /* ADD WEIGHT OF PREVIOUS - CURRENT - NEXT triple */
+ weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, next, angle_weight, length_weight, distance_weight);
+
+ if (weight >= MAX_COST) {
+ continue;
+ }
+
+ /* add node weight */
+ next_node = solveJoints(table, iter, vec_cache, nb_joints, nb_positions, current, next, edge->next, joints_left - 1, angle_weight, length_weight, distance_weight);
+ weight += next_node->weight;
+
+ if (min_node == NULL || weight < min_weight) {
+ min_weight = weight;
+ min_node = next_node;
+ min_next = next;
+ }
+ }
+
+ if (min_node) {
+ node->weight = min_weight;
+ node->next = min_next;
+ return node;
+ }
+ else {
+ node->weight = MAX_COST;
+ return node;
+ }
+ }
+
+}
+
+static int testFlipArc(RigArc *iarc, RigNode *inode_start)
+{
+ ReebArc *earc = iarc->link_mesh;
+ ReebNode *enode_start = BIF_NodeFromIndex(earc, inode_start->link_mesh);
+
+ /* no flip needed if both nodes are the same */
+ if ((enode_start == earc->head && inode_start == iarc->head) ||
+ (enode_start == earc->tail && inode_start == iarc->tail))
+ {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
+{
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator *)&arc_iter;
+ RigEdge *edge;
+ ReebNode *node_start, *node_end;
+ ReebArc *earc = iarc->link_mesh;
+ float angle_weight = 1.0; // GET FROM CONTEXT
+ float length_weight = 1.0;
+ float distance_weight = 1.0;
+#ifndef USE_THREADS
+ float min_cost = FLT_MAX;
+#endif
+ float *vec0, *vec1;
+ int *best_positions;
+ int nb_edges = BLI_listbase_count(&iarc->edges);
+ int nb_joints = nb_edges - 1;
+ RetargetMethod method = METHOD_MEMOIZE;
+ int i;
+
+ if (nb_joints > earc->bcount) {
+ printf("NOT ENOUGH BUCKETS!\n");
+ return;
+ }
+
+ best_positions = MEM_callocN(sizeof(int) * nb_joints, "Best positions");
+
+ if (testFlipArc(iarc, inode_start)) {
+ node_start = earc->tail;
+ node_end = earc->head;
+ }
+ else {
+ node_start = earc->head;
+ node_end = earc->tail;
+ }
+
+ /* equal number of joints and potential position, just fill them in */
+ if (nb_joints == earc->bcount) {
+ /* init with first values */
+ for (i = 0; i < nb_joints; i++) {
+ best_positions[i] = i + 1;
+ }
+ }
+ if (method == METHOD_MEMOIZE) {
+ int nb_positions = earc->bcount;
+ int nb_memo_nodes = nb_positions * nb_positions * (nb_joints + 1);
+ MemoNode *table = MEM_callocN(nb_memo_nodes * sizeof(MemoNode), "memoization table");
+#ifndef USE_THREADS
+ MemoNode *result;
+#endif
+ float **positions_cache = MEM_callocN(sizeof(float *) * (nb_positions + 2), "positions cache");
+
+ positions_cache[0] = node_start->p;
+ positions_cache[nb_positions + 1] = node_end->p;
+
+ initArcIterator(iter, earc, node_start);
+
+ for (i = 1; i <= nb_positions; i++) {
+ EmbedBucket *bucket = IT_peek(iter, i);
+ positions_cache[i] = bucket->p;
+ }
+
+#ifndef USE_THREADS
+ result = solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight);
+ min_cost = result->weight;
+#else
+ solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight);
+#endif
+
+ copyMemoPositions(best_positions, table, earc->bcount, nb_joints);
+
+ MEM_freeN(table);
+ MEM_freeN(positions_cache);
+ }
+
+ vec0 = node_start->p;
+ initArcIterator(iter, earc, node_start);
+
+#ifndef USE_THREADS
+ printPositions(best_positions, nb_joints);
+ printMovesNeeded(best_positions, nb_joints);
+ printf("min_cost %f\n", min_cost);
+ printf("buckets: %i\n", earc->bcount);
+#endif
+
+ /* set joints to best position */
+ for (edge = iarc->edges.first, i = 0;
+ edge;
+ edge = edge->next, i++)
+ {
+ float *no = NULL;
+ if (i < nb_joints) {
+ EmbedBucket *bucket = IT_peek(iter, best_positions[i]);
+ vec1 = bucket->p;
+ no = bucket->no;
+ }
+ else {
+ vec1 = node_end->p;
+ no = node_end->no;
+ }
+
+ if (edge->bone) {
+ repositionBone(C, rigg, edge, vec0, vec1, no);
+ }
+
+ vec0 = vec1;
+ }
+
+ MEM_freeN(best_positions);
+}
+
+static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
+{
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator *)&arc_iter;
+ ReebArc *earc = iarc->link_mesh;
+ ReebNode *node_start, *node_end;
+ RigEdge *edge;
+ EmbedBucket *bucket = NULL;
+ float embedding_length = 0;
+ float *vec0 = NULL;
+ float *vec1 = NULL;
+ float *previous_vec = NULL;
+
+
+ if (testFlipArc(iarc, inode_start)) {
+ node_start = (ReebNode *)earc->tail;
+ node_end = (ReebNode *)earc->head;
+ }
+ else {
+ node_start = (ReebNode *)earc->head;
+ node_end = (ReebNode *)earc->tail;
+ }
+
+ initArcIterator(iter, earc, node_start);
+
+ bucket = IT_next(iter);
+
+ vec0 = node_start->p;
+
+ while (bucket != NULL) {
+ vec1 = bucket->p;
+
+ embedding_length += len_v3v3(vec0, vec1);
+
+ vec0 = vec1;
+ bucket = IT_next(iter);
+ }
+
+ embedding_length += len_v3v3(node_end->p, vec1);
+
+ /* fit bones */
+ initArcIterator(iter, earc, node_start);
+
+ bucket = IT_next(iter);
+
+ vec0 = node_start->p;
+ previous_vec = vec0;
+ vec1 = bucket->p;
+
+ for (edge = iarc->edges.first; edge; edge = edge->next) {
+ float new_bone_length = edge->length / iarc->length * embedding_length;
+ float *no = NULL;
+ float length = 0;
+
+ while (bucket && new_bone_length > length) {
+ length += len_v3v3(previous_vec, vec1);
+ bucket = IT_next(iter);
+ previous_vec = vec1;
+ vec1 = bucket->p;
+ no = bucket->no;
+ }
+
+ if (bucket == NULL) {
+ vec1 = node_end->p;
+ no = node_end->no;
+ }
+
+ /* no need to move virtual edges (space between unconnected bones) */
+ if (edge->bone) {
+ repositionBone(C, rigg, edge, vec0, vec1, no);
+ }
+
+ vec0 = vec1;
+ previous_vec = vec1;
+ }
+}
+
+static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
+{
+ RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam");
+
+ p->rigg = rigg;
+ p->iarc = iarc;
+ p->inode_start = inode_start;
+ p->context = C;
+
+ BLI_task_pool_push(rigg->task_pool, exec_retargetArctoArc, p, true, TASK_PRIORITY_HIGH);
+}
+
+void exec_retargetArctoArc(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid))
+{
+ RetargetParam *p = (RetargetParam *)taskdata;
+ RigGraph *rigg = p->rigg;
+ RigArc *iarc = p->iarc;
+ bContext *C = p->context;
+ RigNode *inode_start = p->inode_start;
+ ReebArc *earc = iarc->link_mesh;
+
+ if (BLI_listbase_is_single(&iarc->edges)) {
+ RigEdge *edge = iarc->edges.first;
+
+ if (testFlipArc(iarc, inode_start)) {
+ repositionBone(C, rigg, edge, earc->tail->p, earc->head->p, earc->head->no);
+ }
+ else {
+ repositionBone(C, rigg, edge, earc->head->p, earc->tail->p, earc->tail->no);
+ }
+ }
+ else {
+ RetargetMode mode = detectArcRetargetMode(iarc);
+
+ if (mode == RETARGET_AGGRESSIVE) {
+ retargetArctoArcAggresive(C, rigg, iarc, inode_start);
+ }
+ else {
+ retargetArctoArcLength(C, rigg, iarc, inode_start);
+ }
+ }
+}
+
+static void matchMultiResolutionNode(RigGraph *rigg, RigNode *inode, ReebNode *top_node)
+{
+ ReebNode *enode = top_node;
+ ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode);
+ int ishape, eshape;
+
+ ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)inode, NULL, 0) % SHAPE_LEVELS;
+ eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS;
+
+ inode->link_mesh = enode;
+
+ while (ishape == eshape && enode->link_down) {
+ inode->link_mesh = enode;
+
+ enode = enode->link_down;
+ reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); /* replace with call to link_down once that exists */
+ eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS;
+ }
+}
+
+static void markMultiResolutionChildArc(ReebNode *end_enode, ReebNode *enode)
+{
+ int i;
+
+ for (i = 0; i < enode->degree; i++) {
+ ReebArc *earc = (ReebArc *)enode->arcs[i];
+
+ if (earc->flag == ARC_FREE) {
+ earc->flag = ARC_TAKEN;
+
+ if (earc->tail->degree > 1 && earc->tail != end_enode) {
+ markMultiResolutionChildArc(end_enode, earc->tail);
+ }
+ break;
+ }
+ }
+}
+
+static void markMultiResolutionArc(ReebArc *start_earc)
+{
+ if (start_earc->link_up) {
+ ReebArc *earc;
+ for (earc = start_earc->link_up; earc; earc = earc->link_up) {
+ earc->flag = ARC_TAKEN;
+
+ if (earc->tail->index != start_earc->tail->index) {
+ markMultiResolutionChildArc(earc->tail, earc->tail);
+ }
+ }
+ }
+}
+
+static void matchMultiResolutionArc(RigGraph *rigg, RigNode *start_node, RigArc *next_iarc, ReebArc *next_earc)
+{
+ ReebNode *enode = next_earc->head;
+ ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode);
+ int ishape, eshape;
+
+ ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)start_node, (BArc *)next_iarc, 1) % SHAPE_LEVELS;
+ eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, (BArc *)next_earc, 1) % SHAPE_LEVELS;
+
+ while (ishape != eshape && next_earc->link_up) {
+ next_earc->flag = ARC_TAKEN; // mark previous as taken, to prevent backtrack on lower levels
+
+ next_earc = next_earc->link_up;
+ reebg = reebg->link_up;
+ enode = next_earc->head;
+ eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, (BArc *)next_earc, 1) % SHAPE_LEVELS;
+ }
+
+ next_earc->flag = ARC_USED;
+ next_iarc->link_mesh = next_earc;
+
+ /* mark all higher levels as taken too */
+ markMultiResolutionArc(next_earc);
+// while (next_earc->link_up)
+// {
+// next_earc = next_earc->link_up;
+// next_earc->flag = ARC_TAKEN;
+// }
+}
+
+static void matchMultiResolutionStartingNode(RigGraph *rigg, ReebGraph *reebg, RigNode *inode)
+{
+ ReebNode *enode;
+ int ishape, eshape;
+
+ enode = reebg->nodes.first;
+
+ ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)inode, NULL, 0) % SHAPE_LEVELS;
+ eshape = BLI_subtreeShape((BGraph *)rigg->link_mesh, (BNode *)enode, NULL, 0) % SHAPE_LEVELS;
+
+ while (ishape != eshape && reebg->link_up) {
+ reebg = reebg->link_up;
+
+ enode = reebg->nodes.first;
+
+ eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS;
+ }
+
+ inode->link_mesh = enode;
+}
+
+static void findCorrespondingArc(RigGraph *rigg, RigArc *start_arc, RigNode *start_node, RigArc *next_iarc, int root)
+{
+ ReebNode *enode = start_node->link_mesh;
+ ReebArc *next_earc;
+ int symmetry_level = next_iarc->symmetry_level;
+ int symmetry_group = next_iarc->symmetry_group;
+ int symmetry_flag = next_iarc->symmetry_flag;
+ int i;
+
+ next_iarc->link_mesh = NULL;
+
+// if (root)
+// {
+// printf("-----------------------\n");
+// printf("MATCHING LIMB\n");
+// RIG_printArcBones(next_iarc);
+// }
+
+ for (i = 0; i < enode->degree; i++) {
+ next_earc = (ReebArc *)enode->arcs[i];
+
+// if (next_earc->flag == ARC_FREE)
+// {
+// printf("candidate (level %i ?= %i) (flag %i ?= %i) (group %i ?= %i)\n",
+// symmetry_level, next_earc->symmetry_level,
+// symmetry_flag, next_earc->symmetry_flag,
+// symmetry_group, next_earc->symmetry_flag);
+// }
+
+ if (next_earc->flag == ARC_FREE &&
+ next_earc->symmetry_flag == symmetry_flag &&
+ next_earc->symmetry_group == symmetry_group &&
+ next_earc->symmetry_level == symmetry_level)
+ {
+// printf("CORRESPONDING ARC FOUND\n");
+// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
+
+ matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc);
+ break;
+ }
+ }
+
+ /* not found, try at higher nodes (lower node might have filtered internal arcs, messing shape of tree */
+ if (next_iarc->link_mesh == NULL) {
+// printf("NO CORRESPONDING ARC FOUND - GOING TO HIGHER LEVELS\n");
+
+ if (enode->link_up) {
+ start_node->link_mesh = enode->link_up;
+ findCorrespondingArc(rigg, start_arc, start_node, next_iarc, 0);
+ }
+ }
+
+ /* still not found, print debug info */
+ if (root && next_iarc->link_mesh == NULL) {
+ start_node->link_mesh = enode; /* linking back with root node */
+
+// printf("NO CORRESPONDING ARC FOUND\n");
+// RIG_printArcBones(next_iarc);
+//
+// printf("ON NODE %i, multilevel %i\n", enode->index, enode->multi_level);
+//
+// printf("LOOKING FOR\n");
+// printf("flag %i -- level %i -- flag %i -- group %i\n", ARC_FREE, symmetry_level, symmetry_flag, symmetry_group);
+//
+// printf("CANDIDATES\n");
+// for (i = 0; i < enode->degree; i++)
+// {
+// next_earc = (ReebArc *)enode->arcs[i];
+// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
+// }
+
+ /* Emergency matching */
+ for (i = 0; i < enode->degree; i++) {
+ next_earc = (ReebArc *)enode->arcs[i];
+
+ if (next_earc->flag == ARC_FREE && next_earc->symmetry_level == symmetry_level) {
+// printf("USING:\n");
+// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
+ matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc);
+ break;
+ }
+ }
+ }
+
+}
+
+static void retargetSubgraph(bContext *C, RigGraph *rigg, RigArc *start_arc, RigNode *start_node)
+{
+ RigNode *inode = start_node;
+ int i;
+
+ /* no start arc on first node */
+ if (start_arc) {
+ ReebNode *enode = start_node->link_mesh;
+ ReebArc *earc = start_arc->link_mesh;
+
+ retargetArctoArc(C, rigg, start_arc, start_node);
+
+ enode = BIF_otherNodeFromIndex(earc, enode);
+ inode = (RigNode *)BLI_otherNode((BArc *)start_arc, (BNode *)inode);
+
+ /* match with lowest node with correct shape */
+ matchMultiResolutionNode(rigg, inode, enode);
+ }
+
+ for (i = 0; i < inode->degree; i++) {
+ RigArc *next_iarc = (RigArc *)inode->arcs[i];
+
+ /* no back tracking */
+ if (next_iarc != start_arc) {
+ findCorrespondingArc(rigg, start_arc, inode, next_iarc, 1);
+ if (next_iarc->link_mesh) {
+ retargetSubgraph(C, rigg, next_iarc, inode);
+ }
+ }
+ }
+}
+
+static void finishRetarget(RigGraph *rigg)
+{
+ BLI_task_pool_work_and_wait(rigg->task_pool);
+}
+
+static void adjustGraphs(bContext *C, RigGraph *rigg)
+{
+ Main *bmain = CTX_data_main(C);
+ bArmature *arm = rigg->ob->data;
+ RigArc *arc;
+
+ for (arc = rigg->arcs.first; arc; arc = arc->next) {
+ if (arc->link_mesh) {
+ retargetArctoArc(C, rigg, arc, arc->head);
+ }
+ }
+
+ finishRetarget(rigg);
+
+ /* Turn the list into an armature */
+ arm->edbo = rigg->editbones;
+ ED_armature_from_edit(bmain, arm);
+
+ ED_undo_push(C, "Retarget Skeleton");
+}
+
+static void retargetGraphs(bContext *C, RigGraph *rigg)
+{
+ Main *bmain = CTX_data_main(C);
+ bArmature *arm = rigg->ob->data;
+ ReebGraph *reebg = rigg->link_mesh;
+ RigNode *inode;
+
+ /* flag all ReebArcs as free */
+ BIF_flagMultiArcs(reebg, ARC_FREE);
+
+ /* return to first level */
+ inode = rigg->head;
+
+ matchMultiResolutionStartingNode(rigg, reebg, inode);
+
+ retargetSubgraph(C, rigg, NULL, inode);
+
+ //generateMissingArcs(rigg);
+
+ finishRetarget(rigg);
+
+ /* Turn the list into an armature */
+ arm->edbo = rigg->editbones;
+ ED_armature_from_edit(bmain, arm);
+}
+
+const char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index)
+{
+ RigArc *arc = BLI_findlink(&rg->arcs, arc_index);
+ RigEdge *iedge;
+
+ if (arc == NULL) {
+ return "None";
+ }
+
+ if (bone_index == BLI_listbase_count(&arc->edges)) {
+ return "Last joint";
+ }
+
+ iedge = BLI_findlink(&arc->edges, bone_index);
+
+ if (iedge == NULL) {
+ return "Done";
+ }
+
+ if (iedge->bone == NULL) {
+ return "Bone offset";
+ }
+
+ return iedge->bone->name;
+}
+
+int RIG_nbJoints(RigGraph *rg)
+{
+ RigArc *arc;
+ int total = 0;
+
+ total += BLI_listbase_count(&rg->nodes);
+
+ for (arc = rg->arcs.first; arc; arc = arc->next) {
+ total += BLI_listbase_count(&arc->edges) - 1; /* -1 because end nodes are already counted */
+ }
+
+ return total;
+}
+
+static void BIF_freeRetarget(void)
+{
+ if (GLOBAL_RIGG) {
+ RIG_freeRigGraph((BGraph *)GLOBAL_RIGG);
+ GLOBAL_RIGG = NULL;
+ }
+}
+
+void BIF_retargetArmature(bContext *C)
+{
+ ReebGraph *reebg;
+ double start_time, end_time;
+ double gstart_time, gend_time;
+ double reeb_time, rig_time = 0.0, retarget_time = 0.0, total_time;
+
+ gstart_time = start_time = PIL_check_seconds_timer();
+
+ reebg = BIF_ReebGraphMultiFromEditMesh(C);
+
+ end_time = PIL_check_seconds_timer();
+ reeb_time = end_time - start_time;
+
+ printf("Reeb Graph created\n");
+
+ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
+ {
+ Object *ob = base->object;
+
+ if (ob->type == OB_ARMATURE) {
+ RigGraph *rigg;
+ bArmature *arm;
+
+ arm = ob->data;
+
+ /* Put the armature into editmode */
+
+
+ start_time = PIL_check_seconds_timer();
+
+ rigg = RIG_graphFromArmature(C, ob, arm);
+
+ end_time = PIL_check_seconds_timer();
+ rig_time = end_time - start_time;
+
+ printf("Armature graph created\n");
+
+ //RIG_printGraph(rigg);
+
+ rigg->link_mesh = reebg;
+
+ printf("retargetting %s\n", ob->id.name);
+
+ start_time = PIL_check_seconds_timer();
+
+ retargetGraphs(C, rigg);
+
+ end_time = PIL_check_seconds_timer();
+ retarget_time = end_time - start_time;
+
+ BIF_freeRetarget();
+
+ GLOBAL_RIGG = rigg;
+
+ break; /* only one armature at a time */
+ }
+ }
+ CTX_DATA_END;
+
+
+ gend_time = PIL_check_seconds_timer();
+
+ total_time = gend_time - gstart_time;
+
+ printf("-----------\n");
+ printf("runtime: \t%.3f\n", total_time);
+ printf("reeb: \t\t%.3f (%.1f%%)\n", reeb_time, reeb_time / total_time * 100);
+ printf("rig: \t\t%.3f (%.1f%%)\n", rig_time, rig_time / total_time * 100);
+ printf("retarget: \t%.3f (%.1f%%)\n", retarget_time, retarget_time / total_time * 100);
+ printf("-----------\n");
+
+ ED_undo_push(C, "Retarget Skeleton");
+
+ // XXX
+// allqueue(REDRAWVIEW3D, 0);
+}
+
+void BIF_retargetArc(bContext *C, ReebArc *earc, RigGraph *template_rigg)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ bArmature *armedit = obedit->data;
+ Object *ob;
+ RigGraph *rigg;
+ RigArc *iarc;
+ char *side_string = scene->toolsettings->skgen_side_string;
+ char *num_string = scene->toolsettings->skgen_num_string;
+ int free_template = 0;
+
+ if (template_rigg) {
+ ob = template_rigg->ob;
+ }
+ else {
+ free_template = 1;
+ ob = obedit;
+ template_rigg = armatureSelectedToGraph(C, ob, ob->data);
+ }
+
+ if (BLI_listbase_is_empty(&template_rigg->arcs)) {
+// XXX
+// error("No Template and no deforming bones selected");
+ return;
+ }
+
+ rigg = cloneRigGraph(template_rigg, armedit->edbo, obedit, side_string, num_string);
+
+ iarc = rigg->arcs.first;
+
+ iarc->link_mesh = earc;
+ iarc->head->link_mesh = earc->head;
+ iarc->tail->link_mesh = earc->tail;
+
+ retargetArctoArc(C, rigg, iarc, iarc->head);
+
+ finishRetarget(rigg);
+
+ /* free template if it comes from the edit armature */
+ if (free_template) {
+ RIG_freeRigGraph((BGraph *)template_rigg);
+ }
+ RIG_freeRigGraph((BGraph *)rigg);
+
+ ED_armature_edit_validate_active(armedit);
+
+// XXX
+// allqueue(REDRAWVIEW3D, 0);
+}
+
+void BIF_adjustRetarget(bContext *C)
+{
+ if (GLOBAL_RIGG) {
+ adjustGraphs(C, GLOBAL_RIGG);
+ }
+}
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index ea4a12482d9..1f01def5133 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -42,6 +42,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "ED_mesh.h"
#include "ED_armature.h"
@@ -96,7 +97,7 @@ struct LaplacianSystem {
float *H; /* diagonal H matrix */
float *p; /* values from all p vectors */
float *mindist; /* minimum distance to a bone for all vertices */
-
+
BVHTree *bvhtree; /* ray tracing acceleration structure */
const MLoopTri **vltree; /* a looptri that the vertex belongs to */
} heat;
@@ -261,7 +262,7 @@ static void laplacian_system_construct_end(LaplacianSystem *sys)
if (sys->areaweights)
for (a = 0, face = sys->faces; a < sys->totface; a++, face++)
laplacian_triangle_area(sys, (*face)[0], (*face)[1], (*face)[2]);
-
+
for (a = 0; a < totvert; a++) {
if (sys->areaweights) {
if (sys->varea[a] != 0.0f)
@@ -277,7 +278,7 @@ static void laplacian_system_construct_end(LaplacianSystem *sys)
if (sys->storeweights)
sys->fweights = MEM_callocN(sizeof(float) * 3 * totface, "LaplacianFWeight");
-
+
for (a = 0, face = sys->faces; a < totface; a++, face++)
laplacian_triangle_weights(sys, a, (*face)[0], (*face)[1], (*face)[2]);
@@ -405,7 +406,7 @@ static void heat_ray_tree_create(LaplacianSystem *sys)
const MLoopTri *lt = &looptri[a];
float bb[6];
int vtri[3];
-
+
vtri[0] = mloop[lt->tri[0]].v;
vtri[1] = mloop[lt->tri[1]].v;
vtri[2] = mloop[lt->tri[2]].v;
@@ -416,14 +417,14 @@ static void heat_ray_tree_create(LaplacianSystem *sys)
minmax_v3v3_v3(bb, bb + 3, verts[vtri[2]]);
BLI_bvhtree_insert(sys->heat.bvhtree, a, bb, 2);
-
+
//Setup inverse pointers to use on isect.orig
sys->heat.vltree[vtri[0]] = lt;
sys->heat.vltree[vtri[1]] = lt;
sys->heat.vltree[vtri[2]] = lt;
}
- BLI_bvhtree_balance(sys->heat.bvhtree);
+ BLI_bvhtree_balance(sys->heat.bvhtree);
}
static int heat_ray_source_visible(LaplacianSystem *sys, int vertex, int source)
@@ -459,7 +460,7 @@ static int heat_ray_source_visible(LaplacianSystem *sys, int vertex, int source)
static float heat_source_distance(LaplacianSystem *sys, int vertex, int source)
{
float closest[3], d[3], dist, cosine;
-
+
/* compute euclidian distance */
closest_to_line_segment_v3(closest, sys->heat.verts[vertex], sys->heat.root[source], sys->heat.tip[source]);
@@ -481,7 +482,7 @@ static int heat_source_closest(LaplacianSystem *sys, int vertex, int source)
if (dist <= sys->heat.mindist[vertex] * (1.0f + DISTANCE_EPSILON))
if (heat_ray_source_visible(sys, vertex, source))
return 1;
-
+
return 0;
}
@@ -516,7 +517,7 @@ static void heat_set_H(LaplacianSystem *sys, int vertex)
}
else
h = 0.0f;
-
+
sys->heat.H[vertex] = h;
}
@@ -533,7 +534,7 @@ static void heat_calc_vnormals(LaplacianSystem *sys)
v3 = (*face)[2];
normal_tri_v3(fnor, sys->verts[v1], sys->verts[v2], sys->verts[v3]);
-
+
add_v3_v3(sys->heat.vnors[v1], fnor);
add_v3_v3(sys->heat.vnors[v2], fnor);
add_v3_v3(sys->heat.vnors[v3], fnor);
@@ -680,7 +681,7 @@ void heat_bone_weighting(
for (a = 0; a < me->totvert; a++)
vertsflipped[a] = mesh_get_x_mirror_vert(ob, NULL, a, use_topology);
}
-
+
/* compute weights per bone */
for (j = 0; j < numsource; j++) {
if (!selected[j])
@@ -718,7 +719,7 @@ void heat_bone_weighting(
continue;
solution = laplacian_system_get_solution(sys, a);
-
+
if (bbone) {
if (solution > 0.0f)
ED_vgroup_vert_add(ob, dgrouplist[j], a, solution,
@@ -853,7 +854,7 @@ typedef struct MeshDeformBind {
/* direct solver */
int *varidx;
-
+
BVHTree *bvhtree;
BVHTreeFromMesh bvhdata;
@@ -874,7 +875,7 @@ typedef struct MeshDeformIsect {
bool isect;
float u, v;
-
+
} MeshDeformIsect;
/* ray intersection */
@@ -894,9 +895,9 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
MeshDeformIsect *isec = data->isec;
float no[3], co[3], dist;
float *face[3];
-
+
lt = &looptri[index];
-
+
face[0] = mdb->cagecos[mloop[lt->tri[0]].v];
face[1] = mdb->cagecos[mloop[lt->tri[1]].v];
face[2] = mdb->cagecos[mloop[lt->tri[2]].v];
@@ -920,7 +921,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
hit->index = index;
hit->dist = dist;
copy_v3_v3(hit->co, co);
-
+
isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f);
isec->lambda = dist;
}
@@ -1003,7 +1004,7 @@ static int meshdeform_inside_cage(MeshDeformBind *mdb, float *co)
copy_v3_v3(start, co);
sub_v3_v3v3(dir, outside, start);
normalize_v3(dir);
-
+
isect = meshdeform_ray_tree_intersect(mdb, start, outside);
if (isect && !isect->facing)
return 1;
@@ -1017,7 +1018,7 @@ static int meshdeform_inside_cage(MeshDeformBind *mdb, float *co)
BLI_INLINE int meshdeform_index(MeshDeformBind *mdb, int x, int y, int z, int n)
{
int size = mdb->size;
-
+
x += MESHDEFORM_OFFSET[n][0];
y += MESHDEFORM_OFFSET[n][1];
z += MESHDEFORM_OFFSET[n][2];
@@ -1121,7 +1122,7 @@ static void meshdeform_bind_floodfill(MeshDeformBind *mdb)
if (mdb->semibound[a])
ts++;
}
-
+
printf("interior %d exterior %d boundary %d semi-boundary %d\n", ti, te, tb, ts);
}
#endif
@@ -1230,7 +1231,7 @@ static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, LinearSolver *contex
return;
EIG_linear_solver_matrix_add(context, mdb->varidx[acenter], mdb->varidx[acenter], 1.0f);
-
+
totweight = meshdeform_boundary_total_weight(mdb, x, y, z);
for (i = 1; i <= 6; i++) {
a = meshdeform_index(mdb, x, y, z, i);
@@ -1280,7 +1281,7 @@ static void meshdeform_matrix_add_semibound_phi(MeshDeformBind *mdb, int x, int
a = meshdeform_index(mdb, x, y, z, 0);
if (!mdb->semibound[a])
return;
-
+
mdb->phi[a] = 0.0f;
totweight = meshdeform_boundary_total_weight(mdb, x, y, z);
@@ -1418,7 +1419,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind
printf("totalphi deficiency [%s|%d] %d: %.10f\n",
(mdb->tag[b] == MESHDEFORM_TAG_INTERIOR) ? "interior" : "boundary", mdb->semibound[b], mdb->varidx[b], mdb->totalphi[b]);
#endif
-
+
/* free */
MEM_freeN(mdb->varidx);
@@ -1504,7 +1505,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
/* start with all cells untyped */
for (a = 0; a < mdb->size3; a++)
mdb->tag[a] = MESHDEFORM_TAG_UNTYPED;
-
+
/* detect intersections and tag boundary cells */
for (z = 0; z < mdb->size; z++)
for (y = 0; y < mdb->size; y++)
@@ -1591,7 +1592,7 @@ void ED_mesh_deform_bind_callback(
/* get mesh and cage mesh */
mdb.vertexcos = MEM_callocN(sizeof(float) * 3 * totvert, "MeshDeformCos");
mdb.totvert = totvert;
-
+
mdb.cagemesh = cagemesh;
mdb.totcagevert = mdb.cagemesh->totvert;
mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.totcagevert, "MeshDeformBindCos");
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 5cb8d37b90a..ffe64cc24b0 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -46,6 +46,7 @@
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_deform.h"
+#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_layer.h"
@@ -91,7 +92,7 @@ bool ED_object_posemode_enter_ex(struct Main *bmain, Object *ob)
{
BLI_assert(!ID_IS_LINKED(ob));
bool ok = false;
-
+
switch (ob->type) {
case OB_ARMATURE:
ob->restore_mode = ob->mode;
@@ -185,15 +186,15 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
struct Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_depsgraph(C);
ListBase targets = {NULL, NULL};
-
+
/* set flag to force recalc, then grab the relevant bones to target */
ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS;
animviz_get_object_motionpaths(ob, &targets);
-
+
/* recalculate paths, then free */
animviz_calc_motionpaths(depsgraph, bmain, scene, &targets);
BLI_freelistN(&targets);
-
+
/* tag armature object for copy on write - so paths will draw/redraw */
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
}
@@ -201,52 +202,52 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
/* show popup to determine settings */
static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
-{
+{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-
+
if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
-
+
/* set default settings from existing/stored settings */
{
bAnimVizSettings *avs = &ob->pose->avs;
PointerRNA avs_ptr;
-
+
RNA_int_set(op->ptr, "start_frame", avs->path_sf);
RNA_int_set(op->ptr, "end_frame", avs->path_ef);
-
+
RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
RNA_enum_set(op->ptr, "bake_location", RNA_enum_get(&avs_ptr, "bake_location"));
}
-
+
/* show popup dialog to allow editing of range... */
// FIXME: hardcoded dimensions here are just arbitrary
return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 10 * UI_UNIT_Y);
}
-/* For the object with pose/action: create path curves for selected bones
+/* For the object with pose/action: create path curves for selected bones
* This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
*/
static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
Scene *scene = CTX_data_scene(C);
-
+
if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
-
+
/* grab baking settings from operator settings */
{
bAnimVizSettings *avs = &ob->pose->avs;
PointerRNA avs_ptr;
-
+
avs->path_sf = RNA_int_get(op->ptr, "start_frame");
avs->path_ef = RNA_int_get(op->ptr, "end_frame");
-
+
RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
RNA_enum_set(&avs_ptr, "bake_location", RNA_enum_get(op->ptr, "bake_location"));
}
-
+
/* set up path data for bones being calculated */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
@@ -262,7 +263,7 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void POSE_OT_paths_calculate(wmOperatorType *ot)
@@ -271,23 +272,23 @@ void POSE_OT_paths_calculate(wmOperatorType *ot)
ot->name = "Calculate Bone Paths";
ot->idname = "POSE_OT_paths_calculate";
ot->description = "Calculate paths for the selected bones";
-
+
/* api callbacks */
ot->invoke = pose_calculate_paths_invoke;
ot->exec = pose_calculate_paths_exec;
ot->poll = ED_operator_posemode_exclusive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
- RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start",
+ RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start",
"First frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0);
- RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End",
+ RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End",
"Last frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0);
-
- RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, 0,
- "Bake Location",
+
+ RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, 0,
+ "Bake Location",
"Which point on the bones is used when calculating paths");
}
@@ -299,7 +300,7 @@ static int pose_update_paths_poll(bContext *C)
Object *ob = CTX_data_active_object(C);
return (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
}
-
+
return false;
}
@@ -307,17 +308,17 @@ static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
Scene *scene = CTX_data_scene(C);
-
+
if (ELEM(NULL, ob, scene))
return OPERATOR_CANCELLED;
/* calculate the bones that now have motionpaths... */
/* TODO: only make for the selected bones? */
ED_pose_recalculate_paths(C, scene, ob);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -327,11 +328,11 @@ void POSE_OT_paths_update(wmOperatorType *ot)
ot->name = "Update Bone Paths";
ot->idname = "POSE_OT_paths_update";
ot->description = "Recalculate paths for bones that already have them";
-
+
/* api callbakcs */
ot->exec = pose_update_paths_exec;
ot->poll = pose_update_paths_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -343,10 +344,10 @@ static void ED_pose_clear_paths(Object *ob, bool only_selected)
{
bPoseChannel *pchan;
bool skipped = false;
-
+
if (ELEM(NULL, ob, ob->pose))
return;
-
+
/* free the motionpath blocks for all bones - This is easier for users to quickly clear all */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->mpath) {
@@ -359,7 +360,7 @@ static void ED_pose_clear_paths(Object *ob, bool only_selected)
}
}
}
-
+
/* if nothing was skipped, there should be no paths left! */
if (skipped == false)
ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
@@ -370,18 +371,18 @@ static int pose_clear_paths_exec(bContext *C, wmOperator *op)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
-
+
/* only continue if there's an object */
if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
-
+
/* use the backend function for this */
ED_pose_clear_paths(ob, only_selected);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
- return OPERATOR_FINISHED;
+
+ return OPERATOR_FINISHED;
}
/* operator callback/wrapper */
@@ -399,17 +400,17 @@ void POSE_OT_paths_clear(wmOperatorType *ot)
ot->name = "Clear Bone Paths";
ot->idname = "POSE_OT_paths_clear";
ot->description = "Clear path caches for all bones, hold Shift key for selected bones only";
-
+
/* api callbacks */
ot->invoke = pose_clear_paths_invoke;
ot->exec = pose_clear_paths_exec;
ot->poll = ED_operator_posemode_exclusive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
- ot->prop = RNA_def_boolean(ot->srna, "only_selected", false, "Only Selected",
+ ot->prop = RNA_def_boolean(ot->srna, "only_selected", false, "Only Selected",
"Only clear paths from selected bones");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
}
@@ -424,13 +425,13 @@ static void pose_copy_menu(Scene *scene)
bPoseChannel *pchan, *pchanact;
short nr = 0;
int i = 0;
-
+
/* paranoia checks */
if (ELEM(NULL, ob, ob->pose)) return;
if ((ob == obedit) || (ob->mode & OB_MODE_POSE) == 0) return;
-
+
pchan = BKE_pose_channel_active(ob);
-
+
if (pchan == NULL) return;
pchanact = pchan;
arm = ob->data;
@@ -452,10 +453,10 @@ static void pose_copy_menu(Scene *scene)
else
nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8");
}
-
- if (nr <= 0)
+
+ if (nr <= 0)
return;
-
+
if (nr != 5) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if ((arm->layer & pchan->bone->layer) &&
@@ -476,23 +477,23 @@ static void pose_copy_menu(Scene *scene)
case 4: /* All Constraints */
{
ListBase tmp_constraints = {NULL, NULL};
-
- /* copy constraints to tmpbase and apply 'local' tags before
+
+ /* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
BKE_constraints_copy(&tmp_constraints, &pchanact->constraints, true);
if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
bConstraint *con;
-
+
/* add proxy-local tags */
for (con = tmp_constraints.first; con; con = con->next)
con->flag |= CONSTRAINT_PROXY_LOCAL;
}
BLI_movelisttolist(&pchan->constraints, &tmp_constraints);
-
+
/* update flags (need to add here, not just copy) */
pchan->constflag |= pchanact->constflag;
-
+
if (ob->pose)
BKE_pose_tag_recalc(bmain, ob->pose);
}
@@ -523,12 +524,12 @@ static void pose_copy_menu(Scene *scene)
case 10: /* Visual Rotation */
{
float delta_mat[4][4];
-
+
BKE_armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
-
+
if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float tmp_quat[4];
-
+
/* need to convert to quat first (in temp var)... */
mat4_to_quat(tmp_quat, delta_mat);
quat_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, tmp_quat);
@@ -542,7 +543,7 @@ static void pose_copy_menu(Scene *scene)
case 11: /* Visual Size */
{
float delta_mat[4][4], size[4];
-
+
BKE_armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
mat4_to_size(size, delta_mat);
copy_v3_v3(pchan->size, size);
@@ -555,20 +556,20 @@ static void pose_copy_menu(Scene *scene)
bConstraint *con, *con_back;
int const_toggle[24] = {0}; /* XXX, initialize as 0 to quiet errors */
ListBase const_copy = {NULL, NULL};
-
+
BLI_duplicatelist(&const_copy, &(pchanact->constraints));
-
+
/* build the puplist of constraints */
for (con = pchanact->constraints.first, i = 0; con; con = con->next, i++) {
const_toggle[i] = 1;
// add_numbut(i, UI_BTYPE_TOGGLE|INT, con->name, 0, 0, &(const_toggle[i]), "");
}
-
+
// if (!do_clever_numbuts("Select Constraints", i, REDRAW)) {
// BLI_freelistN(&const_copy);
// return;
// }
-
+
/* now build a new listbase from the options selected */
for (i = 0, con = const_copy.first; con; i++) {
/* if not selected, free/remove it from the list */
@@ -580,7 +581,7 @@ static void pose_copy_menu(Scene *scene)
else
con = con->next;
}
-
+
/* Copy the temo listbase to the selected posebones */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if ((arm->layer & pchan->bone->layer) &&
@@ -588,8 +589,8 @@ static void pose_copy_menu(Scene *scene)
(pchan != pchanact) )
{
ListBase tmp_constraints = {NULL, NULL};
-
- /* copy constraints to tmpbase and apply 'local' tags before
+
+ /* copy constraints to tmpbase and apply 'local' tags before
* appending to list of constraints for this channel
*/
BKE_constraints_copy(&tmp_constraints, &const_copy, true);
@@ -599,22 +600,22 @@ static void pose_copy_menu(Scene *scene)
con->flag |= CONSTRAINT_PROXY_LOCAL;
}
BLI_movelisttolist(&pchan->constraints, &tmp_constraints);
-
+
/* update flags (need to add here, not just copy) */
pchan->constflag |= pchanact->constflag;
}
}
BLI_freelistN(&const_copy);
BKE_pose_update_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
-
+
if (ob->pose)
BKE_pose_tag_recalc(bmain, ob->pose);
}
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA); // and all its relations
-
+
BIF_undo_push("Copy Pose Attributes");
-
+
}
#endif
@@ -622,9 +623,10 @@ static void pose_copy_menu(Scene *scene)
static int pose_flip_names_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool do_strip_numbers = RNA_boolean_get(op->ptr, "do_strip_numbers");
-
+
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob)
{
bArmature *arm = ob->data;
@@ -636,10 +638,10 @@ static int pose_flip_names_exec(bContext *C, wmOperator *op)
}
FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
- ED_armature_bones_flip_names(arm, &bones_names, do_strip_numbers);
+ ED_armature_bones_flip_names(bmain, arm, &bones_names, do_strip_numbers);
BLI_freelistN(&bones_names);
-
+
/* since we renamed stuff... */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -647,7 +649,7 @@ static int pose_flip_names_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
}
FOREACH_OBJECT_IN_MODE_END;
-
+
return OPERATOR_FINISHED;
}
@@ -657,11 +659,11 @@ void POSE_OT_flip_names(wmOperatorType *ot)
ot->name = "Flip Names";
ot->idname = "POSE_OT_flip_names";
ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones";
-
+
/* api callbacks */
ot->exec = pose_flip_names_exec;
ot->poll = ED_operator_posemode_local;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -674,31 +676,32 @@ void POSE_OT_flip_names(wmOperatorType *ot)
static int pose_autoside_names_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bArmature *arm;
char newname[MAXBONENAME];
short axis = RNA_enum_get(op->ptr, "axis");
-
+
/* paranoia checks */
- if (ELEM(NULL, ob, ob->pose))
+ if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
arm = ob->data;
-
+
/* loop through selected bones, auto-naming them */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
BLI_strncpy(newname, pchan->name, sizeof(newname));
if (bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]))
- ED_armature_bone_rename(arm, pchan->name, newname);
+ ED_armature_bone_rename(bmain, arm, pchan->name, newname);
}
CTX_DATA_END;
-
+
/* since we renamed stuff... */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -710,20 +713,20 @@ void POSE_OT_autoside_names(wmOperatorType *ot)
{2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "AutoName by Axis";
ot->idname = "POSE_OT_autoside_names";
ot->description = "Automatically renames the selected bones according to which side of the target axis they fall on";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = pose_autoside_names_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* settings */
ot->prop = RNA_def_enum(ot->srna, "axis", axis_items, 0, "Axis", "Axis tag names with");
}
@@ -734,18 +737,18 @@ static int pose_bone_rotmode_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
int mode = RNA_enum_get(op->ptr, "type");
-
+
/* set rotation mode of selected bones */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
pchan->rotmode = mode;
}
CTX_DATA_END;
-
+
/* notifiers and updates */
DEG_id_tag_update((ID *)ob, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -755,15 +758,15 @@ void POSE_OT_rotation_mode_set(wmOperatorType *ot)
ot->name = "Set Rotation Mode";
ot->idname = "POSE_OT_rotation_mode_set";
ot->description = "Set the rotation representation used by selected bones";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = pose_bone_rotmode_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_posebone_rotmode_items, 0, "Rotation Mode", "");
}
@@ -805,26 +808,26 @@ static int pose_armature_layers_showall_exec(bContext *C, wmOperator *op)
int maxLayers = (RNA_boolean_get(op->ptr, "all")) ? 32 : 16;
int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
int i;
-
+
/* sanity checking */
if (arm == NULL)
return OPERATOR_CANCELLED;
-
+
/* use RNA to set the layers
* although it would be faster to just set directly using bitflags, we still
* need to setup a RNA pointer so that we get the "update" callbacks for free...
*/
RNA_id_pointer_create(&arm->id, &ptr);
-
+
for (i = 0; i < maxLayers; i++)
layers[i] = 1;
-
+
RNA_boolean_set_array(&ptr, "layers", layers);
-
+
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -835,14 +838,14 @@ void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
ot->name = "Show All Layers";
ot->idname = "ARMATURE_OT_layers_show_all";
ot->description = "Make all armature layers visible";
-
+
/* callbacks */
ot->exec = pose_armature_layers_showall_exec;
ot->poll = armature_layers_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All Layers", "Enable all layers or just the first 16 (top row)");
}
@@ -856,16 +859,16 @@ static int armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *ev
bArmature *arm = armature_layers_get_data(&ob);
PointerRNA ptr;
int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
-
+
/* sanity checking */
if (arm == NULL)
return OPERATOR_CANCELLED;
-
+
/* get RNA pointer to armature data to use that to retrieve the layers as ints to init the operator */
RNA_id_pointer_create((ID *)arm, &ptr);
RNA_boolean_get_array(&ptr, "layers", layers);
RNA_boolean_set_array(op->ptr, "layers", layers);
-
+
/* part to sync with other similar operators... */
return WM_operator_props_popup(C, op, event);
}
@@ -902,15 +905,15 @@ void ARMATURE_OT_armature_layers(wmOperatorType *ot)
ot->name = "Change Armature Layers";
ot->idname = "ARMATURE_OT_armature_layers";
ot->description = "Change the visible armature layers";
-
+
/* callbacks */
ot->invoke = armature_layers_invoke;
ot->exec = armature_layers_exec;
ot->poll = armature_layers_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
}
@@ -921,22 +924,22 @@ void ARMATURE_OT_armature_layers(wmOperatorType *ot)
static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
-
+
/* get layers that are active already */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
short bit;
-
+
/* loop over the bits for this pchan's layers, adding layers where they're needed */
for (bit = 0; bit < 32; bit++) {
layers[bit] = (pchan->bone->layer & (1u << bit)) != 0;
}
}
CTX_DATA_END;
-
+
/* copy layers to operator */
RNA_boolean_set_array(op->ptr, "layers", layers);
-
+
/* part to sync with other similar operators... */
return WM_operator_props_popup(C, op, event);
}
@@ -977,15 +980,15 @@ void POSE_OT_bone_layers(wmOperatorType *ot)
ot->name = "Change Bone Layers";
ot->idname = "POSE_OT_bone_layers";
ot->description = "Change the layers that the selected bones belong to";
-
+
/* callbacks */
ot->invoke = pose_bone_layers_invoke;
ot->exec = pose_bone_layers_exec;
ot->poll = ED_operator_posemode_exclusive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
}
@@ -996,12 +999,12 @@ void POSE_OT_bone_layers(wmOperatorType *ot)
static int armature_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
-
+
/* get layers that are active already */
CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones)
{
short bit;
-
+
/* loop over the bits for this pchan's layers, adding layers where they're needed */
for (bit = 0; bit < 32; bit++) {
if (ebone->layer & (1u << bit)) {
@@ -1010,10 +1013,10 @@ static int armature_bone_layers_invoke(bContext *C, wmOperator *op, const wmEven
}
}
CTX_DATA_END;
-
+
/* copy layers to operator */
RNA_boolean_set_array(op->ptr, "layers", layers);
-
+
/* part to sync with other similar operators... */
return WM_operator_props_popup(C, op, event);
}
@@ -1024,10 +1027,10 @@ static int armature_bone_layers_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_edit_object(C);
PointerRNA ptr;
int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
-
+
/* get the values set in the operator properties */
RNA_boolean_get_array(op->ptr, "layers", layers);
-
+
/* set layers of pchans based on the values set in the operator props */
CTX_DATA_BEGIN_WITH_ID (C, EditBone *, ebone, selected_editable_bones, bArmature *, arm)
{
@@ -1036,10 +1039,10 @@ static int armature_bone_layers_exec(bContext *C, wmOperator *op)
RNA_boolean_set_array(&ptr, "layers", layers);
}
CTX_DATA_END;
-
+
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1049,15 +1052,15 @@ void ARMATURE_OT_bone_layers(wmOperatorType *ot)
ot->name = "Change Bone Layers";
ot->idname = "ARMATURE_OT_bone_layers";
ot->description = "Change the layers that the selected bones belong to";
-
+
/* callbacks */
ot->invoke = armature_bone_layers_invoke;
ot->exec = armature_bone_layers_exec;
ot->poll = ED_operator_editarmature;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
}
@@ -1121,19 +1124,19 @@ void POSE_OT_hide(wmOperatorType *ot)
ot->name = "Hide Selected";
ot->idname = "POSE_OT_hide";
ot->description = "Tag selected bones to not be visible in Pose Mode";
-
+
/* api callbacks */
ot->exec = pose_hide_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "");
}
-static int show_pose_bone_cb(Object *ob, Bone *bone, void *data)
+static int show_pose_bone_cb(Object *ob, Bone *bone, void *data)
{
const bool select = GET_INT_FROM_POINTER(data);
@@ -1184,11 +1187,11 @@ void POSE_OT_reveal(wmOperatorType *ot)
ot->name = "Reveal Selected";
ot->idname = "POSE_OT_reveal";
ot->description = "Reveal all bones hidden in Pose Mode";
-
+
/* api callbacks */
ot->exec = pose_reveal_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1237,11 +1240,11 @@ void POSE_OT_quaternions_flip(wmOperatorType *ot)
ot->name = "Flip Quats";
ot->idname = "POSE_OT_quaternions_flip";
ot->description = "Flip quaternion values to achieve desired rotations, while maintaining the same orientations";
-
+
/* callbacks */
ot->exec = pose_flip_quats_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c
index 62fd0966c53..aefca13d66c 100644
--- a/source/blender/editors/armature/pose_group.c
+++ b/source/blender/editors/armature/pose_group.c
@@ -68,13 +68,13 @@ static int pose_group_add_exec(bContext *C, wmOperator *UNUSED(op))
/* only continue if there's an object and pose */
if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
-
+
/* for now, just call the API function for this */
BKE_pose_add_group(ob->pose, NULL);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -84,11 +84,11 @@ void POSE_OT_group_add(wmOperatorType *ot)
ot->name = "Add Bone Group";
ot->idname = "POSE_OT_group_add";
ot->description = "Add a new bone group";
-
+
/* api callbacks */
ot->exec = pose_group_add_exec;
ot->poll = ED_operator_posemode_context;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -97,18 +97,18 @@ void POSE_OT_group_add(wmOperatorType *ot)
static int pose_group_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_pose_object_from_context(C);
-
+
/* only continue if there's an object and pose */
if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
-
+
/* for now, just call the API function for this */
BKE_pose_remove_group_index(ob->pose, ob->pose->active_group);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
-
+
return OPERATOR_FINISHED;
}
@@ -118,11 +118,11 @@ void POSE_OT_group_remove(wmOperatorType *ot)
ot->name = "Remove Bone Group";
ot->idname = "POSE_OT_group_remove";
ot->description = "Remove the active bone group";
-
+
/* api callbacks */
ot->exec = pose_group_remove_exec;
ot->poll = ED_operator_posemode_context;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -135,14 +135,14 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
Object *ob = ED_pose_object_from_context(C);
bPose *pose;
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type");
-
+
uiPopupMenu *pup;
uiLayout *layout;
bActionGroup *grp;
int i;
-
+
/* only continue if there's an object, and a pose there too */
- if (ELEM(NULL, ob, ob->pose))
+ if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
pose = ob->pose;
@@ -156,28 +156,28 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
return op->type->exec(C, op);
}
}
-
+
/* if there's no active group (or active is invalid), create a new menu to find it */
if (pose->active_group <= 0) {
/* create a new menu, and start populating it with group names */
pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
layout = UI_popup_menu_layout(pup);
-
- /* special entry - allow to create new group, then use that
+
+ /* special entry - allow to create new group, then use that
* (not to be used for removing though)
*/
if (strstr(op->idname, "assign")) {
uiItemIntO(layout, "New Group", ICON_NONE, op->idname, "type", 0);
uiItemS(layout);
}
-
+
/* add entries for each group */
for (grp = pose->agroups.first, i = 1; grp; grp = grp->next, i++)
uiItemIntO(layout, grp->name, ICON_NONE, op->idname, "type", i);
-
+
/* finish building the menu, and process it (should result in calling self again) */
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
else {
@@ -199,14 +199,14 @@ static int pose_group_assign_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
pose = ob->pose;
-
- /* set the active group number to the one from operator props
+
+ /* set the active group number to the one from operator props
* - if 0 after this, make a new group...
*/
pose->active_group = RNA_int_get(op->ptr, "type");
if (pose->active_group == 0)
BKE_pose_add_group(ob->pose, NULL);
-
+
/* add selected bones to group then */
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob, pchan)
{
@@ -218,7 +218,7 @@ static int pose_group_assign_exec(bContext *C, wmOperator *op)
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
-
+
/* report done status */
if (done)
return OPERATOR_FINISHED;
@@ -232,15 +232,15 @@ void POSE_OT_group_assign(wmOperatorType *ot)
ot->name = "Add Selected to Bone Group";
ot->idname = "POSE_OT_group_assign";
ot->description = "Add selected bones to the chosen bone group";
-
+
/* api callbacks */
ot->invoke = pose_groups_menu_invoke;
ot->exec = pose_group_assign_exec;
ot->poll = ED_operator_posemode_context;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_int(ot->srna, "type", 0, 0, INT_MAX, "Bone Group Index", "", 0, 10);
}
@@ -250,11 +250,11 @@ static int pose_group_unassign_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_pose_object_from_context(C);
bool done = false;
-
+
/* only continue if there's an object, and a pose there too */
if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
-
+
/* find selected bones to remove from all bone groups */
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob, pchan)
{
@@ -264,11 +264,11 @@ static int pose_group_unassign_exec(bContext *C, wmOperator *UNUSED(op))
}
}
FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
-
+
/* report done status */
if (done)
return OPERATOR_FINISHED;
@@ -282,11 +282,11 @@ void POSE_OT_group_unassign(wmOperatorType *ot)
ot->name = "Remove Selected from Bone Groups";
ot->idname = "POSE_OT_group_unassign";
ot->description = "Remove selected bones from all bone groups";
-
+
/* api callbacks */
ot->exec = pose_group_unassign_exec;
ot->poll = ED_operator_posemode_context;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -442,16 +442,16 @@ void POSE_OT_group_sort(wmOperatorType *ot)
static void pose_group_select(Object *ob, bool select)
{
bPose *pose = ob->pose;
-
+
FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN (ob, pchan)
{
if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
if (select) {
- if (pchan->agrp_index == pose->active_group)
+ if (pchan->agrp_index == pose->active_group)
pchan->bone->flag |= BONE_SELECTED;
}
else {
- if (pchan->agrp_index == pose->active_group)
+ if (pchan->agrp_index == pose->active_group)
pchan->bone->flag &= ~BONE_SELECTED;
}
}
@@ -462,16 +462,16 @@ static void pose_group_select(Object *ob, bool select)
static int pose_group_select_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_pose_object_from_context(C);
-
+
/* only continue if there's an object, and a pose there too */
if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
-
+
pose_group_select(ob, 1);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -481,11 +481,11 @@ void POSE_OT_group_select(wmOperatorType *ot)
ot->name = "Select Bones of Bone Group";
ot->idname = "POSE_OT_group_select";
ot->description = "Select bones in active Bone Group";
-
+
/* api callbacks */
ot->exec = pose_group_select_exec;
ot->poll = ED_operator_posemode_context;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -493,16 +493,16 @@ void POSE_OT_group_select(wmOperatorType *ot)
static int pose_group_deselect_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_pose_object_from_context(C);
-
+
/* only continue if there's an object, and a pose there too */
if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
-
+
pose_group_select(ob, 0);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -512,11 +512,11 @@ void POSE_OT_group_deselect(wmOperatorType *ot)
ot->name = "Deselect Bone Group";
ot->idname = "POSE_OT_group_deselect";
ot->description = "Deselect bones of active Bone Group";
-
+
/* api callbacks */
ot->exec = pose_group_deselect_exec;
ot->poll = ED_operator_posemode_context;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 007f986104b..b9c4584ff15 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -48,6 +48,7 @@
#include "BKE_armature.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
+#include "BKE_main.h"
#include "BKE_library.h"
#include "BKE_object.h"
@@ -81,7 +82,7 @@
static void action_set_activemarker(void *UNUSED(a), void *UNUSED(b), void *UNUSED(c)) {}
/* ************************************************************* */
-/* == POSE-LIBRARY TOOL FOR BLENDER ==
+/* == POSE-LIBRARY TOOL FOR BLENDER ==
*
* Overview:
* This tool allows animators to store a set of frequently used poses to dump into
@@ -100,7 +101,7 @@ static void action_set_activemarker(void *UNUSED(a), void *UNUSED(b), void *UNUS
/* ************************************************************* */
-/* gets the first available frame in poselib to store a pose on
+/* gets the first available frame in poselib to store a pose on
* - frames start from 1, and a pose should occur on every frame... 0 is error!
*/
static int poselib_get_free_index(bAction *act)
@@ -108,17 +109,17 @@ static int poselib_get_free_index(bAction *act)
TimeMarker *marker;
int low = 0, high = 0;
bool changed = false;
-
+
/* sanity checks */
if (ELEM(NULL, act, act->markers.first)) return 1;
-
- /* As poses are not stored in chronological order, we must iterate over this list
+
+ /* As poses are not stored in chronological order, we must iterate over this list
* a few times until we don't make any new discoveries (mostly about the lower bound).
* Prevents problems with deleting then trying to add new poses [#27412]
*/
do {
changed = false;
-
+
for (marker = act->markers.first; marker; marker = marker->next) {
/* only increase low if value is 1 greater than low, to find "gaps" where
* poses were removed from the poselib
@@ -127,7 +128,7 @@ static int poselib_get_free_index(bAction *act)
low++;
changed = true;
}
-
+
/* value replaces high if it is the highest value encountered yet */
if (marker->frame > high) {
high = marker->frame;
@@ -135,19 +136,19 @@ static int poselib_get_free_index(bAction *act)
}
}
} while (changed != 0);
-
- /* - if low is not equal to high, then low+1 is a gap
- * - if low is equal to high, then high+1 is the next index (add at end)
+
+ /* - if low is not equal to high, then low+1 is a gap
+ * - if low is equal to high, then high+1 is the next index (add at end)
*/
- if (low < high)
+ if (low < high)
return (low + 1);
- else
+ else
return (high + 1);
}
/* returns the active pose for a poselib */
static TimeMarker *poselib_get_active_pose(bAction *act)
-{
+{
if ((act) && (act->active_marker))
return BLI_findlink(&act->markers, act->active_marker - 1);
else
@@ -159,14 +160,14 @@ static TimeMarker *poselib_get_active_pose(bAction *act)
static Object *get_poselib_object(bContext *C)
{
ScrArea *sa;
-
+
/* sanity check */
if (C == NULL)
return NULL;
-
+
sa = CTX_wm_area(C);
-
- if (sa && (sa->spacetype == SPACE_BUTS))
+
+ if (sa && (sa->spacetype == SPACE_BUTS))
return ED_object_context(C);
else
return BKE_object_pose_armature_get(CTX_data_active_object(C));
@@ -191,29 +192,29 @@ static int has_poselib_pose_data_for_editing_poll(bContext *C)
/* ----------------------------------- */
/* Initialize a new poselib (whether it is needed or not) */
-static bAction *poselib_init_new(Object *ob)
+static bAction *poselib_init_new(Main *bmain, Object *ob)
{
/* sanity checks - only for armatures */
if (ELEM(NULL, ob, ob->pose))
return NULL;
-
+
/* init object's poselib action (unlink old one if there) */
if (ob->poselib)
id_us_min(&ob->poselib->id);
-
- ob->poselib = BKE_action_add(G.main, "PoseLib");
+
+ ob->poselib = BKE_action_add(bmain, "PoseLib");
ob->poselib->idroot = ID_OB;
-
+
return ob->poselib;
}
/* Initialize a new poselib (checks if that needs to happen) */
-static bAction *poselib_validate(Object *ob)
+static bAction *poselib_validate(Main *bmain, Object *ob)
{
if (ELEM(NULL, ob, ob->pose))
return NULL;
else if (ob->poselib == NULL)
- return poselib_init_new(ob);
+ return poselib_init_new(bmain, ob);
else
return ob->poselib;
}
@@ -223,18 +224,19 @@ static bAction *poselib_validate(Object *ob)
static int poselib_new_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
Object *ob = get_poselib_object(C);
-
+
/* sanity checks */
if (ob == NULL)
return OPERATOR_CANCELLED;
-
+
/* new method here deals with the rest... */
- poselib_init_new(ob);
-
+ poselib_init_new(bmain, ob);
+
/* notifier here might evolve? */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -244,11 +246,11 @@ void POSELIB_OT_new(wmOperatorType *ot)
ot->name = "New Pose Library";
ot->idname = "POSELIB_OT_new";
ot->description = "Add New Pose Library to active Object";
-
+
/* callbacks */
ot->exec = poselib_new_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -258,18 +260,18 @@ void POSELIB_OT_new(wmOperatorType *ot)
static int poselib_unlink_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = get_poselib_object(C);
-
+
/* sanity checks */
if (ELEM(NULL, ob, ob->poselib))
return OPERATOR_CANCELLED;
-
+
/* there should be a poselib (we just checked above!), so just lower its user count and remove */
id_us_min(&ob->poselib->id);
ob->poselib = NULL;
-
+
/* notifier here might evolve? */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -279,11 +281,11 @@ void POSELIB_OT_unlink(wmOperatorType *ot)
ot->name = "Unlink Pose Library";
ot->idname = "POSELIB_OT_unlink";
ot->description = "Remove Pose Library from active Object";
-
+
/* callbacks */
ot->exec = poselib_unlink_exec;
ot->poll = has_poselib_pose_data_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -291,7 +293,7 @@ void POSELIB_OT_unlink(wmOperatorType *ot)
/* ************************************************************* */
/* Pose Editing Operators */
-/* This tool automagically generates/validates poselib data so that it corresponds to the data
+/* This tool automagically generates/validates poselib data so that it corresponds to the data
* in the action. This is for use in making existing actions usable as poselibs.
*/
static int poselib_sanitize_exec(bContext *C, wmOperator *op)
@@ -301,13 +303,13 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op)
DLRBT_Tree keys;
ActKeyColumn *ak;
TimeMarker *marker, *markern;
-
+
/* validate action */
if (act == NULL) {
BKE_report(op->reports, RPT_WARNING, "No action to validate");
return OPERATOR_CANCELLED;
}
-
+
/* determine which frames have keys */
BLI_dlrbTree_init(&keys);
action_to_keylist(NULL, act, &keys, NULL);
@@ -323,39 +325,39 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op)
break;
}
}
-
+
/* add new if none found */
if (marker == NULL) {
/* add pose to poselib */
marker = MEM_callocN(sizeof(TimeMarker), "ActionMarker");
-
+
BLI_snprintf(marker->name, sizeof(marker->name), "F%d Pose", (int)ak->cfra);
-
+
marker->frame = (int)ak->cfra;
marker->flag = -1;
-
+
BLI_addtail(&act->markers, marker);
}
}
-
+
/* remove all untagged poses (unused), and remove all tags */
for (marker = act->markers.first; marker; marker = markern) {
markern = marker->next;
-
+
if (marker->flag != -1)
BLI_freelinkN(&act->markers, marker);
else
marker->flag = 0;
}
-
+
/* free temp memory */
BLI_dlrbTree_free(&keys);
-
- /* send notifiers for this - using keyframe editing notifiers, since action
- * may be being shown in anim editors as active action
+
+ /* send notifiers for this - using keyframe editing notifiers, since action
+ * may be being shown in anim editors as active action
*/
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -365,11 +367,11 @@ void POSELIB_OT_action_sanitize(wmOperatorType *ot)
ot->name = "Sanitize Pose Library Action";
ot->idname = "POSELIB_OT_action_sanitize";
ot->description = "Make action suitable for use as a Pose Library";
-
+
/* callbacks */
ot->exec = poselib_sanitize_exec;
ot->poll = has_poselib_pose_data_for_editing_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -400,14 +402,14 @@ static void poselib_add_menu_invoke__replacemenu(bContext *C, uiLayout *layout,
Object *ob = get_poselib_object(C);
bAction *act = ob->poselib; /* never NULL */
TimeMarker *marker;
-
+
wmOperatorType *ot = WM_operatortype_find("POSELIB_OT_pose_add", 1);
BLI_assert(ot != NULL);
/* set the operator execution context correctly */
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
-
+
/* add each marker to this menu */
for (marker = act->markers.first; marker; marker = marker->next) {
PointerRNA props_ptr;
@@ -427,30 +429,30 @@ static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
bPose *pose = (ob) ? ob->pose : NULL;
uiPopupMenu *pup;
uiLayout *layout;
-
+
/* sanity check */
- if (ELEM(NULL, ob, pose))
+ if (ELEM(NULL, ob, pose))
return OPERATOR_CANCELLED;
-
+
/* start building */
pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
layout = UI_popup_menu_layout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
-
+
/* add new (adds to the first unoccupied frame) */
uiItemIntO(layout, IFACE_("Add New"), ICON_NONE, "POSELIB_OT_pose_add", "frame", poselib_get_free_index(ob->poselib));
-
+
/* check if we have any choices to add a new pose in any other way */
if ((ob->poselib) && (ob->poselib->markers.first)) {
/* add new (on current frame) */
uiItemIntO(layout, IFACE_("Add New (Current Frame)"), ICON_NONE, "POSELIB_OT_pose_add", "frame", CFRA);
-
+
/* replace existing - submenu */
uiItemMenuF(layout, IFACE_("Replace Existing..."), 0, poselib_add_menu_invoke__replacemenu, NULL);
}
-
+
UI_popup_menu_end(C, pup);
-
+
/* this operator is only for a menu, not used further */
return OPERATOR_INTERFACE;
}
@@ -458,21 +460,22 @@ static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
static int poselib_add_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Object *ob = get_poselib_object(C);
- bAction *act = poselib_validate(ob);
+ bAction *act = poselib_validate(bmain, ob);
bPose *pose = (ob) ? ob->pose : NULL;
TimeMarker *marker;
KeyingSet *ks;
int frame = RNA_int_get(op->ptr, "frame");
char name[64];
-
+
/* sanity check (invoke should have checked this anyway) */
- if (ELEM(NULL, ob, pose))
+ if (ELEM(NULL, ob, pose))
return OPERATOR_CANCELLED;
-
+
/* get name to give to pose */
RNA_string_get(op->ptr, "name", name);
-
+
/* add pose to poselib - replaces any existing pose there
* - for the 'replace' option, this should end up finding the appropriate marker,
* so no new one will be added
@@ -485,20 +488,20 @@ static int poselib_add_exec(bContext *C, wmOperator *op)
}
if (marker == NULL) {
marker = MEM_callocN(sizeof(TimeMarker), "ActionMarker");
-
+
BLI_strncpy(marker->name, name, sizeof(marker->name));
marker->frame = frame;
-
+
BLI_addtail(&act->markers, marker);
}
-
+
/* validate name */
BLI_uniquename(&act->markers, marker, DATA_("Pose"), '.', offsetof(TimeMarker, name), sizeof(marker->name));
-
+
/* use Keying Set to determine what to store for the pose */
ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_WHOLE_CHARACTER_SELECTED_ID); /* this includes custom props :)*/
ANIM_apply_keyingset(C, NULL, act, ks, MODIFYKEY_MODE_INSERT, (float)frame);
-
+
/* store new 'active' pose number */
act->active_marker = BLI_listbase_count(&act->markers);
DEG_id_tag_update(&act->id, DEG_TAG_COPY_ON_WRITE);
@@ -513,15 +516,15 @@ void POSELIB_OT_pose_add(wmOperatorType *ot)
ot->name = "PoseLib Add Pose";
ot->idname = "POSELIB_OT_pose_add";
ot->description = "Add the current Pose to the active Pose Library";
-
+
/* api callbacks */
ot->invoke = poselib_add_menu_invoke;
ot->exec = poselib_add_exec;
ot->poll = poselib_add_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_int(ot->srna, "frame", 1, 0, INT_MAX, "Frame", "Frame to store pose on", 0, INT_MAX);
RNA_def_string(ot->srna, "name", "Pose", 64, "Pose Name", "Name of newly added Pose");
@@ -542,7 +545,7 @@ static const EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA
if (C == NULL) {
return DummyRNA_NULL_items;
}
-
+
/* check that the action exists */
if (act) {
/* add each marker to the list */
@@ -589,12 +592,12 @@ static int poselib_remove_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index);
return OPERATOR_CANCELLED;
}
-
+
/* remove relevant keyframes */
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
BezTriple *bezt;
unsigned int i;
-
+
if (fcu->bezt) {
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
/* check if remove */
@@ -605,15 +608,15 @@ static int poselib_remove_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* remove poselib from list */
BLI_freelinkN(&act->markers, marker);
-
+
/* fix active pose number */
act->active_marker = 0;
-
- /* send notifiers for this - using keyframe editing notifiers, since action
- * may be being shown in anim editors as active action
+
+ /* send notifiers for this - using keyframe editing notifiers, since action
+ * may be being shown in anim editors as active action
*/
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
DEG_id_tag_update(&act->id, DEG_TAG_COPY_ON_WRITE);
@@ -625,20 +628,20 @@ static int poselib_remove_exec(bContext *C, wmOperator *op)
void POSELIB_OT_pose_remove(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "PoseLib Remove Pose";
ot->idname = "POSELIB_OT_pose_remove";
ot->description = "Remove nth pose from the active Pose Library";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = poselib_remove_exec;
ot->poll = has_poselib_pose_data_for_editing_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to remove");
RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
@@ -651,13 +654,13 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, const wmEvent *eve
Object *ob = get_poselib_object(C);
bAction *act = (ob) ? ob->poselib : NULL;
TimeMarker *marker;
-
+
/* check if valid poselib */
if (act == NULL) {
BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
return OPERATOR_CANCELLED;
}
-
+
/* get index (and pointer) of pose to remove */
marker = BLI_findlink(&act->markers, act->active_marker - 1);
if (marker == NULL) {
@@ -669,7 +672,7 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, const wmEvent *eve
RNA_enum_set(op->ptr, "pose", act->active_marker - 1);
RNA_string_set(op->ptr, "name", marker->name);
}
-
+
/* part to sync with other similar operators... */
return WM_operator_props_popup_confirm(C, op, event);
}
@@ -680,32 +683,32 @@ static int poselib_rename_exec(bContext *C, wmOperator *op)
bAction *act = (ob) ? ob->poselib : NULL;
TimeMarker *marker;
char newname[64];
-
+
/* check if valid poselib */
if (act == NULL) {
BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
return OPERATOR_CANCELLED;
}
-
+
/* get index (and pointer) of pose to remove */
marker = BLI_findlink(&act->markers, RNA_enum_get(op->ptr, "pose"));
if (marker == NULL) {
BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
return OPERATOR_CANCELLED;
}
-
+
/* get new name */
RNA_string_get(op->ptr, "name", newname);
-
+
/* copy name and validate it */
BLI_strncpy(marker->name, newname, sizeof(marker->name));
BLI_uniquename(&act->markers, marker, DATA_("Pose"), '.', offsetof(TimeMarker, name), sizeof(marker->name));
-
- /* send notifiers for this - using keyframe editing notifiers, since action
- * may be being shown in anim editors as active action
+
+ /* send notifiers for this - using keyframe editing notifiers, since action
+ * may be being shown in anim editors as active action
*/
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -713,20 +716,20 @@ static int poselib_rename_exec(bContext *C, wmOperator *op)
void POSELIB_OT_pose_rename(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "PoseLib Rename Pose";
ot->idname = "POSELIB_OT_pose_rename";
ot->description = "Rename specified pose from the active Pose Library";
-
+
/* api callbacks */
ot->invoke = poselib_rename_invoke;
ot->exec = poselib_rename_exec;
ot->poll = has_poselib_pose_data_for_editing_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
/* NOTE: name not pose is the operator's "main" property, so that it will get activated in the popup for easy renaming */
ot->prop = RNA_def_string(ot->srna, "name", "RenamedPose", 64, "New Pose Name", "New name for pose");
@@ -825,10 +828,10 @@ void POSELIB_OT_pose_move(wmOperatorType *ot)
typedef struct tPoseLib_PreviewData {
ListBase backups; /* tPoseLib_Backup structs for restoring poses */
ListBase searchp; /* LinkData structs storing list of poses which match the current search-string */
-
+
Scene *scene; /* active scene */
ScrArea *sa; /* active area */
-
+
PointerRNA rna_ptr; /* RNA-Pointer to Object 'ob' */
Object *ob; /* object to work on */
bArmature *arm; /* object's armature data */
@@ -845,7 +848,7 @@ typedef struct tPoseLib_PreviewData {
short search_cursor; /* position of cursor in searchstr (cursor occurs before the item at the nominated index) */
char searchstr[64]; /* (Part of) Name to search for to filter poses that get shown */
char searchold[64]; /* Previously set searchstr (from last loop run), so that we can detected when to rebuild searchp */
-
+
char headerstr[UI_MAX_DRAW_STR]; /* Info-text to print in header */
} tPoseLib_PreviewData;
@@ -855,7 +858,7 @@ enum {
PL_PREVIEW_RUNNING,
PL_PREVIEW_CONFIRM,
PL_PREVIEW_CANCEL,
- PL_PREVIEW_RUNONCE
+ PL_PREVIEW_RUNONCE
};
/* defines for tPoseLib_PreviewData->redraw values */
@@ -877,9 +880,9 @@ enum {
/* simple struct for storing backup info */
typedef struct tPoseLib_Backup {
struct tPoseLib_Backup *next, *prev;
-
+
bPoseChannel *pchan; /* pose channel backups are for */
-
+
bPoseChannel olddata; /* copy of pose channel's old data (at start) */
IDProperty *oldprops; /* copy (needs freeing) of pose channel's properties (at start) */
} tPoseLib_Backup;
@@ -907,22 +910,22 @@ static void poselib_backup_posecopy(tPoseLib_PreviewData *pld)
for (agrp = pld->act->groups.first; agrp; agrp = agrp->next) {
/* try to find posechannel */
pchan = BKE_pose_channel_find_name(pld->pose, agrp->name);
-
+
/* backup data if available */
if (pchan) {
tPoseLib_Backup *plb;
-
+
/* store backup */
plb = MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup");
-
+
plb->pchan = pchan;
memcpy(&plb->olddata, plb->pchan, sizeof(bPoseChannel));
-
+
if (pchan->prop)
plb->oldprops = IDP_CopyProperty(pchan->prop);
-
+
BLI_addtail(&pld->backups, plb);
-
+
/* mark as being affected */
pld->totcount++;
}
@@ -933,7 +936,7 @@ static void poselib_backup_posecopy(tPoseLib_PreviewData *pld)
static void poselib_backup_restore(tPoseLib_PreviewData *pld)
{
tPoseLib_Backup *plb;
-
+
for (plb = pld->backups.first; plb; plb = plb->next) {
/* copy most of data straight back */
memcpy(plb->pchan, &plb->olddata, sizeof(bPoseChannel));
@@ -959,7 +962,7 @@ static void poselib_backup_free_data(tPoseLib_PreviewData *pld)
IDP_FreeProperty(plb->oldprops);
MEM_freeN(plb->oldprops);
}
-
+
/* free backup element now */
BLI_freelinkN(&pld->backups, plb);
}
@@ -980,19 +983,19 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
bPoseChannel *pchan;
bAction *act = pld->act;
bActionGroup *agrp;
-
+
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc group_ok_cb;
int frame = 1;
const bool any_bone_selected = pld->flag & PL_PREVIEW_ANY_BONE_SELECTED;
-
+
/* get the frame */
if (pld->marker)
frame = pld->marker->frame;
else
return;
-
-
+
+
/* init settings for testing groups for keyframes */
group_ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
ked.f1 = ((float)frame) - 0.5f;
@@ -1004,10 +1007,10 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
if (ANIM_animchanneldata_keyframes_loop(&ked, NULL, agrp, ALE_GROUP, NULL, group_ok_cb, NULL)) {
/* has keyframe on this frame, so try to get a PoseChannel with this name */
pchan = BKE_pose_channel_find_name(pose, agrp->name);
-
+
if (pchan) {
bool ok = 0;
-
+
/* check if this bone should get any animation applied */
if (!any_bone_selected) {
/* if no bones are selected, then any bone is ok */
@@ -1023,7 +1026,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
}
}
- if (ok)
+ if (ok)
animsys_evaluate_action_group(ptr, act, agrp, NULL, (float)frame);
}
}
@@ -1037,7 +1040,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
bPoseChannel *pchan;
bAction *act = pld->act;
bActionGroup *agrp;
-
+
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
ListBase dsources = {NULL, NULL};
bool autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id);
@@ -1047,13 +1050,13 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
/* only for selected bones unless there aren't any selected, in which case all are included */
pchan = BKE_pose_channel_find_name(pose, agrp->name);
-
+
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 */
- ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan);
-
+ ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan);
+
/* clear any unkeyed tags */
if (pchan->bone)
pchan->bone->flag &= ~BONE_UNKEYED;
@@ -1066,14 +1069,14 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
}
}
}
-
+
/* perform actual auto-keying now */
if (autokey) {
/* insert keyframes for all relevant bones in one go */
ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
BLI_freelistN(&dsources);
}
-
+
/* send notifiers for this */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
@@ -1082,7 +1085,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
static void poselib_preview_apply(bContext *C, wmOperator *op)
{
tPoseLib_PreviewData *pld = (tPoseLib_PreviewData *)op->customdata;
-
+
/* only recalc pose (and its dependencies) if pose has changed */
if (pld->redraw == PL_PREVIEW_REDRAWALL) {
/* don't clear pose if firsttime */
@@ -1090,7 +1093,7 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
poselib_backup_restore(pld);
else
pld->flag &= ~PL_PREVIEW_FIRSTTIME;
-
+
/* pose should be the right one to draw (unless we're temporarily not showing it) */
if ((pld->flag & PL_PREVIEW_SHOWORIGINAL) == 0) {
RNA_int_set(op->ptr, "pose_index", BLI_findindex(&pld->act->markers, pld->marker));
@@ -1098,8 +1101,8 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
}
else
RNA_int_set(op->ptr, "pose_index", -2); /* -2 means don't apply any pose */
-
- /* old optimize trick... this enforces to bypass the depgraph
+
+ /* old optimize trick... this enforces to bypass the depgraph
* - note: code copied from transform_generics.c -> recalcData()
*/
// FIXME: shouldn't this use the builtin stuff?
@@ -1108,7 +1111,7 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
else
BKE_pose_where_is(CTX_data_depsgraph(C), pld->scene, pld->ob);
}
-
+
/* do header print - if interactively previewing */
if (pld->state == PL_PREVIEW_RUNNING) {
if (pld->flag & PL_PREVIEW_SHOWORIGINAL) {
@@ -1121,10 +1124,10 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
char tempstr[65];
char markern[64];
short index;
-
+
/* get search-string */
index = pld->search_cursor;
-
+
if (index >= 0 && index < sizeof(tempstr) - 1) {
memcpy(&tempstr[0], &pld->searchstr[0], index);
tempstr[index] = '|';
@@ -1133,7 +1136,7 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
else {
BLI_strncpy(tempstr, pld->searchstr, sizeof(tempstr));
}
-
+
/* get marker name */
BLI_strncpy(markern, pld->marker ? pld->marker->name : "No Matches", sizeof(markern));
@@ -1152,7 +1155,7 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
ED_area_headerprint(pld->sa, pld->headerstr);
}
}
-
+
/* request drawing of view + clear redraw flag */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pld->ob);
pld->redraw = PL_PREVIEW_NOREDRAW;
@@ -1160,7 +1163,7 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
/* ---------------------------- */
-/* This helper function is called during poselib_preview_poses to find the
+/* This helper function is called during poselib_preview_poses to find the
* pose to preview next (after a change event)
*/
static void poselib_preview_get_next(tPoseLib_PreviewData *pld, int step)
@@ -1168,20 +1171,20 @@ static void poselib_preview_get_next(tPoseLib_PreviewData *pld, int step)
/* stop if not going anywhere, as we assume that there is a direction to move in */
if (step == 0)
return;
-
+
/* search-string dictates a special approach */
if (pld->searchstr[0]) {
TimeMarker *marker;
LinkData *ld, *ldn, *ldc;
-
+
/* free and rebuild if needed (i.e. if search-str changed) */
if (!STREQ(pld->searchstr, pld->searchold)) {
/* free list of temporary search matches */
BLI_freelistN(&pld->searchp);
-
+
/* generate a new list of search matches */
for (marker = pld->act->markers.first; marker; marker = marker->next) {
- /* does the name partially match?
+ /* does the name partially match?
* - don't worry about case, to make it easier for users to quickly input a name (or
* part of one), which is the whole point of this feature
*/
@@ -1192,17 +1195,17 @@ static void poselib_preview_get_next(tPoseLib_PreviewData *pld, int step)
BLI_addtail(&pld->searchp, ld);
}
}
-
+
/* set current marker to NULL (so that we start from first) */
pld->marker = NULL;
}
-
+
/* check if any matches */
if (BLI_listbase_is_empty(&pld->searchp)) {
pld->marker = NULL;
return;
}
-
+
/* find first match */
for (ldc = pld->searchp.first; ldc; ldc = ldc->next) {
if (ldc->data == pld->marker)
@@ -1210,8 +1213,8 @@ static void poselib_preview_get_next(tPoseLib_PreviewData *pld, int step)
}
if (ldc == NULL)
ldc = pld->searchp.first;
-
- /* Loop through the matches in a cyclic fashion, incrementing/decrementing step as appropriate
+
+ /* Loop through the matches in a cyclic fashion, incrementing/decrementing step as appropriate
* until step == 0. At this point, marker should be the correct marker.
*/
if (step > 0) {
@@ -1222,19 +1225,19 @@ static void poselib_preview_get_next(tPoseLib_PreviewData *pld, int step)
for (ld = ldc; ld && step; ld = ldn, step++)
ldn = (ld->prev) ? ld->prev : pld->searchp.last;
}
-
+
/* set marker */
if (ld)
pld->marker = ld->data;
}
else {
TimeMarker *marker, *next;
-
+
/* if no marker, because we just ended searching, then set that to the start of the list */
if (pld->marker == NULL)
pld->marker = pld->act->markers.first;
-
- /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate
+
+ /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate
* until step == 0. At this point, marker should be the correct marker.
*/
if (step > 0) {
@@ -1245,7 +1248,7 @@ static void poselib_preview_get_next(tPoseLib_PreviewData *pld, int step)
for (marker = pld->marker; marker && step; marker = next, step++)
next = (marker->prev) ? marker->prev : pld->act->markers.last;
}
-
+
/* it should be fairly impossible for marker to be NULL */
if (marker)
pld->marker = marker;
@@ -1262,28 +1265,28 @@ static void poselib_preview_handle_search(tPoseLib_PreviewData *pld, unsigned sh
short len = strlen(pld->searchstr);
short index = pld->search_cursor;
short i;
-
- for (i = index; i <= len; i++)
+
+ for (i = index; i <= len; i++)
pld->searchstr[i - 1] = pld->searchstr[i];
-
+
pld->search_cursor--;
-
+
poselib_preview_get_next(pld, 1);
pld->redraw = PL_PREVIEW_REDRAWALL;
return;
}
break;
-
+
case DELKEY:
if (pld->searchstr[0] && pld->searchstr[1]) {
short len = strlen(pld->searchstr);
short index = pld->search_cursor;
int i;
-
+
if (index < len) {
- for (i = index; i < len; i++)
+ for (i = index; i < len; i++)
pld->searchstr[i] = pld->searchstr[i + 1];
-
+
poselib_preview_get_next(pld, 1);
pld->redraw = PL_PREVIEW_REDRAWALL;
return;
@@ -1291,23 +1294,23 @@ static void poselib_preview_handle_search(tPoseLib_PreviewData *pld, unsigned sh
}
break;
}
-
+
if (ascii) {
/* character to add to the string */
short index = pld->search_cursor;
short len = (pld->searchstr[0]) ? strlen(pld->searchstr) : 0;
short i;
-
+
if (len) {
- for (i = len; i > index; i--)
+ for (i = len; i > index; i--)
pld->searchstr[i] = pld->searchstr[i - 1];
}
else
pld->searchstr[1] = 0;
-
+
pld->searchstr[index] = ascii;
pld->search_cursor++;
-
+
poselib_preview_get_next(pld, 1);
pld->redraw = PL_PREVIEW_REDRAWALL;
}
@@ -1318,18 +1321,18 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
{
tPoseLib_PreviewData *pld = op->customdata;
int ret = OPERATOR_RUNNING_MODAL;
-
+
/* only accept 'press' event, and ignore 'release', so that we don't get double actions */
if (ELEM(event->val, KM_PRESS, KM_NOTHING) == 0) {
//printf("PoseLib: skipping event with type '%s' and val %d\n", WM_key_event_string(event->type, false), event->val);
- return ret;
+ return ret;
}
-
+
/* backup stuff that needs to occur before every operation
* - make a copy of searchstr, so that we know if cache needs to be rebuilt
*/
BLI_strncpy(pld->searchold, pld->searchstr, sizeof(pld->searchold));
-
+
/* if we're currently showing the original pose, only certain events are handled */
if (pld->flag & PL_PREVIEW_SHOWORIGINAL) {
switch (event->type) {
@@ -1338,7 +1341,7 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
case RIGHTMOUSE:
pld->state = PL_PREVIEW_CANCEL;
break;
-
+
/* exit - confirm */
case LEFTMOUSE:
case RETKEY:
@@ -1346,30 +1349,30 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
case SPACEKEY:
pld->state = PL_PREVIEW_CONFIRM;
break;
-
+
/* view manipulation */
- /* we add pass through here, so that the operators responsible for these can still run,
+ /* we add pass through here, so that the operators responsible for these can still run,
* even though we still maintain control (as RUNNING_MODAL flag is still set too)
*/
case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
- case PADPLUSKEY: case PADMINUS:
+ case PADPLUSKEY: case PADMINUS:
case MIDDLEMOUSE: case MOUSEMOVE:
//pld->redraw = PL_PREVIEW_REDRAWHEADER;
ret = OPERATOR_PASS_THROUGH;
break;
-
+
/* quicky compare to original */
case TABKEY:
pld->flag &= ~PL_PREVIEW_SHOWORIGINAL;
pld->redraw = PL_PREVIEW_REDRAWALL;
break;
}
-
+
/* EXITS HERE... */
return ret;
}
-
+
/* NORMAL EVENT HANDLING... */
/* searching takes priority over normal activity */
switch (event->type) {
@@ -1378,7 +1381,7 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
case RIGHTMOUSE:
pld->state = PL_PREVIEW_CANCEL;
break;
-
+
/* exit - confirm */
case LEFTMOUSE:
case RETKEY:
@@ -1386,39 +1389,39 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
case SPACEKEY:
pld->state = PL_PREVIEW_CONFIRM;
break;
-
+
/* toggle between original pose and poselib pose*/
case TABKEY:
pld->flag |= PL_PREVIEW_SHOWORIGINAL;
pld->redraw = PL_PREVIEW_REDRAWALL;
break;
-
+
/* change to previous pose (cyclic) */
case PAGEUPKEY:
case WHEELUPMOUSE:
poselib_preview_get_next(pld, -1);
pld->redraw = PL_PREVIEW_REDRAWALL;
break;
-
+
/* change to next pose (cyclic) */
case PAGEDOWNKEY:
case WHEELDOWNMOUSE:
poselib_preview_get_next(pld, 1);
pld->redraw = PL_PREVIEW_REDRAWALL;
break;
-
+
/* jump 5 poses (cyclic, back) */
case DOWNARROWKEY:
poselib_preview_get_next(pld, -5);
pld->redraw = PL_PREVIEW_REDRAWALL;
break;
-
+
/* jump 5 poses (cyclic, forward) */
case UPARROWKEY:
poselib_preview_get_next(pld, 5);
pld->redraw = PL_PREVIEW_REDRAWALL;
break;
-
+
/* change to next pose or searching cursor control */
case RIGHTARROWKEY:
if (pld->searchstr[0]) {
@@ -1433,7 +1436,7 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
pld->redraw = PL_PREVIEW_REDRAWALL;
}
break;
-
+
/* change to next pose or searching cursor control */
case LEFTARROWKEY:
if (pld->searchstr[0]) {
@@ -1448,7 +1451,7 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
pld->redraw = PL_PREVIEW_REDRAWALL;
}
break;
-
+
/* change to first pose or start of searching string */
case HOMEKEY:
if (pld->searchstr[0]) {
@@ -1459,11 +1462,11 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
/* change to first pose */
pld->marker = pld->act->markers.first;
pld->act->active_marker = 1;
-
+
pld->redraw = PL_PREVIEW_REDRAWALL;
}
break;
-
+
/* change to last pose or start of searching string */
case ENDKEY:
if (pld->searchstr[0]) {
@@ -1474,20 +1477,20 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
/* change to last pose */
pld->marker = pld->act->markers.last;
pld->act->active_marker = BLI_listbase_count(&pld->act->markers);
-
+
pld->redraw = PL_PREVIEW_REDRAWALL;
}
break;
-
+
/* view manipulation */
- /* we add pass through here, so that the operators responsible for these can still run,
+ /* we add pass through here, so that the operators responsible for these can still run,
* even though we still maintain control (as RUNNING_MODAL flag is still set too)
*/
case MIDDLEMOUSE: case MOUSEMOVE:
//pld->redraw = PL_PREVIEW_REDRAWHEADER;
ret = OPERATOR_PASS_THROUGH;
break;
-
+
/* view manipulation, or searching */
case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
@@ -1502,13 +1505,13 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
ret = OPERATOR_PASS_THROUGH;
}
break;
-
+
/* otherwise, assume that searching might be able to handle it */
default:
poselib_preview_handle_search(pld, event->type, event->ascii);
break;
}
-
+
return ret;
}
@@ -1520,19 +1523,19 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op)
tPoseLib_PreviewData *pld;
Object *ob = get_poselib_object(C);
int pose_index = RNA_int_get(op->ptr, "pose_index");
-
+
/* set up preview state info */
op->customdata = pld = MEM_callocN(sizeof(tPoseLib_PreviewData), "PoseLib Preview Data");
-
+
/* get basic data */
pld->ob = ob;
pld->arm = (ob) ? (ob->data) : NULL;
pld->pose = (ob) ? (ob->pose) : NULL;
pld->act = (ob) ? (ob->poselib) : NULL;
-
+
pld->scene = CTX_data_scene(C);
pld->sa = CTX_wm_area(C);
-
+
/* get starting pose based on RNA-props for this operator */
if (pose_index == -1)
pld->marker = poselib_get_active_pose(pld->act);
@@ -1540,7 +1543,7 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op)
pld->flag |= PL_PREVIEW_SHOWORIGINAL;
else
pld->marker = (pld->act) ? BLI_findlink(&pld->act->markers, pose_index) : NULL;
-
+
/* check if valid poselib */
if (ELEM(NULL, pld->ob, pld->pose, pld->arm)) {
BKE_report(op->reports, RPT_ERROR, "Pose lib is only for armatures in pose mode");
@@ -1556,7 +1559,7 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op)
if (pld->act->markers.first) {
/* just use first one then... */
pld->marker = pld->act->markers.first;
- if (pose_index > -2)
+ if (pose_index > -2)
BKE_report(op->reports, RPT_WARNING, "Pose lib had no active pose");
}
else {
@@ -1565,23 +1568,23 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op)
return;
}
}
-
+
/* get ID pointer for applying poses */
RNA_id_pointer_create(&ob->id, &pld->rna_ptr);
-
+
/* make backups for restoring pose */
poselib_backup_posecopy(pld);
-
+
/* set flags for running */
pld->state = PL_PREVIEW_RUNNING;
pld->redraw = PL_PREVIEW_REDRAWALL;
pld->flag |= PL_PREVIEW_FIRSTTIME;
-
+
/* set depsgraph flags */
/* make sure the lock is set OK, unlock can be accidentally saved? */
pld->pose->flag |= POSE_LOCKED;
pld->pose->flag &= ~POSE_DO_UNLOCK;
-
+
/* clear strings + search */
pld->headerstr[0] = pld->searchstr[0] = pld->searchold[0] = '\0';
pld->search_cursor = 0;
@@ -1597,18 +1600,18 @@ static void poselib_preview_cleanup(bContext *C, wmOperator *op)
bArmature *arm = pld->arm;
bAction *act = pld->act;
TimeMarker *marker = pld->marker;
-
+
/* redraw the header so that it doesn't show any of our stuff anymore */
ED_area_headerprint(pld->sa, NULL);
-
+
/* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
pose->flag |= POSE_DO_UNLOCK;
-
+
/* clear pose if canceled */
if (pld->state == PL_PREVIEW_CANCEL) {
poselib_backup_restore(pld);
-
- /* old optimize trick... this enforces to bypass the depgraph
+
+ /* old optimize trick... this enforces to bypass the depgraph
* - note: code copied from transform_generics.c -> recalcData()
*/
if ((arm->flag & ARM_DELAYDEFORM) == 0)
@@ -1619,14 +1622,14 @@ static void poselib_preview_cleanup(bContext *C, wmOperator *op)
else if (pld->state == PL_PREVIEW_CONFIRM) {
/* tag poses as appropriate */
poselib_keytag_pose(C, scene, pld);
-
+
/* change active pose setting */
act->active_marker = BLI_findindex(&act->markers, marker) + 1;
action_set_activemarker(act, marker, NULL);
-
+
/* Update event for pose and deformation children */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
-
+
/* updates */
if (IS_AUTOKEY_MODE(scene, NORMAL)) {
//remake_action_ipos(ob->action);
@@ -1634,14 +1637,14 @@ static void poselib_preview_cleanup(bContext *C, wmOperator *op)
else
BKE_pose_where_is(CTX_data_depsgraph(C), scene, ob);
}
-
+
/* Request final redraw of the view. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pld->ob);
-
+
/* free memory used for backups and searching */
poselib_backup_free_data(pld);
BLI_freelistN(&pld->searchp);
-
+
/* free temp data for operator */
MEM_freeN(pld);
op->customdata = NULL;
@@ -1652,10 +1655,10 @@ static int poselib_preview_exit(bContext *C, wmOperator *op)
{
tPoseLib_PreviewData *pld = op->customdata;
int exit_state = pld->state;
-
+
/* finish up */
poselib_preview_cleanup(C, op);
-
+
if (ELEM(exit_state, PL_PREVIEW_CANCEL, PL_PREVIEW_ERROR))
return OPERATOR_CANCELLED;
else
@@ -1673,18 +1676,18 @@ static int poselib_preview_modal(bContext *C, wmOperator *op, const wmEvent *eve
{
tPoseLib_PreviewData *pld = op->customdata;
int ret;
-
+
/* 1) check state to see if we're still running */
if (pld->state != PL_PREVIEW_RUNNING)
return poselib_preview_exit(C, op);
-
+
/* 2) handle events */
ret = poselib_preview_handle_event(C, op, event);
-
+
/* 3) apply changes and redraw, otherwise, confirming goes wrong */
if (pld->redraw)
poselib_preview_apply(C, op);
-
+
return ret;
}
@@ -1692,20 +1695,20 @@ static int poselib_preview_modal(bContext *C, wmOperator *op, const wmEvent *eve
static int poselib_preview_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseLib_PreviewData *pld;
-
+
/* check if everything is ok, and init settings for modal operator */
poselib_preview_init_data(C, op);
pld = (tPoseLib_PreviewData *)op->customdata;
-
+
if (pld->state == PL_PREVIEW_ERROR) {
/* an error occurred, so free temp mem used */
poselib_preview_cleanup(C, op);
return OPERATOR_CANCELLED;
}
-
+
/* do initial apply to have something to look at */
poselib_preview_apply(C, op);
-
+
/* add temp handler if we're running as a modal operator */
WM_event_add_modal_handler(C, op);
@@ -1716,28 +1719,28 @@ static int poselib_preview_invoke(bContext *C, wmOperator *op, const wmEvent *UN
static int poselib_preview_exec(bContext *C, wmOperator *op)
{
tPoseLib_PreviewData *pld;
-
+
/* check if everything is ok, and init settings for modal operator */
poselib_preview_init_data(C, op);
pld = (tPoseLib_PreviewData *)op->customdata;
-
+
if (pld->state == PL_PREVIEW_ERROR) {
/* an error occurred, so free temp mem used */
poselib_preview_cleanup(C, op);
return OPERATOR_CANCELLED;
}
-
+
/* the exec() callback is effectively a 'run-once' scenario, so set the state to that
* so that everything draws correctly
*/
pld->state = PL_PREVIEW_RUNONCE;
-
+
/* apply the active pose */
poselib_preview_apply(C, op);
-
+
/* now, set the status to exit */
pld->state = PL_PREVIEW_CONFIRM;
-
+
/* cleanup */
return poselib_preview_exit(C, op);
}
@@ -1748,21 +1751,21 @@ void POSELIB_OT_browse_interactive(wmOperatorType *ot)
ot->name = "PoseLib Browse Poses";
ot->idname = "POSELIB_OT_browse_interactive";
ot->description = "Interactively browse poses in 3D-View";
-
+
/* callbacks */
ot->invoke = poselib_preview_invoke;
ot->modal = poselib_preview_modal;
ot->cancel = poselib_preview_cancel;
ot->exec = poselib_preview_exec;
ot->poll = has_poselib_pose_data_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
-
+
/* properties */
// TODO: make the pose_index into a proper enum instead of a cryptic int...
ot->prop = RNA_def_int(ot->srna, "pose_index", -1, -2, INT_MAX, "Pose", "Index of the pose to apply (-2 for no change to pose, -1 for poselib active pose)", 0, INT_MAX);
-
+
// XXX: percentage vs factor?
/* not used yet */
/* RNA_def_float_factor(ot->srna, "blend_factor", 1.0f, 0.0f, 1.0f, "Blend Factor", "Amount that the pose is applied on top of the existing poses", 0.0f, 1.0f); */
@@ -1774,7 +1777,7 @@ void POSELIB_OT_apply_pose(wmOperatorType *ot)
ot->name = "Apply Pose Library Pose";
ot->idname = "POSELIB_OT_apply_pose";
ot->description = "Apply specified Pose Library pose to the rig";
-
+
/* callbacks */
ot->exec = poselib_preview_exec;
ot->poll = has_poselib_pose_data_poll;
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index f0dc680598c..75fd952b52a 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -103,9 +103,9 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
// XXX: actually, we can probably still get away with no object - at most we have no updates
if (ELEM(NULL, ob, ob->pose, pchan, pchan->bone))
return;
-
+
arm = ob->data;
-
+
/* can only change selection state if bone can be modified */
if (PBONE_SELECTABLE(arm, pchan->bone)) {
/* change selection state - activate too if selected */
@@ -117,19 +117,19 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
pchan->bone->flag &= ~BONE_SELECTED;
arm->act_bone = NULL;
}
-
+
// TODO: select and activate corresponding vgroup?
-
- /* tag necessary depsgraph updates
+
+ /* tag necessary depsgraph updates
* (see rna_Bone_select_update() in rna_armature.c for details)
*/
if (arm->flag & ARM_HAS_VIZ_DEPS) {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
-
+
/* send necessary notifiers */
WM_main_add_notifier(NC_GEOM | ND_DATA, ob);
-
+
/* tag armature for copy-on-write update (since act_bone is in armature not object) */
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
@@ -143,7 +143,7 @@ bool ED_armature_pose_select_pick_with_buffer(
{
Object *ob = base->object;
Bone *nearBone;
-
+
if (!ob || !ob->pose) return 0;
Object *ob_act = OBACT(view_layer);
@@ -152,11 +152,11 @@ bool ED_armature_pose_select_pick_with_buffer(
/* Callers happen to already get the active base */
Base *base_dummy = NULL;
nearBone = get_bone_from_selectbuffer(&base, 1, obedit != NULL, buffer, hits, 1, do_nearest, &base_dummy);
-
+
/* if the bone cannot be affected, don't do anything */
if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
bArmature *arm = ob->data;
-
+
/* since we do unified select, we don't shift+select a bone if the
* armature object was not active yet.
* note, special exception for armature mode so we can do multi-select
@@ -205,7 +205,7 @@ bool ED_armature_pose_select_pick_with_buffer(
}
}
}
-
+
if (ob_act) {
/* in weightpaint we select the associated vertex group too */
if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
@@ -214,21 +214,21 @@ bool ED_armature_pose_select_pick_with_buffer(
DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
}
}
- /* if there are some dependencies for visualizing armature state
- * (e.g. Mask Modifier in 'Armature' mode), force update
+ /* if there are some dependencies for visualizing armature state
+ * (e.g. Mask Modifier in 'Armature' mode), force update
*/
else if (arm->flag & ARM_HAS_VIZ_DEPS) {
- /* NOTE: ob not ob_act here is intentional - it's the source of the
+ /* NOTE: ob not ob_act here is intentional - it's the source of the
* bones being selected [T37247]
*/
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
-
+
/* tag armature for copy-on-write update (since act_bone is in armature not object) */
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
}
-
+
return nearBone != NULL;
}
@@ -238,12 +238,12 @@ void ED_pose_deselect_all(Object *ob, int select_mode, const bool ignore_visibil
{
bArmature *arm = ob->data;
bPoseChannel *pchan;
-
+
/* we call this from outliner too */
if (ob->pose == NULL) {
return;
}
-
+
/* Determine if we're selecting or deselecting */
if (select_mode == SEL_TOGGLE) {
select_mode = SEL_SELECT;
@@ -256,7 +256,7 @@ void ED_pose_deselect_all(Object *ob, int select_mode, const bool ignore_visibil
}
}
}
-
+
/* Set the flags accordingly */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* ignore the pchan if it isn't visible or if its selection cannot be changed */
@@ -300,9 +300,9 @@ void ED_pose_deselect_all_multi(Object **objects, uint objects_len, int select_m
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
bArmature *arm = ob_iter->data;
-
+
ED_pose_deselect_all(ob_iter, select_mode, ignore_visibility);
-
+
/* if there are some dependencies for visualizing armature state
* (e.g. Mask Modifier in 'Armature' mode), force update
*/
@@ -312,7 +312,7 @@ void ED_pose_deselect_all_multi(Object **objects, uint objects_len, int select_m
*/
DEG_id_tag_update(&ob_iter->id, OB_RECALC_DATA);
}
-
+
/* need to tag armature for cow updates, or else selection doesn't update */
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
@@ -323,16 +323,16 @@ void ED_pose_deselect_all_multi(Object **objects, uint objects_len, int select_m
static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend)
{
Bone *curBone;
-
+
/* stop when unconnected child is encountered, or when unselectable bone is encountered */
if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE))
return;
-
+
if (extend)
bone->flag &= ~BONE_SELECTED;
else
bone->flag |= BONE_SELECTED;
-
+
for (curBone = bone->childbase.first; curBone; curBone = curBone->next)
selectconnected_posebonechildren(ob, curBone, extend);
}
@@ -353,7 +353,7 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEve
return OPERATOR_CANCELLED;
bArmature *arm = base->object->data;
-
+
/* Select parents */
for (curBone = bone; curBone; curBone = next) {
/* ignore bone if cannot be selected */
@@ -362,7 +362,7 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEve
curBone->flag &= ~BONE_SELECTED;
else
curBone->flag |= BONE_SELECTED;
-
+
if (curBone->flag & BONE_CONNECTED)
next = curBone->parent;
else
@@ -371,19 +371,19 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEve
else
next = NULL;
}
-
+
/* Select children */
for (curBone = bone->childbase.first; curBone; curBone = next)
selectconnected_posebonechildren(base->object, curBone, extend);
-
+
/* updates */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object);
-
+
if (arm->flag & ARM_HAS_VIZ_DEPS) {
/* mask modifier ('armature' mode), etc. */
DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
-
+
/* need to tag armature for cow updates, or else selection doesn't update */
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
@@ -401,15 +401,15 @@ void POSE_OT_select_linked(wmOperatorType *ot)
ot->name = "Select Connected";
ot->idname = "POSE_OT_select_linked";
ot->description = "Select bones related to selected ones by parent/child relationships";
-
+
/* callbacks */
/* leave 'exec' unset */
ot->invoke = pose_select_connected_invoke;
ot->poll = pose_select_linked_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
}
@@ -419,7 +419,7 @@ void POSE_OT_select_linked(wmOperatorType *ot)
static int pose_de_select_all_exec(bContext *C, wmOperator *op)
{
int action = RNA_enum_get(op->ptr, "action");
-
+
Scene *scene = CTX_data_scene(C);
int multipaint = scene->toolsettings->multipaint;
@@ -428,7 +428,7 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
}
Object *ob_prev = NULL;
-
+
/* Set the flags */
CTX_DATA_BEGIN_WITH_ID(C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob)
{
@@ -458,14 +458,14 @@ void POSE_OT_select_all(wmOperatorType *ot)
ot->name = "(De)select All";
ot->idname = "POSE_OT_select_all";
ot->description = "Toggle selection status of all bones";
-
+
/* api callbacks */
ot->exec = pose_de_select_all_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
WM_operator_properties_select_all(ot);
}
@@ -546,10 +546,10 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
-
+
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
-
+
for (ct = targets.first; ct; ct = ct->next) {
if ((ct->tar == ob) && (ct->subtarget[0])) {
bPoseChannel *pchanc = BKE_pose_channel_find_name(ob->pose, ct->subtarget);
@@ -571,7 +571,7 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op
}
}
}
-
+
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 1);
}
@@ -579,10 +579,10 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op
}
}
CTX_DATA_END;
-
+
if (!found)
return OPERATOR_CANCELLED;
-
+
return OPERATOR_FINISHED;
}
@@ -592,11 +592,11 @@ void POSE_OT_select_constraint_target(wmOperatorType *ot)
ot->name = "Select Constraint Target";
ot->idname = "POSE_OT_select_constraint_target";
ot->description = "Select bones used as targets for the currently selected bones";
-
+
/* api callbacks */
ot->exec = pose_select_constraint_target_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -611,7 +611,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
int direction = RNA_enum_get(op->ptr, "direction");
const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
bool changed = false;
-
+
pchan_act = BKE_pose_channel_active(ob);
if (pchan_act == NULL) {
return OPERATOR_CANCELLED;
@@ -668,10 +668,10 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
if (changed == false) {
return OPERATOR_CANCELLED;
}
-
+
/* updates */
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
-
+
if (arm->flag & ARM_HAS_VIZ_DEPS) {
/* mask modifier ('armature' mode), etc. */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -690,19 +690,19 @@ void POSE_OT_select_hierarchy(wmOperatorType *ot)
{BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Select Hierarchy";
ot->idname = "POSE_OT_select_hierarchy";
ot->description = "Select immediate parent/children of selected bones";
-
+
/* api callbacks */
ot->exec = pose_select_hierarchy_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_enum(ot->srna, "direction", direction_items, BONE_SELECT_PARENT, "Direction", "");
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
@@ -724,22 +724,22 @@ static bool pose_select_same_group(bContext *C, Object *ob, bool extend)
char *group_flags;
int numGroups = 0;
bool changed = false, tagged = false;
-
+
/* sanity checks */
if (ELEM(NULL, ob, pose, arm))
return 0;
-
+
/* count the number of groups */
numGroups = BLI_listbase_count(&pose->agroups);
if (numGroups == 0)
return 0;
-
- /* alloc a small array to keep track of the groups to use
+
+ /* alloc a small array to keep track of the groups to use
* - each cell stores on/off state for whether group should be used
* - size is (numGroups + 1), since (index = 0) is used for no-group
*/
group_flags = MEM_callocN(numGroups + 1, "pose_select_same_group");
-
+
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
{
/* keep track of group as group to use later? */
@@ -747,13 +747,13 @@ static bool pose_select_same_group(bContext *C, Object *ob, bool extend)
group_flags[pchan->agrp_index] = 1;
tagged = true;
}
-
+
/* deselect all bones before selecting new ones? */
if ((extend == false) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0)
pchan->bone->flag &= ~BONE_SELECTED;
}
CTX_DATA_END;
-
+
/* small optimization: only loop through bones a second time if there are any groups tagged */
if (tagged) {
/* only if group matches (and is not selected or current bone) */
@@ -769,10 +769,10 @@ static bool pose_select_same_group(bContext *C, Object *ob, bool extend)
}
CTX_DATA_END;
}
-
+
/* free temp info */
MEM_freeN(group_flags);
-
+
return changed;
}
@@ -782,25 +782,25 @@ static bool pose_select_same_layer(bContext *C, Object *ob, bool extend)
bArmature *arm = (ob) ? ob->data : NULL;
bool changed = false;
int layers = 0;
-
+
if (ELEM(NULL, ob, pose, arm))
return 0;
-
+
/* figure out what bones are selected */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
{
/* keep track of layers to use later? */
if (pchan->bone->flag & BONE_SELECTED)
layers |= pchan->bone->layer;
-
+
/* deselect all bones before selecting new ones? */
if ((extend == false) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0)
pchan->bone->flag &= ~BONE_SELECTED;
}
CTX_DATA_END;
- if (layers == 0)
+ if (layers == 0)
return 0;
-
+
/* select bones that are on same layers as layers flag */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
{
@@ -811,7 +811,7 @@ static bool pose_select_same_layer(bContext *C, Object *ob, bool extend)
}
}
CTX_DATA_END;
-
+
return changed;
}
@@ -819,11 +819,11 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, Object
{
KeyingSet *ks = ANIM_scene_get_active_keyingset(CTX_data_scene(C));
KS_Path *ksp;
-
+
bArmature *arm = (ob) ? ob->data : NULL;
bPose *pose = (ob) ? ob->pose : NULL;
bool changed = false;
-
+
/* sanity checks: validate Keying Set and object */
if (ks == NULL) {
BKE_report(reports, RPT_ERROR, "No active Keying Set to use");
@@ -832,7 +832,7 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, Object
else if (ANIM_validate_keyingset(C, NULL, ks) != 0) {
if (ks->paths.first == NULL) {
if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
- BKE_report(reports, RPT_ERROR,
+ BKE_report(reports, RPT_ERROR,
"Use another Keying Set, as the active one depends on the currently "
"selected items or cannot find any targets due to unsuitable context");
}
@@ -842,10 +842,10 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, Object
}
return false;
}
-
+
if (ELEM(NULL, ob, pose, arm))
return false;
-
+
/* if not extending selection, deselect all selected first */
if (extend == false) {
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
@@ -855,8 +855,8 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, Object
}
CTX_DATA_END;
}
-
- /* iterate over elements in the Keying Set, setting selection depending on whether
+
+ /* iterate over elements in the Keying Set, setting selection depending on whether
* that bone is visible or not...
*/
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
@@ -864,10 +864,10 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, Object
if ((ksp->id == &ob->id) && (ksp->rna_path != NULL)) {
if (strstr(ksp->rna_path, "bones")) {
char *boneName = BLI_str_quoted_substrN(ksp->rna_path, "bones[");
-
+
if (boneName) {
bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName);
-
+
if (pchan) {
/* select if bone is visible and can be affected */
if (PBONE_SELECTABLE(arm, pchan->bone)) {
@@ -875,14 +875,14 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, Object
changed = true;
}
}
-
+
/* free temp memory */
MEM_freeN(boneName);
}
}
}
}
-
+
return changed;
}
@@ -893,41 +893,41 @@ static int pose_select_grouped_exec(bContext *C, wmOperator *op)
const ePose_SelectSame_Mode type = RNA_enum_get(op->ptr, "type");
const bool extend = RNA_boolean_get(op->ptr, "extend");
bool changed = false;
-
+
/* sanity check */
if (ob->pose == NULL)
return OPERATOR_CANCELLED;
-
+
/* selection types */
switch (type) {
case POSE_SEL_SAME_LAYER: /* layer */
changed = pose_select_same_layer(C, ob, extend);
break;
-
+
case POSE_SEL_SAME_GROUP: /* group */
changed = pose_select_same_group(C, ob, extend);
break;
-
+
case POSE_SEL_SAME_KEYINGSET: /* Keying Set */
changed = pose_select_same_keyingset(C, op->reports, ob, extend);
break;
-
+
default:
printf("pose_select_grouped() - Unknown selection type %u\n", type);
break;
}
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
-
+
if (arm->flag & ARM_HAS_VIZ_DEPS) {
/* mask modifier ('armature' mode), etc. */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
-
+
/* need to tag armature for cow updates, or else selection doesn't update */
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
-
+
/* report done status */
if (changed)
return OPERATOR_FINISHED;
@@ -948,15 +948,15 @@ void POSE_OT_select_grouped(wmOperatorType *ot)
ot->name = "Select Grouped";
ot->description = "Select all visible bones grouped by similar properties";
ot->idname = "POSE_OT_select_grouped";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = pose_select_grouped_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
@@ -1022,7 +1022,7 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op)
}
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
-
+
/* need to tag armature for cow updates, or else selection doesn't update */
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
@@ -1037,11 +1037,11 @@ void POSE_OT_select_mirror(wmOperatorType *ot)
ot->name = "Flip Active/Selected Bone";
ot->idname = "POSE_OT_select_mirror";
ot->description = "Mirror the bone selection";
-
+
/* api callbacks */
ot->exec = pose_select_mirror_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 88203474d03..b82535f013b 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -63,7 +63,7 @@
#include "armature_intern.h"
/* **************************************************** */
-/* == POSE 'SLIDING' TOOLS ==
+/* == POSE 'SLIDING' TOOLS ==
*
* A) Push & Relax, Breakdowner
* These tools provide the animator with various capabilities
@@ -96,21 +96,21 @@ typedef struct tPoseSlideOp {
DLRBT_Tree keys; /* binary tree for quicker searching for keyframes (when applicable) */
int cframe; /* current frame number - global time */
-
+
int prevFrame; /* frame before current frame (blend-from) - global time */
int nextFrame; /* frame after current frame (blend-to) - global time */
-
+
float prevFrameF; /* prevFrame, but in local action time (for F-Curve lookups to work) */
float nextFrameF; /* nextFrame, but in local action time (for F-Curve lookups to work) */
-
+
short mode; /* sliding mode (ePoseSlide_Modes) */
short flag; /* unused for now, but can later get used for storing runtime settings.... */
-
+
short channels; /* which transforms/channels are affected (ePoseSlide_Channels) */
short axislock; /* axis-limits for transforms (ePoseSlide_AxisLock) */
-
+
float percentage; /* 0-1 value for determining the influence of whatever is relevant */
-
+
NumInput num; /* numeric input */
} tPoseSlideOp;
@@ -125,19 +125,19 @@ typedef enum ePoseSlide_Modes {
/* Transforms/Channels to Affect */
typedef enum ePoseSlide_Channels {
PS_TFM_ALL = 0, /* All transforms and properties */
-
+
PS_TFM_LOC, /* Loc/Rot/Scale */
PS_TFM_ROT,
PS_TFM_SIZE,
-
+
PS_TFM_BBONE_SHAPE, /* Bendy Bones */
-
+
PS_TFM_PROPS /* Custom Properties */
} ePoseSlide_Channels;
/* Property enum for ePoseSlide_Channels */
static const EnumPropertyItem prop_channels_types[] = {
- {PS_TFM_ALL, "ALL", 0, "All Properties",
+ {PS_TFM_ALL, "ALL", 0, "All Properties",
"All properties, including transforms, bendy bone shape, and custom properties"},
{PS_TFM_LOC, "LOC", 0, "Location", "Location only"},
{PS_TFM_ROT, "ROT", 0, "Rotation", "Rotation only"},
@@ -171,60 +171,60 @@ static int pose_slide_init(bContext *C, wmOperator *op, short mode)
{
tPoseSlideOp *pso;
bAction *act = NULL;
-
+
/* init slide-op data */
pso = op->customdata = MEM_callocN(sizeof(tPoseSlideOp), "tPoseSlideOp");
-
+
/* get info from context */
pso->scene = CTX_data_scene(C);
pso->ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
pso->arm = (pso->ob) ? pso->ob->data : NULL;
pso->sa = CTX_wm_area(C); /* only really needed when doing modal() */
pso->ar = CTX_wm_region(C); /* only really needed when doing modal() */
-
+
pso->cframe = pso->scene->r.cfra;
pso->mode = mode;
-
+
/* set range info from property values - these may get overridden for the invoke() */
pso->percentage = RNA_float_get(op->ptr, "percentage");
pso->prevFrame = RNA_int_get(op->ptr, "prev_frame");
pso->nextFrame = RNA_int_get(op->ptr, "next_frame");
-
+
/* get the set of properties/axes that can be operated on */
pso->channels = RNA_enum_get(op->ptr, "channels");
pso->axislock = RNA_enum_get(op->ptr, "axis_lock");
-
+
/* ensure validity of the settings from the context */
if (ELEM(NULL, pso->ob, pso->arm, pso->ob->adt, pso->ob->adt->action))
return 0;
-
+
act = pso->ob->adt->action;
-
+
/* apply NLA mapping corrections so the frame lookups work */
pso->prevFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
pso->nextFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
-
- /* for each Pose-Channel which gets affected, get the F-Curves for that channel
+
+ /* for each Pose-Channel which gets affected, get the F-Curves for that channel
* and set the relevant transform flags...
*/
poseAnim_mapping_get(C, &pso->pfLinks, pso->ob, act);
-
+
/* set depsgraph flags */
/* make sure the lock is set OK, unlock can be accidentally saved? */
pso->ob->pose->flag |= POSE_LOCKED;
pso->ob->pose->flag &= ~POSE_DO_UNLOCK;
-
- /* do basic initialize of RB-BST used for finding keyframes, but leave the filling of it up
+
+ /* do basic initialize of RB-BST used for finding keyframes, but leave the filling of it up
* to the caller of this (usually only invoke() will do it, to make things more efficient).
*/
BLI_dlrbTree_init(&pso->keys);
-
+
/* initialise numeric input */
initNumInput(&pso->num);
pso->num.idx_max = 0; /* one axis */
pso->num.val_flag[0] |= NUM_NO_NEGATIVE;
pso->num.unit_type[0] = B_UNIT_NONE; /* percentages don't have any units... */
-
+
/* return status is whether we've got all the data we were requested to get */
return 1;
}
@@ -233,19 +233,19 @@ static int pose_slide_init(bContext *C, wmOperator *op, short mode)
static void pose_slide_exit(wmOperator *op)
{
tPoseSlideOp *pso = op->customdata;
-
+
/* if data exists, clear its data and exit */
if (pso) {
/* free the temp pchan links and their data */
poseAnim_mapping_free(&pso->pfLinks);
-
+
/* free RB-BST for keyframes (if it contained data) */
BLI_dlrbTree_free(&pso->keys);
-
+
/* free data itself */
MEM_freeN(pso);
}
-
+
/* cleanup */
op->customdata = NULL;
}
@@ -265,19 +265,19 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, float *val)
float cframe = (float)pso->cframe;
float sVal, eVal;
float w1, w2;
-
+
/* get keyframe values for endpoint poses to blend with */
/* previous/start */
sVal = evaluate_fcurve(fcu, pso->prevFrameF);
/* next/end */
eVal = evaluate_fcurve(fcu, pso->nextFrameF);
-
+
/* if both values are equal, don't do anything */
if (IS_EQF(sVal, eVal)) {
(*val) = sVal;
return;
}
-
+
/* calculate the relative weights of the endpoints */
if (pso->mode == POSESLIDE_BREAKDOWN) {
/* get weights from the percentage control */
@@ -285,20 +285,20 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, float *val)
w2 = 1.0f - w1; /* this must come first */
}
else {
- /* - these weights are derived from the relative distance of these
+ /* - these weights are derived from the relative distance of these
* poses from the current frame
* - they then get normalized so that they only sum up to 1
*/
- float wtot;
-
+ float wtot;
+
w1 = cframe - (float)pso->prevFrame;
w2 = (float)pso->nextFrame - cframe;
-
+
wtot = w1 + w2;
w1 = (w1 / wtot);
w2 = (w2 / wtot);
}
-
+
/* depending on the mode, calculate the new value
* - in all of these, the start+end values are multiplied by w2 and w1 (respectively),
* since multiplication in another order would decrease the value the current frame is closer to
@@ -311,7 +311,7 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, float *val)
* - perform this weighting a number of times given by the percentage...
*/
int iters = (int)ceil(10.0f * pso->percentage); /* TODO: maybe a sensitivity ctrl on top of this is needed */
-
+
while (iters-- > 0) {
(*val) = (-((sVal * w2) + (eVal * w1)) + ((*val) * 6.0f) ) / 5.0f;
}
@@ -324,7 +324,7 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, float *val)
* - perform this weighting a number of times given by the percentage...
*/
int iters = (int)ceil(10.0f * pso->percentage); /* TODO: maybe a sensitivity ctrl on top of this is needed */
-
+
while (iters-- > 0) {
(*val) = ( ((sVal * w2) + (eVal * w1)) + ((*val) * 5.0f) ) / 6.0f;
}
@@ -345,19 +345,19 @@ static void pose_slide_apply_vec3(tPoseSlideOp *pso, tPChanFCurveLink *pfl, floa
{
LinkData *ld = NULL;
char *path = NULL;
-
+
/* get the path to use... */
path = BLI_sprintfN("%s.%s", pfl->pchan_path, propName);
-
+
/* using this path, find each matching F-Curve for the variables we're interested in */
while ( (ld = poseAnim_mapping_getNextFCurve(&pfl->fcurves, ld, path)) ) {
FCurve *fcu = (FCurve *)ld->data;
const int idx = fcu->array_index;
const int lock = pso->axislock;
-
+
/* check if this F-Curve is ok given the current axis locks */
BLI_assert(fcu->array_index < 3);
-
+
if ((lock == 0) ||
((lock & PS_LOCK_X) && (idx == 0)) ||
((lock & PS_LOCK_Y) && (idx == 1)) ||
@@ -367,7 +367,7 @@ static void pose_slide_apply_vec3(tPoseSlideOp *pso, tPChanFCurveLink *pfl, floa
pose_slide_apply_val(pso, fcu, &vec[fcu->array_index]);
}
}
-
+
/* free the temp path we got */
MEM_freeN(path);
}
@@ -378,11 +378,11 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, tPChanFCurveLink *pfl, con
PointerRNA ptr = {{NULL}};
LinkData *ld;
int len = strlen(pfl->pchan_path);
-
+
/* setup pointer RNA for resolving paths */
RNA_pointer_create(NULL, &RNA_PoseBone, pfl->pchan, &ptr);
-
- /* - custom properties are just denoted using ["..."][etc.] after the end of the base path,
+
+ /* - custom properties are just denoted using ["..."][etc.] after the end of the base path,
* so just check for opening pair after the end of the path
* - bbone properties are similar, but they always start with a prefix "bbone_*",
* so a similar method should work here for those too
@@ -390,23 +390,23 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, tPChanFCurveLink *pfl, con
for (ld = pfl->fcurves.first; ld; ld = ld->next) {
FCurve *fcu = (FCurve *)ld->data;
const char *bPtr, *pPtr;
-
+
if (fcu->rna_path == NULL)
continue;
-
- /* do we have a match?
+
+ /* do we have a match?
* - bPtr is the RNA Path with the standard part chopped off
* - pPtr is the chunk of the path which is left over
*/
bPtr = strstr(fcu->rna_path, pfl->pchan_path) + len;
pPtr = strstr(bPtr, prop_prefix);
-
+
if (pPtr) {
/* use RNA to try and get a handle on this property, then, assuming that it is just
* numerical, try and grab the value as a float for temp editing before setting back
*/
PropertyRNA *prop = RNA_struct_find_property(&ptr, pPtr);
-
+
if (prop) {
switch (RNA_property_type(prop)) {
/* continuous values that can be smoothly interpolated... */
@@ -424,7 +424,7 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, tPChanFCurveLink *pfl, con
RNA_property_int_set(&ptr, prop, (int)tval);
break;
}
-
+
/* values which can only take discrete values */
case PROP_BOOLEAN:
{
@@ -440,7 +440,7 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, tPChanFCurveLink *pfl, con
*/
break;
}
-
+
default:
/* cannot handle */
//printf("Cannot Pose Slide non-numerical property\n");
@@ -459,17 +459,17 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
LinkData *ld = NULL;
char *path = NULL;
float cframe;
-
+
/* get the path to use - this should be quaternion rotations only (needs care) */
path = BLI_sprintfN("%s.%s", pfl->pchan_path, "rotation_quaternion");
-
+
/* get the current frame number */
cframe = (float)pso->cframe;
-
+
/* using this path, find each matching F-Curve for the variables we're interested in */
while ( (ld = poseAnim_mapping_getNextFCurve(&pfl->fcurves, ld, path)) ) {
FCurve *fcu = (FCurve *)ld->data;
-
+
/* assign this F-Curve to one of the relevant pointers... */
switch (fcu->array_index) {
case 3: /* z */
@@ -486,22 +486,22 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
break;
}
}
-
+
/* only if all channels exist, proceed */
if (fcu_w && fcu_x && fcu_y && fcu_z) {
float quat_prev[4], quat_next[4];
-
+
/* get 2 quats */
quat_prev[0] = evaluate_fcurve(fcu_w, pso->prevFrameF);
quat_prev[1] = evaluate_fcurve(fcu_x, pso->prevFrameF);
quat_prev[2] = evaluate_fcurve(fcu_y, pso->prevFrameF);
quat_prev[3] = evaluate_fcurve(fcu_z, pso->prevFrameF);
-
+
quat_next[0] = evaluate_fcurve(fcu_w, pso->nextFrameF);
quat_next[1] = evaluate_fcurve(fcu_x, pso->nextFrameF);
quat_next[2] = evaluate_fcurve(fcu_y, pso->nextFrameF);
quat_next[3] = evaluate_fcurve(fcu_z, pso->nextFrameF);
-
+
/* perform blending */
if (pso->mode == POSESLIDE_BREAKDOWN) {
/* just perform the interpol between quat_prev and quat_next using pso->percentage as a guide */
@@ -509,35 +509,35 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
}
else if (pso->mode == POSESLIDE_PUSH) {
float quat_diff[4], quat_orig[4];
-
+
/* calculate the delta transform from the previous to the current */
/* TODO: investigate ways to favour one transform more? */
sub_qt_qtqt(quat_diff, pchan->quat, quat_prev);
-
+
/* make a copy of the original rotation */
copy_qt_qt(quat_orig, pchan->quat);
-
+
/* increase the original by the delta transform, by an amount determined by percentage */
add_qt_qtqt(pchan->quat, quat_orig, quat_diff, pso->percentage);
}
else {
float quat_interp[4], quat_orig[4];
int iters = (int)ceil(10.0f * pso->percentage); /* TODO: maybe a sensitivity ctrl on top of this is needed */
-
+
/* perform this blending several times until a satisfactory result is reached */
while (iters-- > 0) {
/* calculate the interpolation between the endpoints */
interp_qt_qtqt(quat_interp, quat_prev, quat_next, (cframe - pso->prevFrame) / (pso->nextFrame - pso->prevFrame));
-
+
/* make a copy of the original rotation */
copy_qt_qt(quat_orig, pchan->quat);
-
+
/* tricky interpolations - blending between original and new */
interp_qt_qtqt(pchan->quat, quat_orig, quat_interp, 1.0f / 6.0f);
}
}
}
-
+
/* free the path now */
MEM_freeN(path);
}
@@ -546,37 +546,37 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
{
tPChanFCurveLink *pfl;
-
+
/* sanitise the frame ranges */
if (pso->prevFrame == pso->nextFrame) {
/* move out one step either side */
pso->prevFrame--;
pso->nextFrame++;
-
+
/* apply NLA mapping corrections so the frame lookups work */
pso->prevFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
pso->nextFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
}
-
+
/* for each link, handle each set of transforms */
for (pfl = pso->pfLinks.first; pfl; pfl = pfl->next) {
- /* valid transforms for each PoseChannel should have been noted already
- * - sliding the pose should be a straightforward exercise for location+rotation,
- * but rotations get more complicated since we may want to use quaternion blending
+ /* valid transforms for each PoseChannel should have been noted already
+ * - sliding the pose should be a straightforward exercise for location+rotation,
+ * but rotations get more complicated since we may want to use quaternion blending
* for quaternions instead...
*/
bPoseChannel *pchan = pfl->pchan;
-
+
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_LOC) && (pchan->flag & POSE_LOC)) {
/* calculate these for the 'location' vector, and use location curves */
pose_slide_apply_vec3(pso, pfl, pchan->loc, "location");
}
-
+
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_SIZE) && (pchan->flag & POSE_SIZE)) {
/* calculate these for the 'scale' vector, and use scale curves */
pose_slide_apply_vec3(pso, pfl, pchan->size, "scale");
}
-
+
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_ROT) && (pchan->flag & POSE_ROT)) {
/* everything depends on the rotation mode */
if (pchan->rotmode > 0) {
@@ -591,12 +591,12 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
pose_slide_apply_quat(pso, pfl);
}
}
-
+
if (ELEM(pso->channels, PS_TFM_ALL, PS_TFM_BBONE_SHAPE) && (pchan->flag & POSE_BBONE_SHAPE)) {
/* bbone properties - they all start a "bbone_" prefix */
- pose_slide_apply_props(pso, pfl, "bbone_");
+ pose_slide_apply_props(pso, pfl, "bbone_");
}
-
+
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)
@@ -604,7 +604,7 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
pose_slide_apply_props(pso, pfl, "[\""); /* dummy " for texteditor bugs */
}
}
-
+
/* depsgraph updates + redraws */
pose_slide_refresh(C, pso);
}
@@ -633,7 +633,7 @@ static void pose_slide_draw_status(tPoseSlideOp *pso)
char limits_str[UI_MAX_DRAW_STR];
char axis_str[50];
char mode_str[32];
-
+
switch (pso->mode) {
case POSESLIDE_PUSH:
strcpy(mode_str, "Push Pose");
@@ -644,13 +644,13 @@ static void pose_slide_draw_status(tPoseSlideOp *pso)
case POSESLIDE_BREAKDOWN:
strcpy(mode_str, "Breakdown");
break;
-
+
default:
/* unknown */
strcpy(mode_str, "Sliding-Tool");
break;
}
-
+
switch (pso->axislock) {
case PS_LOCK_X:
BLI_strncpy(axis_str, "[X]/Y/Z axis only (X to clear)", sizeof(axis_str));
@@ -661,7 +661,7 @@ static void pose_slide_draw_status(tPoseSlideOp *pso)
case PS_LOCK_Z:
BLI_strncpy(axis_str, "X/Y/[Z] axis only (Z to clear)", sizeof(axis_str));
break;
-
+
default:
if (ELEM(pso->channels, PS_TFM_LOC, PS_TFM_ROT, PS_TFM_SIZE)) {
BLI_strncpy(axis_str, "X/Y/Z = Axis Constraint", sizeof(axis_str));
@@ -671,7 +671,7 @@ static void pose_slide_draw_status(tPoseSlideOp *pso)
}
break;
}
-
+
switch (pso->channels) {
case PS_TFM_LOC:
BLI_snprintf(limits_str, sizeof(limits_str), "[G]/R/S/B/C - Location only (G to clear) | %s", axis_str);
@@ -692,19 +692,19 @@ static void pose_slide_draw_status(tPoseSlideOp *pso)
BLI_strncpy(limits_str, "G/R/S/B/C - Limit to Transform/Property Set", sizeof(limits_str));
break;
}
-
+
if (hasNumInput(&pso->num)) {
Scene *scene = pso->scene;
char str_offs[NUM_STR_REP_LEN];
-
+
outputNumInput(&pso->num, str_offs, &scene->unit);
-
+
BLI_snprintf(status_str, sizeof(status_str), "%s: %s | %s", mode_str, str_offs, limits_str);
}
else {
BLI_snprintf(status_str, sizeof(status_str), "%s: %d %% | %s", mode_str, (int)(pso->percentage * 100.0f), limits_str);
}
-
+
ED_area_headerprint(pso->sa, status_str);
}
@@ -714,34 +714,34 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
tPChanFCurveLink *pfl;
AnimData *adt = pso->ob->adt;
wmWindow *win = CTX_wm_window(C);
-
+
/* for each link, add all its keyframes to the search tree */
for (pfl = pso->pfLinks.first; pfl; pfl = pfl->next) {
LinkData *ld;
-
+
/* do this for each F-Curve */
for (ld = pfl->fcurves.first; ld; ld = ld->next) {
FCurve *fcu = (FCurve *)ld->data;
fcurve_to_keylist(adt, fcu, &pso->keys, NULL);
}
}
-
+
/* consolidate these keyframes, and figure out the nearest ones */
BLI_dlrbTree_linkedlist_sync(&pso->keys);
-
+
/* cancel if no keyframes found... */
if (pso->keys.root) {
ActKeyColumn *ak;
float cframe = (float)pso->cframe;
-
+
/* firstly, check if the current frame is a keyframe... */
ak = (ActKeyColumn *)BLI_dlrbTree_search_exact(&pso->keys, compare_ak_cfraPtr, &cframe);
-
+
if (ak == NULL) {
/* current frame is not a keyframe, so search */
ActKeyColumn *pk = (ActKeyColumn *)BLI_dlrbTree_search_prev(&pso->keys, compare_ak_cfraPtr, &cframe);
ActKeyColumn *nk = (ActKeyColumn *)BLI_dlrbTree_search_next(&pso->keys, compare_ak_cfraPtr, &cframe);
-
+
/* new set the frames */
/* prev frame */
pso->prevFrame = (pk) ? (pk->cfra) : (pso->cframe - 1);
@@ -759,7 +759,7 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
pso->nextFrame = (ak->next) ? (ak->next->cfra) : (pso->cframe + 1);
RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
}
-
+
/* apply NLA mapping corrections so the frame lookups work */
pso->prevFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
pso->nextFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
@@ -769,20 +769,20 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
-
+
/* initial apply for operator... */
/* TODO: need to calculate percentage for initial round too... */
pose_slide_apply(C, pso);
-
+
/* depsgraph updates + redraws */
pose_slide_refresh(C, pso);
-
+
/* set cursor to indicate modal */
WM_cursor_modal_set(win, BC_EW_SCROLLCURSOR);
-
+
/* header print */
pose_slide_draw_status(pso);
-
+
/* add a modal handler for this operator */
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
@@ -810,8 +810,8 @@ static void pose_slide_toggle_channels_mode(wmOperator *op, tPoseSlideOp *pso, e
pso->channels = channel;
}
RNA_enum_set(op->ptr, "channels", pso->channels);
-
-
+
+
/* Reset axis limits too for good measure */
pso->axislock = 0;
RNA_enum_set(op->ptr, "axis_lock", pso->axislock);
@@ -826,7 +826,7 @@ static bool pose_slide_toggle_axis_locks(wmOperator *op, tPoseSlideOp *pso, ePos
RNA_enum_set(op->ptr, "axis_lock", pso->axislock);
return false;
}
-
+
/* Turn on or off? */
if (pso->axislock == axis) {
/* Already limiting on this axis, so turn off */
@@ -837,7 +837,7 @@ static bool pose_slide_toggle_axis_locks(wmOperator *op, tPoseSlideOp *pso, ePos
pso->axislock = axis;
}
RNA_enum_set(op->ptr, "axis_lock", pso->axislock);
-
+
/* Setting changed, so pose update is needed */
return true;
}
@@ -848,9 +848,9 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
tPoseSlideOp *pso = op->customdata;
wmWindow *win = CTX_wm_window(C);
bool do_pose_update = false;
-
+
const bool has_numinput = hasNumInput(&pso->num);
-
+
switch (event->type) {
case LEFTMOUSE: /* confirm */
case RETKEY:
@@ -859,35 +859,35 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* return to normal cursor and header status */
ED_area_headerprint(pso->sa, NULL);
WM_cursor_modal_restore(win);
-
+
/* insert keyframes as required... */
pose_slide_autoKeyframe(C, pso);
pose_slide_exit(op);
-
+
/* done! */
return OPERATOR_FINISHED;
}
-
+
case ESCKEY: /* cancel */
- case RIGHTMOUSE:
+ case RIGHTMOUSE:
{
/* return to normal cursor and header status */
ED_area_headerprint(pso->sa, NULL);
WM_cursor_modal_restore(win);
-
+
/* reset transforms back to original state */
pose_slide_reset(pso);
-
+
/* depsgraph updates + redraws */
pose_slide_refresh(C, pso);
-
+
/* clean up temp data */
pose_slide_exit(op);
-
+
/* canceled! */
return OPERATOR_CANCELLED;
}
-
+
/* Percentage Chane... */
case MOUSEMOVE: /* calculate new position */
{
@@ -895,7 +895,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (has_numinput == false) {
/* update percentage based on position of mouse */
pose_slide_mouse_update_percentage(pso, op, event);
-
+
/* update pose to reflect the new values (see below) */
do_pose_update = true;
}
@@ -905,17 +905,17 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
if ((event->val == KM_PRESS) && handleNumInput(C, &pso->num, event)) {
float value;
-
- /* Grab percentage from numeric input, and store this new value for redo
+
+ /* Grab percentage from numeric input, and store this new value for redo
* NOTE: users see ints, while internally we use a 0-1 float
*/
value = pso->percentage * 100.0f;
applyNumInput(&pso->num, &value);
-
+
pso->percentage = value / 100.0f;
CLAMP(pso->percentage, 0.0f, 1.0f);
RNA_float_set(op->ptr, "percentage", pso->percentage);
-
+
/* Update pose to reflect the new values (see below) */
do_pose_update = true;
break;
@@ -954,8 +954,8 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
do_pose_update = true;
break;
}
-
-
+
+
/* Axis Locks */
/* XXX: Hardcoded... */
case XKEY:
@@ -979,8 +979,8 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
break;
}
-
-
+
+
default: /* Some other unhandled key... */
break;
}
@@ -992,20 +992,20 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
}
-
-
+
+
/* perform pose updates - in response to some user action (e.g. pressing a key or moving the mouse) */
if (do_pose_update) {
/* update percentage indicator in header */
pose_slide_draw_status(pso);
-
+
/* reset transforms (to avoid accumulation errors) */
pose_slide_reset(pso);
-
+
/* apply... */
pose_slide_apply(C, pso);
}
-
+
/* still running... */
return OPERATOR_RUNNING_MODAL;
}
@@ -1022,13 +1022,13 @@ static int pose_slide_exec_common(bContext *C, wmOperator *op, tPoseSlideOp *pso
{
/* settings should have been set up ok for applying, so just apply! */
pose_slide_apply(C, pso);
-
+
/* insert keyframes if needed */
pose_slide_autoKeyframe(C, pso);
-
+
/* cleanup and done */
pose_slide_exit(op);
-
+
return OPERATOR_FINISHED;
}
@@ -1037,10 +1037,10 @@ static int pose_slide_exec_common(bContext *C, wmOperator *op, tPoseSlideOp *pso
static void pose_slide_opdef_properties(wmOperatorType *ot)
{
RNA_def_float_percentage(ot->srna, "percentage", 0.5f, 0.0f, 1.0f, "Percentage", "Weighting factor for which keyframe is favored more", 0.3, 0.7);
-
+
RNA_def_int(ot->srna, "prev_frame", 0, MINAFRAME, MAXFRAME, "Previous Keyframe", "Frame number of keyframe immediately before the current frame", 0, 50);
RNA_def_int(ot->srna, "next_frame", 0, MINAFRAME, MAXFRAME, "Next Keyframe", "Frame number of keyframe immediately after the current frame", 0, 50);
-
+
RNA_def_enum(ot->srna, "channels", prop_channels_types, PS_TFM_ALL, "Channels", "Set of properties that are affected");
RNA_def_enum(ot->srna, "axis_lock", prop_axis_lock_types, 0, "Axis Lock", "Transform axis to restrict effects to");
}
@@ -1051,7 +1051,7 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
-
+
/* initialize data */
if (pose_slide_init(C, op, POSESLIDE_PUSH) == 0) {
pose_slide_exit(op);
@@ -1059,10 +1059,10 @@ static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *ev
}
else
pso = op->customdata;
-
+
/* initialise percentage so that it won't pop on first mouse move */
pose_slide_mouse_update_percentage(pso, op, event);
-
+
/* do common setup work */
return pose_slide_invoke_common(C, op, pso);
}
@@ -1071,7 +1071,7 @@ static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *ev
static int pose_slide_push_exec(bContext *C, wmOperator *op)
{
tPoseSlideOp *pso;
-
+
/* initialize data (from RNA-props) */
if (pose_slide_init(C, op, POSESLIDE_PUSH) == 0) {
pose_slide_exit(op);
@@ -1079,7 +1079,7 @@ static int pose_slide_push_exec(bContext *C, wmOperator *op)
}
else
pso = op->customdata;
-
+
/* do common exec work */
return pose_slide_exec_common(C, op, pso);
}
@@ -1090,17 +1090,17 @@ void POSE_OT_push(wmOperatorType *ot)
ot->name = "Push Pose";
ot->idname = "POSE_OT_push";
ot->description = "Exaggerate the current pose";
-
+
/* callbacks */
ot->exec = pose_slide_push_exec;
ot->invoke = pose_slide_push_invoke;
ot->modal = pose_slide_modal;
ot->cancel = pose_slide_cancel;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
-
+
/* Properties */
pose_slide_opdef_properties(ot);
}
@@ -1111,7 +1111,7 @@ void POSE_OT_push(wmOperatorType *ot)
static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
-
+
/* initialize data */
if (pose_slide_init(C, op, POSESLIDE_RELAX) == 0) {
pose_slide_exit(op);
@@ -1119,10 +1119,10 @@ static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *e
}
else
pso = op->customdata;
-
+
/* initialise percentage so that it won't pop on first mouse move */
pose_slide_mouse_update_percentage(pso, op, event);
-
+
/* do common setup work */
return pose_slide_invoke_common(C, op, pso);
}
@@ -1131,7 +1131,7 @@ static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *e
static int pose_slide_relax_exec(bContext *C, wmOperator *op)
{
tPoseSlideOp *pso;
-
+
/* initialize data (from RNA-props) */
if (pose_slide_init(C, op, POSESLIDE_RELAX) == 0) {
pose_slide_exit(op);
@@ -1139,7 +1139,7 @@ static int pose_slide_relax_exec(bContext *C, wmOperator *op)
}
else
pso = op->customdata;
-
+
/* do common exec work */
return pose_slide_exec_common(C, op, pso);
}
@@ -1150,17 +1150,17 @@ void POSE_OT_relax(wmOperatorType *ot)
ot->name = "Relax Pose";
ot->idname = "POSE_OT_relax";
ot->description = "Make the current pose more similar to its surrounding ones";
-
+
/* callbacks */
ot->exec = pose_slide_relax_exec;
ot->invoke = pose_slide_relax_invoke;
ot->modal = pose_slide_modal;
ot->cancel = pose_slide_cancel;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
-
+
/* Properties */
pose_slide_opdef_properties(ot);
}
@@ -1171,7 +1171,7 @@ void POSE_OT_relax(wmOperatorType *ot)
static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso;
-
+
/* initialize data */
if (pose_slide_init(C, op, POSESLIDE_BREAKDOWN) == 0) {
pose_slide_exit(op);
@@ -1179,10 +1179,10 @@ static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEven
}
else
pso = op->customdata;
-
+
/* initialise percentage so that it won't pop on first mouse move */
pose_slide_mouse_update_percentage(pso, op, event);
-
+
/* do common setup work */
return pose_slide_invoke_common(C, op, pso);
}
@@ -1191,7 +1191,7 @@ static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEven
static int pose_slide_breakdown_exec(bContext *C, wmOperator *op)
{
tPoseSlideOp *pso;
-
+
/* initialize data (from RNA-props) */
if (pose_slide_init(C, op, POSESLIDE_BREAKDOWN) == 0) {
pose_slide_exit(op);
@@ -1199,7 +1199,7 @@ static int pose_slide_breakdown_exec(bContext *C, wmOperator *op)
}
else
pso = op->customdata;
-
+
/* do common exec work */
return pose_slide_exec_common(C, op, pso);
}
@@ -1210,17 +1210,17 @@ void POSE_OT_breakdown(wmOperatorType *ot)
ot->name = "Pose Breakdowner";
ot->idname = "POSE_OT_breakdown";
ot->description = "Create a suitable breakdown pose on the current frame";
-
+
/* callbacks */
ot->exec = pose_slide_breakdown_exec;
ot->invoke = pose_slide_breakdown_invoke;
ot->modal = pose_slide_modal;
ot->cancel = pose_slide_cancel;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
-
+
/* Properties */
pose_slide_opdef_properties(ot);
}
@@ -1240,7 +1240,7 @@ typedef enum ePosePropagate_Termination {
POSE_PROPAGATE_BEFORE_FRAME,
/* stop when we run out of keyframes */
POSE_PROPAGATE_BEFORE_END,
-
+
/* only do on keyframes that are selected */
POSE_PROPAGATE_SELECTED_KEYS,
/* only do on the frames where markers are selected */
@@ -1251,14 +1251,14 @@ typedef enum ePosePropagate_Termination {
typedef union tPosePropagate_ModeData {
/* smart holds + before frame: frame number to stop on */
float end_frame;
-
+
/* selected markers: listbase for CfraElem's marking these frames */
ListBase sel_markers;
} tPosePropagate_ModeData;
/* --------------------------------- */
-/* get frame on which the "hold" for the bone ends
+/* get frame on which the "hold" for the bone ends
* XXX: this may not really work that well if a bone moves on some channels and not others
* if this happens to be a major issue, scrap this, and just make this happen
* independently per F-Curve
@@ -1267,47 +1267,47 @@ static float pose_propagate_get_boneHoldEndFrame(Object *ob, tPChanFCurveLink *p
{
DLRBT_Tree keys, blocks;
ActKeyBlock *ab;
-
+
AnimData *adt = ob->adt;
LinkData *ld;
float endFrame = startFrame;
-
+
/* set up optimized data-structures for searching for relevant keyframes + holds */
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
-
+
for (ld = pfl->fcurves.first; ld; ld = ld->next) {
FCurve *fcu = (FCurve *)ld->data;
fcurve_to_keylist(adt, fcu, &keys, &blocks);
}
-
+
BLI_dlrbTree_linkedlist_sync(&keys);
BLI_dlrbTree_linkedlist_sync(&blocks);
-
- /* find the long keyframe (i.e. hold), and hence obtain the endFrame value
+
+ /* find the long keyframe (i.e. hold), and hence obtain the endFrame value
* - the best case would be one that starts on the frame itself
*/
ab = (ActKeyBlock *)BLI_dlrbTree_search_exact(&blocks, compare_ab_cfraPtr, &startFrame);
-
+
if (actkeyblock_is_valid(ab, &keys) == 0) {
/* There are only two cases for no-exact match:
* 1) the current frame is just before another key but not on a key itself
* 2) the current frame is on a key, but that key doesn't link to the next
*
- * If we've got the first case, then we can search for another block,
+ * If we've got the first case, then we can search for another block,
* otherwise forget it, as we'd be overwriting some valid data.
*/
if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &startFrame) == NULL) {
/* we've got case 1, so try the one after */
ab = (ActKeyBlock *)BLI_dlrbTree_search_next(&blocks, compare_ab_cfraPtr, &startFrame);
-
+
if (actkeyblock_is_valid(ab, &keys) == 0) {
/* try the block before this frame then as last resort */
ab = (ActKeyBlock *)BLI_dlrbTree_search_prev(&blocks, compare_ab_cfraPtr, &startFrame);
-
+
/* whatever happens, stop searching now... */
if (actkeyblock_is_valid(ab, &keys) == 0) {
- /* restrict range to just the frame itself
+ /* restrict range to just the frame itself
* i.e. everything is in motion, so no holds to safely overwrite
*/
ab = NULL;
@@ -1319,13 +1319,13 @@ static float pose_propagate_get_boneHoldEndFrame(Object *ob, tPChanFCurveLink *p
ab = NULL;
}
}
-
+
/* check if we can go any further than we've already gone */
if (ab) {
/* go to next if it is also valid and meets "extension" criteria */
while (ab->next) {
ActKeyBlock *abn = (ActKeyBlock *)ab->next;
-
+
/* must be valid */
if (actkeyblock_is_valid(abn, &keys) == 0)
break;
@@ -1335,24 +1335,24 @@ static float pose_propagate_get_boneHoldEndFrame(Object *ob, tPChanFCurveLink *p
/* should have the same number of curves */
if (ab->totcurve != abn->totcurve)
break;
- /* should have the same value
+ /* should have the same value
* XXX: this may be a bit fuzzy on larger data sets, so be careful
*/
if (ab->val != abn->val)
break;
-
+
/* we can extend the bounds to the end of this "next" block now */
ab = abn;
}
-
+
/* end frame can now take the value of the end of the block */
endFrame = ab->end;
}
-
+
/* free temp memory */
BLI_dlrbTree_free(&keys);
BLI_dlrbTree_free(&blocks);
-
+
/* return the end frame we've found */
return endFrame;
}
@@ -1363,10 +1363,10 @@ static bool pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
bool found = false;
-
+
/* base pointer is always the object -> id_ptr */
RNA_id_pointer_create(&ob->id, &id_ptr);
-
+
/* resolve the property... */
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
if (RNA_property_array_check(prop)) {
@@ -1411,7 +1411,7 @@ static bool pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value)
}
}
}
-
+
return found;
}
@@ -1420,25 +1420,25 @@ static void pose_propagate_fcurve(wmOperator *op, Object *ob, FCurve *fcu,
float startFrame, tPosePropagate_ModeData modeData)
{
const int mode = RNA_enum_get(op->ptr, "mode");
-
+
BezTriple *bezt;
float refVal = 0.0f;
bool keyExists;
int i, match;
short first = 1;
-
+
/* skip if no keyframes to edit */
if ((fcu->bezt == NULL) || (fcu->totvert < 2))
return;
-
+
/* find the reference value from bones directly, which means that the user
- * doesn't need to firstly keyframe the pose (though this doesn't mean that
+ * doesn't need to firstly keyframe the pose (though this doesn't mean that
* they can't either)
*/
if (!pose_propagate_get_refVal(ob, fcu, &refVal))
return;
-
- /* find the first keyframe to start propagating from
+
+ /* find the first keyframe to start propagating from
* - if there's a keyframe on the current frame, we probably want to save this value there too
* since it may be as of yet unkeyed
* - if starting before the starting frame, don't touch the key, as it may have had some valid
@@ -1447,7 +1447,7 @@ static void pose_propagate_fcurve(wmOperator *op, Object *ob, FCurve *fcu,
*/
if (mode != POSE_PROPAGATE_SELECTED_KEYS) {
match = binarysearch_bezt_index(fcu->bezt, startFrame, fcu->totvert, &keyExists);
-
+
if (fcu->bezt[match].vec[1][0] < startFrame)
i = match + 1;
else
@@ -1457,13 +1457,13 @@ static void pose_propagate_fcurve(wmOperator *op, Object *ob, FCurve *fcu,
/* selected - start from first keyframe */
i = 0;
}
-
+
for (bezt = &fcu->bezt[i]; i < fcu->totvert; i++, bezt++) {
/* additional termination conditions based on the operator 'mode' property go here... */
if (ELEM(mode, POSE_PROPAGATE_BEFORE_FRAME, POSE_PROPAGATE_SMART_HOLDS)) {
/* stop if keyframe is outside the accepted range */
if (bezt->vec[1][0] > modeData.end_frame)
- break;
+ break;
}
else if (mode == POSE_PROPAGATE_NEXT_KEY) {
/* stop after the first keyframe has been processed */
@@ -1478,13 +1478,13 @@ static void pose_propagate_fcurve(wmOperator *op, Object *ob, FCurve *fcu,
else if (mode == POSE_PROPAGATE_SELECTED_MARKERS) {
/* only allow if there's a marker on this frame */
CfraElem *ce = NULL;
-
+
/* stop on matching marker if there is one */
for (ce = modeData.sel_markers.first; ce; ce = ce->next) {
if (ce->cfra == round_fl_to_int(bezt->vec[1][0]))
break;
}
-
+
/* skip this keyframe if no marker */
if (ce == NULL)
continue;
@@ -1494,11 +1494,11 @@ static void pose_propagate_fcurve(wmOperator *op, Object *ob, FCurve *fcu,
if (BEZT_ISSEL_ANY(bezt) == 0)
continue;
}
-
+
/* just flatten handles, since values will now be the same either side... */
/* TODO: perhaps a fade-out modulation of the value is required here (optional once again)? */
bezt->vec[0][1] = bezt->vec[1][1] = bezt->vec[2][1] = refVal;
-
+
/* select keyframe to indicate that it's been changed */
bezt->f2 |= SELECT;
first = 0;
@@ -1512,13 +1512,13 @@ static int pose_propagate_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bAction *act = (ob && ob->adt) ? ob->adt->action : NULL;
-
+
ListBase pflinks = {NULL, NULL};
tPChanFCurveLink *pfl;
-
+
tPosePropagate_ModeData modeData;
const int mode = RNA_enum_get(op->ptr, "mode");
-
+
/* sanity checks */
if (ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No object to propagate poses for");
@@ -1528,10 +1528,10 @@ static int pose_propagate_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No keyframed poses to propagate to");
return OPERATOR_CANCELLED;
}
-
+
/* isolate F-Curves related to the selected bones */
poseAnim_mapping_get(C, &pflinks, ob, act);
-
+
/* mode-specific data preprocessing (requiring no access to curves) */
if (mode == POSE_PROPAGATE_SELECTED_MARKERS) {
/* get a list of selected markers */
@@ -1541,11 +1541,11 @@ static int pose_propagate_exec(bContext *C, wmOperator *op)
/* assume everything else wants endFrame */
modeData.end_frame = RNA_float_get(op->ptr, "end_frame");
}
-
+
/* for each bone, perform the copying required */
for (pfl = pflinks.first; pfl; pfl = pfl->next) {
LinkData *ld;
-
+
/* mode-specific data preprocessing (requiring access to all curves) */
if (mode == POSE_PROPAGATE_SMART_HOLDS) {
/* we store in endFrame the end frame of the "long keyframe" (i.e. a held value) starting
@@ -1553,21 +1553,21 @@ static int pose_propagate_exec(bContext *C, wmOperator *op)
*/
modeData.end_frame = pose_propagate_get_boneHoldEndFrame(ob, pfl, (float)CFRA);
}
-
+
/* go through propagating pose to keyframes, curve by curve */
for (ld = pfl->fcurves.first; ld; ld = ld->next)
pose_propagate_fcurve(op, ob, (FCurve *)ld->data, (float)CFRA, modeData);
}
-
+
/* free temp data */
poseAnim_mapping_free(&pflinks);
-
+
if (mode == POSE_PROPAGATE_SELECTED_MARKERS)
BLI_freelistN(&modeData.sel_markers);
-
+
/* updates + notifiers */
poseAnim_mapping_refresh(C, scene, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1591,19 +1591,19 @@ void POSE_OT_propagate(wmOperatorType *ot)
{POSE_PROPAGATE_SELECTED_MARKERS, "SELECTED_MARKERS", 0, "On Selected Markers",
"Propagate pose to all keyframes occurring on frames with Scene Markers after the current frame"},
{0, NULL, 0, NULL, NULL}};
-
+
/* identifiers */
ot->name = "Propagate Pose";
ot->idname = "POSE_OT_propagate";
ot->description = "Copy selected aspects of the current pose to subsequent poses already keyframed";
-
+
/* callbacks */
ot->exec = pose_propagate_exec;
ot->poll = ED_operator_posemode; /* XXX: needs selected bones! */
-
+
/* flag */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
/* TODO: add "fade out" control for tapering off amount of propagation as time goes by? */
ot->prop = RNA_def_enum(ot->srna, "mode", terminate_items, POSE_PROPAGATE_SMART_HOLDS, "Terminate Mode", "Method used to determine when to stop propagating pose to keyframes");
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index e212d426c9a..22c710dcda5 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -78,16 +78,16 @@ static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Objec
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Main *bmain = CTX_data_main(C);
Object workob, *ob;
-
+
/* go through all objects in database */
for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* if parent is bone in this armature, apply corrections */
if ((ob->parent == armob) && (ob->partype == PARBONE)) {
- /* apply current transform from parent (not yet destroyed),
+ /* apply current transform from parent (not yet destroyed),
* then calculate new parent inverse matrix
*/
BKE_object_apply_mat4(ob, ob->obmat, false, false);
-
+
BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
invert_m4_m4(ob->parentinv, workob.obmat);
}
@@ -97,6 +97,7 @@ static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Objec
/* set the current pose as the restpose */
static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Scene *scene = CTX_data_scene(C);
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); // must be active object, not edit-object
@@ -123,18 +124,18 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
/* Get editbones of active armature to alter */
ED_armature_to_edit(arm);
-
+
/* get pose of active object and move it out of posemode */
pose = ob->pose;
-
+
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
-
+
/* simply copy the head/tail values from pchan over to curbone */
copy_v3_v3(curbone->head, pchan_eval->pose_head);
copy_v3_v3(curbone->tail, pchan_eval->pose_tail);
-
+
/* fix roll:
* 1. find auto-calculated roll value for this bone now
* 2. remove this from the 'visual' y-rotation
@@ -142,23 +143,23 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
{
float premat[3][3], imat[3][3], pmat[3][3], tmat[3][3];
float delta[3], eul[3];
-
+
/* obtain new auto y-rotation */
sub_v3_v3v3(delta, curbone->tail, curbone->head);
vec_roll_to_mat3(delta, 0.0f, premat);
invert_m3_m3(imat, premat);
-
+
/* get pchan 'visual' matrix */
copy_m3_m4(pmat, pchan_eval->pose_mat);
-
+
/* remove auto from visual and get euler rotation */
mul_m3_m3m3(tmat, imat, pmat);
mat3_to_eul(eul, tmat);
-
+
/* just use this euler-y as new roll value */
curbone->roll = eul[1];
}
-
+
/* combine pose and rest values for bendy bone settings,
* then clear the pchan values (so we don't get a double-up)
*/
@@ -174,7 +175,7 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
curbone->ease2 += pchan_eval->ease2;
curbone->scaleIn += pchan_eval->scaleIn;
curbone->scaleOut += pchan_eval->scaleOut;
-
+
/* reset pose values */
pchan->curveInX = pchan->curveOutX = 0.0f;
pchan->curveInY = pchan->curveOutY = 0.0f;
@@ -182,32 +183,32 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
pchan->ease1 = pchan->ease2 = 0.0f;
pchan->scaleIn = pchan->scaleOut = 1.0f;
}
-
+
/* clear transform values for pchan */
zero_v3(pchan->loc);
zero_v3(pchan->eul);
unit_qt(pchan->quat);
unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f;
-
+
/* set anim lock */
curbone->flag |= BONE_UNKEYED;
}
-
+
/* convert editbones back to bones, and then free the edit-data */
- ED_armature_from_edit(arm);
+ ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
-
+
/* flush positions of posebones */
BKE_pose_where_is(depsgraph, scene, ob);
-
+
/* fix parenting of objects which are bone-parented */
applyarmature_fix_boneparents(C, scene, ob);
-
+
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
-
+
return OPERATOR_FINISHED;
}
@@ -217,11 +218,11 @@ void POSE_OT_armature_apply(wmOperatorType *ot)
ot->name = "Apply Pose as Rest Pose";
ot->idname = "POSE_OT_armature_apply";
ot->description = "Apply the current pose as the new rest pose";
-
+
/* callbacks */
ot->exec = apply_armature_pose2bones_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -244,21 +245,21 @@ static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
float delta_mat[4][4];
-
+
/* chan_mat already contains the delta transform from rest pose to pose-mode pose
* as that is baked into there so that B-Bones will work. Once we've set this as the
- * new raw-transform components, don't recalc the poses yet, otherwise IK result will
+ * new raw-transform components, don't recalc the poses yet, otherwise IK result will
* change, thus changing the result we may be trying to record.
*/
/* XXX For some reason, we can't use pchan->chan_mat here, gives odd rotation/offset (see T38251).
* Using pchan->pose_mat and bringing it back in bone space seems to work as expected!
*/
BKE_armature_mat_pose_to_bone(pchan_eval, pchan_eval->pose_mat, delta_mat);
-
+
BKE_pchan_apply_mat4(pchan, delta_mat, true);
}
FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
/* note, notifier might evolve */
@@ -275,11 +276,11 @@ void POSE_OT_visual_transform_apply(wmOperatorType *ot)
ot->name = "Apply Visual Transform to Pose";
ot->idname = "POSE_OT_visual_transform_apply";
ot->description = "Apply final constrained position of pose bones to their transform";
-
+
/* callbacks */
ot->exec = pose_visual_transform_apply_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -287,7 +288,7 @@ void POSE_OT_visual_transform_apply(wmOperatorType *ot)
/* ********************************************** */
/* Copy/Paste */
-/* This function is used to indicate that a bone is selected
+/* This function is used to indicate that a bone is selected
* and needs to be included in copy buffer (used to be for inserting keys)
*/
static void set_pose_keys(Object *ob)
@@ -320,33 +321,33 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo
bPoseChannel *pchan;
char name[MAXBONENAME];
short paste_ok;
-
+
/* get the name - if flipping, we must flip this first */
if (flip)
BLI_string_flip_side_name(name, chan->name, false, sizeof(name));
else
BLI_strncpy(name, chan->name, sizeof(name));
-
+
/* only copy when:
* 1) channel exists - poses are not meant to add random channels to anymore
* 2) if selection-masking is on, channel is selected - only selected bones get pasted on, allowing making both sides symmetrical
*/
pchan = BKE_pose_channel_find_name(ob->pose, name);
-
+
if (selOnly)
paste_ok = ((pchan) && (pchan->bone->flag & BONE_SELECTED));
else
paste_ok = (pchan != NULL);
-
+
/* continue? */
if (paste_ok) {
- /* only loc rot size
- * - only copies transform info for the pose
+ /* only loc rot size
+ * - only copies transform info for the pose
*/
copy_v3_v3(pchan->loc, chan->loc);
copy_v3_v3(pchan->size, chan->size);
pchan->flag = chan->flag;
-
+
/* check if rotation modes are compatible (i.e. do they need any conversions) */
if (pchan->rotmode == chan->rotmode) {
/* copy the type of rotation in use */
@@ -382,29 +383,29 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo
else
axis_angle_to_quat(pchan->quat, chan->rotAxis, pchan->rotAngle);
}
-
+
/* B-Bone posing options should also be included... */
pchan->curveInX = chan->curveInX;
pchan->curveInY = chan->curveInY;
pchan->curveOutX = chan->curveOutX;
pchan->curveOutY = chan->curveOutY;
-
+
pchan->roll1 = chan->roll1;
pchan->roll2 = chan->roll2;
pchan->ease1 = chan->ease1;
pchan->ease2 = chan->ease2;
pchan->scaleIn = chan->scaleIn;
pchan->scaleOut = chan->scaleOut;
-
+
/* paste flipped pose? */
if (flip) {
pchan->loc[0] *= -1;
-
+
pchan->curveInX *= -1;
pchan->curveOutX *= -1;
pchan->roll1 *= -1; // XXX?
pchan->roll2 *= -1; // XXX?
-
+
/* has to be done as eulers... */
if (pchan->rotmode > 0) {
pchan->eul[1] *= -1;
@@ -412,7 +413,7 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float eul[3];
-
+
axis_angle_to_eulO(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, pchan->rotAngle);
eul[1] *= -1;
eul[2] *= -1;
@@ -420,7 +421,7 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo
}
else {
float eul[3];
-
+
normalize_qt(pchan->quat);
quat_to_eul(eul, pchan->quat);
eul[1] *= -1;
@@ -428,12 +429,12 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo
eul_to_quat(pchan->quat, eul);
}
}
-
+
/* ID properties */
if (chan->prop) {
if (pchan->prop) {
- /* if we have existing properties on a bone, just copy over the values of
- * matching properties (i.e. ones which will have some impact) on to the
+ /* if we have existing properties on a bone, just copy over the values of
+ * matching properties (i.e. ones which will have some impact) on to the
* target instead of just blinding replacing all [
*/
IDP_SyncGroupValues(pchan->prop, chan->prop);
@@ -444,7 +445,7 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo
}
}
}
-
+
/* return whether paste went ahead */
return pchan;
}
@@ -502,11 +503,11 @@ void POSE_OT_copy(wmOperatorType *ot)
ot->name = "Copy Pose";
ot->idname = "POSE_OT_copy";
ot->description = "Copies the current pose of the selected bones to copy/paste buffer";
-
+
/* api callbacks */
ot->exec = pose_copy_exec;
ot->poll = ED_operator_posemode;
-
+
/* flag */
ot->flag = OPTYPE_REGISTER;
}
@@ -520,15 +521,15 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
bPoseChannel *chan;
const bool flip = RNA_boolean_get(op->ptr, "flipped");
bool selOnly = RNA_boolean_get(op->ptr, "selected_mask");
-
+
/* Get KeyingSet to use. */
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
-
+
/* Sanity checks. */
if (ELEM(NULL, ob, ob->pose)) {
return OPERATOR_CANCELLED;
}
-
+
/* Read copy buffer .blend file. */
char str[FILE_MAX];
Main *tmp_bmain = BKE_main_new();
@@ -544,7 +545,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
BKE_main_free(tmp_bmain);
return OPERATOR_CANCELLED;
}
-
+
Object *object_from = tmp_bmain->object.first;
bPose *pose_from = object_from->pose;
if (pose_from == NULL) {
@@ -552,7 +553,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
BKE_main_free(tmp_bmain);
return OPERATOR_CANCELLED;
}
-
+
/* If selOnly option is enabled, if user hasn't selected any bones,
* just go back to default behavior to be more in line with other
* pose tools.
@@ -562,7 +563,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
selOnly = false;
}
}
-
+
/* Safely merge all of the channels in the buffer pose into any
* existing pose.
*/
@@ -577,15 +578,15 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
}
}
BKE_main_free(tmp_bmain);
-
+
/* Update event for pose and deformation children. */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
-
+
/* Recalculate paths if any of the bones have paths... */
if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
ED_pose_recalculate_paths(C, scene, ob);
}
-
+
/* Notifiers for updates, */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
@@ -600,14 +601,14 @@ void POSE_OT_paste(wmOperatorType *ot)
ot->name = "Paste Pose";
ot->idname = "POSE_OT_paste";
ot->description = "Paste the stored pose on to the current pose";
-
+
/* api callbacks */
ot->exec = pose_paste_exec;
ot->poll = ED_operator_posemode;
-
+
/* flag */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "flipped", false, "Flipped on X-Axis", "Paste the stored pose flipped on to current pose");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -627,9 +628,9 @@ static void pchan_clear_scale(bPoseChannel *pchan)
pchan->size[1] = 1.0f;
if ((pchan->protectflag & OB_LOCK_SCALEZ) == 0)
pchan->size[2] = 1.0f;
-
+
pchan->ease1 = 0.0f;
- pchan->ease2 = 0.0f;
+ pchan->ease2 = 0.0f;
pchan->scaleIn = 1.0f;
pchan->scaleOut = 1.0f;
}
@@ -661,7 +662,7 @@ static void pchan_clear_rot(bPoseChannel *pchan)
pchan->rotAxis[1] = 0.0f;
if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
pchan->rotAxis[2] = 0.0f;
-
+
/* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
if (IS_EQF(pchan->rotAxis[0], pchan->rotAxis[1]) && IS_EQF(pchan->rotAxis[1], pchan->rotAxis[2]))
pchan->rotAxis[1] = 1.0f;
@@ -690,7 +691,7 @@ static void pchan_clear_rot(bPoseChannel *pchan)
/* perform clamping using euler form (3-components) */
float eul[3], oldeul[3], quat1[4] = {0};
float qlen = 0.0f;
-
+
if (pchan->rotmode == ROT_MODE_QUAT) {
qlen = normalize_qt_qt(quat1, pchan->quat);
quat_to_eul(oldeul, quat1);
@@ -701,22 +702,22 @@ static void pchan_clear_rot(bPoseChannel *pchan)
else {
copy_v3_v3(oldeul, pchan->eul);
}
-
+
eul[0] = eul[1] = eul[2] = 0.0f;
-
+
if (pchan->protectflag & OB_LOCK_ROTX)
eul[0] = oldeul[0];
if (pchan->protectflag & OB_LOCK_ROTY)
eul[1] = oldeul[1];
if (pchan->protectflag & OB_LOCK_ROTZ)
eul[2] = oldeul[2];
-
+
if (pchan->rotmode == ROT_MODE_QUAT) {
eul_to_quat(pchan->quat, eul);
-
+
/* restore original quat size */
mul_qt_fl(pchan->quat, qlen);
-
+
/* quaternions flip w sign to accumulate rotations correctly */
if ((quat1[0] < 0.0f && pchan->quat[0] > 0.0f) || (quat1[0] > 0.0f && pchan->quat[0] < 0.0f)) {
mul_qt_fl(pchan->quat, -1.0f);
@@ -742,11 +743,11 @@ static void pchan_clear_rot(bPoseChannel *pchan)
zero_v3(pchan->eul);
}
}
-
+
/* Clear also Bendy Bone stuff - Roll is obvious, but Curve X/Y stuff is also kindof rotational in nature... */
pchan->roll1 = 0.0f;
pchan->roll2 = 0.0f;
-
+
pchan->curveInX = 0.0f;
pchan->curveInY = 0.0f;
pchan->curveOutX = 0.0f;
@@ -764,7 +765,7 @@ static void pchan_clear_transforms(bPoseChannel *pchan)
/* --------------- */
/* generic exec for clear-pose operators */
-static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
+static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
void (*clear_func)(bPoseChannel *), const char default_ksName[])
{
Scene *scene = CTX_data_scene(C);
@@ -798,7 +799,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
}
/* tag for autokeying later */
ANIM_relative_keyingset_add_source(&dsources, &ob_iter->id, &RNA_PoseBone, pchan);
-
+
#if 1 /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */
bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
clear_func(pchan_eval);
@@ -845,7 +846,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
/* --------------- */
-static int pose_clear_scale_exec(bContext *C, wmOperator *op)
+static int pose_clear_scale_exec(bContext *C, wmOperator *op)
{
return pose_clear_transform_generic_exec(C, op, pchan_clear_scale, ANIM_KS_SCALING_ID);
}
@@ -856,17 +857,17 @@ void POSE_OT_scale_clear(wmOperatorType *ot)
ot->name = "Clear Pose Scale";
ot->idname = "POSE_OT_scale_clear";
ot->description = "Reset scaling of selected bones to their default values";
-
+
/* api callbacks */
ot->exec = pose_clear_scale_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int pose_clear_rot_exec(bContext *C, wmOperator *op)
+static int pose_clear_rot_exec(bContext *C, wmOperator *op)
{
return pose_clear_transform_generic_exec(C, op, pchan_clear_rot, ANIM_KS_ROTATION_ID);
}
@@ -877,17 +878,17 @@ void POSE_OT_rot_clear(wmOperatorType *ot)
ot->name = "Clear Pose Rotation";
ot->idname = "POSE_OT_rot_clear";
ot->description = "Reset rotations of selected bones to their default values";
-
+
/* api callbacks */
ot->exec = pose_clear_rot_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int pose_clear_loc_exec(bContext *C, wmOperator *op)
+static int pose_clear_loc_exec(bContext *C, wmOperator *op)
{
return pose_clear_transform_generic_exec(C, op, pchan_clear_loc, ANIM_KS_LOCATION_ID);
}
@@ -898,17 +899,17 @@ void POSE_OT_loc_clear(wmOperatorType *ot)
ot->name = "Clear Pose Location";
ot->idname = "POSE_OT_loc_clear";
ot->description = "Reset locations of selected bones to their default values";
-
+
/* api callbacks */
ot->exec = pose_clear_loc_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int pose_clear_transforms_exec(bContext *C, wmOperator *op)
+static int pose_clear_transforms_exec(bContext *C, wmOperator *op)
{
return pose_clear_transform_generic_exec(C, op, pchan_clear_transforms, ANIM_KS_LOC_ROT_SCALE_ID);
}
@@ -919,11 +920,11 @@ void POSE_OT_transforms_clear(wmOperatorType *ot)
ot->name = "Clear Pose Transforms";
ot->idname = "POSE_OT_transforms_clear";
ot->description = "Reset location, rotation, and scaling of selected bones to their default values";
-
+
/* api callbacks */
ot->exec = pose_clear_transforms_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -937,7 +938,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
float cframe = (float)CFRA;
const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
-
+
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob)
{
if ((ob->adt) && (ob->adt->action)) {
@@ -947,10 +948,10 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
bPose *dummyPose = NULL;
Object workob = {{NULL}};
bPoseChannel *pchan;
-
+
/* execute animation step for current frame using a dummy copy of the pose */
BKE_pose_copy_data(&dummyPose, ob->pose, 0);
-
+
BLI_strncpy(workob.id.name, "OB<ClearTfmWorkOb>", sizeof(workob.id.name));
workob.type = OB_ARMATURE;
workob.data = ob->data;
@@ -958,12 +959,12 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
workob.pose = dummyPose;
BKE_animsys_evaluate_animdata(NULL, scene, &workob.id, workob.adt, cframe, ADT_RECALC_ANIM);
-
+
/* copy back values, but on selected bones only */
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
pose_bone_do_paste(ob, pchan, only_select, 0);
}
-
+
/* free temp data - free manually as was copied without constraints */
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->prop) {
@@ -971,7 +972,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
MEM_freeN(pchan->prop);
}
}
-
+
/* was copied without constraints */
BLI_freelistN(&dummyPose->chanbase);
MEM_freeN(dummyPose);
@@ -982,13 +983,13 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
*/
BKE_pose_rest(ob->pose);
}
-
+
/* notifiers and updates */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
}
FOREACH_OBJECT_IN_MODE_END;
-
+
return OPERATOR_FINISHED;
}
@@ -998,11 +999,11 @@ void POSE_OT_user_transforms_clear(wmOperatorType *ot)
ot->name = "Clear User Transforms";
ot->idname = "POSE_OT_user_transforms_clear";
ot->description = "Reset pose on selected bones to keyframed state";
-
+
/* callbacks */
ot->exec = pose_clear_user_transforms_exec;
ot->poll = ED_operator_posemode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index a419f22a9f9..b64c8528010 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -63,7 +63,7 @@
* convenience functions, such as applying/getting pose values
* and/or inserting keyframes for these.
*/
-/* *********************************************** */
+/* *********************************************** */
/* FCurves <-> PoseChannels Links */
/* helper for poseAnim_mapping_get() -> get the relevant F-Curves per PoseChannel */
@@ -71,25 +71,25 @@ static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *a
{
ListBase curves = {NULL, NULL};
int transFlags = action_get_item_transforms(act, ob, pchan, &curves);
-
+
pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
-
+
/* check if any transforms found... */
if (transFlags) {
/* make new linkage data */
tPChanFCurveLink *pfl = MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink");
PointerRNA ptr;
-
+
pfl->fcurves = curves;
pfl->pchan = pchan;
-
+
/* get the RNA path to this pchan - this needs to be freed! */
RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan, &ptr);
pfl->pchan_path = RNA_path_from_ID_to_struct(&ptr);
-
+
/* add linkage data to operator data */
BLI_addtail(pfLinks, pfl);
-
+
/* set pchan's transform flags */
if (transFlags & ACT_TRANS_LOC)
pchan->flag |= POSE_LOC;
@@ -99,7 +99,7 @@ static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *a
pchan->flag |= POSE_SIZE;
if (transFlags & ACT_TRANS_BBONE)
pchan->flag |= POSE_BBONE_SHAPE;
-
+
/* store current transforms */
copy_v3_v3(pfl->oldloc, pchan->loc);
copy_v3_v3(pfl->oldrot, pchan->eul);
@@ -107,7 +107,7 @@ static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *a
copy_qt_qt(pfl->oldquat, pchan->quat);
copy_v3_v3(pfl->oldaxis, pchan->rotAxis);
pfl->oldangle = pchan->rotAngle;
-
+
/* store current bbone values */
pfl->roll1 = pchan->roll1;
pfl->roll2 = pchan->roll2;
@@ -119,18 +119,18 @@ static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *a
pfl->ease2 = pchan->ease2;
pfl->scaleIn = pchan->scaleIn;
pfl->scaleOut = pchan->scaleOut;
-
+
/* make copy of custom properties */
if (pchan->prop && (transFlags & ACT_TRANS_PROP))
pfl->oldprops = IDP_CopyProperty(pchan->prop);
}
-}
+}
/* get sets of F-Curves providing transforms for the bones in the Pose */
void poseAnim_mapping_get(bContext *C, ListBase *pfLinks, Object *ob, bAction *act)
-{
- /* for each Pose-Channel which gets affected, get the F-Curves for that channel
+{
+ /* for each Pose-Channel which gets affected, get the F-Curves for that channel
* and set the relevant transform flags...
*/
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
@@ -138,7 +138,7 @@ void poseAnim_mapping_get(bContext *C, ListBase *pfLinks, Object *ob, bAction *a
fcurves_to_pchan_links_get(pfLinks, ob, act, pchan);
}
CTX_DATA_END;
-
+
/* if no PoseChannels were found, try a second pass, doing visible ones instead
* i.e. if nothing selected, do whole pose
*/
@@ -148,7 +148,7 @@ void poseAnim_mapping_get(bContext *C, ListBase *pfLinks, Object *ob, bAction *a
fcurves_to_pchan_links_get(pfLinks, ob, act, pchan);
}
CTX_DATA_END;
-
+
}
}
@@ -156,23 +156,23 @@ void poseAnim_mapping_get(bContext *C, ListBase *pfLinks, Object *ob, bAction *a
void poseAnim_mapping_free(ListBase *pfLinks)
{
tPChanFCurveLink *pfl, *pfln = NULL;
-
+
/* free the temp pchan links and their data */
for (pfl = pfLinks->first; pfl; pfl = pfln) {
pfln = pfl->next;
-
+
/* free custom properties */
if (pfl->oldprops) {
IDP_FreeProperty(pfl->oldprops);
MEM_freeN(pfl->oldprops);
}
-
+
/* free list of F-Curve reference links */
BLI_freelistN(&pfl->fcurves);
-
+
/* free pchan RNA Path */
MEM_freeN(pfl->pchan_path);
-
+
/* free link itself */
BLI_freelinkN(pfLinks, pfl);
}
@@ -185,8 +185,8 @@ void poseAnim_mapping_refresh(bContext *C, Scene *scene, Object *ob)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
bArmature *arm = (bArmature *)ob->data;
-
- /* old optimize trick... this enforces to bypass the depgraph
+
+ /* old optimize trick... this enforces to bypass the depgraph
* - note: code copied from transform_generics.c -> recalcData()
*/
/* FIXME: shouldn't this use the builtin stuff? */
@@ -194,7 +194,7 @@ void poseAnim_mapping_refresh(bContext *C, Scene *scene, Object *ob)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
else
BKE_pose_where_is(depsgraph, scene, ob);
-
+
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); /* otherwise animation doesn't get updated */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
}
@@ -203,11 +203,11 @@ void poseAnim_mapping_refresh(bContext *C, Scene *scene, Object *ob)
void poseAnim_mapping_reset(ListBase *pfLinks)
{
tPChanFCurveLink *pfl;
-
+
/* iterate over each pose-channel affected, restoring all channels to their original values */
for (pfl = pfLinks->first; pfl; pfl = pfl->next) {
bPoseChannel *pchan = pfl->pchan;
-
+
/* just copy all the values over regardless of whether they changed or not */
copy_v3_v3(pchan->loc, pfl->oldloc);
copy_v3_v3(pchan->eul, pfl->oldrot);
@@ -215,7 +215,7 @@ void poseAnim_mapping_reset(ListBase *pfLinks)
copy_qt_qt(pchan->quat, pfl->oldquat);
copy_v3_v3(pchan->rotAxis, pfl->oldaxis);
pchan->rotAngle = pfl->oldangle;
-
+
/* store current bbone values */
pchan->roll1 = pfl->roll1;
pchan->roll2 = pfl->roll2;
@@ -227,7 +227,7 @@ void poseAnim_mapping_reset(ListBase *pfLinks)
pchan->ease2 = pfl->ease2;
pchan->scaleIn = pfl->scaleIn;
pchan->scaleOut = pfl->scaleOut;
-
+
/* just overwrite values of properties from the stored copies (there should be some) */
if (pfl->oldprops)
IDP_SyncGroupValues(pfl->pchan->prop, pfl->oldprops);
@@ -242,26 +242,26 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBa
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
ListBase dsources = {NULL, NULL};
tPChanFCurveLink *pfl;
-
+
/* iterate over each pose-channel affected, tagging bones to be keyed */
- /* XXX: here we already have the information about what transforms exist, though
+ /* XXX: here we already have the information about what transforms exist, though
* it might be easier to just overwrite all using normal mechanisms
*/
for (pfl = pfLinks->first; pfl; pfl = pfl->next) {
bPoseChannel *pchan = pfl->pchan;
-
+
/* add datasource override for the PoseChannel, to be used later */
- ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan);
-
+ ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan);
+
/* clear any unkeyed tags */
if (pchan->bone)
pchan->bone->flag &= ~BONE_UNKEYED;
}
-
+
/* insert keyframes for all relevant bones in one go */
ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cframe);
BLI_freelistN(&dsources);
-
+
/* do the bone paths
* - only do this if keyframes should have been added
* - do not calculate unless there are paths already to update...
@@ -275,25 +275,25 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBa
/* ------------------------- */
-/* find the next F-Curve for a PoseChannel with matching path...
+/* find the next F-Curve for a PoseChannel with matching path...
* - path is not just the pfl rna_path, since that path doesn't have property info yet
*/
LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, const char *path)
{
LinkData *first = (prev) ? prev->next : (fcuLinks) ? fcuLinks->first : NULL;
LinkData *ld;
-
+
/* check each link to see if the linked F-Curve has a matching path */
for (ld = first; ld; ld = ld->next) {
FCurve *fcu = (FCurve *)ld->data;
-
+
/* check if paths match */
if (STREQ(path, fcu->rna_path))
return ld;
}
-
+
/* none found */
return NULL;
}
-/* *********************************************** */
+/* *********************************************** */
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index 85b561f3a9f..5d27e13ed17 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -73,10 +73,10 @@ void ED_operatortypes_curve(void)
WM_operatortype_append(FONT_OT_change_character);
WM_operatortype_append(FONT_OT_change_spacing);
-
+
WM_operatortype_append(FONT_OT_open);
WM_operatortype_append(FONT_OT_unlink);
-
+
WM_operatortype_append(FONT_OT_textbox_add);
WM_operatortype_append(FONT_OT_textbox_remove);
@@ -98,20 +98,20 @@ void ED_operatortypes_curve(void)
WM_operatortype_append(CURVE_OT_shade_smooth);
WM_operatortype_append(CURVE_OT_shade_flat);
WM_operatortype_append(CURVE_OT_tilt_clear);
-
+
WM_operatortype_append(CURVE_OT_primitive_bezier_curve_add);
WM_operatortype_append(CURVE_OT_primitive_bezier_circle_add);
WM_operatortype_append(CURVE_OT_primitive_nurbs_curve_add);
WM_operatortype_append(CURVE_OT_primitive_nurbs_circle_add);
WM_operatortype_append(CURVE_OT_primitive_nurbs_path_add);
-
+
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_curve_add);
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_circle_add);
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_surface_add);
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_cylinder_add);
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_sphere_add);
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_torus_add);
-
+
WM_operatortype_append(CURVE_OT_smooth);
WM_operatortype_append(CURVE_OT_smooth_weight);
WM_operatortype_append(CURVE_OT_smooth_radius);
@@ -168,10 +168,10 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
keymap = WM_keymap_find(keyconf, "Font", 0, 0);
keymap->poll = ED_operator_editfont;
-
+
/* only set in editmode font, by space_view3d listener */
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_style_toggle", BKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_CHINFO_BOLD);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_style_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_CHINFO_ITALIC);
@@ -233,7 +233,7 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
keymap->poll = ED_operator_editsurfcurve;
WM_keymap_add_menu(keymap, "INFO_MT_edit_curve_add", AKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", VKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CURVE_OT_vertex_add", ACTIONMOUSE, KM_CLICK, KM_CTRL, 0);
@@ -289,7 +289,7 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CURVE_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_curve_specials", WKEY, KM_PRESS, 0, 0);
/* menus */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 1987fe56bdb..616017dac0a 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1105,7 +1105,7 @@ static int *initialize_index_map(Object *obedit, int *r_old_totvert)
return old_to_new_map;
}
-static void remap_hooks_and_vertex_parents(Object *obedit)
+static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
{
Object *object;
Curve *curve = (Curve *) obedit->data;
@@ -1121,7 +1121,7 @@ static void remap_hooks_and_vertex_parents(Object *obedit)
return;
}
- for (object = G.main->object.first; object; object = object->id.next) {
+ for (object = bmain->object.first; object; object = object->id.next) {
ModifierData *md;
int index;
if ((object->parent) &&
@@ -1184,7 +1184,7 @@ static void remap_hooks_and_vertex_parents(Object *obedit)
}
/* load editNurb in object */
-void ED_curve_editnurb_load(Object *obedit)
+void ED_curve_editnurb_load(Main *bmain, Object *obedit)
{
ListBase *editnurb = object_editcurve_get(obedit);
@@ -1195,7 +1195,7 @@ void ED_curve_editnurb_load(Object *obedit)
Nurb *nu, *newnu;
ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb;
- remap_hooks_and_vertex_parents(obedit);
+ remap_hooks_and_vertex_parents(bmain, obedit);
for (nu = editnurb->first; nu; nu = nu->next) {
newnu = BKE_nurb_duplicate(nu);
@@ -1325,7 +1325,7 @@ static int separate_exec(bContext *C, wmOperator *op)
BLI_movelisttolist(&newedit->nurbs, &newnurb);
/* 4. put old object out of editmode and delete separated geometry */
- ED_curve_editnurb_load(newob);
+ ED_curve_editnurb_load(bmain, newob);
ED_curve_editnurb_free(newob);
curve_delete_segments(oldob, true);
@@ -1346,12 +1346,12 @@ void CURVE_OT_separate(wmOperatorType *ot)
ot->name = "Separate";
ot->idname = "CURVE_OT_separate";
ot->description = "Separate selected points from connected unselected points into a new object";
-
+
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = separate_exec;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1856,7 +1856,7 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag)
while (a--) {
select_bpoint(bp, SELECT, flag, HIDDEN);
select_bpoint(newbp, DESELECT, flag, HIDDEN);
- bp++;
+ bp++;
newbp++;
}
@@ -2336,7 +2336,7 @@ void CURVE_OT_switch_direction(wmOperatorType *ot)
ot->name = "Switch Direction";
ot->description = "Switch direction of selected splines";
ot->idname = "CURVE_OT_switch_direction";
-
+
/* api callbacks */
ot->exec = switch_direction_exec;
ot->poll = ED_operator_editsurfcurve;
@@ -2356,7 +2356,7 @@ static int set_goal_weight_exec(bContext *C, wmOperator *op)
BPoint *bp;
float weight = RNA_float_get(op->ptr, "weight");
int a;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->bezt) {
for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
@@ -2384,7 +2384,7 @@ void CURVE_OT_spline_weight_set(wmOperatorType *ot)
ot->name = "Set Goal Weight";
ot->description = "Set softbody goal weight for selected points";
ot->idname = "CURVE_OT_spline_weight_set";
-
+
/* api callbacks */
ot->exec = set_goal_weight_exec;
ot->invoke = WM_operator_props_popup;
@@ -2408,7 +2408,7 @@ static int set_radius_exec(bContext *C, wmOperator *op)
BPoint *bp;
float radius = RNA_float_get(op->ptr, "radius");
int a;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->bezt) {
for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
@@ -2436,7 +2436,7 @@ void CURVE_OT_radius_set(wmOperatorType *ot)
ot->name = "Set Curve Radius";
ot->description = "Set per-point radius which is used for bevel tapering";
ot->idname = "CURVE_OT_radius_set";
-
+
/* api callbacks */
ot->exec = set_radius_exec;
ot->invoke = WM_operator_props_popup;
@@ -2588,7 +2588,7 @@ void CURVE_OT_smooth(wmOperatorType *ot)
ot->name = "Smooth";
ot->description = "Flatten angles of selected points";
ot->idname = "CURVE_OT_smooth";
-
+
/* api callbacks */
ot->exec = smooth_exec;
ot->poll = ED_operator_editsurfcurve;
@@ -2792,7 +2792,7 @@ static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
ListBase *editnurb = object_editcurve_get(obedit);
-
+
curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius));
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
@@ -2807,11 +2807,11 @@ void CURVE_OT_smooth_radius(wmOperatorType *ot)
ot->name = "Smooth Curve Radius";
ot->description = "Interpolate radii of selected points";
ot->idname = "CURVE_OT_smooth_radius";
-
+
/* api clastbacks */
ot->exec = curve_smooth_radius_exec;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2909,14 +2909,14 @@ void CURVE_OT_hide(wmOperatorType *ot)
ot->name = "Hide Selected";
ot->idname = "CURVE_OT_hide";
ot->description = "Hide (un)selected control points";
-
+
/* api callbacks */
ot->exec = hide_exec;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
}
@@ -2971,11 +2971,11 @@ void CURVE_OT_reveal(wmOperatorType *ot)
ot->name = "Reveal Hidden";
ot->idname = "CURVE_OT_reveal";
ot->description = "Reveal hidden control points";
-
+
/* api callbacks */
ot->exec = reveal_exec;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3231,7 +3231,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
for (b = 0; b < nu->pntsu; b++) {
*bpn = *bp;
keyIndex_updateBP(editnurb, bp, bpn, 1);
- bpn++;
+ bpn++;
bp++;
if (b < nu->pntsu - 1) {
prevbp = bp - 1;
@@ -3259,7 +3259,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
interp_v4_v4v4(tmp->vec, prevbp->vec, bp->vec, factor);
tmp += countu;
}
- bp++;
+ bp++;
prevbp++;
bpn++;
}
@@ -3335,7 +3335,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
for (b = 0; b < nu->pntsu; b++) {
*bpn = *bp;
keyIndex_updateBP(editnurb, bp, bpn, 1);
- bpn++;
+ bpn++;
bp++;
if ( (b < nu->pntsu - 1) && usel[b] == nu->pntsv && usel[b + 1] == nu->pntsv) {
/*
@@ -3362,7 +3362,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
}
}
}
- MEM_freeN(usel);
+ MEM_freeN(usel);
MEM_freeN(vsel);
} /* End of 'if (nu->type == CU_NURBS)' */
@@ -3406,11 +3406,11 @@ void CURVE_OT_subdivide(wmOperatorType *ot)
ot->name = "Subdivide";
ot->description = "Subdivide selected segments";
ot->idname = "CURVE_OT_subdivide";
-
+
/* api callbacks */
ot->exec = subdivide_exec;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3568,7 +3568,7 @@ static int set_spline_type_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Not yet implemented");
return OPERATOR_CANCELLED;
}
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (ED_curve_nurb_select_check(obedit->data, nu)) {
const int pntsu_prev = nu->pntsu;
@@ -3618,12 +3618,12 @@ void CURVE_OT_spline_type_set(wmOperatorType *ot)
ot->name = "Set Spline Type";
ot->description = "Set type of active spline";
ot->idname = "CURVE_OT_spline_type_set";
-
+
/* api callbacks */
ot->exec = set_spline_type_exec;
ot->invoke = WM_menu_invoke;
ot->poll = ED_operator_editcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3663,12 +3663,12 @@ void CURVE_OT_handle_type_set(wmOperatorType *ot)
ot->name = "Set Handle Type";
ot->description = "Set type of handles for selected control points";
ot->idname = "CURVE_OT_handle_type_set";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = set_handle_type_exec;
ot->poll = ED_operator_editcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3718,9 +3718,9 @@ static void switchdirection_knots(float *base, int tot)
{
float *fp1, *fp2, *tempf;
int a;
-
+
if (base == NULL || tot == 0) return;
-
+
/* reverse knots */
a = tot;
fp1 = base;
@@ -3729,7 +3729,7 @@ static void switchdirection_knots(float *base, int tot)
while (fp1 != fp2 && a > 0) {
SWAP(float, *fp1, *fp2);
a--;
- fp1++;
+ fp1++;
fp2--;
}
@@ -3761,15 +3761,15 @@ static void rotate_direction_nurb(Nurb *nu)
{
BPoint *bp1, *bp2, *temp;
int u, v;
-
+
SWAP(int, nu->pntsu, nu->pntsv);
SWAP(short, nu->orderu, nu->orderv);
SWAP(short, nu->resolu, nu->resolv);
SWAP(short, nu->flagu, nu->flagv);
-
+
SWAP(float *, nu->knotsu, nu->knotsv);
switchdirection_knots(nu->knotsv, KNOTSV(nu));
-
+
temp = MEM_dupallocN(nu->bp);
bp1 = nu->bp;
for (v = 0; v < nu->pntsv; v++) {
@@ -3786,7 +3786,7 @@ static bool is_u_selected(Nurb *nu, int u)
{
BPoint *bp;
int v;
-
+
/* what about resolu == 2? */
bp = &nu->bp[u];
for (v = 0; v < nu->pntsv - 1; v++, bp += nu->pntsu) {
@@ -3794,7 +3794,7 @@ static bool is_u_selected(Nurb *nu, int u)
return true;
}
}
-
+
return false;
}
@@ -3815,14 +3815,14 @@ static void make_selection_list_nurb(Curve *cu, ListBase *editnurb)
BPoint *bp;
float dist, headdist, taildist;
int a;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (ED_curve_nurb_select_check(cu, nu)) {
-
+
nus = (NurbSort *)MEM_callocN(sizeof(NurbSort), "sort");
BLI_addhead(&nbase, nus);
nus->nu = nu;
-
+
bp = nu->bp;
a = nu->pntsu;
while (a--) {
@@ -3830,8 +3830,8 @@ static void make_selection_list_nurb(Curve *cu, ListBase *editnurb)
bp++;
}
mul_v3_fl(nus->vec, 1.0f / (float)nu->pntsu);
-
-
+
+
}
}
@@ -3839,10 +3839,10 @@ static void make_selection_list_nurb(Curve *cu, ListBase *editnurb)
nus = nbase.first;
BLI_remlink(&nbase, nus);
BLI_addtail(&nsortbase, nus);
-
+
/* now add, either at head or tail, the closest one */
while (nbase.first) {
-
+
headdist = taildist = 1.0e30;
headdo = taildo = NULL;
@@ -3862,7 +3862,7 @@ static void make_selection_list_nurb(Curve *cu, ListBase *editnurb)
}
nustest = nustest->next;
}
-
+
if (headdist < taildist) {
BLI_remlink(&nbase, headdo);
BLI_addhead(&nsortbase, headdo);
@@ -3879,12 +3879,12 @@ static void merge_2_nurb(wmOperator *op, Curve *cu, ListBase *editnurb, Nurb *nu
BPoint *bp, *bp1, *bp2, *temp;
float len1, len2;
int origu, u, v;
-
+
/* first nurbs will be changed to make u = resolu-1 selected */
/* 2nd nurbs will be changed to make u = 0 selected */
/* first nurbs: u = resolu-1 selected */
-
+
if (is_u_selected(nu1, nu1->pntsu - 1)) {
/* pass */
}
@@ -3915,7 +3915,7 @@ static void merge_2_nurb(wmOperator *op, Curve *cu, ListBase *editnurb, Nurb *nu
}
}
}
-
+
/* 2nd nurbs: u = 0 selected */
if (is_u_selected(nu2, 0)) {
/* pass */
@@ -3945,19 +3945,19 @@ static void merge_2_nurb(wmOperator *op, Curve *cu, ListBase *editnurb, Nurb *nu
}
}
}
-
+
if (nu1->pntsv != nu2->pntsv) {
BKE_report(op->reports, RPT_ERROR, "Resolution does not match");
return;
}
-
+
/* ok, now nu1 has the rightmost column and nu2 the leftmost column selected */
/* maybe we need a 'v' flip of nu2? */
-
+
bp1 = &nu1->bp[nu1->pntsu - 1];
bp2 = nu2->bp;
len1 = 0.0;
-
+
for (v = 0; v < nu1->pntsv; v++, bp1 += nu1->pntsu, bp2 += nu2->pntsu) {
len1 += len_v3v3(bp1->vec, bp2->vec);
}
@@ -3965,7 +3965,7 @@ static void merge_2_nurb(wmOperator *op, Curve *cu, ListBase *editnurb, Nurb *nu
bp1 = &nu1->bp[nu1->pntsu - 1];
bp2 = &nu2->bp[nu2->pntsu * (nu2->pntsv - 1)];
len2 = 0.0;
-
+
for (v = 0; v < nu1->pntsv; v++, bp1 += nu1->pntsu, bp2 -= nu2->pntsu) {
len2 += len_v3v3(bp1->vec, bp2->vec);
}
@@ -3977,12 +3977,12 @@ static void merge_2_nurb(wmOperator *op, Curve *cu, ListBase *editnurb, Nurb *nu
if (nu1->orderv < 3 && nu1->orderv < nu1->pntsv) nu1->orderv++;
temp = nu1->bp;
nu1->bp = MEM_mallocN(nu1->pntsu * nu1->pntsv * sizeof(BPoint), "mergeBP");
-
+
bp = nu1->bp;
bp1 = temp;
-
+
for (v = 0; v < nu1->pntsv; v++) {
-
+
/* switch direction? */
if (len1 < len2) bp2 = &nu2->bp[v * nu2->pntsu];
else bp2 = &nu2->bp[(nu1->pntsv - v - 1) * nu2->pntsu];
@@ -4003,11 +4003,11 @@ static void merge_2_nurb(wmOperator *op, Curve *cu, ListBase *editnurb, Nurb *nu
if (nu1->type == CU_NURBS) {
/* merge knots */
BKE_nurb_knot_calc_u(nu1);
-
+
/* make knots, for merged curved for example */
BKE_nurb_knot_calc_v(nu1);
}
-
+
MEM_freeN(temp);
BLI_remlink(editnurb, nu2);
BKE_nurb_free(nu2);
@@ -4020,15 +4020,15 @@ static int merge_nurb(bContext *C, wmOperator *op)
ListBase *editnurb = object_editcurve_get(obedit);
NurbSort *nus1, *nus2;
bool ok = true;
-
+
make_selection_list_nurb(cu, editnurb);
-
+
if (nsortbase.first == nsortbase.last) {
BLI_freelistN(&nsortbase);
BKE_report(op->reports, RPT_ERROR, "Too few selections to merge");
return OPERATOR_CANCELLED;
}
-
+
nus1 = nsortbase.first;
nus2 = nus1->next;
@@ -4058,7 +4058,7 @@ static int merge_nurb(bContext *C, wmOperator *op)
else {
ok = 0;
}
-
+
if (ok == 0) {
BKE_report(op->reports, RPT_ERROR, "Resolution does not match");
BLI_freelistN(&nsortbase);
@@ -4069,14 +4069,14 @@ static int merge_nurb(bContext *C, wmOperator *op)
merge_2_nurb(op, cu, editnurb, nus1->nu, nus2->nu);
nus2 = nus2->next;
}
-
+
BLI_freelistN(&nsortbase);
-
+
BKE_curve_nurb_active_set(obedit->data, NULL);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
DEG_id_tag_update(obedit->data, 0);
-
+
return OPERATOR_FINISHED;
}
@@ -4094,7 +4094,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
/* first decide if this is a surface merge! */
if (obedit->type == OB_SURF) nu = nubase->first;
else nu = NULL;
-
+
while (nu) {
const int nu_select_num = ED_curve_nurb_select_count(cu, nu);
if (nu_select_num) {
@@ -4123,7 +4123,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
if (nu)
return merge_nurb(C, op);
-
+
/* find both nurbs and points, nu1 will be put behind nu2 */
for (nu = nubase->first; nu; nu = nu->next) {
if (nu->pntsu == 1)
@@ -4293,7 +4293,7 @@ void CURVE_OT_make_segment(wmOperatorType *ot)
ot->name = "Make Segment";
ot->idname = "CURVE_OT_make_segment";
ot->description = "Join two curves by their selected ends";
-
+
/* api callbacks */
ot->exec = make_segment_exec;
ot->poll = ED_operator_editsurfcurve;
@@ -4316,10 +4316,10 @@ bool ED_curve_editnurb_select_pick(bContext *C, const int mval[2], bool extend,
const void *vert = BKE_curve_vert_active_get(cu);
int location[2];
short hand;
-
+
view3d_operator_needs_opengl(C);
ED_view3d_viewcontext_init(C, &vc);
-
+
location[0] = mval[0];
location[1] = mval[1];
@@ -4417,7 +4417,7 @@ bool ED_curve_editnurb_select_pick(bContext *C, const int mval[2], bool extend,
return true;
}
-
+
return false;
}
@@ -4442,7 +4442,7 @@ bool ed_editnurb_spin(float viewmat[4][4], Object *obedit, const float axis[3],
/* imat and center and size */
copy_m3_m4(bmat, obedit->obmat);
invert_m3_m3(imat, bmat);
-
+
axis_angle_to_mat3(cmat, axis, M_PI / 4.0);
mul_m3_m3m3(tmat, cmat, bmat);
mul_m3_m3m3(rotmat, imat, tmat);
@@ -4505,18 +4505,18 @@ static int spin_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
RegionView3D *rv3d = ED_view3d_context_rv3d(C);
float cent[3], axis[3], viewmat[4][4];
-
+
RNA_float_get_array(op->ptr, "center", cent);
RNA_float_get_array(op->ptr, "axis", axis);
-
+
invert_m4_m4(obedit->imat, obedit->obmat);
mul_m4_v3(obedit->imat, cent);
-
+
if (rv3d)
copy_m4_m4(viewmat, rv3d->viewmat);
else
unit_m4(viewmat);
-
+
if (!ed_editnurb_spin(viewmat, obedit, axis, cent)) {
BKE_report(op->reports, RPT_ERROR, "Cannot spin");
return OPERATOR_CANCELLED;
@@ -4537,13 +4537,13 @@ static int spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = ED_view3d_context_rv3d(C);
float axis[3] = {0.0f, 0.0f, 1.0f};
-
+
if (rv3d)
copy_v3_v3(axis, rv3d->viewinv[2]);
-
+
RNA_float_set_array(op->ptr, "center", ED_view3d_cursor3d_get(scene, v3d)->location);
RNA_float_set_array(op->ptr, "axis", axis);
-
+
return spin_exec(C, op);
}
@@ -4553,7 +4553,7 @@ void CURVE_OT_spin(wmOperatorType *ot)
ot->name = "Spin";
ot->idname = "CURVE_OT_spin";
ot->description = "Extrude selected boundary row around pivot point and current view axis";
-
+
/* api callbacks */
ot->exec = spin_exec;
ot->invoke = spin_invoke;
@@ -4561,7 +4561,7 @@ void CURVE_OT_spin(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -OBJECT_ADD_SIZE_MAXF, OBJECT_ADD_SIZE_MAXF,
"Center", "Center in global view space", -1000.0f, 1000.0f);
RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -1.0f, 1.0f);
@@ -5026,7 +5026,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const float mval[2] = {UNPACK2(event->mval)};
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- vc.scene, CTX_data_depsgraph(C), 0, vc.ar, vc.v3d);
+ vc.bmain, vc.scene, vc.depsgraph, 0, vc.ar, vc.v3d);
ED_transform_snap_object_project_view3d(
snap_context,
@@ -5085,7 +5085,7 @@ void CURVE_OT_vertex_add(wmOperatorType *ot)
ot->name = "Add Vertex";
ot->idname = "CURVE_OT_vertex_add";
ot->description = "Add a new control point (linked to only selected end-curve one, if any)";
-
+
/* api callbacks */
ot->exec = add_vertex_exec;
ot->invoke = add_vertex_invoke;
@@ -5108,7 +5108,7 @@ static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op))
EditNurb *editnurb = cu->editnurb;
bool changed = false;
bool as_curve = false;
-
+
/* first test: curve? */
if (obedit->type != OB_CURVE) {
Nurb *nu;
@@ -5147,7 +5147,7 @@ void CURVE_OT_extrude(wmOperatorType *ot)
ot->name = "Extrude";
ot->description = "Extrude selected control point(s)";
ot->idname = "CURVE_OT_extrude";
-
+
/* api callbacks */
ot->exec = curve_extrude_exec;
ot->poll = ED_operator_editsurfcurve;
@@ -5214,7 +5214,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
a = nu->pntsu * nu->pntsv;
bp = nu->bp;
while (a--) {
-
+
if (bp->f1 & SELECT) {
if (direction == 0 && nu->pntsu > 1) {
nu->flagu ^= CU_NURB_CYCLIC;
@@ -5228,7 +5228,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
}
bp++;
}
-
+
}
}
}
@@ -5276,7 +5276,7 @@ void CURVE_OT_cyclic_toggle(wmOperatorType *ot)
ot->name = "Toggle Cyclic";
ot->description = "Make active spline closed/opened loop";
ot->idname = "CURVE_OT_cyclic_toggle";
-
+
/* api callbacks */
ot->exec = toggle_cyclic_exec;
ot->invoke = toggle_cyclic_invoke;
@@ -5316,11 +5316,11 @@ void CURVE_OT_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Curve";
ot->description = "Duplicate selected control points";
ot->idname = "CURVE_OT_duplicate";
-
+
/* api callbacks */
ot->exec = duplicate_exec;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -5791,12 +5791,12 @@ void CURVE_OT_delete(wmOperatorType *ot)
ot->name = "Delete";
ot->description = "Delete selected control points or segments";
ot->idname = "CURVE_OT_delete";
-
+
/* api callbacks */
ot->exec = curve_delete_exec;
ot->invoke = WM_menu_invoke;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -6005,17 +6005,17 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
ListBase *editnurb = object_editcurve_get(obedit);
Nurb *nu;
int clear = (STREQ(op->idname, "CURVE_OT_shade_flat"));
-
+
if (obedit->type != OB_CURVE)
return OPERATOR_CANCELLED;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (ED_curve_nurb_select_check(obedit->data, nu)) {
if (!clear) nu->flag |= CU_SMOOTH;
else nu->flag &= ~CU_SMOOTH;
}
}
-
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
DEG_id_tag_update(obedit->data, 0);
@@ -6028,11 +6028,11 @@ void CURVE_OT_shade_smooth(wmOperatorType *ot)
ot->name = "Shade Smooth";
ot->idname = "CURVE_OT_shade_smooth";
ot->description = "Set shading to smooth";
-
+
/* api callbacks */
ot->exec = shade_smooth_exec;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -6043,11 +6043,11 @@ void CURVE_OT_shade_flat(wmOperatorType *ot)
ot->name = "Shade Flat";
ot->idname = "CURVE_OT_shade_flat";
ot->description = "Set shading to flat";
-
+
/* api callbacks */
ot->exec = shade_smooth_exec;
ot->poll = ED_operator_editsurfcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -6084,21 +6084,21 @@ int join_curve_exec(bContext *C, wmOperator *op)
}
BLI_listbase_clear(&tempbase);
-
+
/* trasnform all selected curves inverse in obact */
invert_m4_m4(imat, ob->obmat);
-
+
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
{
if (base->object->type == ob->type) {
if (base->object != ob) {
-
+
cu = base->object->data;
-
+
if (cu->nurb.first) {
/* watch it: switch order here really goes wrong */
mul_m4_m4m4(cmat, imat, base->object->obmat);
-
+
nu = cu->nurb.first;
while (nu) {
newnu = BKE_nurb_duplicate(nu);
@@ -6109,7 +6109,7 @@ int join_curve_exec(bContext *C, wmOperator *op)
newnu->mat_nr = 0;
}
BLI_addtail(&tempbase, newnu);
-
+
if ((bezt = newnu->bezt)) {
a = newnu->pntsu;
while (a--) {
@@ -6130,16 +6130,16 @@ int join_curve_exec(bContext *C, wmOperator *op)
nu = nu->next;
}
}
-
+
ED_object_base_free_and_unlink(bmain, scene, base->object);
}
}
}
CTX_DATA_END;
-
+
cu = ob->data;
BLI_movelisttolist(&cu->nurb, &tempbase);
-
+
if (ob->type == OB_CURVE) {
/* Account for mixed 2D/3D curves when joining */
BKE_curve_curve_dimension_update(cu);
@@ -6198,11 +6198,11 @@ void CURVE_OT_tilt_clear(wmOperatorType *ot)
ot->name = "Clear Tilt";
ot->idname = "CURVE_OT_tilt_clear";
ot->description = "Clear the tilt of selected control points";
-
+
/* api callbacks */
ot->exec = clear_tilt_exec;
ot->poll = ED_operator_editcurve;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index bbe88bd1446..887f3dd13da 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -34,6 +34,7 @@
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_fcurve.h"
+#include "BKE_main.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
@@ -616,6 +617,7 @@ static bool curve_draw_init(bContext *C, wmOperator *op, bool is_invoke)
}
}
else {
+ cdd->vc.bmain = CTX_data_main(C);
cdd->vc.depsgraph = CTX_data_depsgraph(C);
cdd->vc.scene = CTX_data_scene(C);
cdd->vc.view_layer = CTX_data_view_layer(C);
@@ -1016,7 +1018,7 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
nu->resolv = 1;
nu->orderu = 4;
nu->orderv = 1;
-
+
BPoint *bp = nu->bp;
BLI_mempool_iternew(cdd->stroke_elem_pool, &iter);
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index a9a8901acc6..7cdfafdad43 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -82,7 +82,7 @@ static int kill_selection(Object *obedit, int ins);
static char findaccent(char char1, unsigned int code)
{
char new = 0;
-
+
if (char1 == 'a') {
if (code == '`') new = 224;
else if (code == 39) new = 225;
@@ -214,7 +214,7 @@ static char findaccent(char char1, unsigned int code)
else if (char1 == '+') {
if (code == '-') new = 177;
}
-
+
if (new) return new;
else return char1;
}
@@ -223,7 +223,7 @@ static int insert_into_textbuf(Object *obedit, uintptr_t c)
{
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
-
+
if (ef->len < MAXTEXT - 1) {
int x;
@@ -233,7 +233,7 @@ static int insert_into_textbuf(Object *obedit, uintptr_t c)
ef->textbufinfo[ef->pos] = cu->curinfo;
ef->textbufinfo[ef->pos].kern = 0;
ef->textbufinfo[ef->pos].mat_nr = obedit->actcol;
-
+
ef->pos++;
ef->len++;
ef->textbuf[ef->len] = '\0';
@@ -378,7 +378,7 @@ static int paste_from_file_exec(bContext *C, wmOperator *op)
{
char *path;
int retval;
-
+
path = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0);
retval = paste_from_file(C, op->reports, path);
MEM_freeN(path);
@@ -391,7 +391,7 @@ static int paste_from_file_invoke(bContext *C, wmOperator *op, const wmEvent *UN
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return paste_from_file_exec(C, op);
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -402,12 +402,12 @@ void FONT_OT_text_paste_from_file(wmOperatorType *ot)
ot->name = "Paste File";
ot->description = "Paste contents from file";
ot->idname = "FONT_OT_text_paste_from_file";
-
+
/* api callbacks */
ot->exec = paste_from_file_exec;
ot->invoke = paste_from_file_invoke;
ot->poll = ED_operator_editfont;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -433,7 +433,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
char *s;
int a;
float rot[3] = {0.f, 0.f, 0.f};
-
+
obedit = BKE_object_add(bmain, scene, view_layer, OB_FONT, NULL);
base = view_layer->basact;
@@ -506,12 +506,12 @@ void ED_text_to_object(bContext *C, Text *text, const bool split_lines)
linenum++;
continue;
}
-
+
/* do the translation */
offset[0] = 0;
offset[1] = -linenum;
offset[2] = 0;
-
+
if (rv3d)
mul_mat3_m4_v3(rv3d->viewinv, offset);
@@ -607,11 +607,11 @@ void FONT_OT_style_set(wmOperatorType *ot)
ot->name = "Set Style";
ot->description = "Set font style";
ot->idname = "FONT_OT_style_set";
-
+
/* api callbacks */
ot->exec = set_style_exec;
ot->poll = ED_operator_editfont;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -630,7 +630,7 @@ static int toggle_style_exec(bContext *C, wmOperator *op)
if (!BKE_vfont_select_get(obedit, &selstart, &selend))
return OPERATOR_CANCELLED;
-
+
style = RNA_enum_get(op->ptr, "style");
cu->curinfo.flag ^= style;
@@ -645,11 +645,11 @@ void FONT_OT_style_toggle(wmOperatorType *ot)
ot->name = "Toggle Style";
ot->description = "Toggle font style";
ot->idname = "FONT_OT_style_toggle";
-
+
/* api callbacks */
ot->exec = toggle_style_exec;
ot->poll = ED_operator_editfont;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -703,7 +703,7 @@ void FONT_OT_select_all(wmOperatorType *ot)
static void copy_selection(Object *obedit)
{
int selstart, selend;
-
+
if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
@@ -740,7 +740,7 @@ void FONT_OT_text_copy(wmOperatorType *ot)
ot->name = "Copy Text";
ot->description = "Copy selected text to clipboard";
ot->idname = "FONT_OT_text_copy";
-
+
/* api callbacks */
ot->exec = copy_text_exec;
ot->poll = ED_operator_editfont;
@@ -770,7 +770,7 @@ void FONT_OT_text_cut(wmOperatorType *ot)
ot->name = "Cut Text";
ot->description = "Cut selected text to clipboard";
ot->idname = "FONT_OT_text_cut";
-
+
/* api callbacks */
ot->exec = cut_text_exec;
ot->poll = ED_operator_editfont;
@@ -871,7 +871,7 @@ void FONT_OT_text_paste(wmOperatorType *ot)
ot->name = "Paste Text";
ot->description = "Paste text from clipboard";
ot->idname = "FONT_OT_text_paste";
-
+
/* api callbacks */
ot->exec = paste_text_exec;
ot->poll = ED_operator_editfont;
@@ -915,7 +915,7 @@ static int move_cursor(bContext *C, int type, const bool select)
}
cursmove = FO_CURS;
break;
-
+
case LINE_END:
while (ef->pos < ef->len) {
if (ef->textbuf[ef->pos] == 0) break;
@@ -958,7 +958,7 @@ static int move_cursor(bContext *C, int type, const bool select)
case PREV_LINE:
cursmove = FO_CURSUP;
break;
-
+
case NEXT_LINE:
cursmove = FO_CURSDOWN;
break;
@@ -971,7 +971,7 @@ static int move_cursor(bContext *C, int type, const bool select)
cursmove = FO_PAGEDOWN;
break;
}
-
+
if (cursmove == -1)
return OPERATOR_CANCELLED;
@@ -1016,7 +1016,7 @@ void FONT_OT_move(wmOperatorType *ot)
ot->name = "Move Cursor";
ot->description = "Move cursor to position type";
ot->idname = "FONT_OT_move";
-
+
/* api callbacks */
ot->exec = move_exec;
ot->poll = ED_operator_editfont;
@@ -1043,7 +1043,7 @@ void FONT_OT_move_select(wmOperatorType *ot)
ot->name = "Move Select";
ot->description = "Move the cursor while selecting";
ot->idname = "FONT_OT_move_select";
-
+
/* api callbacks */
ot->exec = move_select_exec;
ot->poll = ED_operator_editfont;
@@ -1084,7 +1084,7 @@ void FONT_OT_change_spacing(wmOperatorType *ot)
ot->name = "Change Spacing";
ot->description = "Change font spacing";
ot->idname = "FONT_OT_change_spacing";
-
+
/* api callbacks */
ot->exec = change_spacing_exec;
ot->poll = ED_operator_editfont;
@@ -1128,7 +1128,7 @@ void FONT_OT_change_character(wmOperatorType *ot)
ot->name = "Change Character";
ot->description = "Change font character code";
ot->idname = "FONT_OT_change_character";
-
+
/* api callbacks */
ot->exec = change_character_exec;
ot->poll = ED_operator_editfont;
@@ -1163,7 +1163,7 @@ void FONT_OT_line_break(wmOperatorType *ot)
ot->name = "Line Break";
ot->description = "Insert line break at cursor position";
ot->idname = "FONT_OT_line_break";
-
+
/* api callbacks */
ot->exec = line_break_exec;
ot->poll = ED_operator_editfont;
@@ -1289,7 +1289,7 @@ void FONT_OT_delete(wmOperatorType *ot)
ot->name = "Delete";
ot->description = "Delete text by cursor position";
ot->idname = "FONT_OT_delete";
-
+
/* api callbacks */
ot->exec = delete_exec;
ot->poll = ED_operator_editfont;
@@ -1312,7 +1312,7 @@ static int insert_text_exec(bContext *C, wmOperator *op)
if (!RNA_struct_property_is_set(op->ptr, "text"))
return OPERATOR_CANCELLED;
-
+
inserted_utf8 = RNA_string_get_alloc(op->ptr, "text", NULL, 0);
len = BLI_strlen_utf8(inserted_utf8);
@@ -1350,7 +1350,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
accentcode = 1;
return OPERATOR_FINISHED;
}
-
+
/* tab should exit editmode, but we allow it to be typed using modifier keys */
if (event_type == TABKEY) {
if ((alt || ctrl || shift) == 0)
@@ -1358,7 +1358,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else
ascii = 9;
}
-
+
if (event_type == BACKSPACEKEY) {
if (alt && ef->len != 0 && ef->pos > 0)
accentcode = 1;
@@ -1394,7 +1394,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else {
BLI_assert(0);
}
-
+
kill_selection(obedit, 1);
text_update_edited(C, obedit, FO_EDIT);
}
@@ -1418,7 +1418,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* reset property? */
if (event_val == 0)
accentcode = 0;
-
+
return OPERATOR_FINISHED;
}
@@ -1428,12 +1428,12 @@ void FONT_OT_text_insert(wmOperatorType *ot)
ot->name = "Insert Text";
ot->description = "Insert text at cursor position";
ot->idname = "FONT_OT_text_insert";
-
+
/* api callbacks */
ot->exec = insert_text_exec;
ot->invoke = insert_text_invoke;
ot->poll = ED_operator_editfont;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1449,14 +1449,14 @@ static int textbox_add_exec(bContext *C, wmOperator *UNUSED(op))
Object *obedit = CTX_data_active_object(C);
Curve *cu = obedit->data;
int i;
-
+
if (cu->totbox < 256) {
for (i = cu->totbox; i > cu->actbox; i--) cu->tb[i] = cu->tb[i - 1];
cu->tb[cu->actbox] = cu->tb[cu->actbox - 1];
cu->actbox++;
cu->totbox++;
}
-
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
return OPERATOR_FINISHED;
}
@@ -1467,15 +1467,15 @@ void FONT_OT_textbox_add(wmOperatorType *ot)
ot->name = "Add Textbox";
ot->description = "Add a new text box";
ot->idname = "FONT_OT_textbox_add";
-
+
/* api callbacks */
ot->exec = textbox_add_exec;
ot->poll = ED_operator_object_active_editable_font;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
-
+
+
}
@@ -1490,17 +1490,17 @@ static int textbox_remove_exec(bContext *C, wmOperator *op)
Curve *cu = obedit->data;
int i;
int index = RNA_int_get(op->ptr, "index");
-
-
+
+
if (cu->totbox > 1) {
for (i = index; i < cu->totbox; i++) cu->tb[i] = cu->tb[i + 1];
cu->totbox--;
if (cu->actbox >= index)
cu->actbox--;
}
-
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
-
+
return OPERATOR_FINISHED;
}
@@ -1510,14 +1510,14 @@ void FONT_OT_textbox_remove(wmOperatorType *ot)
ot->name = "Remove Textbox";
ot->description = "Remove the textbox";
ot->idname = "FONT_OT_textbox_remove";
-
+
/* api callbacks */
ot->exec = textbox_remove_exec;
ot->poll = ED_operator_object_active_editable_font;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "The current text box", 0, INT_MAX);
}
@@ -1530,14 +1530,14 @@ void ED_curve_editfont_make(Object *obedit)
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
int len_wchar;
-
+
if (ef == NULL) {
ef = cu->editfont = MEM_callocN(sizeof(EditFont), "editfont");
-
+
ef->textbuf = MEM_callocN((MAXTEXT + 4) * sizeof(wchar_t), "texteditbuf");
ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo");
}
-
+
/* Convert the original text to wchar_t */
len_wchar = BLI_strncpy_wchar_from_utf8(ef->textbuf, cu->str, MAXTEXT + 4);
BLI_assert(len_wchar == cu->len_wchar);
@@ -1576,7 +1576,7 @@ void ED_curve_editfont_load(Object *obedit)
/* Copy the wchar to UTF-8 */
BLI_strncpy_wchar_as_utf8(cu->str, ef->textbuf, cu->len + 1);
-
+
if (cu->strinfo)
MEM_freeN(cu->strinfo);
cu->strinfo = MEM_callocN((cu->len_wchar + 4) * sizeof(CharInfo), "texteditinfo");
@@ -1608,7 +1608,7 @@ static int set_case(bContext *C, int ccase)
wchar_t *str;
int len;
int selstart, selend;
-
+
if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
len = (selend - selstart) + 1;
str = &ef->textbuf[selstart];
@@ -1648,7 +1648,7 @@ void FONT_OT_case_set(wmOperatorType *ot)
ot->name = "Set Case";
ot->description = "Set font case";
ot->idname = "FONT_OT_case_set";
-
+
/* api callbacks */
ot->exec = set_case_exec;
ot->poll = ED_operator_editfont;
@@ -1669,7 +1669,7 @@ static int toggle_case_exec(bContext *C, wmOperator *UNUSED(op))
EditFont *ef = cu->editfont;
wchar_t *str;
int len, ccase = CASE_UPPER;
-
+
len = wcslen(ef->textbuf);
str = ef->textbuf;
while (len) {
@@ -1681,7 +1681,7 @@ static int toggle_case_exec(bContext *C, wmOperator *UNUSED(op))
len--;
str++;
}
-
+
return set_case(C, ccase);
}
@@ -1691,7 +1691,7 @@ void FONT_OT_case_toggle(wmOperatorType *ot)
ot->name = "Toggle Case";
ot->description = "Toggle font case";
ot->idname = "FONT_OT_case_toggle";
-
+
/* api callbacks */
ot->exec = toggle_case_exec;
ot->poll = ED_operator_editfont;
@@ -1705,7 +1705,7 @@ void FONT_OT_case_toggle(wmOperatorType *ot)
static void font_ui_template_init(bContext *C, wmOperator *op)
{
PropertyPointerRNA *pprop;
-
+
op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
}
@@ -1734,7 +1734,7 @@ static int font_open_exec(bContext *C, wmOperator *op)
if (!op->customdata)
font_ui_template_init(C, op);
-
+
/* hook into UI */
pprop = op->customdata;
@@ -1742,7 +1742,7 @@ static int font_open_exec(bContext *C, wmOperator *op)
/* when creating new ID blocks, use is already 1, but RNA
* pointer use also increases user, so this compensates it */
id_us_min(&font->id);
-
+
RNA_id_pointer_create(&font->id, &idptr);
RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
RNA_property_update(C, &pprop->ptr, pprop->prop);
@@ -1777,7 +1777,7 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)
return font_open_exec(C, op);
RNA_string_set(op->ptr, "filepath", path);
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1788,15 +1788,15 @@ void FONT_OT_open(wmOperatorType *ot)
ot->name = "Open Font";
ot->idname = "FONT_OT_open";
ot->description = "Load a new font from a file";
-
+
/* api callbacks */
ot->exec = font_open_exec;
ot->invoke = open_invoke;
ot->cancel = font_open_cancel;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_filesel(
ot, FILE_TYPE_FOLDER | FILE_TYPE_FTFONT, FILE_SPECIAL, FILE_OPENFILE,
@@ -1813,7 +1813,7 @@ static int font_unlink_exec(bContext *C, wmOperator *op)
PropertyPointerRNA pprop;
UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop);
-
+
if (pprop.prop == NULL) {
BKE_report(op->reports, RPT_ERROR, "Incorrect context for running font unlink");
return OPERATOR_CANCELLED;
@@ -1834,7 +1834,7 @@ void FONT_OT_unlink(wmOperatorType *ot)
ot->name = "Unlink";
ot->idname = "FONT_OT_unlink";
ot->description = "Unlink active font data-block";
-
+
/* api callbacks */
ot->exec = font_unlink_exec;
}
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 50a6e9125a0..a30cb578046 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -249,7 +249,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short
immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints - i + 1);
/* need to roll-back one point to ensure that there are no gaps in the stroke */
- if (i != 0) {
+ if (i != 0) {
gp_set_tpoint_varying_color(pt - 1, ink, color);
immVertex2iv(pos, &(pt - 1)->x);
++draw_points;
@@ -389,7 +389,7 @@ static void gp_draw_stroke_volumetric_3d(
const bGPDspoint *pt = points;
for (int i = 0; i < totpoints && pt; i++, pt++) {
- gp_set_point_varying_color(pt, ink, color);
+ gp_set_point_varying_color(pt, ink, color);
immAttrib1f(size, pt->pressure * thickness); /* TODO: scale based on view transform */
immVertex3fv(pos, &pt->x); /* we can adjust size in vertex shader based on view/projection! */
}
@@ -650,7 +650,7 @@ static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thi
immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add);
/* need to roll-back one point to ensure that there are no gaps in the stroke */
- if (i != 0) {
+ if (i != 0) {
const bGPDspoint *pt2 = pt - 1;
mul_v3_m4v3(fpt, diff_mat, &pt2->x);
gp_set_point_varying_color(pt2, ink, color);
@@ -1322,7 +1322,7 @@ void ED_gp_draw_interpolation(tGPDinterpolate *tgpi, const int type)
UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, color);
color[3] = 0.6f;
- int dflag = 0;
+ int dflag = 0;
/* if 3d stuff, enable flags */
if (type == REGION_DRAW_POST_VIEW) {
dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
@@ -1366,7 +1366,7 @@ static void gp_draw_data_layers(
/* set basic stroke thickness */
glLineWidth(lthick);
-
+
/* Add layer drawing settings to the set of "draw flags"
* NOTE: If the setting doesn't apply, it *must* be cleared,
* as dflag's carry over from the previous layer
@@ -1386,7 +1386,7 @@ static void gp_draw_data_layers(
GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_HQ_FILL), GP_DRAWDATA_HQ_FILL);
#undef GP_DRAWFLAG_APPLY
-
+
/* Draw 'onionskins' (frame left + right)
* - It is only possible to show these if the option is enabled
* - The "no onions" flag prevents ghosts from appearing during animation playback/scrubbing
@@ -1394,8 +1394,8 @@ static void gp_draw_data_layers(
* - The per-layer "always show" flag however overrides the playback/render restriction,
* allowing artists to selectively turn onionskins on/off during playback
*/
- if ((gpl->flag & GP_LAYER_ONIONSKIN) &&
- ((dflag & GP_DRAWDATA_NO_ONIONS) == 0 || (gpl->flag & GP_LAYER_GHOST_ALWAYS)))
+ if ((gpl->flag & GP_LAYER_ONIONSKIN) &&
+ ((dflag & GP_DRAWDATA_NO_ONIONS) == 0 || (gpl->flag & GP_LAYER_GHOST_ALWAYS)))
{
/* Drawing method - only immediately surrounding (gstep = 0),
* or within a frame range on either side (gstep > 0)
@@ -1430,7 +1430,7 @@ static void gp_draw_data_layers(
{
/* Buffer stroke needs to be drawn with a different linestyle
* to help differentiate them from normal strokes.
- *
+ *
* It should also be noted that sbuffer contains temporary point types
* i.e. tGPspoints NOT bGPDspoints
*/
@@ -1465,7 +1465,7 @@ static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar)
int font_id = BLF_default();
BLF_width_and_height(font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
-
+
int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
int yco = (rect.ymax - U.widget_unit);
@@ -1499,7 +1499,7 @@ static void gp_draw_data(
/* turn on smooth lines (i.e. anti-aliasing) */
glEnable(GL_LINE_SMOOTH);
- /* XXX: turn on some way of ensuring that the polygon edges get smoothed
+ /* XXX: turn on some way of ensuring that the polygon edges get smoothed
* GL_POLYGON_SMOOTH is nasty and shouldn't be used, as it ends up
* creating internal white rays due to the ways it accumulates stuff
*/
@@ -1643,7 +1643,7 @@ void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d)
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
int dflag = 0;
-
+
/* check that we have grease-pencil stuff to draw */
if (sa == NULL) return;
bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX
@@ -1725,7 +1725,7 @@ void ED_gpencil_draw_view3d(wmWindowManager *wm,
}
/* draw it! */
- gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
+ gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
}
void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype)
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index 90d44503013..5e62a87caf3 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -66,18 +66,18 @@
bool ED_gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDframe *, Scene *))
{
bGPDframe *gpf;
-
+
/* error checker */
if (gpl == NULL)
return false;
-
+
/* do loop */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
/* execute callback */
if (gpf_cb(gpf, scene))
return true;
}
-
+
/* nothing to return */
return false;
}
@@ -90,19 +90,19 @@ void ED_gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, bool onlysel)
{
bGPDframe *gpf;
CfraElem *ce;
-
+
/* error checking */
if (ELEM(NULL, gpl, elems))
return;
-
+
/* loop through gp-frames, adding */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
if ((onlysel == 0) || (gpf->flag & GP_FRAME_SELECT)) {
ce = MEM_callocN(sizeof(CfraElem), "CfraElem");
-
+
ce->cfra = (float)gpf->framenum;
ce->sel = (gpf->flag & GP_FRAME_SELECT) ? 1 : 0;
-
+
BLI_addtail(elems, ce);
}
}
@@ -115,17 +115,17 @@ void ED_gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, bool onlysel)
bool ED_gplayer_frame_select_check(bGPDlayer *gpl)
{
bGPDframe *gpf;
-
+
/* error checking */
if (gpl == NULL)
return false;
-
+
/* stop at the first one found */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
if (gpf->flag & GP_FRAME_SELECT)
return true;
}
-
+
/* not found */
return false;
}
@@ -135,7 +135,7 @@ static void gpframe_select(bGPDframe *gpf, short select_mode)
{
if (gpf == NULL)
return;
-
+
switch (select_mode) {
case SELECT_ADD:
gpf->flag |= GP_FRAME_SELECT;
@@ -153,11 +153,11 @@ static void gpframe_select(bGPDframe *gpf, short select_mode)
void ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode)
{
bGPDframe *gpf;
-
+
/* error checking */
if (gpl == NULL)
return;
-
+
/* handle according to mode */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
gpframe_select(gpf, select_mode);
@@ -170,7 +170,7 @@ void ED_gplayer_frame_select_set(bGPDlayer *gpl, short mode)
/* error checking */
if (gpl == NULL)
return;
-
+
/* now call the standard function */
ED_gpencil_select_frames(gpl, mode);
}
@@ -179,12 +179,12 @@ void ED_gplayer_frame_select_set(bGPDlayer *gpl, short mode)
void ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode)
{
bGPDframe *gpf;
-
+
if (gpl == NULL)
return;
-
+
gpf = BKE_gpencil_layer_find_frame(gpl, selx);
-
+
if (gpf) {
gpframe_select(gpf, select_mode);
}
@@ -194,10 +194,10 @@ void ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode)
void ED_gplayer_frames_select_border(bGPDlayer *gpl, float min, float max, short select_mode)
{
bGPDframe *gpf;
-
+
if (gpl == NULL)
return;
-
+
/* only select those frames which are in bounds */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
if (IN_RANGE(gpf->framenum, min, max))
@@ -209,21 +209,21 @@ void ED_gplayer_frames_select_border(bGPDlayer *gpl, float min, float max, short
void ED_gplayer_frames_select_region(KeyframeEditData *ked, bGPDlayer *gpl, short tool, short select_mode)
{
bGPDframe *gpf;
-
+
if (gpl == NULL)
return;
-
+
/* only select frames which are within the region */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
/* construct a dummy point coordinate to do this testing with */
float pt[2] = {0};
-
+
pt[0] = gpf->framenum;
pt[1] = ked->channel_y;
-
+
/* check the necessary regions */
if (tool == BEZT_OK_CHANNEL_LASSO) {
- /* Lasso */
+ /* Lasso */
if (keyframe_region_lasso_test(ked->data, pt))
gpframe_select(gpf, select_mode);
}
@@ -243,21 +243,21 @@ bool ED_gplayer_frames_delete(bGPDlayer *gpl)
{
bGPDframe *gpf, *gpfn;
bool changed = false;
-
+
/* error checking */
if (gpl == NULL)
return false;
-
+
/* check for frames to delete */
for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
gpfn = gpf->next;
-
+
if (gpf->flag & GP_FRAME_SELECT) {
BKE_gpencil_layer_delframe(gpl, gpf);
changed = true;
}
}
-
+
return changed;
}
@@ -265,23 +265,23 @@ bool ED_gplayer_frames_delete(bGPDlayer *gpl)
void ED_gplayer_frames_duplicate(bGPDlayer *gpl)
{
bGPDframe *gpf, *gpfn;
-
+
/* error checking */
if (gpl == NULL)
return;
-
+
/* duplicate selected frames */
for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
gpfn = gpf->next;
-
+
/* duplicate this frame */
if (gpf->flag & GP_FRAME_SELECT) {
bGPDframe *gpfd;
-
+
/* duplicate frame, and deselect self */
gpfd = BKE_gpencil_frame_duplicate(gpf);
gpf->flag &= ~GP_FRAME_SELECT;
-
+
BLI_insertlinkafter(&gpl->frames, gpf, gpfd);
}
}
@@ -293,10 +293,10 @@ void ED_gplayer_frames_duplicate(bGPDlayer *gpl)
void ED_gplayer_frames_keytype_set(bGPDlayer *gpl, short type)
{
bGPDframe *gpf;
-
+
if (gpl == NULL)
return;
-
+
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
if (gpf->flag & GP_FRAME_SELECT) {
gpf->key_type = type;
@@ -327,7 +327,7 @@ void ED_gpencil_anim_copybuf_free(void)
{
BKE_gpencil_free_layers(&gp_anim_copybuf);
BLI_listbase_clear(&gp_anim_copybuf);
-
+
gp_anim_copy_firstframe = 999999999;
gp_anim_copy_lastframe = -999999999;
gp_anim_copy_cfra = 0;
@@ -344,23 +344,23 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
Scene *scene = ac->scene;
-
-
+
+
/* clear buffer first */
ED_gpencil_anim_copybuf_free();
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* assume that each of these is a GP layer */
for (ale = anim_data.first; ale; ale = ale->next) {
ListBase copied_frames = {NULL, NULL};
bGPDlayer *gpl = (bGPDlayer *)ale->data;
bGPDframe *gpf;
-
+
/* loop over frames, and copy only selected frames */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
/* if frame is selected, make duplicate it and its strokes */
@@ -368,41 +368,41 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
/* make a copy of this frame */
bGPDframe *new_frame = BKE_gpencil_frame_duplicate(gpf);
BLI_addtail(&copied_frames, new_frame);
-
+
/* extend extents for keyframes encountered */
if (gpf->framenum < gp_anim_copy_firstframe)
- gp_anim_copy_firstframe = gpf->framenum;
+ gp_anim_copy_firstframe = gpf->framenum;
if (gpf->framenum > gp_anim_copy_lastframe)
gp_anim_copy_lastframe = gpf->framenum;
}
}
-
+
/* create a new layer in buffer if there were keyframes here */
if (BLI_listbase_is_empty(&copied_frames) == false) {
bGPDlayer *new_layer = MEM_callocN(sizeof(bGPDlayer), "GPCopyPasteLayer");
BLI_addtail(&gp_anim_copybuf, new_layer);
-
+
/* move over copied frames */
BLI_movelisttolist(&new_layer->frames, &copied_frames);
BLI_assert(copied_frames.first == NULL);
-
+
/* make a copy of the layer's name - for name-based matching later... */
BLI_strncpy(new_layer->info, gpl->info, sizeof(new_layer->info));
}
}
-
+
/* in case 'relative' paste method is used */
gp_anim_copy_cfra = CFRA;
-
+
/* clean up */
ANIM_animdata_freelist(&anim_data);
-
+
/* check if anything ended up in the buffer */
if (ELEM(NULL, gp_anim_copybuf.first, gp_anim_copybuf.last)) {
BKE_report(ac->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
return false;
}
-
+
/* report success */
return true;
}
@@ -414,22 +414,22 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
Scene *scene = ac->scene;
bool no_name = false;
int offset = 0;
-
+
/* check if buffer is empty */
if (BLI_listbase_is_empty(&gp_anim_copybuf)) {
BKE_report(ac->reports, RPT_ERROR, "No data in buffer to paste");
return false;
}
-
+
/* check if single channel in buffer (disregard names if so) */
if (gp_anim_copybuf.first == gp_anim_copybuf.last) {
no_name = true;
}
-
+
/* methods of offset (eKeyPasteOffset) */
switch (offset_mode) {
case KEYFRAME_PASTE_OFFSET_CFRA_START:
@@ -446,19 +446,19 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
break;
}
-
+
/* filter data */
// TODO: try doing it with selection, then without selection imits
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* from selected channels */
for (ale = anim_data.first; ale; ale = ale->next) {
bGPDlayer *gpld = (bGPDlayer *)ale->data;
bGPDlayer *gpls = NULL;
bGPDframe *gpfs, *gpf;
-
-
+
+
/* find suitable layer from buffer to use to paste from */
for (gpls = gp_anim_copybuf.first; gpls; gpls = gpls->next) {
/* check if layer name matches */
@@ -466,21 +466,21 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
break;
}
}
-
+
/* this situation might occur! */
if (gpls == NULL)
continue;
-
+
/* add frames from buffer */
for (gpfs = gpls->frames.first; gpfs; gpfs = gpfs->next) {
/* temporarily apply offset to buffer-frame while copying */
gpfs->framenum += offset;
-
+
/* get frame to copy data into (if no frame returned, then just ignore) */
gpf = BKE_gpencil_layer_getframe(gpld, gpfs->framenum, 1);
if (gpf) {
bGPDstroke *gps, *gpsn;
-
+
/* This should be the right frame... as it may be a pre-existing frame,
* must make sure that only compatible stroke types get copied over
* - We cannot just add a duplicate frame, as that would cause errors
@@ -495,19 +495,19 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
/* duplicate triangle information */
gpsn->triangles = MEM_dupallocN(gps->triangles);
/* append stroke to frame */
- BLI_addtail(&gpf->strokes, gpsn);
+ BLI_addtail(&gpf->strokes, gpsn);
}
-
+
/* if no strokes (i.e. new frame) added, free gpf */
if (BLI_listbase_is_empty(&gpf->strokes))
BKE_gpencil_layer_delframe(gpld, gpf);
}
-
+
/* unapply offset from buffer-frame */
gpfs->framenum -= offset;
}
}
-
+
/* clean up */
ANIM_animdata_freelist(&anim_data);
return true;
@@ -574,37 +574,37 @@ void ED_gplayer_snap_frames(bGPDlayer *gpl, Scene *scene, short mode)
static short mirror_gpf_cframe(bGPDframe *gpf, Scene *scene)
{
int diff;
-
+
if (gpf->flag & GP_FRAME_SELECT) {
diff = CFRA - gpf->framenum;
gpf->framenum = CFRA + diff;
}
-
+
return 0;
}
static short mirror_gpf_yaxis(bGPDframe *gpf, Scene *UNUSED(scene))
{
int diff;
-
+
if (gpf->flag & GP_FRAME_SELECT) {
diff = -gpf->framenum;
gpf->framenum = diff;
}
-
+
return 0;
}
static short mirror_gpf_xaxis(bGPDframe *gpf, Scene *UNUSED(scene))
{
int diff;
-
+
/* NOTE: since we can't really do this, we just do the same as for yaxis... */
if (gpf->flag & GP_FRAME_SELECT) {
diff = -gpf->framenum;
gpf->framenum = diff;
}
-
+
return 0;
}
@@ -613,7 +613,7 @@ static short mirror_gpf_marker(bGPDframe *gpf, Scene *scene)
static TimeMarker *marker;
static short initialized = 0;
int diff;
-
+
/* In order for this mirror function to work without
* any extra arguments being added, we use the case
* of bezt==NULL to denote that we should find the
@@ -621,7 +621,7 @@ static short mirror_gpf_marker(bGPDframe *gpf, Scene *scene)
* to use this way, as it will be set to null after
* each cycle in which this is called.
*/
-
+
if (gpf) {
/* mirroring time */
if ((gpf->flag & GP_FRAME_SELECT) && (marker)) {
@@ -644,7 +644,7 @@ static short mirror_gpf_marker(bGPDframe *gpf, Scene *scene)
}
}
}
-
+
return 0;
}
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index 1cb882e9a43..c2e532be0b3 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -87,54 +87,54 @@ typedef struct tGP_BrushEditData {
/* Current editor/region/etc. */
/* NOTE: This stuff is mainly needed to handle 3D view projection stuff... */
Scene *scene;
-
+
ScrArea *sa;
ARegion *ar;
-
+
/* Current GPencil datablock */
bGPdata *gpd;
-
+
/* Brush Settings */
GP_BrushEdit_Settings *settings;
GP_EditBrush_Data *brush;
-
+
eGP_EditBrush_Types brush_type;
eGP_EditBrush_Flag flag;
-
+
/* Space Conversion Data */
GP_SpaceConversion gsc;
-
-
+
+
/* Is the brush currently painting? */
bool is_painting;
-
+
/* Start of new sculpt stroke */
bool first;
-
+
/* Current frame */
int cfra;
-
-
+
+
/* Brush Runtime Data: */
/* - position and pressure
* - the *_prev variants are the previous values
*/
int mval[2], mval_prev[2];
float pressure, pressure_prev;
-
+
/* - effect vector (e.g. 2D/3D translation for grab brush) */
float dvec[3];
-
+
/* brush geometry (bounding box) */
rcti brush_rect;
-
+
/* Custom data for certain brushes */
/* - map from bGPDstroke's to structs containing custom data about those strokes */
GHash *stroke_customdata;
/* - general customdata */
void *customdata;
-
-
+
+
/* Timer for in-place accumulation of brush effect */
wmTimer *timer;
bool timerTick; /* is this event from a timer */
@@ -170,12 +170,12 @@ static bool gp_brush_invert_check(tGP_BrushEditData *gso)
{
/* The basic setting is the brush's setting (from the panel) */
bool invert = ((gso->brush->flag & GP_EDITBRUSH_FLAG_INVERT) != 0);
-
+
/* During runtime, the user can hold down the Ctrl key to invert the basic behaviour */
if (gso->flag & GP_EDITBRUSH_FLAG_INVERT) {
invert ^= true;
}
-
+
return invert;
}
@@ -183,26 +183,26 @@ static bool gp_brush_invert_check(tGP_BrushEditData *gso)
static float gp_brush_influence_calc(tGP_BrushEditData *gso, const int radius, const int co[2])
{
GP_EditBrush_Data *brush = gso->brush;
-
+
/* basic strength factor from brush settings */
float influence = brush->strength;
-
+
/* use pressure? */
if (brush->flag & GP_EDITBRUSH_FLAG_USE_PRESSURE) {
influence *= gso->pressure;
}
-
+
/* distance fading */
if (brush->flag & GP_EDITBRUSH_FLAG_USE_FALLOFF) {
float distance = (float)len_v2v2_int(gso->mval, co);
float fac;
-
+
CLAMP(distance, 0.0f, (float)radius);
fac = 1.0f - (distance / (float)radius);
-
+
influence *= fac;
}
-
+
/* return influence */
return influence;
}
@@ -241,7 +241,7 @@ static bool gp_brush_smooth_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_THICKNESS) {
gp_smooth_stroke_thickness(gps, i, inf);
}
-
+
return true;
}
@@ -254,13 +254,13 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
{
bGPDspoint *pt = gps->points + i;
float inf;
-
+
/* Compute strength of effect
* - We divide the strength by 10, so that users can set "sane" values.
* Otherwise, good default values are in the range of 0.093
*/
inf = gp_brush_influence_calc(gso, radius, co) / 10.0f;
-
+
/* apply */
// XXX: this is much too strong, and it should probably do some smoothing with the surrounding stuff
if (gp_brush_invert_check(gso)) {
@@ -271,7 +271,7 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
/* make line thicker - increase stroke pressure */
pt->pressure += inf;
}
-
+
/* Pressure should stay within [0.0, 1.0]
* However, it is nice for volumetric strokes to be able to exceed
* the upper end of this range. Therefore, we don't actually clamp
@@ -279,7 +279,7 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
*/
if (pt->pressure < 0.0f)
pt->pressure = 0.0f;
-
+
return true;
}
@@ -333,7 +333,7 @@ typedef struct tGPSB_Grab_StrokeData {
int *points;
/* array of influence weights for each of the included points */
float *weights;
-
+
/* capacity of the arrays */
int capacity;
/* actual number of items currently stored */
@@ -344,9 +344,9 @@ typedef struct tGPSB_Grab_StrokeData {
static void gp_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
{
tGPSB_Grab_StrokeData *data = NULL;
-
+
BLI_assert(gps->totpoints > 0);
-
+
/* Check if there are buffers already (from a prior run) */
if (BLI_ghash_haskey(gso->stroke_customdata, gps)) {
/* Ensure that the caches are empty
@@ -355,25 +355,25 @@ static void gp_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
*/
data = BLI_ghash_lookup(gso->stroke_customdata, gps);
BLI_assert(data != NULL);
-
+
data->size = 0; /* minimum requirement - so that we can repopulate again */
-
+
memset(data->points, 0, sizeof(int) * data->capacity);
memset(data->weights, 0, sizeof(float) * data->capacity);
}
else {
/* Create new instance */
data = MEM_callocN(sizeof(tGPSB_Grab_StrokeData), "GP Stroke Grab Data");
-
+
data->capacity = gps->totpoints;
data->size = 0;
-
+
data->points = MEM_callocN(sizeof(int) * data->capacity, "GP Stroke Grab Indices");
data->weights = MEM_callocN(sizeof(float) * data->capacity, "GP Stroke Grab Weights");
-
+
/* hook up to the cache */
BLI_ghash_insert(gso->stroke_customdata, gps, data);
- }
+ }
}
/* store references to stroke points in the initial stage */
@@ -382,15 +382,15 @@ static bool gp_brush_grab_store_points(tGP_BrushEditData *gso, bGPDstroke *gps,
{
tGPSB_Grab_StrokeData *data = BLI_ghash_lookup(gso->stroke_customdata, gps);
float inf = gp_brush_influence_calc(gso, radius, co);
-
+
BLI_assert(data != NULL);
BLI_assert(data->size < data->capacity);
-
+
/* insert this point into the set of affected points */
data->points[data->size] = i;
data->weights[data->size] = inf;
data->size++;
-
+
/* done */
return true;
}
@@ -406,13 +406,13 @@ static void gp_brush_grab_calc_dvec(tGP_BrushEditData *gso)
RegionView3D *rv3d = gso->ar->regiondata;
float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location;
float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
-
+
float mval_f[2];
-
+
/* convert from 2D screenspace to 3D... */
mval_f[0] = (float)(gso->mval[0] - gso->mval_prev[0]);
mval_f[1] = (float)(gso->mval[1] - gso->mval_prev[1]);
-
+
ED_view3d_win_to_delta(gso->ar, mval_f, gso->dvec, zfac);
}
else {
@@ -435,7 +435,7 @@ static void gp_brush_grab_apply_cached(
for (i = 0; i < data->size; i++) {
bGPDspoint *pt = &gps->points[data->points[i]];
float delta[3] = {0.0f};
-
+
/* adjust the amount of displacement to apply */
mul_v3_v3fl(delta, gso->dvec, data->weights[i]);
if (!parented) {
@@ -454,7 +454,7 @@ static void gp_brush_grab_apply_cached(
invert_m4_m4(inverse_diff_mat, diff_mat);
mul_m4_v3(inverse_diff_mat, &pt->x);
}
-
+
}
}
@@ -462,11 +462,11 @@ static void gp_brush_grab_apply_cached(
static void gp_brush_grab_stroke_free(void *ptr)
{
tGPSB_Grab_StrokeData *data = (tGPSB_Grab_StrokeData *)ptr;
-
+
/* free arrays */
MEM_freeN(data->points);
MEM_freeN(data->weights);
-
+
/* ... and this item itself, since it was also allocated */
MEM_freeN(data);
}
@@ -481,10 +481,10 @@ static bool gp_brush_push_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
bGPDspoint *pt = gps->points + i;
float inf = gp_brush_influence_calc(gso, radius, co);
float delta[3] = {0.0f};
-
+
/* adjust the amount of displacement to apply */
mul_v3_v3fl(delta, gso->dvec, inf);
-
+
/* apply */
add_v3_v3(&pt->x, delta);
@@ -506,12 +506,12 @@ static void gp_brush_calc_midpoint(tGP_BrushEditData *gso)
RegionView3D *rv3d = gso->ar->regiondata;
float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location;
float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
-
+
float mval_f[2] = {UNPACK2(gso->mval)};
float mval_prj[2];
float dvec[3];
-
-
+
+
if (ED_view3d_project_float_global(gso->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
sub_v2_v2v2(mval_f, mval_prj, mval_f);
ED_view3d_win_to_delta(gso->ar, mval_f, dvec, zfac);
@@ -537,17 +537,17 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
bGPDspoint *pt = gps->points + i;
float fac, inf;
float vec[3];
-
+
/* Scale down standard influence value to get it more manageable...
* - No damping = Unmanageable at > 0.5 strength
* - Div 10 = Not enough effect
* - Div 5 = Happy medium... (by trial and error)
*/
inf = gp_brush_influence_calc(gso, radius, co) / 5.0f;
-
+
/* 1) Make this point relative to the cursor/midpoint (dvec) */
sub_v3_v3v3(vec, &pt->x, gso->dvec);
-
+
/* 2) Shrink the distance by pulling the point towards the midpoint
* (0.0 = at midpoint, 1 = at edge of brush region)
* OR
@@ -562,10 +562,10 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
fac = 1.0f - (inf * inf); /* squared to temper the effect... */
}
mul_v3_fl(vec, fac);
-
+
/* 3) Translate back to original space, with the shrinkage applied */
add_v3_v3v3(&pt->x, gso->dvec, vec);
-
+
/* done */
return true;
}
@@ -582,16 +582,16 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
{
bGPDspoint *pt = gps->points + i;
float angle, inf;
-
+
/* Angle to rotate by */
inf = gp_brush_influence_calc(gso, radius, co);
angle = DEG2RADF(1.0f) * inf;
-
+
if (gp_brush_invert_check(gso)) {
/* invert angle that we rotate by */
angle *= -1;
}
-
+
/* Rotate in 2D or 3D space? */
if (gps->flag & GP_STROKE_3DSPACE) {
/* Perform rotation in 3D space... */
@@ -599,13 +599,13 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
float rmat[3][3];
float axis[3];
float vec[3];
-
+
/* Compute rotation matrix - rotate around view vector by angle */
negate_v3_v3(axis, rv3d->persinv[2]);
normalize_v3(axis);
-
+
axis_angle_normalized_to_mat3(rmat, axis, angle);
-
+
/* Rotate point (no matrix-space transforms needed, as GP points are in world space) */
sub_v3_v3v3(vec, &pt->x, gso->dvec); /* make relative to center (center is stored in dvec) */
mul_m3_v3(rmat, vec);
@@ -615,20 +615,20 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
const float axis[3] = {0.0f, 0.0f, 1.0f};
float vec[3] = {0.0f};
float rmat[3][3];
-
+
/* Express position of point relative to cursor, ready to rotate */
// XXX: There is still some offset here, but it's close to working as expected...
vec[0] = (float)(co[0] - gso->mval[0]);
vec[1] = (float)(co[1] - gso->mval[1]);
-
+
/* rotate point */
axis_angle_normalized_to_mat3(rmat, axis, angle);
mul_m3_v3(rmat, vec);
-
+
/* Convert back to screen-coordinates */
vec[0] += (float)gso->mval[0];
vec[1] += (float)gso->mval[1];
-
+
/* Map from screen-coordinates to final coordinate space */
if (gps->flag & GP_STROKE_2DSPACE) {
View2D *v2d = gso->gsc.v2d;
@@ -639,7 +639,7 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
copy_v2_v2(&pt->x, vec);
}
}
-
+
/* done */
return true;
}
@@ -653,7 +653,7 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
const int radius, const int co[2])
{
bGPDspoint *pt = gps->points + i;
-
+
/* Amount of jitter to apply depends on the distance of the point to the cursor,
* as well as the strength of the brush
*/
@@ -766,13 +766,13 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
typedef struct tGPSB_CloneBrushData {
/* midpoint of the strokes on the clipboard */
float buffer_midpoint[3];
-
+
/* number of strokes in the paste buffer (and/or to be created each time) */
size_t totitems;
-
+
/* for "stamp" mode, the currently pasted brushes */
bGPDstroke **new_strokes;
-
+
/* mapping from colors referenced per stroke, to the new colours in the "pasted" strokes */
GHash *new_colors;
} tGPSB_CloneBrushData;
@@ -782,43 +782,43 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data;
bGPDstroke *gps;
-
+
/* init custom data */
gso->customdata = data = MEM_callocN(sizeof(tGPSB_CloneBrushData), "CloneBrushData");
-
+
/* compute midpoint of strokes on clipboard */
for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
const float dfac = 1.0f / ((float)gps->totpoints);
float mid[3] = {0.0f};
-
+
bGPDspoint *pt;
int i;
-
+
/* compute midpoint of this stroke */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
float co[3];
-
+
mul_v3_v3fl(co, &pt->x, dfac);
add_v3_v3(mid, co);
}
-
+
/* combine this stroke's data with the main data */
add_v3_v3(data->buffer_midpoint, mid);
data->totitems++;
}
}
-
+
/* Divide the midpoint by the number of strokes, to finish averaging it */
if (data->totitems > 1) {
mul_v3_fl(data->buffer_midpoint, 1.0f / (float)data->totitems);
}
-
+
/* Create a buffer for storing the current strokes */
if (1 /*gso->brush->mode == GP_EDITBRUSH_CLONE_MODE_STAMP*/) {
data->new_strokes = MEM_callocN(sizeof(bGPDstroke *) * data->totitems, "cloned strokes ptr array");
}
-
+
/* Init colormap for mapping between the pasted stroke's source colour(names)
* and the final colours that will be used here instead...
*/
@@ -829,19 +829,19 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
static void gp_brush_clone_free(tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data = gso->customdata;
-
+
/* free strokes array */
if (data->new_strokes) {
MEM_freeN(data->new_strokes);
data->new_strokes = NULL;
}
-
+
/* free copybuf colormap */
if (data->new_colors) {
BLI_ghash_free(data->new_colors, NULL, NULL);
data->new_colors = NULL;
}
-
+
/* free the customdata itself */
MEM_freeN(data);
gso->customdata = NULL;
@@ -851,44 +851,44 @@ static void gp_brush_clone_free(tGP_BrushEditData *gso)
static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data = gso->customdata;
-
+
Scene *scene = gso->scene;
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
bGPDstroke *gps;
-
+
float delta[3];
size_t strokes_added = 0;
-
+
/* Compute amount to offset the points by */
/* NOTE: This assumes that screenspace strokes are NOT used in the 3D view... */
-
+
gp_brush_calc_midpoint(gso); /* this puts the cursor location into gso->dvec */
sub_v3_v3v3(delta, gso->dvec, data->buffer_midpoint);
-
+
/* Copy each stroke into the layer */
for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
bGPDstroke *new_stroke;
bGPDspoint *pt;
int i;
-
+
/* Make a new stroke */
new_stroke = MEM_dupallocN(gps);
-
+
new_stroke->points = MEM_dupallocN(gps->points);
new_stroke->triangles = MEM_dupallocN(gps->triangles);
-
+
new_stroke->next = new_stroke->prev = NULL;
BLI_addtail(&gpf->strokes, new_stroke);
-
+
/* Fix color references */
BLI_assert(new_stroke->colorname[0] != '\0');
new_stroke->palcolor = BLI_ghash_lookup(data->new_colors, new_stroke->colorname);
-
+
BLI_assert(new_stroke->palcolor != NULL);
BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
-
+
/* Adjust all the stroke's points, so that the strokes
* get pasted relative to where the cursor is now
*/
@@ -896,7 +896,7 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
/* assume that the delta can just be applied, and then everything works */
add_v3_v3(&pt->x, delta);
}
-
+
/* Store ref for later */
if ((data->new_strokes) && (strokes_added < data->totitems)) {
data->new_strokes[strokes_added] = new_stroke;
@@ -911,31 +911,31 @@ static void gp_brush_clone_adjust(tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data = gso->customdata;
size_t snum;
-
+
/* Compute the amount of movement to apply (overwrites dvec) */
gp_brush_grab_calc_dvec(gso);
-
+
/* For each of the stored strokes, apply the offset to each point */
/* NOTE: Again this assumes that in the 3D view, we only have 3d space and not screenspace strokes... */
for (snum = 0; snum < data->totitems; snum++) {
bGPDstroke *gps = data->new_strokes[snum];
bGPDspoint *pt;
int i;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (gso->brush->flag & GP_EDITBRUSH_FLAG_USE_FALLOFF) {
/* "Smudge" Effect when falloff is enabled */
float delta[3] = {0.0f};
int sco[2] = {0};
float influence;
-
+
/* compute influence on point */
gp_point_to_xy(&gso->gsc, gps, pt, &sco[0], &sco[1]);
influence = gp_brush_influence_calc(gso, gso->brush->size, sco);
-
+
/* adjust the amount of displacement to apply */
mul_v3_v3fl(delta, gso->dvec, influence);
-
+
/* apply */
add_v3_v3(&pt->x, delta);
}
@@ -967,7 +967,7 @@ static bool gpsculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso)
gp_brush_clone_add(C, gso);
}
}
-
+
return true;
}
@@ -1007,7 +1007,7 @@ static void gp_brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customda
static void gpencil_toggle_brush_cursor(bContext *C, bool enable)
{
GP_BrushEdit_Settings *gset = gpsculpt_get_settings(CTX_data_scene(C));
-
+
if (gset->paintcursor && !enable) {
/* clear cursor */
WM_paint_cursor_end(CTX_wm_manager(C), gset->paintcursor);
@@ -1015,8 +1015,8 @@ static void gpencil_toggle_brush_cursor(bContext *C, bool enable)
}
else if (enable) {
/* enable cursor */
- gset->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C),
- NULL,
+ gset->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ NULL,
gp_brush_drawcursor, NULL);
}
}
@@ -1029,15 +1029,15 @@ static void gpsculpt_brush_header_set(bContext *C, tGP_BrushEditData *gso)
{
const char *brush_name = NULL;
char str[UI_MAX_DRAW_STR] = "";
-
+
RNA_enum_name(rna_enum_gpencil_sculpt_brush_items, gso->brush_type, &brush_name);
-
+
BLI_snprintf(str, sizeof(str),
IFACE_("GPencil Sculpt: %s Stroke | LMB to paint | RMB/Escape to Exit"
" | Ctrl to Invert Action | Wheel Up/Down for Size "
" | Shift-Wheel Up/Down for Strength"),
(brush_name) ? brush_name : "<?>");
-
+
ED_area_headerprint(CTX_wm_area(C), str);
}
@@ -1050,36 +1050,36 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
tGP_BrushEditData *gso;
-
+
/* setup operator data */
gso = MEM_callocN(sizeof(tGP_BrushEditData), "tGP_BrushEditData");
op->customdata = gso;
-
+
/* store state */
gso->settings = gpsculpt_get_settings(scene);
gso->brush = gpsculpt_get_brush(scene);
-
+
gso->brush_type = gso->settings->brushtype;
-
-
+
+
gso->is_painting = false;
gso->first = true;
-
+
gso->gpd = ED_gpencil_data_get_active(C);
gso->cfra = INT_MAX; /* NOTE: So that first stroke will get handled in init_stroke() */
-
+
gso->scene = scene;
-
+
gso->sa = CTX_wm_area(C);
gso->ar = CTX_wm_region(C);
-
+
/* initialise custom data for brushes */
switch (gso->brush_type) {
case GP_EDITBRUSH_TYPE_CLONE:
{
bGPDstroke *gps;
bool found = false;
-
+
/* check that there are some usable strokes in the buffer */
for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
@@ -1087,12 +1087,12 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
break;
}
}
-
+
if (found == false) {
/* STOP HERE! Nothing to paste! */
- BKE_report(op->reports, RPT_ERROR,
+ BKE_report(op->reports, RPT_ERROR,
"Copy some strokes to the clipboard before using the Clone brush to paste copies of them");
-
+
MEM_freeN(gso);
op->customdata = NULL;
return false;
@@ -1103,30 +1103,30 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
}
break;
}
-
+
case GP_EDITBRUSH_TYPE_GRAB:
{
/* initialise the cache needed for this brush */
gso->stroke_customdata = BLI_ghash_ptr_new("GP Grab Brush - Strokes Hash");
break;
}
-
+
/* Others - No customdata needed */
default:
break;
}
-
-
+
+
/* setup space conversions */
gp_point_conversion_init(C, &gso->gsc);
-
+
/* update header */
gpsculpt_brush_header_set(C, gso);
-
+
/* setup cursor drawing */
WM_cursor_modal_set(CTX_wm_window(C), BC_CROSSCURSOR);
gpencil_toggle_brush_cursor(C, true);
-
+
return true;
}
@@ -1134,7 +1134,7 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
{
tGP_BrushEditData *gso = op->customdata;
wmWindow *win = CTX_wm_window(C);
-
+
/* free brush-specific data */
switch (gso->brush_type) {
case GP_EDITBRUSH_TYPE_GRAB:
@@ -1146,18 +1146,18 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
BLI_ghash_free(gso->stroke_customdata, NULL, gp_brush_grab_stroke_free);
break;
}
-
+
case GP_EDITBRUSH_TYPE_CLONE:
{
/* Free customdata */
gp_brush_clone_free(gso);
break;
}
-
+
default:
break;
}
-
+
/* unregister timer (only used for realtime) */
if (gso->timer) {
WM_event_remove_timer(CTX_wm_manager(C), win, gso->timer);
@@ -1167,7 +1167,7 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
ED_area_headerprint(CTX_wm_area(C), NULL);
WM_cursor_modal_restore(win);
gpencil_toggle_brush_cursor(C, false);
-
+
/* free operator data */
MEM_freeN(gso);
op->customdata = NULL;
@@ -1188,18 +1188,18 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
bGPdata *gpd = gso->gpd;
bGPDlayer *gpl;
int cfra = CFRA;
-
+
/* only try to add a new frame if this is the first stroke, or the frame has changed */
if ((gpd == NULL) || (cfra == gso->cfra))
return;
-
+
/* go through each layer, and ensure that we've got a valid frame to use */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* only editable and visible layers are considered */
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
bGPDframe *gpf = gpl->actframe;
-
- /* Make a new frame to work on if the layer's frame and the current scene frame don't match up
+
+ /* Make a new frame to work on if the layer's frame and the current scene frame don't match up
* - This is useful when animating as it saves that "uh-oh" moment when you realize you've
* spent too much time editing the wrong frame...
*/
@@ -1209,7 +1209,7 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
}
}
}
-
+
/* save off new current frame, so that next update works fine */
gso->cfra = cfra;
}
@@ -1224,7 +1224,7 @@ static bool gpsculpt_brush_do_stroke(
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
const int radius = gso->brush->size;
-
+
bGPDspoint *pt1, *pt2;
int pc1[2] = {0};
int pc2[2] = {0};
@@ -1241,7 +1241,7 @@ static bool gpsculpt_brush_do_stroke(
gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
}
-
+
/* do boundbox check first */
if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
@@ -1252,14 +1252,14 @@ static bool gpsculpt_brush_do_stroke(
}
}
else {
- /* Loop over the points in the stroke, checking for intersections
+ /* Loop over the points in the stroke, checking for intersections
* - an intersection means that we touched the stroke
*/
for (i = 0; (i + 1) < gps->totpoints; i++) {
/* Get points to work with */
pt1 = gps->points + i;
pt2 = gps->points + i + 1;
-
+
/* Skip if neither one is selected (and we are only allowed to edit/consider selected points) */
if (gso->settings->flag & GP_BRUSHEDIT_FLAG_SELECT_MASK) {
if (!(pt1->flag & GP_SPOINT_SELECT) && !(pt2->flag & GP_SPOINT_SELECT)) {
@@ -1292,14 +1292,14 @@ static bool gpsculpt_brush_do_stroke(
if (gp_stroke_inside_circle(gso->mval, gso->mval_prev, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
/* Apply operation to these points */
bool ok = false;
-
+
/* To each point individually... */
ok = apply(gso, gps, i, radius, pc1);
-
+
/* Only do the second point if this is the last segment,
* and it is unlikely that the point will get handled
- * otherwise.
- *
+ * otherwise.
+ *
* NOTE: There is a small risk here that the second point wasn't really
* actually in-range. In that case, it only got in because
* the line linking the points was!
@@ -1311,13 +1311,13 @@ static bool gpsculpt_brush_do_stroke(
else {
include_last = true;
}
-
+
changed |= ok;
}
else if (include_last) {
/* This case is for cases where for whatever reason the second vert (1st here) doesn't get included
* because the whole edge isn't in bounds, but it would've qualified since it did with the
- * previous step (but wasn't added then, to avoid double-ups)
+ * previous step (but wasn't added then, to avoid double-ups)
*/
changed |= apply(gso, gps, i, radius, pc1);
include_last = false;
@@ -1325,7 +1325,7 @@ static bool gpsculpt_brush_do_stroke(
}
}
}
-
+
return changed;
}
@@ -1333,7 +1333,7 @@ static bool gpsculpt_brush_do_stroke(
static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
{
bool changed = false;
-
+
/* Calculate brush-specific data which applies equally to all points */
switch (gso->brush_type) {
case GP_EDITBRUSH_TYPE_GRAB: /* Grab points */
@@ -1343,7 +1343,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
gp_brush_grab_calc_dvec(gso);
break;
}
-
+
case GP_EDITBRUSH_TYPE_PINCH: /* Pinch points */
case GP_EDITBRUSH_TYPE_TWIST: /* Twist points around midpoint */
{
@@ -1351,19 +1351,19 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
gp_brush_calc_midpoint(gso);
break;
}
-
+
case GP_EDITBRUSH_TYPE_RANDOMIZE: /* Random jitter */
{
/* compute the displacement vector for the cursor (in data space) */
gp_brush_grab_calc_dvec(gso);
break;
}
-
+
default:
break;
}
-
-
+
+
/* Find visible strokes, and perform operations on those if hit */
float diff_mat[4][4];
bool parented = false;
@@ -1373,7 +1373,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
bGPDframe *gpf = gpl->actframe;
if (gpf == NULL)
continue;
-
+
/* calculate difference matrix if parent object */
if (gpl->parent != NULL) {
ED_gpencil_parent_location(gpl, diff_mat);
@@ -1382,7 +1382,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
else {
parented = false;
}
-
+
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
@@ -1477,34 +1477,34 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt
float mousef[2];
int mouse[2];
bool changed = false;
-
+
/* Get latest mouse coordinates */
RNA_float_get_array(itemptr, "mouse", mousef);
gso->mval[0] = mouse[0] = (int)(mousef[0]);
gso->mval[1] = mouse[1] = (int)(mousef[1]);
-
+
gso->pressure = RNA_float_get(itemptr, "pressure");
-
+
if (RNA_boolean_get(itemptr, "pen_flip"))
gso->flag |= GP_EDITBRUSH_FLAG_INVERT;
else
gso->flag &= ~GP_EDITBRUSH_FLAG_INVERT;
-
-
+
+
/* Store coordinates as reference, if operator just started running */
if (gso->first) {
gso->mval_prev[0] = gso->mval[0];
gso->mval_prev[1] = gso->mval[1];
gso->pressure_prev = gso->pressure;
}
-
+
/* Update brush_rect, so that it represents the bounding rectangle of brush */
gso->brush_rect.xmin = mouse[0] - radius;
gso->brush_rect.ymin = mouse[1] - radius;
gso->brush_rect.xmax = mouse[0] + radius;
gso->brush_rect.ymax = mouse[1] + radius;
-
-
+
+
/* Apply brush */
if (gso->brush_type == GP_EDITBRUSH_TYPE_CLONE) {
changed = gpsculpt_brush_apply_clone(C, gso);
@@ -1512,13 +1512,13 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt
else {
changed = gpsculpt_brush_apply_standard(C, gso);
}
-
-
+
+
/* Updates */
if (changed) {
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
-
+
/* Store values for next step */
gso->mval_prev[0] = gso->mval[0];
gso->mval_prev[1] = gso->mval[1];
@@ -1535,24 +1535,24 @@ static void gpsculpt_brush_apply_event(bContext *C, wmOperator *op, const wmEven
PointerRNA itemptr;
float mouse[2];
int tablet = 0;
-
+
mouse[0] = event->mval[0] + 1;
mouse[1] = event->mval[1] + 1;
-
+
/* fill in stroke */
RNA_collection_add(op->ptr, "stroke", &itemptr);
-
+
RNA_float_set_array(&itemptr, "mouse", mouse);
RNA_boolean_set(&itemptr, "pen_flip", event->ctrl != false);
RNA_boolean_set(&itemptr, "is_start", gso->first);
-
+
/* handle pressure sensitivity (which is supplied by tablets) */
if (event->tablet_data) {
const wmTabletData *wmtab = event->tablet_data;
float pressure = wmtab->Pressure;
-
+
tablet = (wmtab->Active != EVT_TABLET_NONE);
-
+
/* special exception here for too high pressure values on first touch in
* windows for some tablets: clamp the values to be sane
*/
@@ -1564,7 +1564,7 @@ static void gpsculpt_brush_apply_event(bContext *C, wmOperator *op, const wmEven
else {
RNA_float_set(&itemptr, "pressure", 1.0f);
}
-
+
/* apply */
gpsculpt_brush_apply(C, op, &itemptr);
}
@@ -1574,15 +1574,15 @@ static int gpsculpt_brush_exec(bContext *C, wmOperator *op)
{
if (!gpsculpt_brush_init(C, op))
return OPERATOR_CANCELLED;
-
- RNA_BEGIN(op->ptr, itemptr, "stroke")
+
+ RNA_BEGIN(op->ptr, itemptr, "stroke")
{
gpsculpt_brush_apply(C, op, &itemptr);
}
RNA_END;
-
+
gpsculpt_brush_exit(C, op);
-
+
return OPERATOR_FINISHED;
}
@@ -1594,13 +1594,13 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
bool needs_timer = false;
float brush_rate = 0.0f;
-
+
/* init painting data */
if (!gpsculpt_brush_init(C, op))
return OPERATOR_CANCELLED;
-
+
gso = op->customdata;
-
+
/* initialise type-specific data (used for the entire session) */
switch (gso->brush_type) {
/* Brushes requiring timer... */
@@ -1608,7 +1608,7 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
brush_rate = 0.01f; // XXX: hardcoded
needs_timer = true;
break;
-
+
case GP_EDITBRUSH_TYPE_STRENGTH:
brush_rate = 0.01f; // XXX: hardcoded
needs_timer = true;
@@ -1618,39 +1618,39 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
brush_rate = 0.001f; // XXX: hardcoded
needs_timer = true;
break;
-
+
case GP_EDITBRUSH_TYPE_TWIST:
brush_rate = 0.01f; // XXX: hardcoded
needs_timer = true;
break;
-
+
default:
break;
}
-
+
/* register timer for increasing influence by hovering over an area */
if (needs_timer) {
gso->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, brush_rate);
}
-
+
/* register modal handler */
WM_event_add_modal_handler(C, op);
-
+
/* start drawing immediately? */
if (is_modal == false) {
ARegion *ar = CTX_wm_region(C);
-
+
/* ensure that we'll have a new frame to draw on */
gpsculpt_brush_init_stroke(gso);
-
+
/* apply first dab... */
gso->is_painting = true;
gpsculpt_brush_apply_event(C, op, event);
-
+
/* redraw view with feedback */
ED_region_tag_redraw(ar);
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -1661,7 +1661,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
bool redraw_region = false;
bool redraw_toolsettings = false;
-
+
/* The operator can be in 2 states: Painting and Idling */
if (gso->is_painting) {
/* Painting */
@@ -1671,11 +1671,11 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
case INBETWEEN_MOUSEMOVE:
/* apply brush effect at new position */
gpsculpt_brush_apply_event(C, op, event);
-
+
/* force redraw, so that the cursor will at least be valid */
redraw_region = true;
break;
-
+
/* Timer Tick - Only if this was our own timer */
case TIMER:
if (event->customdata == gso->timer) {
@@ -1684,7 +1684,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
gso->timerTick = false;
}
break;
-
+
/* Adjust brush settings */
/* FIXME: Step increments and modifier keys are hardcoded here! */
case WHEELUPMOUSE:
@@ -1699,12 +1699,12 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
gso->brush->size += 3;
CLAMP_MAX(gso->brush->size, 300);
}
-
+
redraw_region = true;
redraw_toolsettings = true;
break;
-
- case WHEELDOWNMOUSE:
+
+ case WHEELDOWNMOUSE:
case PADMINUS:
if (event->shift) {
/* decrease strength */
@@ -1716,11 +1716,11 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
gso->brush->size -= 3;
CLAMP_MIN(gso->brush->size, 1);
}
-
+
redraw_region = true;
redraw_toolsettings = true;
break;
-
+
/* Painting mbut release = Stop painting (back to idle) */
case LEFTMOUSE:
//BLI_assert(event->val == KM_RELEASE);
@@ -1731,12 +1731,12 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
else {
/* end sculpt session, since we're not modal */
gso->is_painting = false;
-
+
gpsculpt_brush_exit(C, op);
return OPERATOR_FINISHED;
}
break;
-
+
/* Abort painting if any of the usual things are tried */
case MIDDLEMOUSE:
case RIGHTMOUSE:
@@ -1748,34 +1748,34 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
else {
/* Idling */
BLI_assert(is_modal == true);
-
+
switch (event->type) {
/* Painting mbut press = Start painting (switch to painting state) */
case LEFTMOUSE:
/* do initial "click" apply */
gso->is_painting = true;
gso->first = true;
-
+
gpsculpt_brush_init_stroke(gso);
gpsculpt_brush_apply_event(C, op, event);
break;
-
+
/* Exit modal operator, based on the "standard" ops */
case RIGHTMOUSE:
case ESCKEY:
gpsculpt_brush_exit(C, op);
return OPERATOR_FINISHED;
-
+
/* MMB is often used for view manipulations */
case MIDDLEMOUSE:
return OPERATOR_PASS_THROUGH;
-
+
/* Mouse movements should update the brush cursor - Just redraw the active region */
case MOUSEMOVE:
case INBETWEEN_MOUSEMOVE:
redraw_region = true;
break;
-
+
/* Adjust brush settings */
/* FIXME: Step increments and modifier keys are hardcoded here! */
case WHEELUPMOUSE:
@@ -1790,12 +1790,12 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
gso->brush->size += 3;
CLAMP_MAX(gso->brush->size, 300);
}
-
+
redraw_region = true;
redraw_toolsettings = true;
break;
-
- case WHEELDOWNMOUSE:
+
+ case WHEELDOWNMOUSE:
case PADMINUS:
if (event->shift) {
/* decrease strength */
@@ -1807,41 +1807,41 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
gso->brush->size -= 3;
CLAMP_MIN(gso->brush->size, 1);
}
-
+
redraw_region = true;
redraw_toolsettings = true;
break;
-
+
/* Change Frame - Allowed */
case LEFTARROWKEY:
case RIGHTARROWKEY:
case UPARROWKEY:
case DOWNARROWKEY:
return OPERATOR_PASS_THROUGH;
-
+
/* Camera/View Manipulations - Allowed */
/* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */
case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
return OPERATOR_PASS_THROUGH;
-
+
/* Unhandled event */
default:
break;
}
}
-
+
/* Redraw region? */
if (redraw_region) {
ARegion *ar = CTX_wm_region(C);
ED_region_tag_redraw(ar);
}
-
+
/* Redraw toolsettings (brush settings)? */
if (redraw_toolsettings) {
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -1854,7 +1854,7 @@ void GPENCIL_OT_brush_paint(wmOperatorType *ot)
ot->name = "Stroke Sculpt";
ot->idname = "GPENCIL_OT_brush_paint";
ot->description = "Apply tweaks to strokes by painting over the strokes"; // XXX
-
+
/* api callbacks */
ot->exec = gpsculpt_brush_exec;
ot->invoke = gpsculpt_brush_invoke;
@@ -1869,7 +1869,7 @@ void GPENCIL_OT_brush_paint(wmOperatorType *ot)
PropertyRNA *prop;
prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
-
+
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input",
"Enter a mini 'sculpt-mode' if enabled, otherwise, exit after drawing a single stroke");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index e503b35d878..dfaa1420d68 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -66,6 +66,7 @@
#include "BKE_gpencil.h"
#include "BKE_layer.h"
#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -179,7 +180,7 @@ static void gp_strokepoint_convertcoords(
else {
const float *fp = ED_view3d_cursor3d_get(scene, v3d)->location;
float mvalf[2];
-
+
/* get screen coordinate */
if (gps->flag & GP_STROKE_2DSPACE) {
View2D *v2d = &ar->v2d;
@@ -195,7 +196,7 @@ static void gp_strokepoint_convertcoords(
mvalf[1] = (float)pt->y / 100.0f * ar->winy;
}
}
-
+
ED_view3d_win_to_3d(v3d, ar, fp, mvalf, p3d);
}
}
@@ -211,19 +212,19 @@ typedef struct tGpTimingData {
bool realtime; /* Will overwrite end_frame in case of Original or CustomGap timing... */
float gap_duration, gap_randomness; /* To be used with CustomGap mode*/
int seed;
-
+
/* Data set from points, used to compute final timing FCurve */
int num_points, cur_point;
-
+
/* Distances */
float *dists;
float tot_dist;
-
+
/* Times */
float *times; /* Note: Gap times will be negative! */
float tot_time, gap_tot_time;
double inittime;
-
+
/* Only used during creation of dists & times lists. */
float offset_time;
} tGpTimingData;
@@ -234,9 +235,9 @@ typedef struct tGpTimingData {
static void gp_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
{
float *tmp;
-
+
BLI_assert(nbr > gtd->num_points);
-
+
/* distances */
tmp = gtd->dists;
gtd->dists = MEM_callocN(sizeof(float) * nbr, __func__);
@@ -244,7 +245,7 @@ static void gp_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
memcpy(gtd->dists, tmp, sizeof(float) * gtd->num_points);
MEM_freeN(tmp);
}
-
+
/* times */
tmp = gtd->times;
gtd->times = MEM_callocN(sizeof(float) * nbr, __func__);
@@ -252,7 +253,7 @@ static void gp_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
memcpy(gtd->times, tmp, sizeof(float) * gtd->num_points);
MEM_freeN(tmp);
}
-
+
gtd->num_points = nbr;
}
@@ -262,7 +263,7 @@ static void gp_timing_data_add_point(tGpTimingData *gtd, const double stroke_ini
{
float delta_time = 0.0f;
const int cur_point = gtd->cur_point;
-
+
if (!cur_point) {
/* Special case, first point, if time is not 0.0f we have to compensate! */
gtd->offset_time = -time;
@@ -272,18 +273,18 @@ static void gp_timing_data_add_point(tGpTimingData *gtd, const double stroke_ini
/* This is a gap, negative value! */
gtd->times[cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time + gtd->offset_time);
delta_time = -gtd->times[cur_point] - gtd->times[cur_point - 1];
-
+
gtd->gap_tot_time += delta_time;
}
else {
gtd->times[cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time + gtd->offset_time);
delta_time = gtd->times[cur_point] - fabsf(gtd->times[cur_point - 1]);
}
-
+
gtd->tot_time += delta_time;
gtd->tot_dist += delta_dist;
gtd->dists[cur_point] = gtd->tot_dist;
-
+
gtd->cur_point++;
}
@@ -298,7 +299,7 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, RNG *rng, const int idx
float *next_delta_time)
{
int j;
-
+
for (j = idx + 1; j < gtd->num_points; j++) {
if (gtd->times[j] < 0) {
gtd->times[j] = -gtd->times[j];
@@ -317,16 +318,16 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, RNG *rng, const int idx
}
else {
float delta, min, max;
-
+
/* This code ensures that if the first gaps have been shorter than average gap_duration,
* next gaps will tend to be longer (i.e. try to recover the lateness), and vice-versa!
*/
delta = delta_time - (gtd->gap_duration * (*nbr_done_gaps));
-
+
/* Clamp min between [-gap_randomness, 0.0], with lower delta giving higher min */
min = -gtd->gap_randomness - delta;
CLAMP(min, -gtd->gap_randomness, 0.0f);
-
+
/* Clamp max between [0.0, gap_randomness], with lower delta giving higher max */
max = gtd->gap_randomness - delta;
CLAMP(max, 0.0f, gtd->gap_randomness);
@@ -341,7 +342,7 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, RNG *rng, const int idx
break;
}
}
-
+
return j - 1;
}
@@ -349,7 +350,7 @@ static void gp_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, RNG *rn
{
int i;
float delta_time = 0.0f;
-
+
for (i = 0; i < gtd->num_points; i++) {
if (gtd->times[i] < 0 && i) {
(*nbr_gaps)++;
@@ -362,7 +363,7 @@ static void gp_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, RNG *rn
}
}
gtd->tot_time -= delta_time;
-
+
*tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration;
gtd->tot_time += *tot_gaps_time;
if (G.debug & G_DEBUG) {
@@ -379,18 +380,18 @@ static void gp_stroke_path_animation_add_keyframes(Depsgraph *depsgraph, ReportL
{
/* Use actual recorded timing! */
const float time_start = (float)gtd->start_frame;
-
+
float last_valid_time = 0.0f;
int end_stroke_idx = -1, start_stroke_idx = 0;
float end_stroke_time = 0.0f;
-
+
/* CustomGaps specific */
float delta_time = 0.0f, next_delta_time = 0.0f;
int nbr_done_gaps = 0;
-
+
int i;
float cfra;
-
+
/* This is a bit tricky, as:
* - We can't add arbitrarily close points on FCurve (in time).
* - We *must* have all "caps" points of all strokes in FCurve, as much as possible!
@@ -406,11 +407,11 @@ static void gp_stroke_path_animation_add_keyframes(Depsgraph *depsgraph, ReportL
/* This one should *never* be negative! */
end_stroke_time = time_start + ((gtd->times[end_stroke_idx] + delta_time) / gtd->tot_time * time_range);
}
-
+
/* Simple proportional stuff... */
cu->ctime = gtd->dists[i] / gtd->tot_dist * cu->pathlen;
cfra = time_start + ((gtd->times[i] + delta_time) / gtd->tot_time * time_range);
-
+
/* And now, the checks about timing... */
if (i == start_stroke_idx) {
/* If first point of a stroke, be sure it's enough ahead of last valid keyframe, and
@@ -456,49 +457,50 @@ static void gp_stroke_path_animation_add_keyframes(Depsgraph *depsgraph, ReportL
static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu, tGpTimingData *gtd)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
bAction *act;
FCurve *fcu;
PointerRNA ptr;
PropertyRNA *prop = NULL;
int nbr_gaps = 0, i;
-
+
if (gtd->mode == GP_STROKECONVERT_TIMING_NONE)
return;
-
+
/* gap_duration and gap_randomness are in frames, but we need seconds!!! */
gtd->gap_duration = FRA2TIME(gtd->gap_duration);
gtd->gap_randomness = FRA2TIME(gtd->gap_randomness);
-
+
/* Enable path! */
cu->flag |= CU_PATH;
cu->pathlen = gtd->frame_range;
-
+
/* Get RNA pointer to read/write path time values */
RNA_id_pointer_create((ID *)cu, &ptr);
prop = RNA_struct_find_property(&ptr, "eval_time");
-
+
/* Ensure we have an F-Curve to add keyframes to */
- act = verify_adt_action((ID *)cu, true);
+ act = verify_adt_action(bmain, (ID *)cu, true);
fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, true);
-
+
if (G.debug & G_DEBUG) {
printf("%s: tot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
for (i = 0; i < gtd->num_points; i++) {
printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]);
}
}
-
+
if (gtd->mode == GP_STROKECONVERT_TIMING_LINEAR) {
float cfra;
-
+
/* Linear extrapolation! */
fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
-
+
cu->ctime = 0.0f;
cfra = (float)gtd->start_frame;
insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
-
+
cu->ctime = cu->pathlen;
if (gtd->realtime) {
cfra += (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
@@ -512,35 +514,35 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
/* Use actual recorded timing! */
RNG *rng = BLI_rng_new(0);
float time_range;
-
+
/* CustomGaps specific */
float tot_gaps_time = 0.0f;
-
+
/* Pre-process gaps, in case we don't want to keep their original timing */
if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
gp_stroke_path_animation_preprocess_gaps(gtd, rng, &nbr_gaps, &tot_gaps_time);
}
-
+
if (gtd->realtime) {
time_range = (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
}
else {
time_range = (float)(gtd->end_frame - gtd->start_frame);
}
-
+
if (G.debug & G_DEBUG) {
printf("GP Stroke Path Conversion: Starting keying!\n");
}
-
+
gp_stroke_path_animation_add_keyframes(depsgraph, reports, ptr, prop, fcu, cu, gtd, rng, time_range,
nbr_gaps, tot_gaps_time);
-
+
BLI_rng_free(rng);
}
-
+
/* As we used INSERTKEY_FAST mode, we need to recompute all curve's handles now */
calchandles_fcurve(fcu);
-
+
if (G.debug & G_DEBUG) {
printf("%s: \ntot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
for (i = 0; i < gtd->num_points; i++) {
@@ -548,9 +550,9 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
}
printf("\n\n");
}
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
/* send updates */
DEG_id_tag_update(&cu->id, 0);
}
@@ -570,7 +572,7 @@ static void gp_stroke_to_path_add_point(tGpTimingData *gtd, BPoint *bp, const fl
{
copy_v3_v3(bp->vec, p);
bp->vec[3] = 1.0f;
-
+
/* set settings */
bp->f1 = SELECT;
bp->radius = width * rad_fac;
@@ -582,7 +584,7 @@ static void gp_stroke_to_path_add_point(tGpTimingData *gtd, BPoint *bp, const fl
else if (bp->weight > minmax_weights[1]) {
minmax_weights[1] = bp->weight;
}
-
+
/* Update timing data */
if (do_gtd) {
gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p));
@@ -599,7 +601,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
const bool do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
const int add_start_end_points = (add_start_point ? 1 : 0) + (add_end_point ? 1 : 0);
int i, old_nbp = 0;
-
+
/* create new 'nurb' or extend current one within the curve */
if (nu) {
old_nbp = nu->pntsu;
@@ -611,7 +613,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
}
else {
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)");
-
+
nu->pntsu = gps->totpoints + add_start_end_points;
nu->pntsv = 1;
nu->orderu = 2; /* point-to-point! */
@@ -620,16 +622,16 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
nu->resolu = cu->resolu;
nu->resolv = cu->resolv;
nu->knotsu = NULL;
-
+
nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * nu->pntsu, "bpoints");
-
+
stitch = false; /* Security! */
}
-
+
if (do_gtd) {
gp_timing_data_set_nbr(gtd, nu->pntsu);
}
-
+
/* If needed, make the link between both strokes with two zero-radius additional points */
/* About "zero-radius" point interpolations:
* - If we have at least two points in current curve (most common case), we linearly extrapolate
@@ -642,16 +644,16 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
if (curnu && !stitch && old_nbp) {
float p1[3], p2[3], p[3], next_p[3];
float dt1 = 0.0f, dt2 = 0.0f;
-
+
BLI_assert(gps->prev != NULL);
-
+
prev_bp = NULL;
if ((old_nbp > 1) && (gps->prev->totpoints > 1)) {
/* Only use last curve segment if previous stroke was not a single-point one! */
prev_bp = &nu->bp[old_nbp - 2];
}
bp = &nu->bp[old_nbp - 1];
-
+
/* First point */
gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
if (prev_bp) {
@@ -670,7 +672,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
bp++;
gp_stroke_to_path_add_point(gtd, bp, p1, (bp - 1)->vec, do_gtd, gps->prev->inittime, dt1,
0.0f, rad_fac, minmax_weights);
-
+
/* Second point */
/* Note dt2 is always negative, which marks the gap. */
if (gps->totpoints > 1) {
@@ -688,13 +690,13 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
}
bp++;
gp_stroke_to_path_add_point(gtd, bp, p2, p1, do_gtd, gps->inittime, dt2, 0.0f, rad_fac, minmax_weights);
-
+
old_nbp += 2;
}
else if (add_start_point) {
float p[3], next_p[3];
float dt = 0.0f;
-
+
gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
if (gps->totpoints > 1) {
gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
@@ -712,14 +714,14 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
* would not work (it would be *before* gtd->inittime, which is not supported currently).
*/
gp_stroke_to_path_add_point(gtd, bp, p, p, do_gtd, gps->inittime, dt, 0.0f, rad_fac, minmax_weights);
-
+
old_nbp++;
}
-
+
if (old_nbp) {
prev_bp = &nu->bp[old_nbp - 1];
}
-
+
/* add points */
for (i = (stitch) ? 1 : 0, pt = &gps->points[(stitch) ? 1 : 0], bp = &nu->bp[old_nbp];
i < gps->totpoints;
@@ -727,20 +729,20 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
{
float p[3];
float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC;
-
+
/* get coordinates to add at */
gp_strokepoint_convertcoords(C, gpl, gps, pt, p, subrect);
-
+
gp_stroke_to_path_add_point(gtd, bp, p, (prev_bp) ? prev_bp->vec : p, do_gtd, gps->inittime, pt->time,
width, rad_fac, minmax_weights);
-
+
prev_bp = bp;
}
if (add_end_point) {
float p[3];
float dt = 0.0f;
-
+
if (gps->totpoints > 1) {
interp_v3_v3v3(p, prev_bp->vec, (prev_bp - 1)->vec, -GAP_DFAC);
if (do_gtd) {
@@ -756,7 +758,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
/* Note bp has already been incremented in main loop above, so it points to the right place. */
gp_stroke_to_path_add_point(gtd, bp, p, prev_bp->vec, do_gtd, gps->inittime, dt, 0.0f, rad_fac, minmax_weights);
}
-
+
/* add nurb to curve */
if (!curnu || !*curnu) {
BLI_addtail(&cu->nurb, nu);
@@ -764,7 +766,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
if (curnu) {
*curnu = nu;
}
-
+
BKE_nurb_knot_calc_u(nu);
}
@@ -779,7 +781,7 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd, BezTriple *bezt,
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p);
copy_v3_v3(bezt->vec[2], h2);
-
+
/* set settings */
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
@@ -792,7 +794,7 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd, BezTriple *bezt,
else if (bezt->weight > minmax_weights[1]) {
minmax_weights[1] = bezt->weight;
}
-
+
/* Update timing data */
if (do_gtd) {
gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p));
@@ -810,7 +812,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
const int add_start_end_points = (add_start_point ? 1 : 0) + (add_end_point ? 1 : 0);
float p3d_cur[3], p3d_prev[3], p3d_next[3], h1[3], h2[3];
const bool do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
-
+
/* create new 'nurb' or extend current one within the curve */
if (nu) {
old_nbezt = nu->pntsu;
@@ -822,22 +824,22 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
}
else {
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
-
+
nu->pntsu = gps->totpoints + add_start_end_points;
nu->resolu = 12;
nu->resolv = 12;
nu->type = CU_BEZIER;
nu->bezt = (BezTriple *)MEM_callocN(sizeof(BezTriple) * nu->pntsu, "bezts");
-
+
stitch = false; /* Security! */
}
-
+
if (do_gtd) {
gp_timing_data_set_nbr(gtd, nu->pntsu);
}
-
+
tot = gps->totpoints;
-
+
/* get initial coordinates */
pt = gps->points;
if (tot) {
@@ -849,11 +851,11 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
}
}
-
+
/* If needed, make the link between both strokes with two zero-radius additional points */
if (curnu && old_nbezt) {
BLI_assert(gps->prev != NULL);
-
+
/* Update last point's second handle */
if (stitch) {
bezt = &nu->bezt[old_nbezt - 1];
@@ -861,7 +863,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
copy_v3_v3(bezt->vec[2], h2);
pt++;
}
-
+
/* Create "link points" */
/* About "zero-radius" point interpolations:
* - If we have at least two points in current curve (most common case), we linearly extrapolate
@@ -874,14 +876,14 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else {
float p1[3], p2[3];
float dt1 = 0.0f, dt2 = 0.0f;
-
+
prev_bezt = NULL;
if ((old_nbezt > 1) && (gps->prev->totpoints > 1)) {
/* Only use last curve segment if previous stroke was not a single-point one! */
prev_bezt = &nu->bezt[old_nbezt - 2];
}
bezt = &nu->bezt[old_nbezt - 1];
-
+
/* First point */
if (prev_bezt) {
interp_v3_v3v3(p1, prev_bezt->vec[1], bezt->vec[1], 1.0f + GAP_DFAC);
@@ -896,7 +898,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
dt1 = interpf(gps->inittime - gps->prev->inittime, 0.0f, GAP_DFAC);
}
}
-
+
/* Second point */
/* Note dt2 is always negative, which marks the gap. */
if (tot > 1) {
@@ -911,25 +913,25 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
dt2 = interpf(gps->prev->inittime - gps->inittime, 0.0f, GAP_DFAC);
}
}
-
+
/* Second handle of last point of previous stroke. */
interp_v3_v3v3(h2, bezt->vec[1], p1, BEZT_HANDLE_FAC);
copy_v3_v3(bezt->vec[2], h2);
-
+
/* First point */
interp_v3_v3v3(h1, p1, bezt->vec[1], BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p1, p2, BEZT_HANDLE_FAC);
bezt++;
gp_stroke_to_bezier_add_point(gtd, bezt, p1, h1, h2, (bezt - 1)->vec[1], do_gtd, gps->prev->inittime, dt1,
0.0f, rad_fac, minmax_weights);
-
+
/* Second point */
interp_v3_v3v3(h1, p2, p1, BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p2, p3d_cur, BEZT_HANDLE_FAC);
bezt++;
gp_stroke_to_bezier_add_point(gtd, bezt, p2, h1, h2, p1, do_gtd, gps->inittime, dt2,
0.0f, rad_fac, minmax_weights);
-
+
old_nbezt += 2;
copy_v3_v3(p3d_prev, p2);
}
@@ -937,7 +939,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else if (add_start_point) {
float p[3];
float dt = 0.0f;
-
+
if (gps->totpoints > 1) {
interp_v3_v3v3(p, p3d_cur, p3d_next, -GAP_DFAC);
if (do_gtd) {
@@ -954,51 +956,51 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
bezt = &nu->bezt[old_nbezt];
gp_stroke_to_bezier_add_point(gtd, bezt, p, h1, h2, p, do_gtd, gps->inittime, dt,
0.0f, rad_fac, minmax_weights);
-
+
old_nbezt++;
copy_v3_v3(p3d_prev, p);
}
-
+
if (old_nbezt) {
prev_bezt = &nu->bezt[old_nbezt - 1];
}
-
+
/* add points */
for (i = stitch ? 1 : 0, bezt = &nu->bezt[old_nbezt]; i < tot; i++, pt++, bezt++) {
float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC;
-
+
if (i || old_nbezt) {
interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC);
}
else {
interp_v3_v3v3(h1, p3d_cur, p3d_next, -BEZT_HANDLE_FAC);
}
-
+
if (i < tot - 1) {
interp_v3_v3v3(h2, p3d_cur, p3d_next, BEZT_HANDLE_FAC);
}
else {
interp_v3_v3v3(h2, p3d_cur, p3d_prev, -BEZT_HANDLE_FAC);
}
-
+
gp_stroke_to_bezier_add_point(gtd, bezt, p3d_cur, h1, h2, prev_bezt ? prev_bezt->vec[1] : p3d_cur,
do_gtd, gps->inittime, pt->time, width, rad_fac, minmax_weights);
-
+
/* shift coord vects */
copy_v3_v3(p3d_prev, p3d_cur);
copy_v3_v3(p3d_cur, p3d_next);
-
+
if (i + 2 < tot) {
gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
}
-
+
prev_bezt = bezt;
}
if (add_end_point) {
float p[3];
float dt = 0.0f;
-
+
if (gps->totpoints > 1) {
interp_v3_v3v3(p, prev_bezt->vec[1], (prev_bezt - 1)->vec[1], -GAP_DFAC);
if (do_gtd) {
@@ -1011,11 +1013,11 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
p[0] += GAP_DFAC; /* Rather arbitrary... */
dt = GAP_DFAC; /* Rather arbitrary too! */
}
-
+
/* Second handle of last point of this stroke. */
interp_v3_v3v3(h2, prev_bezt->vec[1], p, BEZT_HANDLE_FAC);
copy_v3_v3(prev_bezt->vec[2], h2);
-
+
/* The end point */
interp_v3_v3v3(h1, p, prev_bezt->vec[1], BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p, prev_bezt->vec[1], -BEZT_HANDLE_FAC);
@@ -1023,10 +1025,10 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
gp_stroke_to_bezier_add_point(gtd, bezt, p, h1, h2, prev_bezt->vec[1], do_gtd, gps->inittime, dt,
0.0f, rad_fac, minmax_weights);
}
-
+
/* must calculate handles or else we crash */
BKE_nurb_handles_calc(nu);
-
+
if (!curnu || !*curnu) {
BLI_addtail(&cu->nurb, nu);
}
@@ -1056,7 +1058,7 @@ static void gp_stroke_finalize_curve_endpoints(Curve *cu)
bp[i].weight = bp[i].radius = 0.0f;
}
}
-
+
/* end */
nu = cu->nurb.last;
i = nu->pntsu - 1;
@@ -1080,13 +1082,13 @@ static void gp_stroke_norm_curve_weights(Curve *cu, const float minmax_weights[2
const float delta = minmax_weights[0];
float fac;
int i;
-
+
/* when delta == minmax_weights[0] == minmax_weights[1], we get div by zero [#35686] */
if (IS_EQF(delta, minmax_weights[1]))
fac = 1.0f;
else
fac = 1.0f / (minmax_weights[1] - delta);
-
+
for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
@@ -1107,10 +1109,10 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
{
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
-
+
if (v3d) {
RegionView3D *rv3d = ar->regiondata;
-
+
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
Scene *scene = CTX_data_scene(C);
@@ -1119,7 +1121,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
return 1;
}
}
-
+
return 0;
}
@@ -1138,23 +1140,23 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
Nurb *nu = NULL;
Base *base_new = NULL;
float minmax_weights[2] = {1.0f, 0.0f};
-
+
/* camera framing */
rctf subrect, *subrect_ptr = NULL;
-
+
/* error checking */
if (ELEM(NULL, gpd, gpl, gpf))
return;
-
+
/* only convert if there are any strokes on this layer's frame to convert */
if (BLI_listbase_is_empty(&gpf->strokes))
return;
-
+
/* initialize camera framing */
if (gp_camera_view_subrect(C, &subrect)) {
subrect_ptr = &subrect;
}
-
+
/* init the curve object (remove rotation and get curve data from it)
* - must clear transforms set on object, as those skew our results
*/
@@ -1162,32 +1164,32 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVE);
BKE_collection_object_add(bmain, collection, ob);
base_new = BKE_view_layer_base_find(view_layer, ob);
-
+
cu->flag |= CU_3D;
-
+
gtd->inittime = ((bGPDstroke *)gpf->strokes.first)->inittime;
-
+
/* add points to curve */
for (gps = gpf->strokes.first; gps; gps = gps->next) {
const bool add_start_point = (link_strokes && !(prev_gps));
const bool add_end_point = (link_strokes && !(gps->next));
-
+
/* Detect new strokes created because of GP_STROKE_BUFFER_MAX reached, and stitch them to previous one. */
bool stitch = false;
if (prev_gps) {
bGPDspoint *pt1 = &prev_gps->points[prev_gps->totpoints - 1];
bGPDspoint *pt2 = &gps->points[0];
-
+
if ((pt1->x == pt2->x) && (pt1->y == pt2->y)) {
stitch = true;
}
}
-
+
/* Decide whether we connect this stroke to previous one */
if (!(stitch || link_strokes)) {
nu = NULL;
}
-
+
switch (mode) {
case GP_STROKECONVERT_PATH:
gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch,
@@ -1204,26 +1206,26 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
}
prev_gps = gps;
}
-
+
/* If link_strokes, be sure first and last points have a zero weight/size! */
if (link_strokes) {
gp_stroke_finalize_curve_endpoints(cu);
}
-
+
/* Update curve's weights, if needed */
if (norm_weights && ((minmax_weights[0] > 0.0f) || (minmax_weights[1] < 1.0f))) {
gp_stroke_norm_curve_weights(cu, minmax_weights);
}
-
+
/* Create the path animation, if needed */
gp_stroke_path_animation(C, reports, cu, gtd);
-
+
if (mode == GP_STROKECONVERT_POLY) {
for (nu = cu->nurb.first; nu; nu = nu->next) {
BKE_nurb_type_convert(nu, CU_POLY, false);
}
}
-
+
/* set the layer and select */
base_new->flag |= SELECT;
BKE_scene_object_base_flag_sync_from_base(base_new);
@@ -1243,17 +1245,17 @@ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOpe
double base_time, cur_time, prev_time = -1.0;
int i;
bool valid = true;
-
+
if (!gpl || !(gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) || !(gps = gpf->strokes.first))
return false;
-
+
do {
base_time = cur_time = gps->inittime;
if (cur_time <= prev_time) {
valid = false;
break;
}
-
+
prev_time = cur_time;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
cur_time = base_time + (double)pt->time;
@@ -1266,12 +1268,12 @@ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOpe
}
prev_time = cur_time;
}
-
+
if (!valid) {
break;
}
} while ((gps = gps->next));
-
+
if (op) {
RNA_boolean_set(op->ptr, "use_timing_data", valid);
}
@@ -1283,7 +1285,7 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UN
{
int start_frame = RNA_int_get(ptr, "start_frame");
int end_frame = RNA_int_get(ptr, "end_frame");
-
+
if (end_frame <= start_frame) {
RNA_int_set(ptr, "end_frame", start_frame + 1);
}
@@ -1297,7 +1299,7 @@ static int gp_convert_poll(bContext *C)
ScrArea *sa = CTX_wm_area(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
-
+
/* only if the current view is 3D View, if there's valid data (i.e. at least one stroke!),
* and if we are not in edit mode!
*/
@@ -1320,19 +1322,19 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
const bool link_strokes = RNA_boolean_get(op->ptr, "use_link_strokes");
bool valid_timing;
tGpTimingData gtd;
-
+
/* check if there's data to work with */
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data to work on");
return OPERATOR_CANCELLED;
}
-
+
if (!RNA_property_is_set(op->ptr, prop) && !gp_convert_check_has_valid_timing(C, gpl, op)) {
BKE_report(op->reports, RPT_WARNING,
"Current Grease Pencil strokes have no valid timing data, most timing options will be hidden!");
}
valid_timing = RNA_property_boolean_get(op->ptr, prop);
-
+
gtd.mode = RNA_enum_get(op->ptr, "timing_mode");
/* Check for illegal timing mode! */
if (!valid_timing && !ELEM(gtd.mode, GP_STROKECONVERT_TIMING_NONE, GP_STROKECONVERT_TIMING_LINEAR)) {
@@ -1342,7 +1344,7 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
if (!link_strokes) {
gtd.mode = GP_STROKECONVERT_TIMING_NONE;
}
-
+
/* grab all relevant settings */
gtd.frame_range = RNA_int_get(op->ptr, "frame_range");
gtd.start_frame = RNA_int_get(op->ptr, "start_frame");
@@ -1357,10 +1359,10 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
gtd.tot_dist = gtd.tot_time = gtd.gap_tot_time = 0.0f;
gtd.inittime = 0.0;
gtd.offset_time = 0.0f;
-
+
/* perform conversion */
gp_layer_to_curve(C, op->reports, gpd, gpl, mode, norm_weights, rad_fac, link_strokes, &gtd);
-
+
/* free temp memory */
if (gtd.dists) {
MEM_freeN(gtd.dists);
@@ -1370,11 +1372,11 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
MEM_freeN(gtd.times);
gtd.times = NULL;
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1388,7 +1390,7 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
float gap_duration = RNA_float_get(ptr, "gap_duration");
float gap_randomness = RNA_float_get(ptr, "gap_randomness");
const bool valid_timing = RNA_boolean_get(ptr, "use_timing_data");
-
+
/* Always show those props */
if (STREQ(prop_id, "type") ||
STREQ(prop_id, "use_normalize_weights") ||
@@ -1397,16 +1399,16 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
{
return true;
}
-
+
/* Never show this prop */
if (STREQ(prop_id, "use_timing_data"))
return false;
-
+
if (link_strokes) {
/* Only show when link_stroke is true */
if (STREQ(prop_id, "timing_mode"))
return true;
-
+
if (timing_mode != GP_STROKECONVERT_TIMING_NONE) {
/* Only show when link_stroke is true and stroke timing is enabled */
if (STREQ(prop_id, "frame_range") ||
@@ -1414,31 +1416,31 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
{
return true;
}
-
+
/* Only show if we have valid timing data! */
if (valid_timing && STREQ(prop_id, "use_realtime"))
return true;
-
+
/* Only show if realtime or valid_timing is false! */
if ((!realtime || !valid_timing) && STREQ(prop_id, "end_frame"))
return true;
-
+
if (valid_timing && timing_mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
/* Only show for custom gaps! */
if (STREQ(prop_id, "gap_duration"))
return true;
-
+
/* Only show randomness for non-null custom gaps! */
if (STREQ(prop_id, "gap_randomness") && (gap_duration > 0.0f))
return true;
-
+
/* Only show seed for randomize action! */
if (STREQ(prop_id, "seed") && (gap_duration > 0.0f) && (gap_randomness > 0.0f))
return true;
}
}
}
-
+
/* Else, hidden! */
return false;
}
@@ -1448,9 +1450,9 @@ static void gp_convert_ui(bContext *C, wmOperator *op)
uiLayout *layout = op->layout;
wmWindowManager *wm = CTX_wm_manager(C);
PointerRNA ptr;
-
+
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
+
/* Main auto-draw call */
uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
}
@@ -1458,35 +1460,35 @@ static void gp_convert_ui(bContext *C, wmOperator *op)
void GPENCIL_OT_convert(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Convert Grease Pencil";
ot->idname = "GPENCIL_OT_convert";
ot->description = "Convert the active Grease Pencil layer to a new Curve Object";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = gp_convert_layer_exec;
ot->poll = gp_convert_poll;
ot->ui = gp_convert_ui;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", "Which type of curve to convert to");
-
+
RNA_def_boolean(ot->srna, "use_normalize_weights", true, "Normalize Weight",
"Normalize weight (set from stroke width)");
RNA_def_float(ot->srna, "radius_multiplier", 1.0f, 0.0f, 1000.0f, "Radius Fac",
"Multiplier for the points' radii (set from stroke width)", 0.0f, 10.0f);
RNA_def_boolean(ot->srna, "use_link_strokes", true, "Link Strokes",
"Whether to link strokes with zero-radius sections of curves");
-
+
prop = RNA_def_enum(ot->srna, "timing_mode", prop_gpencil_convert_timingmodes, GP_STROKECONVERT_TIMING_FULL,
"Timing Mode", "How to use timing data stored in strokes");
RNA_def_enum_funcs(prop, rna_GPConvert_mode_items);
-
+
RNA_def_int(ot->srna, "frame_range", 100, 1, 10000, "Frame Range",
"The duration of evaluation of the path control curve", 1, 1000);
RNA_def_int(ot->srna, "start_frame", 1, 1, 100000, "Start Frame",
@@ -1496,7 +1498,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
prop = RNA_def_int(ot->srna, "end_frame", 250, 1, 100000, "End Frame",
"The end frame of the path control curve (if Realtime is not set)", 1, 100000);
RNA_def_property_update_runtime(prop, gp_convert_set_end_frame);
-
+
RNA_def_float(ot->srna, "gap_duration", 0.0f, 0.0f, 10000.0f, "Gap Duration",
"Custom Gap mode: (Average) length of gaps, in frames "
"(Note: Realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
@@ -1504,7 +1506,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
"Custom Gap mode: Number of frames that gap lengths can vary", 0.0f, 1000.0f);
RNA_def_int(ot->srna, "seed", 0, 0, 1000, "Random Seed",
"Custom Gap mode: Random generator seed", 0, 100);
-
+
/* Note: Internal use, this one will always be hidden by UI code... */
prop = RNA_def_boolean(ot->srna, "use_timing_data", false, "Has Valid Timing",
"Whether the converted Grease Pencil layer has valid timing data (internal use)");
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 9d183222c2d..2e8e48b2f15 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -93,7 +93,7 @@ static int gp_data_add_exec(bContext *C, wmOperator *op)
else {
/* decrement user count and add new datablock */
bGPdata *gpd = (*gpd_ptr);
-
+
id_us_min(&gpd->id);
*gpd_ptr = BKE_gpencil_data_addnew(DATA_("GPencil"));
@@ -106,10 +106,10 @@ static int gp_data_add_exec(bContext *C, wmOperator *op)
}
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -120,7 +120,7 @@ void GPENCIL_OT_data_add(wmOperatorType *ot)
ot->idname = "GPENCIL_OT_data_add";
ot->description = "Add new Grease Pencil data-block";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_data_add_exec;
ot->poll = gp_add_poll;
@@ -132,7 +132,7 @@ void GPENCIL_OT_data_add(wmOperatorType *ot)
static int gp_data_unlink_poll(bContext *C)
{
bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+
/* if we have access to some active data, make sure there's a datablock before enabling this */
return (gpd_ptr && *gpd_ptr);
}
@@ -142,7 +142,7 @@ static int gp_data_unlink_poll(bContext *C)
static int gp_data_unlink_exec(bContext *C, wmOperator *op)
{
bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+
if (gpd_ptr == NULL) {
BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
return OPERATOR_CANCELLED;
@@ -154,10 +154,10 @@ static int gp_data_unlink_exec(bContext *C, wmOperator *op)
id_us_min(&gpd->id);
*gpd_ptr = NULL;
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -168,7 +168,7 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot)
ot->idname = "GPENCIL_OT_data_unlink";
ot->description = "Unlink active Grease Pencil data-block";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_data_unlink_exec;
ot->poll = gp_data_unlink_poll;
@@ -193,7 +193,7 @@ static int gp_layer_add_exec(bContext *C, wmOperator *op)
}
if (*gpd_ptr == NULL)
*gpd_ptr = BKE_gpencil_data_addnew(DATA_("GPencil"));
-
+
/* if not exist brushes, create a new set */
if (ts) {
if (BLI_listbase_is_empty(&ts->gp_brushes)) {
@@ -204,10 +204,10 @@ static int gp_layer_add_exec(bContext *C, wmOperator *op)
/* add new layer now */
BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), true);
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -217,9 +217,9 @@ void GPENCIL_OT_layer_add(wmOperatorType *ot)
ot->name = "Add New Layer";
ot->idname = "GPENCIL_OT_layer_add";
ot->description = "Add new Grease Pencil layer for the active Grease Pencil data-block";
-
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_layer_add_exec;
ot->poll = gp_add_poll;
@@ -231,16 +231,16 @@ static int gp_layer_remove_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
/* sanity checks */
if (ELEM(NULL, gpd, gpl))
return OPERATOR_CANCELLED;
-
+
if (gpl->flag & GP_LAYER_LOCKED) {
BKE_report(op->reports, RPT_ERROR, "Cannot delete locked layers");
return OPERATOR_CANCELLED;
}
-
+
/* make the layer before this the new active layer
* - use the one after if this is the first
* - if this is the only layer, this naturally becomes NULL
@@ -249,13 +249,13 @@ static int gp_layer_remove_exec(bContext *C, wmOperator *op)
BKE_gpencil_layer_setactive(gpd, gpl->prev);
else
BKE_gpencil_layer_setactive(gpd, gpl->next);
-
+
/* delete the layer now... */
BKE_gpencil_layer_delete(gpd, gpl);
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -265,9 +265,9 @@ void GPENCIL_OT_layer_remove(wmOperatorType *ot)
ot->name = "Remove Layer";
ot->idname = "GPENCIL_OT_layer_remove";
ot->description = "Remove active Grease Pencil layer";
-
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_layer_remove_exec;
ot->poll = gp_active_layer_poll;
@@ -284,18 +284,18 @@ static int gp_layer_move_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
int direction = RNA_enum_get(op->ptr, "type");
-
+
/* sanity checks */
if (ELEM(NULL, gpd, gpl))
return OPERATOR_CANCELLED;
-
+
BLI_assert(ELEM(direction, -1, 0, 1)); /* we use value below */
if (BLI_listbase_link_move(&gpd->layers, gpl, direction)) {
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -306,19 +306,19 @@ void GPENCIL_OT_layer_move(wmOperatorType *ot)
{GP_LAYER_MOVE_DOWN, "DOWN", 0, "Down", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Move Grease Pencil Layer";
ot->idname = "GPENCIL_OT_layer_move";
ot->description = "Move the active Grease Pencil layer up/down in the list";
-
+
/* api callbacks */
ot->exec = gp_layer_move_exec;
ot->poll = gp_active_layer_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
}
@@ -329,22 +329,22 @@ static int gp_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
bGPDlayer *new_layer;
-
+
/* 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);
-
+
/* ensure new layer has a unique name, and is now the active layer */
BLI_uniquename(&gpd->layers, new_layer, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(new_layer->info));
BKE_gpencil_layer_setactive(gpd, new_layer);
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -354,11 +354,11 @@ void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Layer";
ot->idname = "GPENCIL_OT_layer_duplicate";
ot->description = "Make a copy of the active Grease Pencil layer";
-
+
/* callbacks */
ot->exec = gp_layer_copy_exec;
ot->poll = gp_active_layer_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -370,14 +370,14 @@ static int gp_hide_exec(bContext *C, wmOperator *op)
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *layer = BKE_gpencil_layer_getactive(gpd);
bool unselected = RNA_boolean_get(op->ptr, "unselected");
-
+
/* sanity checks */
if (ELEM(NULL, gpd, layer))
return OPERATOR_CANCELLED;
-
+
if (unselected) {
bGPDlayer *gpl;
-
+
/* hide unselected */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl != layer) {
@@ -389,10 +389,10 @@ static int gp_hide_exec(bContext *C, wmOperator *op)
/* hide selected/active */
layer->flag |= GP_LAYER_HIDE;
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -402,14 +402,14 @@ void GPENCIL_OT_hide(wmOperatorType *ot)
ot->name = "Hide Layer(s)";
ot->idname = "GPENCIL_OT_hide";
ot->description = "Hide selected/unselected Grease Pencil layers";
-
+
/* callbacks */
ot->exec = gp_hide_exec;
ot->poll = gp_active_layer_poll; /* NOTE: we need an active layer to play with */
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected layers");
}
@@ -452,7 +452,7 @@ static int gp_reveal_exec(bContext *C, wmOperator *op)
/* sanity checks */
if (gpd == NULL)
return OPERATOR_CANCELLED;
-
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl->flag & GP_LAYER_HIDE) {
@@ -476,10 +476,10 @@ static int gp_reveal_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -489,11 +489,11 @@ void GPENCIL_OT_reveal(wmOperatorType *ot)
ot->name = "Show All Layers";
ot->idname = "GPENCIL_OT_reveal";
ot->description = "Show all Grease Pencil layers";
-
+
/* callbacks */
ot->exec = gp_reveal_exec;
ot->poll = gp_reveal_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -507,19 +507,19 @@ static int gp_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl;
-
+
/* sanity checks */
if (gpd == NULL)
return OPERATOR_CANCELLED;
-
+
/* make all layers non-editable */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
gpl->flag |= GP_LAYER_LOCKED;
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -529,11 +529,11 @@ void GPENCIL_OT_lock_all(wmOperatorType *ot)
ot->name = "Lock All Layers";
ot->idname = "GPENCIL_OT_lock_all";
ot->description = "Lock all Grease Pencil layers to prevent them from being accidentally modified";
-
+
/* callbacks */
ot->exec = gp_lock_all_exec;
ot->poll = gp_reveal_poll; /* XXX: could use dedicated poll later */
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -544,19 +544,19 @@ static int gp_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl;
-
+
/* sanity checks */
if (gpd == NULL)
return OPERATOR_CANCELLED;
-
+
/* make all layers editable again */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
gpl->flag &= ~GP_LAYER_LOCKED;
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -566,11 +566,11 @@ void GPENCIL_OT_unlock_all(wmOperatorType *ot)
ot->name = "Unlock All Layers";
ot->idname = "GPENCIL_OT_unlock_all";
ot->description = "Unlock all Grease Pencil layers so that they can be edited";
-
+
/* callbacks */
ot->exec = gp_unlock_all_exec;
ot->poll = gp_reveal_poll; /* XXX: could use dedicated poll later */
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -584,21 +584,21 @@ static int gp_isolate_layer_exec(bContext *C, wmOperator *op)
bGPDlayer *gpl;
int flags = GP_LAYER_LOCKED;
bool isolate = false;
-
+
if (RNA_boolean_get(op->ptr, "affect_visibility"))
flags |= GP_LAYER_HIDE;
-
+
if (ELEM(NULL, gpd, layer)) {
BKE_report(op->reports, RPT_ERROR, "No active layer to isolate");
return OPERATOR_CANCELLED;
}
-
+
/* Test whether to isolate or clear all flags */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* Skip if this is the active layer */
if (gpl == layer)
continue;
-
+
/* If the flags aren't set, that means that the layer is
* not alone, so we have some layers to isolate still
*/
@@ -607,7 +607,7 @@ static int gp_isolate_layer_exec(bContext *C, wmOperator *op)
break;
}
}
-
+
/* Set/Clear flags as appropriate */
/* TODO: Include onionskinning on this list? */
if (isolate) {
@@ -625,10 +625,10 @@ static int gp_isolate_layer_exec(bContext *C, wmOperator *op)
gpl->flag &= ~flags;
}
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -638,14 +638,14 @@ void GPENCIL_OT_layer_isolate(wmOperatorType *ot)
ot->name = "Isolate Layer";
ot->idname = "GPENCIL_OT_layer_isolate";
ot->description = "Toggle whether the active layer is the only one that can be edited and/or visible";
-
+
/* callbacks */
ot->exec = gp_isolate_layer_exec;
ot->poll = gp_active_layer_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "affect_visibility", false, "Affect Visibility",
"In addition to toggling the editability, also affect the visibility");
@@ -712,13 +712,13 @@ static int gp_layer_change_invoke(bContext *C, wmOperator *op, const wmEvent *UN
{
uiPopupMenu *pup;
uiLayout *layout;
-
+
/* call the menu, which will call this operator again, hence the canceled */
pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, "GPENCIL_OT_layer_change", "layer");
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -727,7 +727,7 @@ static int gp_layer_change_exec(bContext *C, wmOperator *op)
bGPdata *gpd = CTX_data_gpencil_data(C);
bGPDlayer *gpl = NULL;
int layer_num = RNA_enum_get(op->ptr, "layer");
-
+
/* Get layer or create new one */
if (layer_num == -1) {
/* Create layer */
@@ -736,19 +736,19 @@ static int gp_layer_change_exec(bContext *C, wmOperator *op)
else {
/* Try to get layer */
gpl = BLI_findlink(&gpd->layers, layer_num);
-
+
if (gpl == NULL) {
BKE_reportf(op->reports, RPT_ERROR, "Cannot change to non-existent layer (index = %d)", layer_num);
return OPERATOR_CANCELLED;
}
}
-
+
/* Set active layer */
BKE_gpencil_layer_setactive(gpd, gpl);
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -758,15 +758,15 @@ void GPENCIL_OT_layer_change(wmOperatorType *ot)
ot->name = "Change Layer";
ot->idname = "GPENCIL_OT_layer_change";
ot->description = "Change active Grease Pencil layer";
-
+
/* callbacks */
ot->invoke = gp_layer_change_invoke;
ot->exec = gp_layer_change_exec;
ot->poll = gp_active_layer_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* gp layer to use (dynamic enum) */
ot->prop = RNA_def_enum(ot->srna, "layer", DummyRNA_DEFAULT_items, 0, "Grease Pencil Layer", "");
RNA_def_enum_funcs(ot->prop, ED_gpencil_layers_with_new_enum_itemf);
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index cf9cbbe3765..45caadf3742 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -57,6 +57,7 @@
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_screen.h"
@@ -93,10 +94,10 @@ static int gpencil_editmode_toggle_poll(bContext *C)
static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
-
+
if (gpd == NULL)
return OPERATOR_CANCELLED;
-
+
/* Just toggle editmode flag... */
gpd->flag ^= GP_DATA_STROKE_EDITMODE;
/* recalculate parent matrix */
@@ -107,7 +108,7 @@ static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op))
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
WM_event_add_notifier(C, NC_GPENCIL | ND_GPENCIL_EDITMODE, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -117,11 +118,11 @@ void GPENCIL_OT_editmode_toggle(wmOperatorType *ot)
ot->name = "Strokes Edit Mode Toggle";
ot->idname = "GPENCIL_OT_editmode_toggle";
ot->description = "Enter/Exit edit mode for Grease Pencil strokes";
-
+
/* callbacks */
ot->exec = gpencil_editmode_toggle_exec;
ot->poll = gpencil_editmode_toggle_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
}
@@ -182,10 +183,10 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, co
{
bGPDspoint *pt;
int i;
-
+
int start_idx = -1;
-
-
+
+
/* Step through the original stroke's points:
* - We accumulate selected points (from start_idx to current index)
* and then convert that to a new stroke
@@ -200,7 +201,7 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, co
}
else {
size_t len = 0;
-
+
/* is this the end of current island yet?
* 1) Point i-1 was the last one that was selected
* 2) Point i is the last in the array
@@ -212,29 +213,29 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, co
len = i - start_idx + 1;
}
//printf("copying from %d to %d = %d\n", start_idx, i, len);
-
+
/* make copies of the relevant data */
if (len) {
bGPDstroke *gpsd;
-
+
/* make a stupid copy first of the entire stroke (to get the flags too) */
gpsd = MEM_dupallocN(gps);
BLI_strncpy(gpsd->tmp_layerinfo, layername, sizeof(gpsd->tmp_layerinfo)); /* saves original layer name */
-
+
/* initialize triangle memory - will be calculated on next redraw */
gpsd->triangles = NULL;
gpsd->flag |= GP_STROKE_RECALC_CACHES;
gpsd->tot_triangles = 0;
-
+
/* now, make a new points array, and copy of the relevant parts */
gpsd->points = MEM_callocN(sizeof(bGPDspoint) * len, "gps stroke points copy");
memcpy(gpsd->points, gps->points + start_idx, sizeof(bGPDspoint) * len);
gpsd->totpoints = len;
-
+
/* add to temp buffer */
gpsd->next = gpsd->prev = NULL;
BLI_addtail(new_strokes, gpsd);
-
+
/* cleanup + reset for next */
start_idx = -1;
}
@@ -245,12 +246,12 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, co
static int gp_duplicate_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
-
+
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
return OPERATOR_CANCELLED;
}
-
+
/* for each visible (and editable) layer's selected strokes,
* copy the strokes into a temporary buffer, then append
* once all done
@@ -260,22 +261,22 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
ListBase new_strokes = {NULL, NULL};
bGPDframe *gpf = gpl->actframe;
bGPDstroke *gps;
-
+
if (gpf == NULL)
continue;
-
+
/* make copies of selected strokes, and deselect these once we're done */
for (gps = gpf->strokes.first; gps; gps = gps->next) {
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
-
+
if (gps->flag & GP_STROKE_SELECT) {
if (gps->totpoints == 1) {
/* Special Case: If there's just a single point in this stroke... */
bGPDstroke *gpsd;
-
+
/* make direct copies of the stroke and its points */
gpsd = MEM_dupallocN(gps);
BLI_strncpy(gpsd->tmp_layerinfo, gpl->info, sizeof(gpsd->tmp_layerinfo));
@@ -284,7 +285,7 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
/* triangle information - will be calculated on next redraw */
gpsd->flag |= GP_STROKE_RECALC_CACHES;
gpsd->triangles = NULL;
-
+
/* add to temp buffer */
gpsd->next = gpsd->prev = NULL;
BLI_addtail(&new_strokes, gpsd);
@@ -293,23 +294,23 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
/* delegate to a helper, as there's too much to fit in here (for copying subsets)... */
gp_duplicate_points(gps, &new_strokes, gpl->info);
}
-
+
/* deselect original stroke, or else the originals get moved too
* (when using the copy + move macro)
*/
gps->flag &= ~GP_STROKE_SELECT;
}
}
-
+
/* add all new strokes in temp buffer to the frame (preventing double-copies) */
BLI_movelisttolist(&gpf->strokes, &new_strokes);
BLI_assert(new_strokes.first == NULL);
}
CTX_DATA_END;
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -319,11 +320,11 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Strokes";
ot->idname = "GPENCIL_OT_duplicate";
ot->description = "Duplicate the selected Grease Pencil strokes";
-
+
/* callbacks */
ot->exec = gp_duplicate_exec;
ot->poll = gp_stroke_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -352,7 +353,7 @@ static GHash *gp_strokes_copypastebuf_colors = NULL;
void ED_gpencil_strokes_copybuf_free(void)
{
bGPDstroke *gps, *gpsn;
-
+
/* Free the palettes buffer
* NOTE: This is done before the strokes so that the name ptrs (keys) are still safe
*/
@@ -360,17 +361,17 @@ void ED_gpencil_strokes_copybuf_free(void)
BLI_ghash_free(gp_strokes_copypastebuf_colors, NULL, MEM_freeN);
gp_strokes_copypastebuf_colors = NULL;
}
-
+
/* Free the stroke buffer */
for (gps = gp_strokes_copypastebuf.first; gps; gps = gpsn) {
gpsn = gps->next;
-
+
if (gps->points) MEM_freeN(gps->points);
if (gps->triangles) MEM_freeN(gps->triangles);
-
+
BLI_freelinkN(&gp_strokes_copypastebuf, gps);
}
-
+
gp_strokes_copypastebuf.first = gp_strokes_copypastebuf.last = NULL;
}
@@ -381,18 +382,18 @@ GHash *gp_copybuf_validate_colormap(bGPdata *gpd)
{
GHash *new_colors = BLI_ghash_str_new("GPencil Paste Dst Colors");
GHashIterator gh_iter;
-
+
/* If there's no active palette yet (i.e. new datablock), add one */
bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
if (palette == NULL) {
palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true);
}
-
+
/* For each color, figure out what to map to... */
GHASH_ITER(gh_iter, gp_strokes_copypastebuf_colors) {
bGPDpalettecolor *palcolor;
char *name = BLI_ghashIterator_getKey(&gh_iter);
-
+
/* Look for existing color to map to */
/* XXX: What to do if same name but different color? Behaviour here should depend on a property? */
palcolor = BKE_gpencil_palettecolor_getbyname(palette, name);
@@ -400,17 +401,17 @@ GHash *gp_copybuf_validate_colormap(bGPdata *gpd)
/* Doesn't Exist - Create new matching color for this palette */
/* XXX: This still doesn't fix the pasting across file boundaries problem... */
bGPDpalettecolor *src_color = BLI_ghashIterator_getValue(&gh_iter);
-
+
palcolor = MEM_dupallocN(src_color);
BLI_addtail(&palette->colors, palcolor);
-
+
BLI_uniquename(&palette->colors, palcolor, DATA_("GP Color"), '.', offsetof(bGPDpalettecolor, info), sizeof(palcolor->info));
}
-
+
/* Store this mapping (for use later when pasting) */
BLI_ghash_insert(new_colors, name, palcolor);
}
-
+
return new_colors;
}
@@ -420,15 +421,15 @@ GHash *gp_copybuf_validate_colormap(bGPdata *gpd)
static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
-
+
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
return OPERATOR_CANCELLED;
}
-
+
/* clear the buffer first */
ED_gpencil_strokes_copybuf_free();
-
+
/* for each visible (and editable) layer's selected strokes,
* copy the strokes into a temporary buffer, then append
* once all done
@@ -437,31 +438,31 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
{
bGPDframe *gpf = gpl->actframe;
bGPDstroke *gps;
-
+
if (gpf == NULL)
continue;
-
+
/* make copies of selected strokes, and deselect these once we're done */
for (gps = gpf->strokes.first; gps; gps = gps->next) {
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
-
+
if (gps->flag & GP_STROKE_SELECT) {
if (gps->totpoints == 1) {
/* Special Case: If there's just a single point in this stroke... */
bGPDstroke *gpsd;
-
+
/* make direct copies of the stroke and its points */
gpsd = MEM_dupallocN(gps);
BLI_strncpy(gpsd->tmp_layerinfo, gpl->info, sizeof(gpsd->tmp_layerinfo)); /* saves original layer name */
gpsd->points = MEM_dupallocN(gps->points);
-
+
/* triangles cache - will be recalculated on next redraw */
gpsd->flag |= GP_STROKE_RECALC_CACHES;
gpsd->tot_triangles = 0;
gpsd->triangles = NULL;
-
+
/* add to temp buffer */
gpsd->next = gpsd->prev = NULL;
BLI_addtail(&gp_strokes_copypastebuf, gpsd);
@@ -474,26 +475,26 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
/* Build up hash of colors used in these strokes, making copies of these to protect against dangling pointers */
if (gp_strokes_copypastebuf.first) {
gp_strokes_copypastebuf_colors = BLI_ghash_str_new("GPencil CopyBuf Colors");
-
+
for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, gps->colorname) == false) {
bGPDpalettecolor *color = MEM_dupallocN(gps->palcolor);
-
+
BLI_ghash_insert(gp_strokes_copypastebuf_colors, gps->colorname, color);
gps->palcolor = color;
}
}
}
}
-
+
/* updates (to ensure operator buttons are refreshed, when used via hotkeys) */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL); // XXX?
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -504,11 +505,11 @@ void GPENCIL_OT_copy(wmOperatorType *ot)
ot->name = "Copy Strokes";
ot->idname = "GPENCIL_OT_copy";
ot->description = "Copy selected Grease Pencil points and strokes";
-
+
/* callbacks */
ot->exec = gp_strokes_copy_exec;
ot->poll = gp_stroke_edit_poll;
-
+
/* flags */
//ot->flag = OPTYPE_REGISTER;
}
@@ -537,10 +538,10 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); /* only use active for copy merge */
bGPDframe *gpf;
-
+
eGP_PasteMode type = RNA_enum_get(op->ptr, "type");
GHash *new_colors;
-
+
/* check for various error conditions */
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
@@ -562,14 +563,14 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
/* Check that some of the strokes in the buffer can be used */
bGPDstroke *gps;
bool ok = false;
-
+
for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
ok = true;
break;
}
}
-
+
if (ok == false) {
/* XXX: this check is not 100% accurate (i.e. image editor is incompatible with normal 2D strokes),
* but should be enough to give users a good idea of what's going on
@@ -578,28 +579,28 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Cannot paste 2D strokes in 3D View");
else
BKE_report(op->reports, RPT_ERROR, "Cannot paste 3D strokes in 2D editors");
-
+
return OPERATOR_CANCELLED;
}
}
-
+
/* Deselect all strokes first */
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
bGPDspoint *pt;
int i;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
-
+
gps->flag &= ~GP_STROKE_SELECT;
}
CTX_DATA_END;
-
+
/* Ensure that all the necessary colors exist */
new_colors = gp_copybuf_validate_colormap(gpd);
-
+
/* Copy over the strokes from the buffer (and adjust the colors) */
for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
@@ -611,7 +612,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
gpl = CTX_data_active_gpencil_layer(C);
}
}
-
+
/* Ensure we have a frame to draw into
* NOTE: Since this is an op which creates strokes,
* we are obliged to add a new frame if one
@@ -622,33 +623,33 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
/* Create new stroke */
bGPDstroke *new_stroke = MEM_dupallocN(gps);
new_stroke->tmp_layerinfo[0] = '\0';
-
+
new_stroke->points = MEM_dupallocN(gps->points);
-
+
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
new_stroke->triangles = NULL;
-
+
new_stroke->next = new_stroke->prev = NULL;
BLI_addtail(&gpf->strokes, new_stroke);
-
+
/* Fix color references */
BLI_assert(new_stroke->colorname[0] != '\0');
new_stroke->palcolor = BLI_ghash_lookup(new_colors, new_stroke->colorname);
-
+
BLI_assert(new_stroke->palcolor != NULL);
BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
-
+
/*new_stroke->flag |= GP_STROKE_RECALC_COLOR; */
}
}
}
-
+
/* free temp data */
BLI_ghash_free(new_colors, NULL, NULL);
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -659,19 +660,19 @@ void GPENCIL_OT_paste(wmOperatorType *ot)
{GP_COPY_MERGE, "MERGE", 0, "Merge", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Paste Strokes";
ot->idname = "GPENCIL_OT_paste";
ot->description = "Paste previously copied strokes or copy and merge in active layer";
-
+
/* callbacks */
ot->exec = gp_strokes_paste_exec;
ot->poll = gp_strokes_paste_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", copy_type, 0, "Type", "");
}
@@ -682,13 +683,13 @@ static int gp_move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *U
{
uiPopupMenu *pup;
uiLayout *layout;
-
+
/* call the menu, which will call this operator again, hence the canceled */
pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, "GPENCIL_OT_move_to_layer", "layer");
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -699,7 +700,7 @@ static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
bGPDlayer *target_layer = NULL;
ListBase strokes = {NULL, NULL};
int layer_num = RNA_enum_get(op->ptr, "layer");
-
+
/* Get layer or create new one */
if (layer_num == -1) {
/* Create layer */
@@ -708,13 +709,13 @@ static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
else {
/* Try to get layer */
target_layer = BLI_findlink(&gpd->layers, layer_num);
-
+
if (target_layer == NULL) {
BKE_reportf(op->reports, RPT_ERROR, "There is no layer number %d", layer_num);
return OPERATOR_CANCELLED;
}
}
-
+
/* Extract all strokes to move to this layer
* NOTE: We need to do this in a two-pass system to avoid conflicts with strokes
* getting repeatedly moved
@@ -723,19 +724,19 @@ static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
{
bGPDframe *gpf = gpl->actframe;
bGPDstroke *gps, *gpsn;
-
+
/* skip if no frame with strokes, or if this is the layer we're moving strokes to */
if ((gpl == target_layer) || (gpf == NULL))
continue;
-
+
/* make copies of selected strokes, and deselect these once we're done */
for (gps = gpf->strokes.first; gps; gps = gpsn) {
gpsn = gps->next;
-
+
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
-
+
/* TODO: Don't just move entire strokes - instead, only copy the selected portions... */
if (gps->flag & GP_STROKE_SELECT) {
BLI_remlink(&gpf->strokes, gps);
@@ -744,19 +745,19 @@ static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
/* Paste them all in one go */
if (strokes.first) {
Scene *scene = CTX_data_scene(C);
bGPDframe *gpf = BKE_gpencil_layer_getframe(target_layer, CFRA, true);
-
+
BLI_movelisttolist(&gpf->strokes, &strokes);
BLI_assert((strokes.first == strokes.last) && (strokes.first == NULL));
}
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -766,15 +767,15 @@ void GPENCIL_OT_move_to_layer(wmOperatorType *ot)
ot->name = "Move Strokes to Layer";
ot->idname = "GPENCIL_OT_move_to_layer";
ot->description = "Move selected strokes to another layer"; // XXX: allow moving individual points too?
-
+
/* callbacks */
ot->invoke = gp_move_to_layer_invoke;
ot->exec = gp_move_to_layer_exec;
ot->poll = gp_stroke_edit_poll; // XXX?
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* gp layer to use (dynamic enum) */
ot->prop = RNA_def_enum(ot->srna, "layer", DummyRNA_DEFAULT_items, 0, "Grease Pencil Layer", "");
RNA_def_enum_funcs(ot->prop, ED_gpencil_layers_with_new_enum_itemf);
@@ -797,7 +798,7 @@ static int UNUSED_FUNCTION(gp_blank_frame_add_poll)(bContext *C)
else {
CTX_wm_operator_poll_msg_set(C, "Active region not set");
}
-
+
return 0;
}
@@ -814,8 +815,8 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
/* let's just be lazy, and call the "Add New Layer" operator, which sets everything up as required */
WM_operator_name_call(C, "GPENCIL_OT_layer_add", WM_OP_EXEC_DEFAULT, NULL);
}
-
- /* Go through each layer, adding a frame after the active one
+
+ /* Go through each layer, adding a frame after the active one
* and/or shunting all the others out of the way
*/
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
@@ -832,15 +833,15 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
gpf->framenum += 1;
}
}
-
+
/* 2) Now add a new frame, with nothing in it */
gpl->actframe = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_NEW);
}
CTX_DATA_END;
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -851,11 +852,11 @@ void GPENCIL_OT_blank_frame_add(wmOperatorType *ot)
ot->idname = "GPENCIL_OT_blank_frame_add";
ot->description = "Insert a blank frame on the current frame "
"(all subsequently existing frames, if any, are shifted right by one frame)";
-
+
/* callbacks */
ot->exec = gp_blank_frame_add_exec;
ot->poll = gp_add_poll;
-
+
/* properties */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "all_layers", false, "All Layers", "Create blank frame in all layers, not only active");
@@ -867,7 +868,7 @@ static int gp_actframe_delete_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
/* only if there's an active layer with an active frame */
return (gpl && gpl->actframe);
}
@@ -879,7 +880,7 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
-
+
/* if there's no existing Grease-Pencil data there, add some */
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No grease pencil data");
@@ -889,13 +890,13 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active frame to delete");
return OPERATOR_CANCELLED;
}
-
+
/* delete it... */
BKE_gpencil_layer_delframe(gpl, gpf);
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -905,9 +906,9 @@ void GPENCIL_OT_active_frame_delete(wmOperatorType *ot)
ot->name = "Delete Active Frame";
ot->idname = "GPENCIL_OT_active_frame_delete";
ot->description = "Delete the active frame for the active Grease Pencil Layer";
-
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_actframe_delete_exec;
ot->poll = gp_actframe_delete_poll;
@@ -918,7 +919,7 @@ void GPENCIL_OT_active_frame_delete(wmOperatorType *ot)
static int gp_actframe_delete_all_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
-
+
/* 1) There must be grease pencil data
* 2) Hopefully some of the layers have stuff we can use
*/
@@ -929,26 +930,26 @@ static int gp_actframe_delete_all_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
bool success = false;
-
+
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
/* try to get the "active" frame - but only if it actually occurs on this frame */
bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
-
+
if (gpf == NULL)
continue;
-
+
/* delete it... */
BKE_gpencil_layer_delframe(gpl, gpf);
-
+
/* we successfully modified something */
success = true;
}
CTX_DATA_END;
-
+
/* updates */
if (success) {
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
else {
@@ -963,9 +964,9 @@ void GPENCIL_OT_active_frames_delete_all(wmOperatorType *ot)
ot->name = "Delete All Active Frames";
ot->idname = "GPENCIL_OT_active_frames_delete_all";
ot->description = "Delete the active frame(s) of all editable Grease Pencil layers";
-
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_actframe_delete_all_exec;
ot->poll = gp_actframe_delete_all_poll;
@@ -988,36 +989,36 @@ typedef enum eGP_DeleteMode {
static int gp_delete_selected_strokes(bContext *C)
{
bool changed = false;
-
+
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
bGPDframe *gpf = gpl->actframe;
bGPDstroke *gps, *gpsn;
-
+
if (gpf == NULL)
continue;
-
+
/* simply delete strokes which are selected */
for (gps = gpf->strokes.first; gps; gps = gpsn) {
gpsn = gps->next;
-
+
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
-
+
/* free stroke if selected */
if (gps->flag & GP_STROKE_SELECT) {
/* free stroke memory arrays, then stroke itself */
if (gps->points) MEM_freeN(gps->points);
if (gps->triangles) MEM_freeN(gps->triangles);
BLI_freelinkN(&gpf->strokes, gps);
-
+
changed = true;
}
}
}
CTX_DATA_END;
-
+
if (changed) {
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -1033,34 +1034,34 @@ static int gp_delete_selected_strokes(bContext *C)
static int gp_dissolve_selected_points(bContext *C)
{
bool changed = false;
-
+
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
bGPDframe *gpf = gpl->actframe;
bGPDstroke *gps, *gpsn;
-
+
if (gpf == NULL)
continue;
-
+
/* simply delete points from selected strokes
* NOTE: we may still have to remove the stroke if it ends up having no points!
*/
for (gps = gpf->strokes.first; gps; gps = gpsn) {
gpsn = gps->next;
-
+
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* check if the color is editable */
if (ED_gpencil_stroke_color_use(gpl, gps) == false)
continue;
-
+
if (gps->flag & GP_STROKE_SELECT) {
bGPDspoint *pt;
int i;
-
+
int tot = gps->totpoints; /* number of points in new buffer */
-
+
/* First Pass: Count how many points are selected (i.e. how many to remove) */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (pt->flag & GP_SPOINT_SELECT) {
@@ -1068,7 +1069,7 @@ static int gp_dissolve_selected_points(bContext *C)
tot--;
}
}
-
+
/* if no points are left, we simply delete the entire stroke */
if (tot <= 0) {
/* remove the entire stroke */
@@ -1082,35 +1083,35 @@ static int gp_dissolve_selected_points(bContext *C)
/* just copy all unselected into a smaller buffer */
bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, "new gp stroke points copy");
bGPDspoint *npt = new_points;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if ((pt->flag & GP_SPOINT_SELECT) == 0) {
*npt = *pt;
npt++;
}
}
-
+
/* free the old buffer */
MEM_freeN(gps->points);
-
+
/* save the new buffer */
gps->points = new_points;
gps->totpoints = tot;
-
+
/* triangles cache needs to be recalculated */
gps->flag |= GP_STROKE_RECALC_CACHES;
gps->tot_triangles = 0;
-
+
/* deselect the stroke, since none of its selected points will still be selected */
gps->flag &= ~GP_STROKE_SELECT;
}
-
+
changed = true;
}
}
}
CTX_DATA_END;
-
+
if (changed) {
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -1150,10 +1151,10 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
tGPDeleteIsland *islands = MEM_callocN(sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2, "gp_point_islands");
bool in_island = false;
int num_islands = 0;
-
+
bGPDspoint *pt;
int i;
-
+
/* First Pass: Identify start/end of islands */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (pt->flag & tag_flags) {
@@ -1163,7 +1164,7 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
else {
/* unselected - start of a new island? */
int idx;
-
+
if (in_island) {
/* extend existing island */
idx = num_islands - 1;
@@ -1173,37 +1174,37 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
/* start of new island */
in_island = true;
num_islands++;
-
+
idx = num_islands - 1;
islands[idx].start_idx = islands[idx].end_idx = i;
}
}
}
-
+
/* Watch out for special case where No islands = All points selected = Delete Stroke only */
if (num_islands) {
/* there are islands, so create a series of new strokes, adding them before the "next" stroke */
int idx;
-
+
/* Create each new stroke... */
for (idx = 0; idx < num_islands; idx++) {
tGPDeleteIsland *island = &islands[idx];
bGPDstroke *new_stroke = MEM_dupallocN(gps);
-
+
/* initialize triangle memory - to be calculated on next redraw */
new_stroke->triangles = NULL;
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
new_stroke->tot_triangles = 0;
-
+
/* Compute new buffer size (+ 1 needed as the endpoint index is "inclusive") */
new_stroke->totpoints = island->end_idx - island->start_idx + 1;
new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints, "gp delete stroke fragment");
-
+
/* Copy over the relevant points */
memcpy(new_stroke->points, gps->points + island->start_idx, sizeof(bGPDspoint) * new_stroke->totpoints);
-
-
- /* Each island corresponds to a new stroke. We must adjust the
+
+
+ /* Each island corresponds to a new stroke. We must adjust the
* timings of these new strokes:
*
* Each point's timing data is a delta from stroke's inittime, so as we erase some points from
@@ -1215,15 +1216,15 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
bGPDspoint *pts;
float delta = gps->points[island->start_idx].time;
int j;
-
+
new_stroke->inittime += (double)delta;
-
+
pts = new_stroke->points;
for (j = 0; j < new_stroke->totpoints; j++, pts++) {
pts->time -= delta;
}
}
-
+
/* Add new stroke to the frame */
if (next_stroke) {
BLI_insertlinkbefore(&gpf->strokes, next_stroke, new_stroke);
@@ -1233,10 +1234,10 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
}
}
}
-
+
/* free islands */
MEM_freeN(islands);
-
+
/* Delete the old stroke */
MEM_freeN(gps->points);
if (gps->triangles) {
@@ -1250,40 +1251,40 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
static int gp_delete_selected_points(bContext *C)
{
bool changed = false;
-
+
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
bGPDframe *gpf = gpl->actframe;
bGPDstroke *gps, *gpsn;
-
+
if (gpf == NULL)
continue;
-
+
/* simply delete strokes which are selected */
for (gps = gpf->strokes.first; gps; gps = gpsn) {
gpsn = gps->next;
-
+
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* check if the color is editable */
if (ED_gpencil_stroke_color_use(gpl, gps) == false)
continue;
-
-
+
+
if (gps->flag & GP_STROKE_SELECT) {
/* deselect old stroke, since it will be used as template for the new strokes */
gps->flag &= ~GP_STROKE_SELECT;
-
+
/* delete unwanted points by splitting stroke into several smaller ones */
gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT);
-
+
changed = true;
}
}
}
CTX_DATA_END;
-
+
if (changed) {
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
@@ -1299,21 +1300,21 @@ static int gp_delete_exec(bContext *C, wmOperator *op)
{
eGP_DeleteMode mode = RNA_enum_get(op->ptr, "type");
int result = OPERATOR_CANCELLED;
-
+
switch (mode) {
case GP_DELETEOP_STROKES: /* selected strokes */
result = gp_delete_selected_strokes(C);
break;
-
+
case GP_DELETEOP_POINTS: /* selected points (breaks the stroke into segments) */
result = gp_delete_selected_points(C);
break;
-
+
case GP_DELETEOP_FRAME: /* active frame */
result = gp_actframe_delete_exec(C, op);
break;
}
-
+
return result;
}
@@ -1325,20 +1326,20 @@ void GPENCIL_OT_delete(wmOperatorType *ot)
{GP_DELETEOP_FRAME, "FRAME", 0, "Frame", "Delete active frame"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Delete";
ot->idname = "GPENCIL_OT_delete";
ot->description = "Delete selected Grease Pencil strokes, vertices, or frames";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = gp_delete_exec;
ot->poll = gp_stroke_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
-
+
/* props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_delete_types, 0, "Type", "Method used for deleting Grease Pencil data");
}
@@ -1373,7 +1374,7 @@ static int gp_snap_poll(bContext *C)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
ScrArea *sa = CTX_wm_area(C);
-
+
return (gpd != NULL) && ((sa != NULL) && (sa->spacetype == SPACE_VIEW3D));
}
@@ -1384,29 +1385,29 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
bGPdata *gpd = ED_gpencil_data_get_active(C);
RegionView3D *rv3d = CTX_wm_region_data(C);
const float gridf = rv3d->gridview;
-
+
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* only editable and visible layers are considered */
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
bGPDframe *gpf = gpl->actframe;
float diff_mat[4][4];
-
+
/* calculate difference matrix if parent object */
if (gpl->parent != NULL) {
ED_gpencil_parent_location(gpl, diff_mat);
}
-
+
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
bGPDspoint *pt;
int i;
-
+
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* check if the color is editable */
if (ED_gpencil_stroke_color_use(gpl, gps) == false)
continue;
-
+
// TODO: if entire stroke is selected, offset entire stroke by same amount?
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
/* only if point is selected */
@@ -1420,11 +1421,11 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
/* apply parent transformations */
float fpt[3];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
-
+
fpt[0] = gridf * floorf(0.5f + fpt[0] / gridf);
fpt[1] = gridf * floorf(0.5f + fpt[1] / gridf);
fpt[2] = gridf * floorf(0.5f + fpt[2] / gridf);
-
+
/* return data */
copy_v3_v3(&pt->x, fpt);
gp_apply_parent_point(gpl, pt);
@@ -1434,7 +1435,7 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
}
}
}
-
+
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -1445,11 +1446,11 @@ void GPENCIL_OT_snap_to_grid(wmOperatorType *ot)
ot->name = "Snap Selection to Grid";
ot->idname = "GPENCIL_OT_snap_to_grid";
ot->description = "Snap selected points to the nearest grid points";
-
+
/* callbacks */
ot->exec = gp_snap_to_grid;
ot->poll = gp_snap_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1459,28 +1460,28 @@ void GPENCIL_OT_snap_to_grid(wmOperatorType *ot)
static int gp_snap_to_cursor(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
-
+
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
-
+
const bool use_offset = RNA_boolean_get(op->ptr, "use_offset");
const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d)->location;
-
+
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* only editable and visible layers are considered */
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
bGPDframe *gpf = gpl->actframe;
float diff_mat[4][4];
-
+
/* calculate difference matrix if parent object */
if (gpl->parent != NULL) {
ED_gpencil_parent_location(gpl, diff_mat);
}
-
+
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
bGPDspoint *pt;
int i;
-
+
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
@@ -1490,14 +1491,14 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op)
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
if ((gps->flag & GP_STROKE_SELECT) == 0)
continue;
-
+
if (use_offset) {
float offset[3];
-
+
/* compute offset from first point of stroke to cursor */
/* TODO: Allow using midpoint instead? */
sub_v3_v3v3(offset, cursor_global, &gps->points->x);
-
+
/* apply offset to all points in the stroke */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
add_v3_v3(&pt->x, offset);
@@ -1515,10 +1516,10 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op)
}
}
}
-
+
}
}
-
+
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -1529,14 +1530,14 @@ void GPENCIL_OT_snap_to_cursor(wmOperatorType *ot)
ot->name = "Snap Selection to Cursor";
ot->idname = "GPENCIL_OT_snap_to_cursor";
ot->description = "Snap selected points/strokes to the cursor";
-
+
/* callbacks */
ot->exec = gp_snap_to_cursor;
ot->poll = gp_snap_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_boolean(ot->srna, "use_offset", true, "With Offset",
"Offset the entire stroke instead of selected points only");
@@ -1547,33 +1548,33 @@ void GPENCIL_OT_snap_to_cursor(wmOperatorType *ot)
static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
-
+
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
-
+
float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location;
float centroid[3] = {0.0f};
float min[3], max[3];
size_t count = 0;
-
+
INIT_MINMAX(min, max);
-
+
/* calculate midpoints from selected points */
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* only editable and visible layers are considered */
if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
bGPDframe *gpf = gpl->actframe;
float diff_mat[4][4];
-
+
/* calculate difference matrix if parent object */
if (gpl->parent != NULL) {
ED_gpencil_parent_location(gpl, diff_mat);
}
-
+
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
bGPDspoint *pt;
int i;
-
+
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false)
continue;
@@ -1583,7 +1584,7 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
/* only continue if this stroke is selected (editable doesn't guarantee this)... */
if ((gps->flag & GP_STROKE_SELECT) == 0)
continue;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (pt->flag & GP_SPOINT_SELECT) {
if (gpl->parent == NULL) {
@@ -1594,18 +1595,18 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
/* apply parent transformations */
float fpt[3];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
-
+
add_v3_v3(centroid, fpt);
minmax_v3v3_v3(min, max, fpt);
}
count++;
}
}
-
+
}
}
}
-
+
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEAN && count) {
mul_v3_fl(centroid, 1.0f / (float)count);
copy_v3_v3(cursor, centroid);
@@ -1614,7 +1615,7 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
mid_v3_v3v3(cursor, min, max);
}
-
+
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -1625,11 +1626,11 @@ void GPENCIL_OT_snap_cursor_to_selected(wmOperatorType *ot)
ot->name = "Snap Cursor to Selected Points";
ot->idname = "GPENCIL_OT_snap_cursor_to_selected";
ot->description = "Snap cursor to center of selected points";
-
+
/* callbacks */
ot->exec = gp_snap_cursor_to_sel;
ot->poll = gp_snap_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1685,27 +1686,27 @@ static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
const int type = RNA_enum_get(op->ptr, "type");
-
+
/* sanity checks */
if (ELEM(NULL, gpd))
return OPERATOR_CANCELLED;
-
+
/* loop all selected strokes */
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
if (gpl->actframe == NULL)
continue;
-
+
for (bGPDstroke *gps = gpl->actframe->strokes.last; gps; gps = gps->prev) {
bGPDpalettecolor *palcolor = gps->palcolor;
-
+
/* skip strokes that are not selected or invalid for current view */
if (((gps->flag & GP_STROKE_SELECT) == 0) || ED_gpencil_stroke_can_use(C, gps) == false)
continue;
/* skip hidden or locked colors */
if (!palcolor || (palcolor->flag & PC_COLOR_HIDE) || (palcolor->flag & PC_COLOR_LOCKED))
continue;
-
+
switch (type) {
case GP_STROKE_CYCLIC_CLOSE:
/* Close all (enable) */
@@ -1726,10 +1727,10 @@ static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1745,19 +1746,19 @@ void GPENCIL_OT_stroke_cyclical_set(wmOperatorType *ot)
{GP_STROKE_CYCLIC_TOGGLE, "TOGGLE", 0, "Toggle", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Set Cyclical State";
ot->idname = "GPENCIL_OT_stroke_cyclical_set";
ot->description = "Close or open the selected stroke adding an edge from last to first point";
-
+
/* api callbacks */
ot->exec = gp_stroke_cyclical_set_exec;
ot->poll = gp_active_layer_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", cyclic_type, GP_STROKE_CYCLIC_TOGGLE, "Type", "");
}
@@ -1768,11 +1769,11 @@ void GPENCIL_OT_stroke_cyclical_set(wmOperatorType *ot)
static void gpencil_flip_stroke(bGPDstroke *gps)
{
int end = gps->totpoints - 1;
-
+
for (int i = 0; i < gps->totpoints / 2; i++) {
bGPDspoint *point, *point2;
bGPDspoint pt;
-
+
/* save first point */
point = &gps->points[i];
pt.x = point->x;
@@ -1782,7 +1783,7 @@ static void gpencil_flip_stroke(bGPDstroke *gps)
pt.pressure = point->pressure;
pt.strength = point->strength;
pt.time = point->time;
-
+
/* replace first point with last point */
point2 = &gps->points[end];
point->x = point2->x;
@@ -1792,7 +1793,7 @@ static void gpencil_flip_stroke(bGPDstroke *gps)
point->pressure = point2->pressure;
point->strength = point2->strength;
point->time = point2->time;
-
+
/* replace last point with first saved before */
point = &gps->points[end];
point->x = pt.x;
@@ -1802,7 +1803,7 @@ static void gpencil_flip_stroke(bGPDstroke *gps)
point->pressure = pt.pressure;
point->strength = pt.strength;
point->time = pt.time;
-
+
end--;
}
}
@@ -1812,10 +1813,10 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, float
float pressure, float strength, float deltatime)
{
bGPDspoint *newpoint;
-
+
gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
gps->totpoints++;
-
+
newpoint = &gps->points[gps->totpoints - 1];
newpoint->x = point->x * delta[0];
newpoint->y = point->y * delta[1];
@@ -1834,28 +1835,28 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a, bGPDstroke *gps_b, co
int i;
float delta[3] = {1.0f, 1.0f, 1.0f};
float deltatime = 0.0f;
-
+
/* sanity checks */
if (ELEM(NULL, gps_a, gps_b))
return;
-
+
if ((gps_a->totpoints == 0) || (gps_b->totpoints == 0))
return;
-
+
/* define start and end points of each stroke */
float sa[3], sb[3], ea[3], eb[3];
pt = &gps_a->points[0];
copy_v3_v3(sa, &pt->x);
-
+
pt = &gps_a->points[gps_a->totpoints - 1];
copy_v3_v3(ea, &pt->x);
-
+
pt = &gps_b->points[0];
copy_v3_v3(sb, &pt->x);
-
+
pt = &gps_b->points[gps_b->totpoints - 1];
copy_v3_v3(eb, &pt->x);
-
+
/* review if need flip stroke B */
float ea_sb = len_squared_v3v3(ea, sb);
float ea_eb = len_squared_v3v3(ea, eb);
@@ -1863,19 +1864,19 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a, bGPDstroke *gps_b, co
if (ea_eb < ea_sb) {
gpencil_flip_stroke(gps_b);
}
-
+
/* don't visibly link the first and last points? */
if (leave_gaps) {
/* 1st: add one tail point to start invisible area */
point = gps_a->points[gps_a->totpoints - 1];
deltatime = point.time;
gpencil_stroke_copy_point(gps_a, &point, delta, 0.0f, 0.0f, 0.0f);
-
+
/* 2nd: add one head point to finish invisible area */
point = gps_b->points[0];
gpencil_stroke_copy_point(gps_a, &point, delta, 0.0f, 0.0f, deltatime);
}
-
+
/* 3rd: add all points */
for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) {
/* check if still room in buffer */
@@ -1892,25 +1893,25 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
bGPDstroke *gps, *gpsn;
bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
-
+
bGPDframe *gpf_a = NULL;
bGPDstroke *stroke_a = NULL;
bGPDstroke *stroke_b = NULL;
bGPDstroke *new_stroke = NULL;
-
+
const int type = RNA_enum_get(op->ptr, "type");
const bool leave_gaps = RNA_boolean_get(op->ptr, "leave_gaps");
-
+
/* sanity checks */
if (ELEM(NULL, gpd))
return OPERATOR_CANCELLED;
-
+
if (activegpl->flag & GP_LAYER_LOCKED)
return OPERATOR_CANCELLED;
-
+
BLI_assert(ELEM(type, GP_STROKE_JOIN, GP_STROKE_JOINCOPY));
-
-
+
+
/* read all selected strokes */
bool first = false;
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
@@ -1918,7 +1919,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
bGPDframe *gpf = gpl->actframe;
if (gpf == NULL)
continue;
-
+
for (gps = gpf->strokes.first; gps; gps = gpsn) {
gpsn = gps->next;
if (gps->flag & GP_STROKE_SELECT) {
@@ -1930,10 +1931,10 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
continue;
}
-
+
/* to join strokes, cyclic must be disabled */
gps->flag &= ~GP_STROKE_CYCLIC;
-
+
/* saves first frame and stroke */
if (!first) {
first = true;
@@ -1942,7 +1943,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
}
else {
stroke_b = gps;
-
+
/* create a new stroke if was not created before (only created if something to join) */
if (new_stroke == NULL) {
new_stroke = MEM_dupallocN(stroke_a);
@@ -1950,7 +1951,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
new_stroke->triangles = NULL;
new_stroke->tot_triangles = 0;
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
-
+
/* if new, set current color */
if (type == GP_STROKE_JOINCOPY) {
new_stroke->palcolor = palcolor;
@@ -1958,10 +1959,10 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
new_stroke->flag |= GP_STROKE_RECALC_COLOR;
}
}
-
+
/* join new_stroke and stroke B. New stroke will contain all the previous data */
gpencil_stroke_join_strokes(new_stroke, stroke_b, leave_gaps);
-
+
/* if join only, delete old strokes */
if (type == GP_STROKE_JOIN) {
if (stroke_a) {
@@ -1981,21 +1982,21 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
/* add new stroke if was not added before */
if (type == GP_STROKE_JOINCOPY) {
if (new_stroke) {
/* Add a new frame if needed */
if (activegpl->actframe == NULL)
activegpl->actframe = BKE_gpencil_frame_addnew(activegpl, gpf_a->framenum);
-
+
BLI_addtail(&activegpl->actframe->strokes, new_stroke);
}
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2006,19 +2007,19 @@ void GPENCIL_OT_stroke_join(wmOperatorType *ot)
{GP_STROKE_JOINCOPY, "JOINCOPY", 0, "Join and Copy", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Join Strokes";
ot->idname = "GPENCIL_OT_stroke_join";
ot->description = "Join selected strokes (optionally as new stroke)";
-
+
/* api callbacks */
ot->exec = gp_stroke_join_exec;
ot->poll = gp_active_layer_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", join_type, GP_STROKE_JOIN, "Type", "");
RNA_def_boolean(ot->srna, "leave_gaps", false, "Leave Gaps", "Leave gaps between joined strokes instead of linking them");
@@ -2040,7 +2041,7 @@ static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op))
bGPDframe *gpf = gpl->actframe;
if (gpf == NULL)
continue;
-
+
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
if (gps->flag & GP_STROKE_SELECT) {
/* skip strokes that are invalid for current view */
@@ -2051,17 +2052,17 @@ static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op))
if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
continue;
}
-
+
/* flip stroke */
gpencil_flip_stroke(gps);
}
}
}
CTX_DATA_END;
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2071,11 +2072,11 @@ void GPENCIL_OT_stroke_flip(wmOperatorType *ot)
ot->name = "Flip Stroke";
ot->idname = "GPENCIL_OT_stroke_flip";
ot->description = "Change direction of the points of the selected strokes";
-
+
/* api callbacks */
ot->exec = gp_stroke_flip_exec;
ot->poll = gp_active_layer_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2103,19 +2104,19 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
GP_SpaceConversion gsc = {NULL};
eGP_ReprojectModes mode = RNA_boolean_get(op->ptr, "type");
-
+
/* init space conversion stuff */
gp_point_conversion_init(C, &gsc);
-
+
/* init autodist for geometry projection */
if (mode == GP_REPROJECT_SURFACE) {
struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar);
ED_view3d_autodist_init(depsgraph, gsc.ar, CTX_wm_view3d(C), 0);
}
-
+
// TODO: For deforming geometry workflow, create new frames?
-
+
/* Go through each editable + selected stroke, adjusting each of its points one by one... */
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
{
@@ -2123,17 +2124,17 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
bGPDspoint *pt;
int i;
float inverse_diff_mat[4][4];
-
+
/* Compute inverse matrix for unapplying parenting once instead of doing per-point */
/* TODO: add this bit to the iteration macro? */
if (gpl->parent) {
invert_m4_m4(inverse_diff_mat, diff_mat);
}
-
+
/* Adjust each point */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
float xy[2];
-
+
/* 3D to Screenspace */
/* Note: We can't use gp_point_to_xy() here because that uses ints for the screenspace
* coordinates, resulting in lost precision, which in turn causes stairstepping
@@ -2147,7 +2148,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
gp_point_to_parent_space(pt, diff_mat, &pt2);
gp_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]);
}
-
+
/* Project screenspace back to 3D space (from current perspective)
* so that all points have been treated the same way
*/
@@ -2159,10 +2160,10 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
/* Geometry - Snap to surfaces of visible geometry */
/* XXX: There will be precision loss (possible stairstep artifacts) from this conversion to satisfy the API's */
const int screen_co[2] = {(int)xy[0], (int)xy[1]};
-
+
int depth_margin = 0; // XXX: 4 for strokes, 0 for normal
float depth;
-
+
/* XXX: The proper procedure computes the depths into an array, to have smooth transitions when all else fails... */
if (ED_view3d_autodist_depth(gsc.ar, screen_co, depth_margin, &depth)) {
ED_view3d_autodist_simple(gsc.ar, screen_co, &pt->x, 0, &depth);
@@ -2172,7 +2173,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
gp_point_xy_to_3d(&gsc, scene, xy, &pt->x);
}
}
-
+
/* Unapply parent corrections */
if (gpl->parent) {
mul_m4_v3(inverse_diff_mat, &pt->x);
@@ -2181,7 +2182,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
}
}
GP_EDITABLE_STROKES_END;
-
+
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
@@ -2189,29 +2190,29 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
void GPENCIL_OT_reproject(wmOperatorType *ot)
{
static const EnumPropertyItem reproject_type[] = {
- {GP_REPROJECT_PLANAR, "PLANAR", 0, "Planar",
+ {GP_REPROJECT_PLANAR, "PLANAR", 0, "Planar",
"Reproject the strokes to end up on the same plane, as if drawn from the current viewpoint "
"using 'Cursor' Stroke Placement"},
{GP_REPROJECT_SURFACE, "SURFACE", 0, "Surface",
"Reproject the strokes on to the scene geometry, as if drawn using 'Surface' placement"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Reproject Strokes";
ot->idname = "GPENCIL_OT_reproject";
ot->description = "Reproject the selected strokes from the current viewpoint as if they had been newly drawn "
"(e.g. to fix problems from accidental 3D cursor movement or accidental viewport changes, "
"or for matching deforming geometry)";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = gp_strokes_reproject_exec;
ot->poll = gp_strokes_reproject_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", reproject_type, GP_REPROJECT_PLANAR, "Projection Type", "");
}
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 83e2a85db49..ff3f5b20858 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -89,18 +89,18 @@ static int gpencil_view3d_poll(bContext *C)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
-
+
/* only 3D view */
ScrArea *sa = CTX_wm_area(C);
if (sa && sa->spacetype != SPACE_VIEW3D) {
return 0;
}
-
+
/* need data to interpolate */
if (ELEM(NULL, gpd, gpl)) {
return 0;
}
-
+
return 1;
}
@@ -108,13 +108,13 @@ static int gpencil_view3d_poll(bContext *C)
static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_to, bGPDstroke *new_stroke, float factor)
{
bGPDspoint *prev, *pt, *next;
-
+
/* update points */
for (int i = 0; i < new_stroke->totpoints; i++) {
prev = &gps_from->points[i];
pt = &new_stroke->points[i];
next = &gps_to->points[i];
-
+
/* Interpolate all values */
interp_v3_v3v3(&pt->x, &prev->x, &next->x, factor);
pt->pressure = interpf(prev->pressure, next->pressure, 1.0f - factor);
@@ -130,32 +130,32 @@ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi)
{
tGPDinterpolate_layer *tgpil;
const float shift = tgpi->shift;
-
+
for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) {
bGPDstroke *new_stroke;
const float factor = tgpil->factor + shift;
-
+
for (new_stroke = tgpil->interFrame->strokes.first; new_stroke; new_stroke = new_stroke->next) {
bGPDstroke *gps_from, *gps_to;
int stroke_idx;
-
+
if (new_stroke->totpoints == 0) {
continue;
}
-
+
/* get strokes to interpolate */
stroke_idx = BLI_findindex(&tgpil->interFrame->strokes, new_stroke);
-
+
gps_from = BLI_findlink(&tgpil->prevFrame->strokes, stroke_idx);
gps_to = BLI_findlink(&tgpil->nextFrame->strokes, stroke_idx);
-
+
/* update points position */
if ((gps_from) && (gps_to)) {
gp_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
}
}
}
-
+
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
}
@@ -164,7 +164,7 @@ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd)
{
ToolSettings *ts = CTX_data_tool_settings(C);
eGP_Interpolate_SettingsFlag flag = ts->gp_interpolate.flag;
-
+
/* get layers */
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* all layers or only active */
@@ -175,12 +175,12 @@ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd)
if (!gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
continue;
}
-
+
/* read strokes */
for (bGPDstroke *gps_from = gpl->actframe->strokes.first; gps_from; gps_from = gps_from->next) {
bGPDstroke *gps_to;
int fFrame;
-
+
/* only selected */
if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) {
continue;
@@ -193,14 +193,14 @@ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd)
if (ED_gpencil_stroke_color_use(gpl, gps_from) == false) {
continue;
}
-
+
/* get final stroke to interpolate */
fFrame = BLI_findindex(&gpl->actframe->strokes, gps_from);
gps_to = BLI_findlink(&gpl->actframe->next->strokes, fFrame);
if (gps_to == NULL) {
continue;
}
-
+
return true;
}
}
@@ -213,18 +213,18 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
bGPdata *gpd = tgpi->gpd;
bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C);
bGPDframe *actframe = active_gpl->actframe;
-
+
/* save initial factor for active layer to define shift limits */
tgpi->init_factor = (float)(tgpi->cframe - actframe->framenum) / (actframe->next->framenum - actframe->framenum + 1);
-
+
/* limits are 100% below 0 and 100% over the 100% */
tgpi->low_limit = -1.0f - tgpi->init_factor;
tgpi->high_limit = 2.0f - tgpi->init_factor;
-
+
/* set layers */
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
tGPDinterpolate_layer *tgpil;
-
+
/* all layers or only active */
if (!(tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS) && (gpl != active_gpl)) {
continue;
@@ -233,32 +233,32 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
if (!gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
continue;
}
-
+
/* create temp data for each layer */
tgpil = MEM_callocN(sizeof(tGPDinterpolate_layer), "GPencil Interpolate Layer");
-
+
tgpil->gpl = gpl;
tgpil->prevFrame = gpl->actframe;
tgpil->nextFrame = gpl->actframe->next;
-
+
BLI_addtail(&tgpi->ilayers, tgpil);
-
+
/* create a new temporary frame */
tgpil->interFrame = MEM_callocN(sizeof(bGPDframe), "bGPDframe");
tgpil->interFrame->framenum = tgpi->cframe;
-
+
/* get interpolation factor by layer (usually must be equal for all layers, but not sure) */
tgpil->factor = (float)(tgpi->cframe - tgpil->prevFrame->framenum) / (tgpil->nextFrame->framenum - tgpil->prevFrame->framenum + 1);
-
+
/* create new strokes data with interpolated points reading original stroke */
for (bGPDstroke *gps_from = tgpil->prevFrame->strokes.first; gps_from; gps_from = gps_from->next) {
bGPDstroke *gps_to;
int fFrame;
-
+
bGPDstroke *new_stroke;
bool valid = true;
-
-
+
+
/* only selected */
if ((tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) {
valid = false;
@@ -267,19 +267,19 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
if (ED_gpencil_stroke_can_use(C, gps_from) == false) {
valid = false;
}
-
+
/* check if the color is editable */
if (ED_gpencil_stroke_color_use(tgpil->gpl, gps_from) == false) {
valid = false;
}
-
+
/* get final stroke to interpolate */
fFrame = BLI_findindex(&tgpil->prevFrame->strokes, gps_from);
gps_to = BLI_findlink(&tgpil->nextFrame->strokes, fFrame);
if (gps_to == NULL) {
valid = false;
}
-
+
/* create new stroke */
new_stroke = MEM_dupallocN(gps_from);
new_stroke->points = MEM_dupallocN(gps_from->points);
@@ -306,7 +306,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
new_stroke->triangles = MEM_recallocN(new_stroke->triangles, sizeof(*new_stroke->triangles));
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
}
-
+
/* add to strokes */
BLI_addtail(&tgpil->interFrame->strokes, new_stroke);
}
@@ -339,14 +339,14 @@ static void gpencil_mouse_update_shift(tGPDinterpolate *tgpi, wmOperator *op, co
{
float mid = (float)(tgpi->ar->winx - tgpi->ar->winrct.xmin) / 2.0f;
float mpos = event->x - tgpi->ar->winrct.xmin;
-
+
if (mpos >= mid) {
tgpi->shift = ((mpos - mid) * tgpi->high_limit) / mid;
}
else {
tgpi->shift = tgpi->low_limit - ((mpos * tgpi->low_limit) / mid);
}
-
+
CLAMP(tgpi->shift, tgpi->low_limit, tgpi->high_limit);
RNA_float_set(op->ptr, "shift", tgpi->shift);
}
@@ -357,19 +357,19 @@ static void gpencil_interpolate_status_indicators(tGPDinterpolate *p)
Scene *scene = p->scene;
char status_str[UI_MAX_DRAW_STR];
char msg_str[UI_MAX_DRAW_STR];
-
+
BLI_strncpy(msg_str, IFACE_("GPencil Interpolation: ESC/RMB to cancel, Enter/LMB to confirm, WHEEL/MOVE to adjust factor"), UI_MAX_DRAW_STR);
-
+
if (hasNumInput(&p->num)) {
char str_offs[NUM_STR_REP_LEN];
-
+
outputNumInput(&p->num, str_offs, &scene->unit);
BLI_snprintf(status_str, sizeof(status_str), "%s: %s", msg_str, str_offs);
}
else {
BLI_snprintf(status_str, sizeof(status_str), "%s: %d %%", msg_str, (int)((p->init_factor + p->shift) * 100.0f));
}
-
+
ED_area_headerprint(p->sa, status_str);
}
@@ -391,7 +391,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op)
{
tGPDinterpolate *tgpi = op->customdata;
tGPDinterpolate_layer *tgpil;
-
+
/* don't assume that operator data exists at all */
if (tgpi) {
/* remove drawing handler */
@@ -401,21 +401,21 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op)
if (tgpi->draw_handle_3d) {
ED_region_draw_cb_exit(tgpi->ar->type, tgpi->draw_handle_3d);
}
-
+
/* clear status message area */
ED_area_headerprint(tgpi->sa, NULL);
-
+
/* finally, free memory used by temp data */
for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) {
BKE_gpencil_free_strokes(tgpil->interFrame);
MEM_freeN(tgpil->interFrame);
}
-
+
BLI_freelistN(&tgpi->ilayers);
MEM_freeN(tgpi);
}
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
-
+
/* clear pointer */
op->customdata = NULL;
}
@@ -425,24 +425,24 @@ static bool gp_interpolate_set_init_values(bContext *C, wmOperator *op, tGPDinte
{
ToolSettings *ts = CTX_data_tool_settings(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
-
+
/* set current scene and window */
tgpi->scene = CTX_data_scene(C);
tgpi->sa = CTX_wm_area(C);
tgpi->ar = CTX_wm_region(C);
tgpi->flag = ts->gp_interpolate.flag;
-
+
/* set current frame number */
tgpi->cframe = tgpi->scene->r.cfra;
-
+
/* set GP datablock */
tgpi->gpd = gpd;
-
+
/* set interpolation weight */
tgpi->shift = RNA_float_get(op->ptr, "shift");
/* set layers */
gp_interpolate_set_points(C, tgpi);
-
+
return 1;
}
@@ -450,10 +450,10 @@ static bool gp_interpolate_set_init_values(bContext *C, wmOperator *op, tGPDinte
static tGPDinterpolate *gp_session_init_interpolation(bContext *C, wmOperator *op)
{
tGPDinterpolate *tgpi = MEM_callocN(sizeof(tGPDinterpolate), "GPencil Interpolate Data");
-
+
/* define initial values */
gp_interpolate_set_init_values(C, op, tgpi);
-
+
/* return context data for running operator */
return tgpi;
}
@@ -462,7 +462,7 @@ static tGPDinterpolate *gp_session_init_interpolation(bContext *C, wmOperator *o
static int gpencil_interpolate_init(bContext *C, wmOperator *op)
{
tGPDinterpolate *tgpi;
-
+
/* check context */
tgpi = op->customdata = gp_session_init_interpolation(C, op);
if (tgpi == NULL) {
@@ -470,7 +470,7 @@ static int gpencil_interpolate_init(bContext *C, wmOperator *op)
gpencil_interpolate_exit(C, op);
return 0;
}
-
+
/* everything is now setup ok */
return 1;
}
@@ -492,19 +492,19 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent
BKE_report(op->reports, RPT_ERROR, "Cannot find a pair of grease pencil frames to interpolate between in active layer");
return OPERATOR_CANCELLED;
}
-
+
/* cannot interpolate in extremes */
if (ELEM(CFRA, actframe->framenum, actframe->next->framenum)) {
BKE_report(op->reports, RPT_ERROR, "Cannot interpolate as current frame already has existing grease pencil frames");
return OPERATOR_CANCELLED;
}
-
+
/* need editable strokes */
if (!gp_interpolate_check_todo(C, gpd)) {
BKE_report(op->reports, RPT_ERROR, "Interpolation requires some editable strokes");
return OPERATOR_CANCELLED;
}
-
+
/* try to initialize context data needed */
if (!gpencil_interpolate_init(C, op)) {
if (op->customdata)
@@ -514,24 +514,24 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent
else {
tgpi = op->customdata;
}
-
+
/* Enable custom drawing handlers
- * It needs 2 handlers because strokes can in 3d space and screen space
- * and each handler use different coord system
+ * It needs 2 handlers because strokes can in 3d space and screen space
+ * and each handler use different coord system
*/
tgpi->draw_handle_screen = ED_region_draw_cb_activate(tgpi->ar->type, gpencil_interpolate_draw_screen, tgpi, REGION_DRAW_POST_PIXEL);
tgpi->draw_handle_3d = ED_region_draw_cb_activate(tgpi->ar->type, gpencil_interpolate_draw_3d, tgpi, REGION_DRAW_POST_VIEW);
-
+
/* set cursor to indicate modal */
WM_cursor_modal_set(win, BC_EW_SCROLLCURSOR);
-
+
/* update shift indicator in header */
gpencil_interpolate_status_indicators(tgpi);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
-
+
/* add a modal handler for this operator */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -544,7 +544,7 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
bGPDstroke *gps_src, *gps_dst;
tGPDinterpolate_layer *tgpil;
const bool has_numinput = hasNumInput(&tgpi->num);
-
+
switch (event->type) {
case LEFTMOUSE: /* confirm */
case RETKEY:
@@ -552,19 +552,19 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
/* return to normal cursor and header status */
ED_area_headerprint(tgpi->sa, NULL);
WM_cursor_modal_restore(win);
-
+
/* insert keyframes as required... */
for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) {
gpf_dst = BKE_gpencil_layer_getframe(tgpil->gpl, tgpi->cframe, GP_GETFRAME_ADD_NEW);
gpf_dst->key_type = BEZT_KEYTYPE_BREAKDOWN;
-
+
/* copy strokes */
BLI_listbase_clear(&gpf_dst->strokes);
for (gps_src = tgpil->interFrame->strokes.first; gps_src; gps_src = gps_src->next) {
if (gps_src->totpoints == 0) {
continue;
}
-
+
/* make copy of source stroke, then adjust pointer to points too */
gps_dst = MEM_dupallocN(gps_src);
gps_dst->points = MEM_dupallocN(gps_src->points);
@@ -573,34 +573,34 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
BLI_addtail(&gpf_dst->strokes, gps_dst);
}
}
-
+
/* clean up temp data */
gpencil_interpolate_exit(C, op);
-
+
/* done! */
return OPERATOR_FINISHED;
}
-
+
case ESCKEY: /* cancel */
case RIGHTMOUSE:
{
/* return to normal cursor and header status */
ED_area_headerprint(tgpi->sa, NULL);
WM_cursor_modal_restore(win);
-
+
/* clean up temp data */
gpencil_interpolate_exit(C, op);
-
+
/* canceled! */
return OPERATOR_CANCELLED;
}
-
+
case WHEELUPMOUSE:
{
tgpi->shift = tgpi->shift + 0.01f;
CLAMP(tgpi->shift, tgpi->low_limit, tgpi->high_limit);
RNA_float_set(op->ptr, "shift", tgpi->shift);
-
+
/* update screen */
gpencil_interpolate_update(C, op, tgpi);
break;
@@ -610,7 +610,7 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
tgpi->shift = tgpi->shift - 0.01f;
CLAMP(tgpi->shift, tgpi->low_limit, tgpi->high_limit);
RNA_float_set(op->ptr, "shift", tgpi->shift);
-
+
/* update screen */
gpencil_interpolate_update(C, op, tgpi);
break;
@@ -621,7 +621,7 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
if (has_numinput == false) {
/* update shift based on position of mouse */
gpencil_mouse_update_shift(tgpi, op, event);
-
+
/* update screen */
gpencil_interpolate_update(C, op, tgpi);
}
@@ -632,21 +632,21 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
if ((event->val == KM_PRESS) && handleNumInput(C, &tgpi->num, event)) {
const float factor = tgpi->init_factor;
float value;
-
+
/* Grab shift from numeric input, and store this new value (the user see an int) */
value = (factor + tgpi->shift) * 100.0f;
applyNumInput(&tgpi->num, &value);
tgpi->shift = value / 100.0f;
-
+
/* recalculate the shift to get the right value in the frame scale */
tgpi->shift = tgpi->shift - factor;
-
+
CLAMP(tgpi->shift, tgpi->low_limit, tgpi->high_limit);
RNA_float_set(op->ptr, "shift", tgpi->shift);
-
+
/* update screen */
gpencil_interpolate_update(C, op, tgpi);
-
+
break;
}
else {
@@ -655,7 +655,7 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
}
}
}
-
+
/* still running... */
return OPERATOR_RUNNING_MODAL;
}
@@ -673,16 +673,16 @@ void GPENCIL_OT_interpolate(wmOperatorType *ot)
ot->name = "Grease Pencil Interpolation";
ot->idname = "GPENCIL_OT_interpolate";
ot->description = "Interpolate grease pencil strokes between frames";
-
+
/* callbacks */
ot->invoke = gpencil_interpolate_invoke;
ot->modal = gpencil_interpolate_modal;
ot->cancel = gpencil_interpolate_cancel;
ot->poll = gpencil_view3d_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
-
+
/* properties */
RNA_def_float_percentage(ot->srna, "shift", 0.0f, -1.0f, 1.0f, "Shift", "Bias factor for which frame has more influence on the interpolated strokes", -0.9f, 0.9f);
}
@@ -695,14 +695,14 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
const float begin = 0.0f;
const float change = 1.0f;
const float duration = 1.0f;
-
+
const float back = ipo_settings->back;
const float amplitude = ipo_settings->amplitude;
const float period = ipo_settings->period;
-
+
eBezTriple_Easing easing = ipo_settings->easing;
float result = time;
-
+
switch (ipo_settings->type) {
case GP_IPO_BACK:
switch (easing) {
@@ -715,7 +715,7 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_back_ease_in_out(time, begin, change, duration, back);
break;
-
+
default: /* default/auto: same as ease out */
result = BLI_easing_back_ease_out(time, begin, change, duration, back);
break;
@@ -733,13 +733,13 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_bounce_ease_in_out(time, begin, change, duration);
break;
-
+
default: /* default/auto: same as ease out */
result = BLI_easing_bounce_ease_out(time, begin, change, duration);
break;
}
break;
-
+
case GP_IPO_CIRC:
switch (easing) {
case BEZT_IPO_EASE_IN:
@@ -751,7 +751,7 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_circ_ease_in_out(time, begin, change, duration);
break;
-
+
default: /* default/auto: same as ease in */
result = BLI_easing_circ_ease_in(time, begin, change, duration);
break;
@@ -769,13 +769,13 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_cubic_ease_in_out(time, begin, change, duration);
break;
-
+
default: /* default/auto: same as ease in */
result = BLI_easing_cubic_ease_in(time, begin, change, duration);
break;
}
break;
-
+
case GP_IPO_ELASTIC:
switch (easing) {
case BEZT_IPO_EASE_IN:
@@ -787,13 +787,13 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_elastic_ease_in_out(time, begin, change, duration, amplitude, period);
break;
-
+
default: /* default/auto: same as ease out */
result = BLI_easing_elastic_ease_out(time, begin, change, duration, amplitude, period);
break;
}
break;
-
+
case GP_IPO_EXPO:
switch (easing) {
case BEZT_IPO_EASE_IN:
@@ -805,13 +805,13 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_expo_ease_in_out(time, begin, change, duration);
break;
-
+
default: /* default/auto: same as ease in */
result = BLI_easing_expo_ease_in(time, begin, change, duration);
break;
}
break;
-
+
case GP_IPO_QUAD:
switch (easing) {
case BEZT_IPO_EASE_IN:
@@ -823,13 +823,13 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_quad_ease_in_out(time, begin, change, duration);
break;
-
+
default: /* default/auto: same as ease in */
result = BLI_easing_quad_ease_in(time, begin, change, duration);
break;
}
break;
-
+
case GP_IPO_QUART:
switch (easing) {
case BEZT_IPO_EASE_IN:
@@ -841,13 +841,13 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_quart_ease_in_out(time, begin, change, duration);
break;
-
+
default: /* default/auto: same as ease in */
result = BLI_easing_quart_ease_in(time, begin, change, duration);
break;
}
break;
-
+
case GP_IPO_QUINT:
switch (easing) {
case BEZT_IPO_EASE_IN:
@@ -859,13 +859,13 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_quint_ease_in_out(time, begin, change, duration);
break;
-
+
default: /* default/auto: same as ease in */
result = BLI_easing_quint_ease_in(time, begin, change, duration);
break;
}
break;
-
+
case GP_IPO_SINE:
switch (easing) {
case BEZT_IPO_EASE_IN:
@@ -877,18 +877,18 @@ static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_setting
case BEZT_IPO_EASE_IN_OUT:
result = BLI_easing_sine_ease_in_out(time, begin, change, duration);
break;
-
+
default: /* default/auto: same as ease in */
result = BLI_easing_sine_ease_in(time, begin, change, duration);
break;
}
break;
-
+
default:
printf("%s: Unknown interpolation type - %d\n", __func__, ipo_settings->type);
break;
}
-
+
return result;
}
@@ -897,12 +897,12 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
bGPdata *gpd = CTX_data_gpencil_data(C);
bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C);
bGPDframe *actframe = active_gpl->actframe;
-
+
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate;
eGP_Interpolate_SettingsFlag flag = ipo_settings->flag;
-
+
/* cannot interpolate if not between 2 frames */
if (ELEM(NULL, actframe, actframe->next)) {
BKE_report(op->reports, RPT_ERROR, "Cannot find a pair of grease pencil frames to interpolate between in active layer");
@@ -913,13 +913,13 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Cannot interpolate as current frame already has existing grease pencil frames");
return OPERATOR_CANCELLED;
}
-
+
/* loop all layer to check if need interpolation */
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
bGPDframe *prevFrame, *nextFrame;
bGPDstroke *gps_from, *gps_to;
int cframe, fFrame;
-
+
/* all layers or only active */
if (((flag & GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS) == 0) && (gpl != active_gpl)) {
continue;
@@ -928,19 +928,19 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
if (!gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
continue;
}
-
+
/* store extremes */
prevFrame = gpl->actframe;
nextFrame = gpl->actframe->next;
-
+
/* Loop over intermediary frames and create the interpolation */
for (cframe = prevFrame->framenum + 1; cframe < nextFrame->framenum; cframe++) {
bGPDframe *interFrame = NULL;
float factor;
-
+
/* get interpolation factor */
factor = (float)(cframe - prevFrame->framenum) / (nextFrame->framenum - prevFrame->framenum + 1);
-
+
if (ipo_settings->type == GP_IPO_CURVEMAP) {
/* custom curvemap */
if (ipo_settings->custom_ipo) {
@@ -954,11 +954,11 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
/* easing equation... */
factor = gp_interpolate_seq_easing_calc(ipo_settings, factor);
}
-
+
/* create new strokes data with interpolated points reading original stroke */
for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) {
bGPDstroke *new_stroke;
-
+
/* only selected */
if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) {
continue;
@@ -971,20 +971,20 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
if (ED_gpencil_stroke_color_use(gpl, gps_from) == false) {
continue;
}
-
+
/* get final stroke to interpolate */
fFrame = BLI_findindex(&prevFrame->strokes, gps_from);
gps_to = BLI_findlink(&nextFrame->strokes, fFrame);
if (gps_to == NULL) {
continue;
}
-
+
/* create a new frame if needed */
if (interFrame == NULL) {
interFrame = BKE_gpencil_layer_getframe(gpl, cframe, GP_GETFRAME_ADD_NEW);
interFrame->key_type = BEZT_KEYTYPE_BREAKDOWN;
}
-
+
/* create new stroke */
new_stroke = MEM_dupallocN(gps_from);
new_stroke->points = MEM_dupallocN(gps_from->points);
@@ -999,19 +999,19 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
new_stroke->tot_triangles = 0;
new_stroke->flag |= GP_STROKE_RECALC_CACHES;
}
-
+
/* update points position */
gp_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
-
+
/* add to strokes */
BLI_addtail(&interFrame->strokes, new_stroke);
}
}
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1021,11 +1021,11 @@ void GPENCIL_OT_interpolate_sequence(wmOperatorType *ot)
ot->name = "Interpolate Sequence";
ot->idname = "GPENCIL_OT_interpolate_sequence";
ot->description = "Generate 'in-betweens' to smoothly interpolate between Grease Pencil frames";
-
+
/* api callbacks */
ot->exec = gpencil_interpolate_seq_exec;
ot->poll = gpencil_view3d_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1045,7 +1045,7 @@ static int gpencil_interpolate_reverse_poll(bContext *C)
CTX_wm_operator_poll_msg_set(C, "Expected current frame to be a breakdown");
return 0;
}
-
+
return 1;
}
@@ -1059,11 +1059,11 @@ static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op))
bGPDframe *start_key = NULL;
bGPDframe *end_key = NULL;
bGPDframe *gpf, *gpfn;
-
+
/* Only continue if we're currently on a breakdown keyframe */
if ((gpl->actframe == NULL) || (gpl->actframe->key_type != BEZT_KEYTYPE_BREAKDOWN))
continue;
-
+
/* Search left for "start_key" (i.e. the first breakdown to remove) */
gpf = gpl->actframe;
while (gpf) {
@@ -1077,7 +1077,7 @@ static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
/* Search right for "end_key" (i.e. the last breakdown to remove) */
gpf = gpl->actframe;
while (gpf) {
@@ -1091,36 +1091,36 @@ static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
/* Did we find anything? */
/* NOTE: We should only proceed if there's something before/after these extents...
* Otherwise, there's just an extent of breakdowns with no keys to interpolate between
*/
- if ((start_key && end_key) &&
+ if ((start_key && end_key) &&
ELEM(NULL, start_key->prev, end_key->next) == false)
{
/* Set actframe to the key before start_key, since the keys have been removed now */
gpl->actframe = start_key->prev;
-
+
/* Free each frame we're removing (except the last one) */
for (gpf = start_key; gpf && gpf != end_key; gpf = gpfn) {
gpfn = gpf->next;
-
+
/* free strokes and their associated memory */
BKE_gpencil_free_strokes(gpf);
BLI_freelinkN(&gpl->frames, gpf);
}
-
+
/* Now free the last one... */
BKE_gpencil_free_strokes(end_key);
BLI_freelinkN(&gpl->frames, end_key);
}
}
CTX_DATA_END;
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1130,11 +1130,11 @@ void GPENCIL_OT_interpolate_reverse(wmOperatorType *ot)
ot->name = "Remove Breakdowns";
ot->idname = "GPENCIL_OT_interpolate_reverse";
ot->description = "Remove breakdown frames generated by interpolating between two Grease Pencil frames";
-
+
/* callbacks */
ot->exec = gpencil_interpolate_reverse_exec;
ot->poll = gpencil_interpolate_reverse_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 2119569298d..cb6ccc8d8ef 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -57,28 +57,28 @@ static void ed_keymap_gpencil_general(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil", 0, 0);
wmKeyMapItem *kmi;
-
+
/* Draw --------------------------------------- */
/* draw */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
-
+
/* draw - straight lines */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
-
+
/* draw - poly lines */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, KM_CTRL, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_POLY);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
-
+
/* erase */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, 0, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
-
+
/* Tablet Mappings for Drawing ------------------ */
/* For now, only support direct drawing using the eraser, as most users using a tablet
* may still want to use that as their primary pointing device!
@@ -88,24 +88,24 @@ static void ed_keymap_gpencil_general(wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
#endif
-
+
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_ERASER, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
-
+
/* Viewport Tools ------------------------------- */
-
+
/* Enter EditMode */
WM_keymap_add_item(keymap, "GPENCIL_OT_editmode_toggle", TABKEY, KM_PRESS, 0, DKEY);
-
+
/* Pie Menu - For standard tools */
WM_keymap_add_menu_pie(keymap, "GPENCIL_MT_pie_tool_palette", QKEY, KM_PRESS, 0, DKEY);
WM_keymap_add_menu_pie(keymap, "GPENCIL_MT_pie_settings_palette", WKEY, KM_PRESS, 0, DKEY);
-
+
/* Add Blank Frame */
/* XXX: BKEY or NKEY? BKEY is easier to reach from DKEY, so we'll use that for now */
WM_keymap_add_item(keymap, "GPENCIL_OT_blank_frame_add", BKEY, KM_PRESS, 0, DKEY);
-
+
/* Delete Active Frame - For easier video tutorials/review sessions */
/* NOTE: This works even when not in EditMode */
WM_keymap_add_item(keymap, "GPENCIL_OT_active_frames_delete_all", XKEY, KM_PRESS, 0, DKEY);
@@ -125,81 +125,81 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Edit Mode", 0, 0);
wmKeyMapItem *kmi;
-
+
/* set poll callback - so that this keymap only gets enabled when stroke editmode is enabled */
keymap->poll = gp_stroke_editmode_poll;
-
+
/* ----------------------------------------------- */
-
+
/* Exit EditMode */
WM_keymap_add_item(keymap, "GPENCIL_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0);
-
+
/* Pie Menu - For settings/tools easy access */
WM_keymap_add_menu_pie(keymap, "GPENCIL_MT_pie_sculpt", EKEY, KM_PRESS, 0, DKEY);
-
+
/* Brush Settings */
/* NOTE: We cannot expose these in the standard keymap, as they will interfere with regular hotkeys
* in other modes. However, when we are dealing with Stroke Edit Mode, we know for certain
* that the only data being edited is that of the Grease Pencil strokes
*/
-
+
/* CTRL + FKEY = Eraser Radius */
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path_primary", "user_preferences.edit.grease_pencil_eraser_radius");
-
+
/* Interpolation */
WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate", EKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate_sequence", EKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
/* Sculpting ------------------------------------- */
-
+
/* Brush-Based Editing:
- * EKEY + LMB = Single stroke, draw immediately
+ * EKEY + LMB = Single stroke, draw immediately
* + Other Modifiers (Ctrl/Shift) = Invert, Smooth, etc.
*
* For the modal version, use D+E -> Sculpt
*/
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, 0, EKEY);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
-
+
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, EKEY);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
/*RNA_boolean_set(kmi->ptr, "use_invert", true);*/
-
+
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_SHIFT, EKEY);
RNA_boolean_set(kmi->ptr, "wait_for_input", false);
/*RNA_boolean_set(kmi->ptr, "use_smooth", true);*/
-
-
+
+
/* Shift-FKEY = Sculpt Strength */
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.strength");
-
+
/* FKEY = Sculpt Brush Size */
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.size");
-
-
+
+
/* Selection ------------------------------------- */
/* select all */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_all", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
-
+
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
-
+
/* circle select */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_circle", CKEY, KM_PRESS, 0, 0);
-
+
/* border select */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0);
-
+
/* lasso select */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
-
+
/* In the Node Editor, lasso select needs ALT modifier too (as somehow CTRL+LMB drag gets taken for "cut" quite early)
* There probably isn't too much harm adding this for other editors too as part of standard GP editing keymap. This hotkey
* combo doesn't seem to see much use under standard scenarios?
@@ -208,57 +208,57 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
-
+
/* normal select */
WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", true);
RNA_boolean_set(kmi->ptr, "toggle", true);
-
+
/* whole stroke select */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "entire_strokes", true);
-
+
/* select linked */
/* NOTE: While LKEY is redundant, not having it breaks the mode illusion too much */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* select grouped */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* select more/less */
WM_keymap_add_item(keymap, "GPENCIL_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
-
+
/* Editing ----------------------------------------- */
-
+
/* duplicate and move selected points */
WM_keymap_add_item(keymap, "GPENCIL_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* delete */
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_gpencil_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_gpencil_delete", DELKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "GPENCIL_OT_dissolve", XKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_dissolve", DELKEY, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "GPENCIL_OT_active_frames_delete_all", XKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* menu edit specials */
WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_edit_specials", WKEY, KM_PRESS, 0, 0);
/* join strokes */
WM_keymap_add_item(keymap, "GPENCIL_OT_stroke_join", JKEY, KM_PRESS, KM_CTRL, 0);
-
+
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_stroke_join", JKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", GP_STROKE_JOINCOPY);
-
+
/* copy + paste */
WM_keymap_add_item(keymap, "GPENCIL_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
-
+
#ifdef __APPLE__
WM_keymap_add_item(keymap, "GPENCIL_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
@@ -266,50 +266,50 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
/* snap */
WM_keymap_add_menu(keymap, "GPENCIL_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
-
-
+
+
/* convert to geometry */
WM_keymap_add_item(keymap, "GPENCIL_OT_convert", CKEY, KM_PRESS, KM_ALT, 0);
-
-
+
+
/* Show/Hide */
/* NOTE: These are available only in EditMode now, since they clash with general-purpose hotkeys */
WM_keymap_add_item(keymap, "GPENCIL_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
-
+
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_hide", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
-
+
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
WM_keymap_add_item(keymap, "GPENCIL_OT_selection_opacity_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* Isolate Layer */
WM_keymap_add_item(keymap, "GPENCIL_OT_layer_isolate", PADASTERKEY, KM_PRESS, 0, 0);
-
+
/* Move to Layer */
WM_keymap_add_item(keymap, "GPENCIL_OT_move_to_layer", MKEY, KM_PRESS, 0, 0);
/* Transform Tools */
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_rotate", RKEY, KM_PRESS, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_resize", SKEY, KM_PRESS, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
-
+
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_bend", WKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "TRANSFORM_OT_tosphere", SKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "TRANSFORM_OT_shear", SKEY, KM_PRESS, KM_ALT | KM_CTRL | KM_SHIFT, 0);
-
+
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_GPENCIL_SHRINKFATTEN);
-
+
/* Proportional Editing */
ED_keymap_proportional_cycle(keyconf, keymap);
ED_keymap_proportional_editmode(keyconf, keymap, true);
@@ -328,11 +328,11 @@ void ED_keymap_gpencil(wmKeyConfig *keyconf)
void ED_operatortypes_gpencil(void)
{
/* Drawing ----------------------- */
-
+
WM_operatortype_append(GPENCIL_OT_draw);
-
+
/* Editing (Strokes) ------------ */
-
+
WM_operatortype_append(GPENCIL_OT_editmode_toggle);
WM_operatortype_append(GPENCIL_OT_selection_opacity_toggle);
@@ -341,41 +341,41 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_select_circle);
WM_operatortype_append(GPENCIL_OT_select_border);
WM_operatortype_append(GPENCIL_OT_select_lasso);
-
+
WM_operatortype_append(GPENCIL_OT_select_linked);
WM_operatortype_append(GPENCIL_OT_select_grouped);
WM_operatortype_append(GPENCIL_OT_select_more);
WM_operatortype_append(GPENCIL_OT_select_less);
WM_operatortype_append(GPENCIL_OT_select_first);
WM_operatortype_append(GPENCIL_OT_select_last);
-
+
WM_operatortype_append(GPENCIL_OT_duplicate);
WM_operatortype_append(GPENCIL_OT_delete);
WM_operatortype_append(GPENCIL_OT_dissolve);
WM_operatortype_append(GPENCIL_OT_copy);
WM_operatortype_append(GPENCIL_OT_paste);
-
+
WM_operatortype_append(GPENCIL_OT_move_to_layer);
WM_operatortype_append(GPENCIL_OT_layer_change);
-
+
WM_operatortype_append(GPENCIL_OT_snap_to_grid);
WM_operatortype_append(GPENCIL_OT_snap_to_cursor);
WM_operatortype_append(GPENCIL_OT_snap_cursor_to_selected);
-
+
WM_operatortype_append(GPENCIL_OT_reproject);
-
+
WM_operatortype_append(GPENCIL_OT_brush_paint);
-
+
/* Editing (Buttons) ------------ */
-
+
WM_operatortype_append(GPENCIL_OT_data_add);
WM_operatortype_append(GPENCIL_OT_data_unlink);
-
+
WM_operatortype_append(GPENCIL_OT_layer_add);
WM_operatortype_append(GPENCIL_OT_layer_remove);
WM_operatortype_append(GPENCIL_OT_layer_move);
WM_operatortype_append(GPENCIL_OT_layer_duplicate);
-
+
WM_operatortype_append(GPENCIL_OT_hide);
WM_operatortype_append(GPENCIL_OT_reveal);
WM_operatortype_append(GPENCIL_OT_lock_all);
@@ -384,10 +384,10 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_layer_merge);
WM_operatortype_append(GPENCIL_OT_blank_frame_add);
-
+
WM_operatortype_append(GPENCIL_OT_active_frame_delete);
WM_operatortype_append(GPENCIL_OT_active_frames_delete_all);
-
+
WM_operatortype_append(GPENCIL_OT_convert);
WM_operatortype_append(GPENCIL_OT_stroke_arrange);
@@ -423,7 +423,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_brush_select);
/* Editing (Time) --------------- */
-
+
/* Interpolation */
WM_operatortype_append(GPENCIL_OT_interpolate);
WM_operatortype_append(GPENCIL_OT_interpolate_sequence);
@@ -434,7 +434,7 @@ void ED_operatormacros_gpencil(void)
{
wmOperatorType *ot;
wmOperatorTypeMacro *otmacro;
-
+
/* Duplicate + Move = Interactively place newly duplicated strokes */
ot = WM_operatortype_append_macro("GPENCIL_OT_duplicate_move", "Duplicate Strokes",
"Make copies of the selected Grease Pencil strokes and move them",
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index f9b5966dee3..437d5cef6f8 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -46,14 +46,15 @@
#include "PIL_time.h"
-#include "BKE_paint.h"
-#include "BKE_gpencil.h"
+#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_gpencil.h"
+#include "BKE_main.h"
+#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_screen.h"
#include "BKE_tracking.h"
-#include "BKE_colortools.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -115,37 +116,38 @@ typedef enum eGPencil_PaintFlags {
* "p" = op->customdata
*/
typedef struct tGPsdata {
+ Main *bmain;
Scene *scene; /* current scene from context */
struct Depsgraph *depsgraph;
-
+
wmWindow *win; /* window where painting originated */
ScrArea *sa; /* area where painting originated */
ARegion *ar; /* region where painting originated */
View2D *v2d; /* needed for GP_STROKE_2DSPACE */
rctf *subrect; /* for using the camera rect within the 3d view */
rctf subrect_data;
-
+
GP_SpaceConversion gsc; /* settings to pass to gp_points_to_xy() */
-
+
PointerRNA ownerPtr; /* pointer to owner of gp-datablock */
bGPdata *gpd; /* gp-datablock layer comes from */
bGPDlayer *gpl; /* layer we're working on */
bGPDframe *gpf; /* frame we're working on */
-
+
char *align_flag; /* projection-mode flags (toolsettings - eGPencil_Placement_Flags) */
-
+
eGPencil_PaintStatus status; /* current status of painting */
eGPencil_PaintModes paintmode; /* mode for painting */
eGPencil_PaintFlags flags; /* flags that can get set during runtime (eGPencil_PaintFlags) */
-
+
short radius; /* radius of influence for eraser */
-
+
int mval[2]; /* current mouse-position */
int mvalo[2]; /* previous recorded mouse-position */
-
+
float pressure; /* current stylus pressure */
float opressure; /* previous stylus pressure */
-
+
/* These need to be doubles, as (at least under unix) they are in seconds since epoch,
* float (and its 7 digits precision) is definitively not enough here!
* double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least.
@@ -153,13 +155,13 @@ typedef struct tGPsdata {
double inittime; /* Used when converting to path */
double curtime; /* Used when converting to path */
double ocurtime; /* Used when converting to path */
-
+
float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space
* to region space */
float mat[4][4];
-
+
float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */
-
+
void *erasercursor; /* radial cursor data for drawing eraser */
bGPDpalettecolor *palettecolor; /* current palette color */
@@ -216,7 +218,7 @@ static int gpencil_draw_poll(bContext *C)
else {
CTX_wm_operator_poll_msg_set(C, "Active region not set");
}
-
+
return 0;
}
@@ -237,12 +239,12 @@ static void gp_get_3d_reference(tGPsdata *p, float vec[3])
{
View3D *v3d = p->sa->spacedata.first;
const float *fp = ED_view3d_cursor3d_get(p->scene, v3d)->location;
-
+
/* the reference point used depends on the owner... */
#if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */
if (p->ownerPtr.type == &RNA_Object) {
Object *ob = (Object *)p->ownerPtr.data;
-
+
/* active Object
* - use relative distance of 3D-cursor from object center
*/
@@ -263,24 +265,24 @@ static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2])
{
int dx = abs(mval[0] - pmval[0]);
int dy = abs(mval[1] - pmval[1]);
-
+
/* if buffer is empty, just let this go through (i.e. so that dots will work) */
if (p->gpd->sbuffer_size == 0)
return true;
-
+
/* check if mouse moved at least certain distance on both axes (best case)
* - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand
*/
else if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX))
return true;
-
+
/* check if the distance since the last point is significant enough
* - prevents points being added too densely
* - distance here doesn't use sqrt to prevent slowness... we should still be safe from overflows though
*/
else if ((dx * dx + dy * dy) > MIN_EUCLIDEAN_PX * MIN_EUCLIDEAN_PX)
return true;
-
+
/* mouse 'didn't move' */
else
return false;
@@ -349,7 +351,7 @@ static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3], float *depth)
{
bGPdata *gpd = p->gpd;
-
+
/* in 3d-space - pt->x/y/z are 3 side-by-side floats */
if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) {
if (gpencil_project_check(p) && (ED_view3d_autodist_simple(p->ar, mval, out, 0, depth))) {
@@ -362,7 +364,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
float rvec[3], dvec[3];
float mval_f[2] = {UNPACK2(mval)};
float zfac;
-
+
/* Current method just converts each point in screen-coordinates to
* 3D-coordinates using the 3D-cursor as reference. In general, this
* works OK, but it could of course be improved.
@@ -371,10 +373,10 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
* - investigate using nearest point(s) on a previous stroke as
* reference point instead or as offset, for easier stroke matching
*/
-
+
gp_get_3d_reference(p, rvec);
zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL);
-
+
if (ED_view3d_project_float_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
sub_v2_v2v2(mval_f, mval_prj, mval_f);
ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac);
@@ -385,13 +387,13 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
}
}
}
-
+
/* 2d - on 'canvas' (assume that p->v2d is set) */
else if ((gpd->sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) {
UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &out[0], &out[1]);
mul_v3_m4v3(out, p->imat, out);
}
-
+
/* 2d - relative to screen (viewport area) */
else {
if (p->subrect == NULL) { /* normal 3D view */
@@ -477,7 +479,7 @@ static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const
fac = 1.0f - fabs(dot_v2v2(v0, mvec)); /* 0.0 to 1.0 */
/* interpolate with previous point for smoother transitions */
mpressure = interpf(pt->pressure - (sen * fac), (pt - 1)->pressure, 0.3f);
- pt->pressure = mpressure;
+ pt->pressure = mpressure;
CLAMP(pt->pressure, GPENCIL_ALPHA_OPACITY_THRESH, 1.0f);
}
@@ -499,13 +501,13 @@ static short gp_stroke_addpoint(
if (gpd->sbuffer_size == 0) {
/* first point in buffer (start point) */
pt = (tGPspoint *)(gpd->sbuffer);
-
+
/* store settings */
copy_v2_v2_int(&pt->x, mval);
pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
-
+
/* increment buffer size */
gpd->sbuffer_size++;
}
@@ -514,17 +516,17 @@ static short gp_stroke_addpoint(
* - assume that pointers for this are always valid...
*/
pt = ((tGPspoint *)(gpd->sbuffer) + 1);
-
+
/* store settings */
copy_v2_v2_int(&pt->x, mval);
pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
-
+
/* now the buffer has 2 points (and shouldn't be allowed to get any larger) */
gpd->sbuffer_size = 2;
}
-
+
/* can keep carrying on this way :) */
return GP_STROKEADD_NORMAL;
}
@@ -532,10 +534,10 @@ static short gp_stroke_addpoint(
/* check if still room in buffer */
if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX)
return GP_STROKEADD_OVERFLOW;
-
+
/* get pointer to destination point */
pt = ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size);
-
+
/* store settings */
/* pressure */
if (brush->flag & GP_BRUSH_USE_PRESSURE) {
@@ -597,10 +599,10 @@ static short gp_stroke_addpoint(
/* point time */
pt->time = (float)(curtime - p->inittime);
-
+
/* increment counters */
gpd->sbuffer_size++;
-
+
/* check if another operation can still occur */
if (gpd->sbuffer_size == GP_STROKE_BUFFER_MAX)
return GP_STROKEADD_FULL;
@@ -608,17 +610,17 @@ static short gp_stroke_addpoint(
return GP_STROKEADD_NORMAL;
}
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
-
+
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
/* get pointer to destination point */
pt = (tGPspoint *)(gpd->sbuffer);
-
+
/* store settings */
copy_v2_v2_int(&pt->x, mval);
pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
-
+
/* if there's stroke for this poly line session add (or replace last) point
* to stroke. This allows to draw lines more interactively (see new segment
* during mouse slide, e.g.)
@@ -626,15 +628,15 @@ static short gp_stroke_addpoint(
if (gp_stroke_added_check(p)) {
bGPDstroke *gps = p->gpf->strokes.last;
bGPDspoint *pts;
-
+
/* first time point is adding to temporary buffer -- need to allocate new point in stroke */
if (gpd->sbuffer_size == 0) {
gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1));
gps->totpoints++;
}
-
+
pts = &gps->points[gps->totpoints - 1];
-
+
/* special case for poly lines: normally,
* depth is needed only when creating new stroke from buffer,
* but poly lines are converting to stroke instantly,
@@ -642,12 +644,12 @@ static short gp_stroke_addpoint(
*/
if (gpencil_project_check(p)) {
View3D *v3d = p->sa->spacedata.first;
-
+
view3d_region_operator_needs_opengl(p->win, p->ar);
ED_view3d_autodist_init(
p->depsgraph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
}
-
+
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL);
/* if axis locked, reproject to plane locked (only in 3d space) */
@@ -665,11 +667,11 @@ static short gp_stroke_addpoint(
/* force fill recalc */
gps->flag |= GP_STROKE_RECALC_CACHES;
}
-
+
/* increment counters */
if (gpd->sbuffer_size == 0)
gpd->sbuffer_size++;
-
+
return GP_STROKEADD_NORMAL;
}
@@ -688,15 +690,15 @@ static void gp_stroke_simplify(tGPsdata *p)
short num_points = gpd->sbuffer_size;
short flag = gpd->sbuffer_sflag;
short i, j;
-
+
/* only simplify if simplification is enabled, and we're not doing a straight line */
if (!(U.gp_settings & GP_PAINT_DOSIMPLIFY) || (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT))
return;
-
+
/* don't simplify if less than 4 points in buffer */
if ((num_points <= 4) || (old_points == NULL))
return;
-
+
/* clear buffer (but don't free mem yet) so that we can write to it
* - firstly set sbuffer to NULL, so a new one is allocated
* - secondly, reset flag after, as it gets cleared auto
@@ -704,7 +706,7 @@ static void gp_stroke_simplify(tGPsdata *p)
gpd->sbuffer = NULL;
gp_session_validatebuffer(p);
gpd->sbuffer_sflag = flag;
-
+
/* macro used in loop to get position of new point
* - used due to the mixture of datatypes in use here
*/
@@ -715,30 +717,30 @@ static void gp_stroke_simplify(tGPsdata *p)
pressure += old_points[offs].pressure * sfac; \
time += old_points[offs].time * sfac; \
} (void)0
-
+
/* XXX Here too, do not lose start and end points! */
gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time);
for (i = 0, j = 0; i < num_points; i++) {
if (i - j == 3) {
float co[2], pressure, time;
int mco[2];
-
+
/* initialize values */
co[0] = 0.0f;
co[1] = 0.0f;
pressure = 0.0f;
time = 0.0f;
-
+
/* using macro, calculate new point */
GP_SIMPLIFY_AVPOINT(j, -0.25f);
GP_SIMPLIFY_AVPOINT(j + 1, 0.75f);
GP_SIMPLIFY_AVPOINT(j + 2, 0.75f);
GP_SIMPLIFY_AVPOINT(j + 3, -0.25f);
-
+
/* set values for adding */
mco[0] = (int)co[0];
mco[1] = (int)co[1];
-
+
/* ignore return values on this... assume to be ok for now */
gp_stroke_addpoint(p, mco, pressure, p->inittime + (double)time);
@@ -747,7 +749,7 @@ static void gp_stroke_simplify(tGPsdata *p)
}
gp_stroke_addpoint(p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure,
p->inittime + (double)old_points[num_points - 1].time);
-
+
/* free old buffer */
MEM_freeN(old_points);
}
@@ -762,11 +764,11 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
tGPspoint *ptc;
bGPDbrush *brush = p->brush;
ToolSettings *ts = p->scene->toolsettings;
-
+
int i, totelem;
/* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */
int depth_margin = (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 4 : 0;
-
+
/* get total number of points to allocate space for
* - drawing straight-lines only requires the endpoints
*/
@@ -774,14 +776,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
totelem = (gpd->sbuffer_size >= 2) ? 2 : gpd->sbuffer_size;
else
totelem = gpd->sbuffer_size;
-
+
/* exit with error if no valid points from this stroke */
if (totelem == 0) {
if (G.debug & G_DEBUG)
printf("Error: No valid points in stroke buffer to convert (tot=%d)\n", gpd->sbuffer_size);
return;
}
-
+
/* special case for poly line -- for already added stroke during session
* coordinates are getting added to stroke immediately to allow more
* interactive behavior
@@ -791,23 +793,23 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
return;
}
}
-
+
/* allocate memory for a new stroke */
gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
-
+
/* copy appropriate settings for stroke */
gps->totpoints = totelem;
gps->thickness = brush->thickness;
gps->flag = gpd->sbuffer_sflag;
gps->inittime = p->inittime;
-
+
/* enable recalculation flag by default (only used if hq fill) */
gps->flag |= GP_STROKE_RECALC_CACHES;
/* allocate enough memory for a continuous array for storage points */
int sublevel = brush->sublevel;
int new_totpoints = gps->totpoints;
-
+
for (i = 0; i < sublevel; i++) {
new_totpoints += new_totpoints - 1;
}
@@ -818,14 +820,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
gps->tot_triangles = 0;
/* set pointer to first non-initialized point */
pt = gps->points + (gps->totpoints - totelem);
-
+
/* copy points from the buffer to the stroke */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only -> only endpoints */
{
/* first point */
ptc = gpd->sbuffer;
-
+
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* if axis locked, reproject to plane locked (only in 3d space) */
@@ -841,14 +843,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
pt->strength = ptc->strength;
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt->time = ptc->time;
-
+
pt++;
}
-
+
if (totelem == 2) {
/* last point if applicable */
ptc = ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1);
-
+
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* if axis locked, reproject to plane locked (only in 3d space) */
@@ -870,7 +872,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
/* first point */
ptc = gpd->sbuffer;
-
+
/* convert screen-coordinates to appropriate coordinates (and store them) */
gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* if axis locked, reproject to plane locked (only in 3d space) */
@@ -1012,7 +1014,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
gps->palcolor = palcolor;
BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname));
- /* add stroke to frame, usually on tail of the listbase, but if on back is enabled the stroke is added on listbase head
+ /* add stroke to frame, usually on tail of the listbase, but if on back is enabled the stroke is added on listbase head
* because the drawing order is inverse and the head stroke is the first to draw. This is very useful for artist
* when drawing the background
*/
@@ -1060,7 +1062,7 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, cons
mul_v3_m4v3(fpt, diff_mat, &pt->x);
const float depth_pt = view3d_point_depth(rv3d, fpt);
-
+
if (depth_pt > depth_mval) {
return true;
}
@@ -1075,13 +1077,13 @@ static float gp_stroke_eraser_calc_influence(tGPsdata *p, const int mval[2], con
/* Linear Falloff... */
float distance = (float)len_v2v2_int(mval, co);
float fac;
-
+
CLAMP(distance, 0.0f, (float)radius);
fac = 1.0f - (distance / (float)radius);
-
+
/* Control this further using pen pressure */
fac *= p->pressure;
-
+
/* Return influence factor computed here */
return fac;
}
@@ -1142,15 +1144,15 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
* below which we would have invisible strokes
*/
const float cull_thresh = (gps->thickness) ? 1.0f / ((float)gps->thickness) : 1.0f;
-
+
/* Amount to decrease the pressure of each point with each stroke */
// TODO: Fetch from toolsettings, or compute based on thickness instead?
const float strength = 0.1f;
-
+
/* Perform culling? */
bool do_cull = false;
-
-
+
+
/* Clear Tags
*
* Note: It's better this way, as we are sure that
@@ -1161,7 +1163,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
bGPDspoint *pt = &gps->points[i];
pt->flag &= ~GP_SPOINT_TAG;
}
-
+
/* First Pass: Loop over the points in the stroke
* 1) Thin out parts of the stroke under the brush
* 2) Tag "too thin" parts for removal (in second pass)
@@ -1174,7 +1176,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
/* only process if it hasn't been masked out... */
if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT))
continue;
-
+
if (gpl->parent == NULL) {
gp_point_to_xy(&p->gsc, gps, pt1, &pc1[0], &pc1[1]);
gp_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]);
@@ -1207,7 +1209,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
*/
pt1->pressure -= gp_stroke_eraser_calc_influence(p, mval, radius, pc1) * strength;
pt2->pressure -= gp_stroke_eraser_calc_influence(p, mval, radius, pc2) * strength / 2.0f;
-
+
/* 2) Tag any point with overly low influence for removal in the next pass */
if (pt1->pressure < cull_thresh) {
pt1->flag |= GP_SPOINT_TAG;
@@ -1221,7 +1223,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
}
}
}
-
+
/* Second Pass: Remove any points that are tagged */
if (do_cull) {
gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG);
@@ -1235,13 +1237,13 @@ static void gp_stroke_doeraser(tGPsdata *p)
bGPDlayer *gpl;
bGPDstroke *gps, *gpn;
rcti rect;
-
+
/* rect is rectangle of eraser */
rect.xmin = p->mval[0] - p->radius;
rect.ymin = p->mval[1] - p->radius;
rect.xmax = p->mval[0] + p->radius;
rect.ymax = p->mval[1] + p->radius;
-
+
if (p->sa->spacetype == SPACE_VIEW3D) {
if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) {
View3D *v3d = p->sa->spacedata.first;
@@ -1249,14 +1251,14 @@ static void gp_stroke_doeraser(tGPsdata *p)
ED_view3d_autodist_init(p->depsgraph, p->ar, v3d, 0);
}
}
-
+
/* loop over all layers too, since while it's easy to restrict editing to
* only a subset of layers, it is harder to perform the same erase operation
* on multiple layers...
*/
for (gpl = p->gpd->layers.first; gpl; gpl = gpl->next) {
bGPDframe *gpf = gpl->actframe;
-
+
/* only affect layer if it's editable (and visible) */
if (gpencil_layer_is_editable(gpl) == false) {
continue;
@@ -1264,7 +1266,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
else if (gpf == NULL) {
continue;
}
-
+
/* loop over strokes, checking segments for intersections */
for (gps = gpf->strokes.first; gps; gps = gpn) {
gpn = gps->next;
@@ -1289,7 +1291,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
static void gp_session_validatebuffer(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
-
+
/* clear memory of buffer (or allocate it if starting a new session) */
if (gpd->sbuffer) {
/* printf("\t\tGP - reset sbuffer\n"); */
@@ -1299,13 +1301,13 @@ static void gp_session_validatebuffer(tGPsdata *p)
/* printf("\t\tGP - allocate sbuffer\n"); */
gpd->sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
}
-
+
/* reset indices */
gpd->sbuffer_size = 0;
-
+
/* reset flags */
gpd->sbuffer_sflag = 0;
-
+
/* reset inittime */
p->inittime = 0.0;
}
@@ -1316,7 +1318,7 @@ static bGPDpalettecolor *gp_create_new_color(bGPDpalette *palette)
bGPDpalettecolor *palcolor;
palcolor = BKE_gpencil_palettecolor_addnew(palette, DATA_("Color"), true);
-
+
return palcolor;
}
@@ -1389,7 +1391,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
ScrArea *curarea = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
ToolSettings *ts = CTX_data_tool_settings(C);
-
+
/* make sure the active view (at the starting time) is a 3d-view */
if (curarea == NULL) {
p->status = GP_STATUS_ERROR;
@@ -1397,22 +1399,23 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
printf("Error: No active view for painting\n");
return 0;
}
-
+
/* pass on current scene and window */
+ p->bmain = CTX_data_main(C);
p->scene = CTX_data_scene(C);
p->depsgraph = CTX_data_depsgraph(C);
p->win = CTX_wm_window(C);
-
+
unit_m4(p->imat);
unit_m4(p->mat);
-
+
switch (curarea->spacetype) {
/* supported views first */
case SPACE_VIEW3D:
{
/* View3D *v3d = curarea->spacedata.first; */
/* RegionView3D *rv3d = ar->regiondata; */
-
+
/* set current area
* - must verify that region data is 3D-view (and not something else)
*/
@@ -1420,7 +1423,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
p->sa = curarea;
p->ar = ar;
p->align_flag = &ts->gpencil_v3d_align;
-
+
if (ar->regiondata == NULL) {
p->status = GP_STATUS_ERROR;
if (G.debug & G_DEBUG)
@@ -1432,7 +1435,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
case SPACE_NODE:
{
/* SpaceNode *snode = curarea->spacedata.first; */
-
+
/* set current area */
p->sa = curarea;
p->ar = ar;
@@ -1443,13 +1446,13 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
case SPACE_SEQ:
{
SpaceSeq *sseq = curarea->spacedata.first;
-
+
/* set current area */
p->sa = curarea;
p->ar = ar;
p->v2d = &ar->v2d;
p->align_flag = &ts->gpencil_seq_align;
-
+
/* check that gpencil data is allowed to be drawn */
if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
p->status = GP_STATUS_ERROR;
@@ -1462,7 +1465,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
case SPACE_IMAGE:
{
/* SpaceImage *sima = curarea->spacedata.first; */
-
+
/* set the current area */
p->sa = curarea;
p->ar = ar;
@@ -1474,7 +1477,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
{
SpaceClip *sc = curarea->spacedata.first;
MovieClip *clip = ED_space_clip_get_clip(sc);
-
+
if (clip == NULL) {
p->status = GP_STATUS_ERROR;
return false;
@@ -1485,15 +1488,15 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
p->ar = ar;
p->v2d = &ar->v2d;
p->align_flag = &ts->gpencil_v2d_align;
-
+
invert_m4_m4(p->imat, sc->unistabmat);
-
+
/* custom color for new layer */
p->custom_color[0] = 1.0f;
p->custom_color[1] = 0.0f;
p->custom_color[2] = 0.5f;
p->custom_color[3] = 0.9f;
-
+
if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
int framenr = ED_space_clip_get_clip_frame_number(sc);
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
@@ -1508,7 +1511,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
return false;
}
}
-
+
invert_m4_m4(p->mat, p->imat);
copy_m4_m4(p->gsc.mat, p->mat);
break;
@@ -1522,7 +1525,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
return 0;
}
}
-
+
/* get gp-data */
gpd_ptr = ED_gpencil_data_get_pointers(C, &p->ownerPtr);
if (gpd_ptr == NULL) {
@@ -1537,14 +1540,14 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
*gpd_ptr = BKE_gpencil_data_addnew("GPencil");
p->gpd = *gpd_ptr;
}
-
+
if (ED_gpencil_session_active() == 0) {
/* initialize undo stack,
* also, existing undo stack would make buffer drawn
*/
gpencil_undo_init(p->gpd);
}
-
+
/* clear out buffer (stored in gp-data), in case something contaminated it */
gp_session_validatebuffer(p);
/* set brush and create a new one if null */
@@ -1567,12 +1570,12 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
static tGPsdata *gp_session_initpaint(bContext *C)
{
tGPsdata *p = NULL;
-
+
/* create new context data */
p = MEM_callocN(sizeof(tGPsdata), "GPencil Drawing Data");
-
+
gp_session_initdata(C, p);
-
+
/* radius for eraser circle is defined in userprefs now */
/* NOTE: we do this here, so that if we exit immediately,
* erase size won't get lost
@@ -1587,18 +1590,18 @@ static tGPsdata *gp_session_initpaint(bContext *C)
static void gp_session_cleanup(tGPsdata *p)
{
bGPdata *gpd = (p) ? p->gpd : NULL;
-
+
/* error checking */
if (gpd == NULL)
return;
-
+
/* free stroke buffer */
if (gpd->sbuffer) {
/* printf("\t\tGP - free sbuffer\n"); */
MEM_freeN(gpd->sbuffer);
gpd->sbuffer = NULL;
}
-
+
/* clear flags */
gpd->sbuffer_size = 0;
gpd->sbuffer_sflag = 0;
@@ -1610,12 +1613,12 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
{
Scene *scene = p->scene;
ToolSettings *ts = scene->toolsettings;
-
+
/* get active layer (or add a new one if non-existent) */
p->gpl = BKE_gpencil_layer_getactive(p->gpd);
if (p->gpl == NULL) {
p->gpl = BKE_gpencil_layer_addnew(p->gpd, "GP_Layer", true);
-
+
if (p->custom_color[3])
copy_v3_v3(p->gpl->color, p->custom_color);
}
@@ -1625,7 +1628,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
printf("Error: Cannot paint on locked layer\n");
return;
}
-
+
/* get active frame (add a new one if not matching frame) */
if (paintmode == GP_PAINTMODE_ERASER) {
/* Eraser mode:
@@ -1634,12 +1637,12 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
* (to avoid problems with other tools which expect it to exist)
*/
bool has_layer_to_erase = false;
-
+
for (bGPDlayer *gpl = p->gpd->layers.first; gpl; gpl = gpl->next) {
/* Skip if layer not editable */
if (gpencil_layer_is_editable(gpl) == false)
continue;
-
+
/* Add a new frame if needed (and based off the active frame,
* as we need some existing strokes to erase)
*
@@ -1651,16 +1654,16 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
gpl->actframe = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_COPY);
has_layer_to_erase = true;
}
-
+
/* XXX: we omit GP_FRAME_PAINT here for now,
* as it is only really useful for doing
* paintbuffer drawing
*/
}
-
+
/* Ensure this gets set... */
p->gpf = p->gpl->actframe;
-
+
/* Restrict eraser to only affecting selected strokes, if the "selection mask" is on
* (though this is only available in editmode)
*/
@@ -1669,7 +1672,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
p->flags |= GP_PAINTFLAG_SELECTMASK;
}
}
-
+
if (has_layer_to_erase == false) {
p->status = GP_STATUS_ERROR;
//if (G.debug & G_DEBUG)
@@ -1680,14 +1683,14 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
else {
/* Drawing Modes - Add a new frame if needed on the active layer */
short add_frame_mode;
-
+
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST)
add_frame_mode = GP_GETFRAME_ADD_COPY;
else
add_frame_mode = GP_GETFRAME_ADD_NEW;
-
+
p->gpf = BKE_gpencil_layer_getframe(p->gpl, CFRA, add_frame_mode);
-
+
if (p->gpf == NULL) {
p->status = GP_STATUS_ERROR;
if (G.debug & G_DEBUG)
@@ -1698,12 +1701,12 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
p->gpf->flag |= GP_FRAME_PAINT;
}
}
-
+
/* set 'eraser' for this stroke if using eraser */
p->paintmode = paintmode;
if (p->paintmode == GP_PAINTMODE_ERASER) {
p->gpd->sbuffer_sflag |= GP_STROKE_ERASER;
-
+
/* check if we should respect depth while erasing */
if (p->sa->spacetype == SPACE_VIEW3D) {
if (p->gpl->flag & GP_LAYER_NO_XRAY) {
@@ -1714,25 +1717,25 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
else {
/* disable eraser flags - so that we can switch modes during a session */
p->gpd->sbuffer_sflag &= ~GP_STROKE_ERASER;
-
+
if (p->sa->spacetype == SPACE_VIEW3D) {
if (p->gpl->flag & GP_LAYER_NO_XRAY) {
p->flags &= ~GP_PAINTFLAG_V3D_ERASER_DEPTH;
}
}
}
-
+
/* set 'initial run' flag, which is only used to denote when a new stroke is starting */
p->flags |= GP_PAINTFLAG_FIRSTRUN;
-
-
+
+
/* when drawing in the camera view, in 2D space, set the subrect */
p->subrect = NULL;
if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) {
if (p->sa->spacetype == SPACE_VIEW3D) {
View3D *v3d = p->sa->spacedata.first;
RegionView3D *rv3d = p->ar->regiondata;
-
+
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
ED_view3d_calc_camera_border(p->scene, depsgraph, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */
@@ -1740,21 +1743,21 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
}
}
}
-
+
/* init stroke point space-conversion settings... */
p->gsc.gpd = p->gpd;
p->gsc.gpl = p->gpl;
-
+
p->gsc.sa = p->sa;
p->gsc.ar = p->ar;
p->gsc.v2d = p->v2d;
-
+
p->gsc.subrect_data = p->subrect_data;
p->gsc.subrect = p->subrect;
-
+
copy_m4_m4(p->gsc.mat, p->mat);
-
-
+
+
/* check if points will need to be made in view-aligned space */
if (*p->align_flag & GP_PROJECT_VIEWSPACE) {
switch (p->sa->spacetype) {
@@ -1776,7 +1779,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
case SPACE_IMAGE:
{
SpaceImage *sima = (SpaceImage *)p->sa->spacedata.first;
-
+
/* only set these flags if the image editor doesn't have an image active,
* otherwise user will be confused by strokes not appearing after they're drawn
*
@@ -1810,12 +1813,12 @@ static void gp_paint_strokeend(tGPsdata *p)
*/
if (gpencil_project_check(p)) {
View3D *v3d = p->sa->spacedata.first;
-
+
/* need to restore the original projection settings before packing up */
view3d_region_operator_needs_opengl(p->win, p->ar);
ED_view3d_autodist_init(p->depsgraph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
}
-
+
/* check if doing eraser or not */
if ((p->gpd->sbuffer_sflag & GP_STROKE_ERASER) == 0) {
/* simplify stroke before transferring? */
@@ -1824,7 +1827,7 @@ static void gp_paint_strokeend(tGPsdata *p)
/* transfer stroke to frame */
gp_stroke_newfrombuffer(p);
}
-
+
/* clean up buffer now */
gp_session_validatebuffer(p);
}
@@ -1839,7 +1842,7 @@ static void gp_paint_cleanup(tGPsdata *p)
/* finish off a stroke */
gp_paint_strokeend(p);
}
-
+
/* "unlock" frame */
if (p->gpf)
p->gpf->flag &= ~GP_FRAME_PAINT;
@@ -1912,7 +1915,7 @@ static bool gpencil_is_tablet_eraser_active(const wmEvent *event)
const wmTabletData *wmtab = event->tablet_data;
return (wmtab->Active == EVT_TABLET_ERASER);
}
-
+
return false;
}
@@ -1921,13 +1924,13 @@ static bool gpencil_is_tablet_eraser_active(const wmEvent *event)
static void gpencil_draw_exit(bContext *C, wmOperator *op)
{
tGPsdata *p = op->customdata;
-
+
/* clear undo stack */
gpencil_undo_finish();
-
+
/* restore cursor to indicate end of drawing */
WM_cursor_modal_restore(CTX_wm_window(C));
-
+
/* don't assume that operator data exists at all */
if (p) {
/* check size of buffer before cleanup, to determine if anything happened here */
@@ -1941,15 +1944,15 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
* have been toggled at some point.
*/
U.gp_eraser = p->radius;
-
+
/* cleanup */
gp_paint_cleanup(p);
gp_session_cleanup(p);
-
+
/* finally, free the temp data */
MEM_freeN(p);
}
-
+
op->customdata = NULL;
}
@@ -1966,7 +1969,7 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p;
eGPencil_PaintModes paintmode = RNA_enum_get(op->ptr, "mode");
-
+
/* check context */
p = op->customdata = gp_session_initpaint(C);
if ((p == NULL) || (p->status == GP_STATUS_ERROR)) {
@@ -1974,7 +1977,7 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
gpencil_draw_exit(C, op);
return 0;
}
-
+
/* init painting data */
gp_paint_initstroke(p, paintmode, CTX_data_depsgraph(C));
if (p->status == GP_STATUS_ERROR) {
@@ -1988,7 +1991,7 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
else {
p->keymodifier = -1;
}
-
+
/* everything is now setup ok */
return 1;
}
@@ -2015,7 +2018,7 @@ static void gpencil_draw_status_indicators(tGPsdata *p)
if (GPENCIL_SKETCH_SESSIONS_ON(p->scene))
ED_area_headerprint(p->sa, IFACE_("Grease Pencil: Drawing/erasing stroke... Release to end stroke"));
break;
-
+
case GP_STATUS_IDLING:
/* print status info */
switch (p->paintmode) {
@@ -2035,13 +2038,13 @@ static void gpencil_draw_status_indicators(tGPsdata *p)
ED_area_headerprint(p->sa, IFACE_("Grease Pencil Poly Session: LMB click to place next stroke vertex | "
"ESC/Enter to end (or click outside this area)"));
break;
-
+
default: /* unhandled future cases */
ED_area_headerprint(p->sa, IFACE_("Grease Pencil Session: ESC/Enter to end (or click outside this area)"));
break;
}
break;
-
+
case GP_STATUS_ERROR:
case GP_STATUS_DONE:
/* clear status string */
@@ -2076,7 +2079,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph
gp_paint_strokeend(p);
/* And start a new one!!! Else, projection errors! */
gp_paint_initstroke(p, p->paintmode, depsgraph);
-
+
/* start a new stroke, starting from previous point */
/* XXX Must manually reset inittime... */
/* XXX We only need to reuse previous point if overflow! */
@@ -2093,12 +2096,12 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph
/* the painting operation cannot continue... */
BKE_report(op->reports, RPT_ERROR, "Cannot paint stroke");
p->status = GP_STATUS_ERROR;
-
+
if (G.debug & G_DEBUG)
printf("Error: Grease-Pencil Paint - Add Point Invalid\n");
return;
}
-
+
/* store used values */
p->mvalo[0] = p->mval[0];
p->mvalo[1] = p->mval[1];
@@ -2114,13 +2117,13 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
PointerRNA itemptr;
float mousef[2];
int tablet = 0;
-
+
/* convert from window-space to area-space mouse coordinates
* NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding...
*/
p->mval[0] = event->mval[0] + 1;
p->mval[1] = event->mval[1] + 1;
-
+
/* verify key status for straight lines */
if ((event->ctrl > 0) || (event->alt > 0)) {
if (p->straight[0] == 0) {
@@ -2146,14 +2149,14 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
}
p->curtime = PIL_check_seconds_timer();
-
+
/* handle pressure sensitivity (which is supplied by tablets) */
if (event->tablet_data) {
const wmTabletData *wmtab = event->tablet_data;
-
+
tablet = (wmtab->Active != EVT_TABLET_NONE);
p->pressure = wmtab->Pressure;
-
+
/* Hack for pressure sensitive eraser on D+RMB when using a tablet:
* The pen has to float over the tablet surface, resulting in
* zero pressure (T47101). Ignore pressure values if floating
@@ -2170,11 +2173,11 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
/* No tablet data -> No pressure info is available */
p->pressure = 1.0f;
}
-
+
/* special exception for start of strokes (i.e. maybe for just a dot) */
if (p->flags & GP_PAINTFLAG_FIRSTRUN) {
p->flags &= ~GP_PAINTFLAG_FIRSTRUN;
-
+
p->mvalo[0] = p->mval[0];
p->mvalo[1] = p->mval[1];
p->opressure = p->pressure;
@@ -2188,7 +2191,7 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
if (tablet && (p->pressure >= 0.99f))
return;
}
-
+
/* check if alt key is pressed and limit to straight lines */
if (p->straight[0] != 0) {
if (p->straight[0] == 1) {
@@ -2203,15 +2206,15 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg
/* fill in stroke data (not actually used directly by gpencil_draw_apply) */
RNA_collection_add(op->ptr, "stroke", &itemptr);
-
+
mousef[0] = p->mval[0];
mousef[1] = p->mval[1];
RNA_float_set_array(&itemptr, "mouse", mousef);
RNA_float_set(&itemptr, "pressure", p->pressure);
RNA_boolean_set(&itemptr, "is_start", (p->flags & GP_PAINTFLAG_FIRSTRUN) != 0);
-
+
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
-
+
/* apply the current latest drawing point */
gpencil_draw_apply(op, p, depsgraph);
@@ -2226,9 +2229,9 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
{
tGPsdata *p = NULL;
Depsgraph *depsgraph = CTX_data_depsgraph(C);
-
+
/* printf("GPencil - Starting Re-Drawing\n"); */
-
+
/* try to initialize context data needed while drawing */
if (!gpencil_draw_init(C, op, NULL)) {
if (op->customdata) MEM_freeN(op->customdata);
@@ -2237,25 +2240,25 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
}
else
p = op->customdata;
-
+
/* printf("\tGP - Start redrawing stroke\n"); */
-
+
/* loop over the stroke RNA elements recorded (i.e. progress of mouse movement),
* setting the relevant values in context at each step, then applying
*/
RNA_BEGIN (op->ptr, itemptr, "stroke")
{
float mousef[2];
-
+
/* printf("\t\tGP - stroke elem\n"); */
-
+
/* get relevant data for this point from stroke */
RNA_float_get_array(&itemptr, "mouse", mousef);
p->mval[0] = (int)mousef[0];
p->mval[1] = (int)mousef[1];
p->pressure = RNA_float_get(&itemptr, "pressure");
p->curtime = (double)RNA_float_get(&itemptr, "time") + p->inittime;
-
+
if (RNA_boolean_get(&itemptr, "is_start")) {
/* if first-run flag isn't set already (i.e. not true first stroke),
* then we must terminate the previous one first before continuing
@@ -2266,30 +2269,30 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
gp_paint_initstroke(p, p->paintmode, depsgraph);
}
}
-
+
/* if first run, set previous data too */
if (p->flags & GP_PAINTFLAG_FIRSTRUN) {
p->flags &= ~GP_PAINTFLAG_FIRSTRUN;
-
+
p->mvalo[0] = p->mval[0];
p->mvalo[1] = p->mval[1];
p->opressure = p->pressure;
p->ocurtime = p->curtime;
}
-
+
/* apply this data as necessary now (as per usual) */
gpencil_draw_apply(op, p, depsgraph);
}
RNA_END;
-
+
/* printf("\tGP - done\n"); */
-
+
/* cleanup */
gpencil_draw_exit(C, op);
-
+
/* refreshes */
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -2300,10 +2303,10 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p = NULL;
-
+
if (G.debug & G_DEBUG)
printf("GPencil - Starting Drawing\n");
-
+
/* try to initialize context data needed while drawing */
if (!gpencil_draw_init(C, op, event)) {
if (op->customdata)
@@ -2314,17 +2317,17 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
}
else
p = op->customdata;
-
+
/* TODO: set any additional settings that we can take from the events?
* TODO? if tablet is erasing, force eraser to be on? */
-
+
/* TODO: move cursor setting stuff to stroke-start so that paintmode can be changed midway... */
-
+
/* if eraser is on, draw radial aid */
if (p->paintmode == GP_PAINTMODE_ERASER) {
gpencil_draw_toggle_eraser_cursor(C, p, true);
}
- /* set cursor
+ /* set cursor
* NOTE: This may change later (i.e. intentionally via brush toggle,
* or unintentionally if the user scrolls outside the area)...
*/
@@ -2345,7 +2348,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
/* printf("\tGP - hotkey invoked... waiting for click-drag\n"); */
op->flag |= OP_IS_MODAL_CURSOR_REGION;
}
-
+
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
/* add a modal handler for this operator, so that we can then draw continuous strokes */
WM_event_add_modal_handler(C, op);
@@ -2362,7 +2365,7 @@ static bool gpencil_area_exists(bContext *C, ScrArea *sa_test)
static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
{
tGPsdata *p = op->customdata;
-
+
/* we must check that we're still within the area that we're set up to work from
* otherwise we could crash (see bug #20586)
*/
@@ -2370,21 +2373,21 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
printf("\t\t\tGP - wrong area execution abort!\n");
p->status = GP_STATUS_ERROR;
}
-
+
/* printf("\t\tGP - start stroke\n"); */
-
+
/* we may need to set up paint env again if we're resuming */
/* XXX: watch it with the paintmode! in future,
* it'd be nice to allow changing paint-mode when in sketching-sessions */
-
+
if (gp_session_initdata(C, p))
gp_paint_initstroke(p, p->paintmode, CTX_data_depsgraph(C));
-
+
if (p->status != GP_STATUS_ERROR) {
p->status = GP_STATUS_PAINTING;
op->flag &= ~OP_IS_MODAL_CURSOR_REGION;
}
-
+
return op->customdata;
}
@@ -2395,12 +2398,12 @@ static void gpencil_stroke_end(wmOperator *op)
gp_paint_cleanup(p);
gpencil_undo_push(p->gpd);
-
+
gp_session_cleanup(p);
-
+
p->status = GP_STATUS_IDLING;
op->flag |= OP_IS_MODAL_CURSOR_REGION;
-
+
p->gpd = NULL;
p->gpl = NULL;
p->gpf = NULL;
@@ -2434,7 +2437,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
tGPsdata *p = op->customdata;
ToolSettings *ts = CTX_data_tool_settings(C);
int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */
-
+
/* if (event->type == NDOF_MOTION)
* return OPERATOR_PASS_THROUGH;
* -------------------------------
@@ -2447,7 +2450,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* better in tools that immediately apply
* in 3D space.
*/
-
+
if (p->status == GP_STATUS_IDLING) {
ARegion *ar = CTX_wm_region(C);
p->ar = ar;
@@ -2484,9 +2487,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_RUNNING_MODAL;
}
}
-
+
//printf("\tGP - handle modal event...\n");
-
+
/* exit painting mode (and/or end current stroke)
* NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647]
*/
@@ -2504,25 +2507,25 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
p->status = GP_STATUS_DONE;
estate = OPERATOR_FINISHED;
}
-
+
/* toggle painting mode upon mouse-button movement
* - LEFTMOUSE = standard drawing (all) / straight line drawing (all) / polyline (toolbox only)
* - RIGHTMOUSE = polyline (hotkey) / eraser (all)
* (Disabling RIGHTMOUSE case here results in bugs like [#32647])
* also making sure we have a valid event value, to not exit too early
*/
- if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && (event->val != KM_NOTHING)) {
+ if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && (ELEM(event->val, KM_PRESS, KM_RELEASE))) {
/* if painting, end stroke */
if (p->status == GP_STATUS_PAINTING) {
int sketch = 0;
-
+
/* basically, this should be mouse-button up = end stroke
* BUT what happens next depends on whether we 'painting sessions' is enabled
*/
sketch |= GPENCIL_SKETCH_SESSIONS_ON(p->scene);
/* polyline drawing is also 'sketching' -- all knots should be added during one session */
sketch |= (p->paintmode == GP_PAINTMODE_DRAW_POLY);
-
+
if (sketch) {
/* end stroke only, and then wait to resume painting soon */
/* printf("\t\tGP - end stroke only\n"); */
@@ -2533,13 +2536,13 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
*/
if (p->paintmode == GP_PAINTMODE_ERASER) {
p->paintmode = RNA_enum_get(op->ptr, "mode");
-
+
/* if the original mode was *still* eraser,
* we'll let it say for now, since this gives
* users an opportunity to have visual feedback
* when adjusting eraser size
*/
- if (p->paintmode != GP_PAINTMODE_ERASER) {
+ if (p->paintmode != GP_PAINTMODE_ERASER) {
/* turn off cursor...
* NOTE: this should be enough for now
* Just hiding this makes it seem like
@@ -2548,10 +2551,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
gpencil_draw_toggle_eraser_cursor(C, p, false);
}
}
-
+
/* we've just entered idling state, so this event was processed (but no others yet) */
estate = OPERATOR_RUNNING_MODAL;
-
+
/* stroke could be smoothed, send notifier to refresh screen */
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
}
@@ -2571,7 +2574,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
else if (event->val == KM_PRESS) {
bool in_bounds = false;
-
+
/* Check if we're outside the bounds of the active region
* NOTE: An exception here is that if launched from the toolbar,
* whatever region we're now in should become the new region
@@ -2579,13 +2582,13 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
if ((p->ar) && (p->ar->regiontype == RGN_TYPE_TOOLS)) {
/* Change to whatever region is now under the mouse */
ARegion *current_region = BKE_area_find_region_xy(p->sa, RGN_TYPE_ANY, event->x, event->y);
-
+
if (G.debug & G_DEBUG) {
printf("found alternative region %p (old was %p) - at %d %d (sa: %d %d -> %d %d)\n",
current_region, p->ar, event->x, event->y,
p->sa->totrct.xmin, p->sa->totrct.ymin, p->sa->totrct.xmax, p->sa->totrct.ymax);
}
-
+
if (current_region) {
/* Assume that since we found the cursor in here, it is in bounds
* and that this should be the region that we begin drawing in
@@ -2597,14 +2600,14 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Out of bounds, or invalid in some other way */
p->status = GP_STATUS_ERROR;
estate = OPERATOR_CANCELLED;
-
+
if (G.debug & G_DEBUG)
printf("%s: Region under cursor is out of bounds, so cannot be drawn on\n", __func__);
}
}
else if (p->ar) {
rcti region_rect;
-
+
/* Perform bounds check using */
ED_region_visible_rect(p->ar, &region_rect);
in_bounds = BLI_rcti_isect_pt_v(&region_rect, event->mval);
@@ -2613,11 +2616,11 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* No region */
p->status = GP_STATUS_ERROR;
estate = OPERATOR_CANCELLED;
-
+
if (G.debug & G_DEBUG)
printf("%s: No active region found in GP Paint session data\n", __func__);
}
-
+
if (in_bounds) {
/* Switch paintmode (temporarily if need be) based on which button was used
* NOTE: This is to make it more convenient to erase strokes when using drawing sessions
@@ -2630,18 +2633,18 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* restore drawmode to default */
p->paintmode = RNA_enum_get(op->ptr, "mode");
}
-
+
gpencil_draw_toggle_eraser_cursor(C, p, p->paintmode == GP_PAINTMODE_ERASER);
-
+
/* not painting, so start stroke (this should be mouse-button down) */
p = gpencil_stroke_begin(C, op);
-
+
if (p->status == GP_STATUS_ERROR) {
estate = OPERATOR_CANCELLED;
}
}
else if (p->status != GP_STATUS_ERROR) {
- /* User clicked outside bounds of window while idling, so exit paintmode
+ /* User clicked outside bounds of window while idling, so exit paintmode
* NOTE: Don't enter this case if an error occurred while finding the
* region (as above)
*/
@@ -2657,12 +2660,12 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_FINISHED;
}
}
- else {
+ else if (event->val == KM_RELEASE) {
p->status = GP_STATUS_IDLING;
op->flag |= OP_IS_MODAL_CURSOR_REGION;
}
}
-
+
/* handle mode-specific events */
if (p->status == GP_STATUS_PAINTING) {
/* handle painting mouse-movements? */
@@ -2695,19 +2698,19 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADPLUSKEY:
p->radius += 5;
break;
-
+
case WHEELUPMOUSE: /* smaller */
case PADMINUS:
p->radius -= 5;
-
+
if (p->radius <= 0)
p->radius = 1;
break;
}
-
+
/* force refresh */
ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */
-
+
/* event handled, so just tag as running modal */
estate = OPERATOR_RUNNING_MODAL;
}
@@ -2719,7 +2722,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_RUNNING_MODAL;
}
}
-
+
/* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
if (0 == gpencil_area_exists(C, p->sa))
estate = OPERATOR_CANCELLED;
@@ -2728,7 +2731,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
gpencil_draw_status_indicators(p);
gpencil_draw_cursor_set(p); /* cursor may have changed outside our control - T44084 */
}
-
+
/* process last operations before exiting */
switch (estate) {
case OPERATOR_FINISHED:
@@ -2736,11 +2739,11 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
gpencil_draw_exit(C, op);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
break;
-
+
case OPERATOR_CANCELLED:
gpencil_draw_exit(C, op);
break;
-
+
case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH:
/* event doesn't need to be handled */
#if 0
@@ -2749,7 +2752,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
#endif
break;
}
-
+
/* return status code */
return estate;
}
@@ -2767,28 +2770,28 @@ static const EnumPropertyItem prop_gpencil_drawmodes[] = {
void GPENCIL_OT_draw(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Grease Pencil Draw";
ot->idname = "GPENCIL_OT_draw";
ot->description = "Make annotations on the active data";
-
+
/* api callbacks */
ot->exec = gpencil_draw_exec;
ot->invoke = gpencil_draw_invoke;
ot->modal = gpencil_draw_modal;
ot->cancel = gpencil_draw_cancel;
ot->poll = gpencil_draw_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
-
+
/* settings for drawing */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements");
prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
-
+
/* NOTE: wait for input is enabled by default, so that all UI code can work properly without needing users to know about this */
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "Wait for first click instead of painting immediately");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index dc3483163bf..ac0b046e499 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -70,14 +70,14 @@
static int gpencil_select_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
-
+
/* we just need some visible strokes, and to be in editmode */
if ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)) {
/* TODO: include a check for visible strokes? */
if (gpd->layers.first)
return true;
}
-
+
return false;
}
@@ -88,16 +88,16 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
int action = RNA_enum_get(op->ptr, "action");
-
+
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
return OPERATOR_CANCELLED;
}
-
+
/* for "toggle", test for existing selected strokes */
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
-
+
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
if (gps->flag & GP_STROKE_SELECT) {
@@ -107,7 +107,7 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
-
+
/* if deselecting, we need to deselect strokes across all frames
* - Currently, an exception is only given for deselection
* Selecting and toggling should only affect what's visible,
@@ -122,21 +122,21 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
bGPDframe *gpf;
-
+
/* deselect all strokes on all frames */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
bGPDstroke *gps;
-
+
for (gps = gpf->strokes.first; gps; gps = gps->next) {
bGPDspoint *pt;
int i;
-
+
/* only edit strokes that are valid in this view... */
if (ED_gpencil_stroke_can_use(C, gps)) {
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
-
+
gps->flag &= ~GP_STROKE_SELECT;
}
}
@@ -151,7 +151,7 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
bGPDspoint *pt;
int i;
bool selected = false;
-
+
/* Change selection status of all points, then make the stroke match */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
switch (action) {
@@ -165,11 +165,11 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
pt->flag ^= GP_SPOINT_SELECT;
break;
}
-
+
if (pt->flag & GP_SPOINT_SELECT)
selected = true;
}
-
+
/* Change status of stroke */
if (selected)
gps->flag |= GP_STROKE_SELECT;
@@ -178,7 +178,7 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@@ -190,14 +190,14 @@ void GPENCIL_OT_select_all(wmOperatorType *ot)
ot->name = "(De)select All Strokes";
ot->idname = "GPENCIL_OT_select_all";
ot->description = "Change selection of all Grease Pencil strokes currently visible";
-
+
/* callbacks */
ot->exec = gpencil_select_all_exec;
ot->poll = gpencil_select_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
WM_operator_properties_select_all(ot);
}
@@ -207,26 +207,26 @@ void GPENCIL_OT_select_all(wmOperatorType *ot)
static int gpencil_select_linked_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
-
+
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
return OPERATOR_CANCELLED;
}
-
+
/* select all points in selected strokes */
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
if (gps->flag & GP_STROKE_SELECT) {
bGPDspoint *pt;
int i;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag |= GP_SPOINT_SELECT;
}
}
}
CTX_DATA_END;
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@@ -238,11 +238,11 @@ void GPENCIL_OT_select_linked(wmOperatorType *ot)
ot->name = "Select Linked";
ot->idname = "GPENCIL_OT_select_linked";
ot->description = "Select all points in same strokes as already selected points";
-
+
/* callbacks */
ot->exec = gpencil_select_linked_exec;
ot->poll = gpencil_select_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -253,10 +253,10 @@ void GPENCIL_OT_select_linked(wmOperatorType *ot)
typedef enum eGP_SelectGrouped {
/* Select strokes in the same layer */
GP_SEL_SAME_LAYER = 0,
-
+
/* Select strokes with the same color */
GP_SEL_SAME_COLOR = 1,
-
+
/* TODO: All with same prefix - Useful for isolating all layers for a particular character for instance */
/* TODO: All with same appearance - colour/opacity/volumetric/fills ? */
} eGP_SelectGrouped;
@@ -267,16 +267,16 @@ typedef enum eGP_SelectGrouped {
static void gp_select_same_layer(bContext *C)
{
Scene *scene = CTX_data_scene(C);
-
+
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
{
bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
bGPDstroke *gps;
bool found = false;
-
+
if (gpf == NULL)
continue;
-
+
/* Search for a selected stroke */
for (gps = gpf->strokes.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
@@ -286,18 +286,18 @@ static void gp_select_same_layer(bContext *C)
}
}
}
-
+
/* Select all if found */
if (found) {
for (gps = gpf->strokes.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
bGPDspoint *pt;
int i;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag |= GP_SPOINT_SELECT;
}
-
+
gps->flag |= GP_STROKE_SELECT;
}
}
@@ -310,11 +310,11 @@ static void gp_select_same_layer(bContext *C)
static void gp_select_same_color(bContext *C)
{
/* First, build set containing all the colors of selected strokes
- * - We use the palette names, so that we can select all strokes with one
+ * - We use the palette names, so that we can select all strokes with one
* (potentially missing) color, and remap them to something else
*/
GSet *selected_colors = BLI_gset_str_new("GP Selected Colors");
-
+
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
if (gps->flag & GP_STROKE_SELECT) {
@@ -325,7 +325,7 @@ static void gp_select_same_color(bContext *C)
}
}
CTX_DATA_END;
-
+
/* Second, select any visible stroke that uses these colors */
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
@@ -333,11 +333,11 @@ static void gp_select_same_color(bContext *C)
/* select this stroke */
bGPDspoint *pt;
int i;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag |= GP_SPOINT_SELECT;
}
-
+
gps->flag |= GP_STROKE_SELECT;
}
}
@@ -350,7 +350,7 @@ static void gp_select_same_color(bContext *C)
static int gpencil_select_grouped_exec(bContext *C, wmOperator *op)
{
eGP_SelectGrouped mode = RNA_enum_get(op->ptr, "type");
-
+
switch (mode) {
case GP_SEL_SAME_LAYER:
gp_select_same_layer(C);
@@ -358,12 +358,12 @@ static int gpencil_select_grouped_exec(bContext *C, wmOperator *op)
case GP_SEL_SAME_COLOR:
gp_select_same_color(C);
break;
-
+
default:
BLI_assert(!"unhandled select grouped gpencil mode");
break;
}
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@@ -376,20 +376,20 @@ void GPENCIL_OT_select_grouped(wmOperatorType *ot)
{GP_SEL_SAME_COLOR, "COLOR", 0, "Color", "Shared colors"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Select Grouped";
ot->idname = "GPENCIL_OT_select_grouped";
ot->description = "Select all strokes with similar characteristics";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = gpencil_select_grouped_exec;
ot->poll = gpencil_select_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, GP_SEL_SAME_LAYER, "Type", "");
}
@@ -401,33 +401,33 @@ static int gpencil_select_first_exec(bContext *C, wmOperator *op)
{
const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes");
const bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
/* skip stroke if we're only manipulating selected strokes */
if (only_selected && !(gps->flag & GP_STROKE_SELECT)) {
continue;
}
-
+
/* select first point */
BLI_assert(gps->totpoints >= 1);
-
+
gps->points->flag |= GP_SPOINT_SELECT;
gps->flag |= GP_STROKE_SELECT;
-
+
/* deselect rest? */
if ((extend == false) && (gps->totpoints > 1)) {
/* start from index 1, to skip the first point that we'd just selected... */
bGPDspoint *pt = &gps->points[1];
int i = 1;
-
+
for (; i < gps->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
}
}
CTX_DATA_END;
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@@ -439,18 +439,18 @@ void GPENCIL_OT_select_first(wmOperatorType *ot)
ot->name = "Select First";
ot->idname = "GPENCIL_OT_select_first";
ot->description = "Select first point in Grease Pencil strokes";
-
+
/* callbacks */
ot->exec = gpencil_select_first_exec;
ot->poll = gpencil_select_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "only_selected_strokes", false, "Selected Strokes Only",
"Only select the first point of strokes that already have points selected");
-
+
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting all other selected points");
}
@@ -461,33 +461,33 @@ static int gpencil_select_last_exec(bContext *C, wmOperator *op)
{
const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes");
const bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
/* skip stroke if we're only manipulating selected strokes */
if (only_selected && !(gps->flag & GP_STROKE_SELECT)) {
continue;
}
-
+
/* select last point */
BLI_assert(gps->totpoints >= 1);
-
+
gps->points[gps->totpoints - 1].flag |= GP_SPOINT_SELECT;
gps->flag |= GP_STROKE_SELECT;
-
+
/* deselect rest? */
if ((extend == false) && (gps->totpoints > 1)) {
/* don't include the last point... */
bGPDspoint *pt = gps->points;
int i = 1;
-
+
for (; i < gps->totpoints - 1; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
}
}
CTX_DATA_END;
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@@ -499,18 +499,18 @@ void GPENCIL_OT_select_last(wmOperatorType *ot)
ot->name = "Select Last";
ot->idname = "GPENCIL_OT_select_last";
ot->description = "Select last point in Grease Pencil strokes";
-
+
/* callbacks */
ot->exec = gpencil_select_last_exec;
ot->poll = gpencil_select_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "only_selected_strokes", false, "Selected Strokes Only",
"Only select the last point of strokes that already have points selected");
-
+
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting all other selected points");
}
@@ -525,8 +525,8 @@ static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op))
bGPDspoint *pt;
int i;
bool prev_sel;
-
- /* First Pass: Go in forward order, expanding selection if previous was selected (pre changes)...
+
+ /* First Pass: Go in forward order, expanding selection if previous was selected (pre changes)...
* - This pass covers the "after" edges of selection islands
*/
prev_sel = false;
@@ -543,8 +543,8 @@ static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op))
prev_sel = false;
}
}
-
- /* Second Pass: Go in reverse order, doing the same as before (except in opposite order)
+
+ /* Second Pass: Go in reverse order, doing the same as before (except in opposite order)
* - This pass covers the "before" edges of selection islands
*/
prev_sel = false;
@@ -563,7 +563,7 @@ static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op))
}
}
CTX_DATA_END;
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@@ -575,11 +575,11 @@ void GPENCIL_OT_select_more(wmOperatorType *ot)
ot->name = "Select More";
ot->idname = "GPENCIL_OT_select_more";
ot->description = "Grow sets of selected Grease Pencil points";
-
+
/* callbacks */
ot->exec = gpencil_select_more_exec;
ot->poll = gpencil_select_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -595,8 +595,8 @@ static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op))
bGPDspoint *pt;
int i;
bool prev_sel;
-
- /* First Pass: Go in forward order, shrinking selection if previous was not selected (pre changes)...
+
+ /* First Pass: Go in forward order, shrinking selection if previous was not selected (pre changes)...
* - This pass covers the "after" edges of selection islands
*/
prev_sel = false;
@@ -613,8 +613,8 @@ static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op))
prev_sel = false;
}
}
-
- /* Second Pass: Go in reverse order, doing the same as before (except in opposite order)
+
+ /* Second Pass: Go in reverse order, doing the same as before (except in opposite order)
* - This pass covers the "before" edges of selection islands
*/
prev_sel = false;
@@ -634,7 +634,7 @@ static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op))
}
}
CTX_DATA_END;
-
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@@ -646,11 +646,11 @@ void GPENCIL_OT_select_less(wmOperatorType *ot)
ot->name = "Select Less";
ot->idname = "GPENCIL_OT_select_less";
ot->description = "Shrink sets of selected Grease Pencil points";
-
+
/* callbacks */
ot->exec = gpencil_select_less_exec;
ot->poll = gpencil_select_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -671,7 +671,7 @@ static bool gp_stroke_do_circle_sel(
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
int i;
bool changed = false;
-
+
if (gps->totpoints == 1) {
if (!parented) {
gp_point_to_xy(gsc, gps, gps->points, &x0, &y0);
@@ -681,7 +681,7 @@ static bool gp_stroke_do_circle_sel(
gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
gp_point_to_xy(gsc, gps, &pt_temp, &x0, &y0);
}
-
+
/* do boundbox check first */
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
/* only check if point is inside */
@@ -695,13 +695,13 @@ static bool gp_stroke_do_circle_sel(
gps->points->flag &= ~GP_SPOINT_SELECT;
gps->flag &= ~GP_STROKE_SELECT;
}
-
+
return true;
}
}
}
else {
- /* Loop over the points in the stroke, checking for intersections
+ /* Loop over the points in the stroke, checking for intersections
* - an intersection means that we touched the stroke
*/
for (i = 0; (i + 1) < gps->totpoints; i++) {
@@ -720,43 +720,43 @@ static bool gp_stroke_do_circle_sel(
gp_point_to_parent_space(pt2, diff_mat, &npt);
gp_point_to_xy(gsc, gps, &npt, &x1, &y1);
}
-
+
/* check that point segment of the boundbox of the selection stroke */
if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1)))
{
int mval[2] = {mx, my};
int mvalo[2] = {mx, my}; /* dummy - this isn't used... */
-
+
/* check if point segment of stroke had anything to do with
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
if (gp_stroke_inside_circle(mval, mvalo, radius, x0, y0, x1, y1)) {
- /* change selection of stroke, and then of both points
+ /* change selection of stroke, and then of both points
* (as the last point otherwise wouldn't get selected
- * as we only do n-1 loops through)
+ * as we only do n-1 loops through)
*/
if (select) {
pt1->flag |= GP_SPOINT_SELECT;
pt2->flag |= GP_SPOINT_SELECT;
-
+
changed = true;
}
else {
pt1->flag &= ~GP_SPOINT_SELECT;
pt2->flag &= ~GP_SPOINT_SELECT;
-
+
changed = true;
}
}
}
}
-
+
/* Ensure that stroke selection is in sync with its points */
BKE_gpencil_stroke_sync_selection(gps);
}
-
+
return changed;
}
@@ -764,36 +764,36 @@ static bool gp_stroke_do_circle_sel(
static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
-
+
const int mx = RNA_int_get(op->ptr, "x");
const int my = RNA_int_get(op->ptr, "y");
const int radius = RNA_int_get(op->ptr, "radius");
-
+
bool select = !RNA_boolean_get(op->ptr, "deselect");
-
+
GP_SpaceConversion gsc = {NULL};
rcti rect = {0}; /* for bounding rect around circle (for quicky intersection testing) */
-
+
bool changed = false;
-
-
+
+
/* sanity checks */
if (sa == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active area");
return OPERATOR_CANCELLED;
}
-
+
/* init space conversion stuff */
gp_point_conversion_init(C, &gsc);
-
-
+
+
/* rect is rectangle of selection circle */
rect.xmin = mx - radius;
rect.ymin = my - radius;
rect.xmax = mx + radius;
rect.ymax = my + radius;
-
-
+
+
/* find visible strokes, and select if hit */
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
{
@@ -807,7 +807,7 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
if (changed) {
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -817,17 +817,17 @@ void GPENCIL_OT_select_circle(wmOperatorType *ot)
ot->name = "Circle Select";
ot->description = "Select Grease Pencil strokes using brush selection";
ot->idname = "GPENCIL_OT_select_circle";
-
+
/* callbacks */
ot->invoke = WM_gesture_circle_invoke;
ot->modal = WM_gesture_circle_modal;
ot->exec = gpencil_circle_select_exec;
ot->poll = gpencil_select_poll;
ot->cancel = WM_gesture_circle_cancel;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_gesture_circle_select(ot);
}
@@ -838,45 +838,45 @@ void GPENCIL_OT_select_circle(wmOperatorType *ot)
static int gpencil_border_select_exec(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
-
+
const bool select = !RNA_boolean_get(op->ptr, "deselect");
const bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
GP_SpaceConversion gsc = {NULL};
rcti rect = {0};
-
+
bool changed = false;
-
-
+
+
/* sanity checks */
if (sa == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active area");
return OPERATOR_CANCELLED;
}
-
+
/* init space conversion stuff */
gp_point_conversion_init(C, &gsc);
-
-
+
+
/* deselect all strokes first? */
if (select && !extend) {
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
bGPDspoint *pt;
int i;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
-
+
gps->flag &= ~GP_STROKE_SELECT;
}
CTX_DATA_END;
}
-
+
/* get settings from operator */
WM_operator_properties_border_to_rcti(op, &rect);
-
+
/* select/deselect points */
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
{
@@ -919,7 +919,7 @@ static int gpencil_border_select_exec(bContext *C, wmOperator *op)
if (changed) {
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -929,18 +929,18 @@ void GPENCIL_OT_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->description = "Select Grease Pencil strokes within a rectangular region";
ot->idname = "GPENCIL_OT_select_border";
-
+
/* callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = gpencil_border_select_exec;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = gpencil_select_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
}
@@ -952,41 +952,41 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
{
GP_SpaceConversion gsc = {NULL};
rcti rect = {0};
-
+
const bool extend = RNA_boolean_get(op->ptr, "extend");
const bool select = !RNA_boolean_get(op->ptr, "deselect");
-
+
int mcords_tot;
const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
-
+
bool changed = false;
-
+
/* sanity check */
if (mcords == NULL)
return OPERATOR_PASS_THROUGH;
-
+
/* compute boundbox of lasso (for faster testing later) */
BLI_lasso_boundbox(&rect, mcords, mcords_tot);
-
+
/* init space conversion stuff */
gp_point_conversion_init(C, &gsc);
-
+
/* deselect all strokes first? */
if (select && !extend) {
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
{
bGPDspoint *pt;
int i;
-
+
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
-
+
gps->flag &= ~GP_STROKE_SELECT;
}
CTX_DATA_END;
}
-
+
/* select/deselect points */
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
{
@@ -1027,12 +1027,12 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
/* cleanup */
MEM_freeN((void *)mcords);
-
+
/* updates */
if (changed) {
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -1041,16 +1041,16 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot)
ot->name = "Lasso Select Strokes";
ot->description = "Select Grease Pencil strokes using lasso selection";
ot->idname = "GPENCIL_OT_select_lasso";
-
+
ot->invoke = WM_gesture_lasso_invoke;
ot->modal = WM_gesture_lasso_modal;
ot->exec = gpencil_lasso_select_exec;
ot->poll = gpencil_select_poll;
ot->cancel = WM_gesture_lasso_cancel;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_gesture_lasso_select(ot);
}
@@ -1061,36 +1061,36 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot)
static int gpencil_select_exec(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
-
+
/* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */
const float radius = 0.75f * U.widget_unit;
const int radius_squared = (int)(radius * radius);
-
+
bool extend = RNA_boolean_get(op->ptr, "extend");
bool deselect = RNA_boolean_get(op->ptr, "deselect");
bool toggle = RNA_boolean_get(op->ptr, "toggle");
bool whole = RNA_boolean_get(op->ptr, "entire_strokes");
-
+
int mval[2] = {0};
-
+
GP_SpaceConversion gsc = {NULL};
-
+
bGPDstroke *hit_stroke = NULL;
bGPDspoint *hit_point = NULL;
int hit_distance = radius_squared;
-
+
/* sanity checks */
if (sa == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active area");
return OPERATOR_CANCELLED;
}
-
+
/* init space conversion stuff */
gp_point_conversion_init(C, &gsc);
-
+
/* get mouse location */
RNA_int_get_array(op->ptr, "location", mval);
-
+
/* First Pass: Find stroke point which gets hit */
/* XXX: maybe we should go from the top of the stack down instead... */
GP_EDITABLE_STROKES_BEGIN(C, gpl, gps)
@@ -1133,38 +1133,38 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
if (ELEM(NULL, hit_stroke, hit_point)) {
return OPERATOR_CANCELLED;
}
-
+
/* adjust selection behaviour - for toggle option */
if (toggle) {
deselect = (hit_point->flag & GP_SPOINT_SELECT) != 0;
}
-
+
/* If not extending selection, deselect everything else */
if (extend == false) {
CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
- {
+ {
/* deselect stroke and its points if selected */
if (gps->flag & GP_STROKE_SELECT) {
bGPDspoint *pt;
int i;
-
+
/* deselect points */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
pt->flag &= ~GP_SPOINT_SELECT;
}
-
+
/* deselect stroke itself too */
gps->flag &= ~GP_STROKE_SELECT;
}
}
CTX_DATA_END;
}
-
+
/* Perform selection operations... */
if (whole) {
bGPDspoint *pt;
int i;
-
+
/* entire stroke's points */
for (i = 0, pt = hit_stroke->points; i < hit_stroke->totpoints; i++, pt++) {
if (deselect == false)
@@ -1172,7 +1172,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
else
pt->flag &= ~GP_SPOINT_SELECT;
}
-
+
/* stroke too... */
if (deselect == false)
hit_stroke->flag |= GP_STROKE_SELECT;
@@ -1189,17 +1189,17 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
else {
/* deselect point */
hit_point->flag &= ~GP_SPOINT_SELECT;
-
+
/* ensure that stroke is selected correctly */
BKE_gpencil_stroke_sync_selection(hit_stroke);
}
}
-
+
/* updates */
if (hit_point != NULL) {
WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -1212,26 +1212,26 @@ static int gpencil_select_invoke(bContext *C, wmOperator *op, const wmEvent *eve
void GPENCIL_OT_select(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Select";
ot->description = "Select Grease Pencil strokes and/or stroke points";
ot->idname = "GPENCIL_OT_select";
-
+
/* callbacks */
ot->invoke = gpencil_select_invoke;
ot->exec = gpencil_select_exec;
ot->poll = gpencil_select_poll;
-
+
/* flag */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_mouse_select(ot);
-
+
prop = RNA_def_boolean(ot->srna, "entire_strokes", false, "Entire Strokes", "Select entire strokes instead of just the nearest stroke vertex");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
+
prop = RNA_def_int_vector(ot->srna, "location", 2, NULL, INT_MIN, INT_MAX, "Location", "Mouse location", INT_MIN, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN);
}
diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c
index 202d7630ae0..5e2be7c41f0 100644
--- a/source/blender/editors/gpencil/gpencil_undo.c
+++ b/source/blender/editors/gpencil/gpencil_undo.c
@@ -55,7 +55,7 @@
typedef struct bGPundonode {
struct bGPundonode *next, *prev;
-
+
char name[BKE_UNDO_STR_MAX];
struct bGPdata *gpd;
} bGPundonode;
@@ -71,9 +71,9 @@ int ED_gpencil_session_active(void)
int ED_undo_gpencil_step(bContext *C, int step, const char *name)
{
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 (cur_node->prev) {
@@ -92,18 +92,18 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name)
}
}
}
-
+
if (new_gpd) {
if (gpd_ptr) {
if (*gpd_ptr) {
bGPdata *gpd = *gpd_ptr;
bGPDlayer *gpl, *gpld;
-
+
BKE_gpencil_free_layers(&gpd->layers);
-
+
/* copy layers */
BLI_listbase_clear(&gpd->layers);
-
+
for (gpl = new_gpd->layers.first; gpl; gpl = gpl->next) {
/* make a copy of source layer and its data */
gpld = BKE_gpencil_layer_duplicate(gpl);
@@ -112,9 +112,9 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name)
}
}
}
-
+
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -129,7 +129,7 @@ static void gpencil_undo_free_node(bGPundonode *undo_node)
* or else the real copy will segfault when accessed
*/
undo_node->gpd->adt = NULL;
-
+
BKE_gpencil_free(undo_node->gpd, false);
MEM_freeN(undo_node->gpd);
}
@@ -137,65 +137,65 @@ static void gpencil_undo_free_node(bGPundonode *undo_node)
void gpencil_undo_push(bGPdata *gpd)
{
bGPundonode *undo_node;
-
+
//printf("\t\tGP - undo push\n");
-
+
if (cur_node) {
/* remove all un-done nodes from stack */
undo_node = cur_node->next;
-
+
while (undo_node) {
bGPundonode *next_node = undo_node->next;
-
+
gpencil_undo_free_node(undo_node);
BLI_freelinkN(&undo_nodes, undo_node);
-
+
undo_node = next_node;
}
}
-
+
/* limit number of undo steps to the maximum undo steps
- * - to prevent running out of memory during **really**
+ * - to prevent running out of memory during **really**
* long drawing sessions (triggering swapping)
*/
/* TODO: Undo-memory constraint is not respected yet, but can be added if we have any need for it */
if (U.undosteps && !BLI_listbase_is_empty(&undo_nodes)) {
/* remove anything older than n-steps before cur_node */
int steps = 0;
-
+
undo_node = (cur_node) ? cur_node : undo_nodes.last;
while (undo_node) {
bGPundonode *prev_node = undo_node->prev;
-
+
if (steps >= U.undosteps) {
gpencil_undo_free_node(undo_node);
BLI_freelinkN(&undo_nodes, undo_node);
}
-
+
steps++;
undo_node = prev_node;
}
}
-
+
/* create new undo node */
undo_node = MEM_callocN(sizeof(bGPundonode), "gpencil undo node");
undo_node->gpd = BKE_gpencil_data_duplicate(G.main, gpd, true);
-
+
cur_node = undo_node;
-
+
BLI_addtail(&undo_nodes, undo_node);
}
void gpencil_undo_finish(void)
{
bGPundonode *undo_node = undo_nodes.first;
-
+
while (undo_node) {
gpencil_undo_free_node(undo_node);
undo_node = undo_node->next;
}
-
+
BLI_freelistN(&undo_nodes);
-
+
cur_node = NULL;
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 0e08630d8bc..f6d72d9e575 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -47,10 +47,11 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
+#include "BKE_action.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
+#include "BKE_main.h"
#include "BKE_tracking.h"
-#include "BKE_action.h"
#include "WM_api.h"
@@ -82,16 +83,16 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
*/
if (sa) {
SpaceLink *sl = sa->spacedata.first;
-
+
switch (sa->spacetype) {
case SPACE_VIEW3D: /* 3D-View */
{
BLI_assert(scene && ELEM(scene->toolsettings->gpencil_src,
GP_TOOL_SOURCE_SCENE, GP_TOOL_SOURCE_OBJECT));
-
+
if (scene->toolsettings->gpencil_src == GP_TOOL_SOURCE_OBJECT) {
/* legacy behaviour for usage with old addons requiring object-linked to objects */
-
+
/* just in case no active/selected object... */
if (ob && (ob->flag & SELECT)) {
/* for now, as long as there's an object, default to using that in 3D-View */
@@ -109,21 +110,21 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
case SPACE_NODE: /* Nodes Editor */
{
SpaceNode *snode = (SpaceNode *)sl;
-
+
/* return the GP data for the active node block/node */
if (snode && snode->nodetree) {
/* for now, as long as there's an active node tree, default to using that in the Nodes Editor */
if (ptr) RNA_id_pointer_create(&snode->nodetree->id, ptr);
return &snode->nodetree->gpd;
}
-
+
/* even when there is no node-tree, don't allow this to flow to scene */
return NULL;
}
case SPACE_SEQ: /* Sequencer */
{
SpaceSeq *sseq = (SpaceSeq *)sl;
-
+
/* for now, Grease Pencil data is associated with the space (actually preview region only) */
/* XXX our convention for everything else is to link to data though... */
if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, ptr);
@@ -132,7 +133,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
case SPACE_IMAGE: /* Image/UV Editor */
{
SpaceImage *sima = (SpaceImage *)sl;
-
+
/* for now, Grease Pencil data is associated with the space... */
/* XXX our convention for everything else is to link to data though... */
if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr);
@@ -142,23 +143,23 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
{
SpaceClip *sc = (SpaceClip *)sl;
MovieClip *clip = ED_space_clip_get_clip(sc);
-
+
if (clip) {
if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
-
+
if (!track)
return NULL;
-
+
if (ptr)
RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr);
-
+
return &track->gpd;
}
else {
if (ptr)
RNA_id_pointer_create(&clip->id, ptr);
-
+
return &clip->gpd;
}
}
@@ -168,7 +169,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
return NULL;
}
}
-
+
/* just fall back on the scene's GP data */
if (ptr) RNA_id_pointer_create((ID *)scene, ptr);
return (scene) ? &scene->gpd : NULL;
@@ -181,7 +182,7 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
Scene *scene = CTX_data_scene(C);
ScrArea *sa = CTX_wm_area(C);
Object *ob = CTX_data_active_object(C);
-
+
return ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, ptr);
}
@@ -211,7 +212,7 @@ bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, ViewLayer *view_layer)
/* We have to make sure active object is actually visible and selected, else we must use default scene gpd,
* to be consistent with ED_gpencil_data_get_active's behavior.
*/
-
+
if (base && TESTBASE(base)) {
gpd = base->object->gpd;
}
@@ -239,7 +240,7 @@ bool ED_gpencil_has_keyframe_v3d(Scene *scene, Object *ob, int cfra)
}
}
}
-
+
if (ob && ob->gpd) {
bGPDlayer *gpl = BKE_gpencil_layer_getactive(ob->gpd);
if (gpl) {
@@ -253,7 +254,7 @@ bool ED_gpencil_has_keyframe_v3d(Scene *scene, Object *ob, int cfra)
}
}
}
-
+
return false;
}
@@ -272,7 +273,7 @@ int gp_active_layer_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
return (gpl != NULL);
}
@@ -317,25 +318,25 @@ const EnumPropertyItem *ED_gpencil_layers_enum_itemf(
EnumPropertyItem *item = NULL, item_tmp = {0};
int totitem = 0;
int i = 0;
-
+
if (ELEM(NULL, C, gpd)) {
return DummyRNA_DEFAULT_items;
}
-
+
/* Existing layers */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next, i++) {
item_tmp.identifier = gpl->info;
item_tmp.name = gpl->info;
item_tmp.value = i;
-
+
if (gpl->flag & GP_LAYER_ACTIVE)
item_tmp.icon = ICON_GREASEPENCIL;
- else
+ else
item_tmp.icon = ICON_NONE;
-
+
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
-
+
RNA_enum_item_end(&item, &totitem);
*r_free = true;
@@ -351,11 +352,11 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(
EnumPropertyItem *item = NULL, item_tmp = {0};
int totitem = 0;
int i = 0;
-
+
if (ELEM(NULL, C, gpd)) {
return DummyRNA_DEFAULT_items;
}
-
+
/* Create new layer */
/* TODO: have some way of specifying that we don't want this? */
{
@@ -365,25 +366,25 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(
item_tmp.value = -1;
item_tmp.icon = ICON_ZOOMIN;
RNA_enum_item_add(&item, &totitem, &item_tmp);
-
+
/* separator */
RNA_enum_item_add_separator(&item, &totitem);
}
-
+
/* Existing layers */
for (gpl = gpd->layers.first, i = 0; gpl; gpl = gpl->next, i++) {
item_tmp.identifier = gpl->info;
item_tmp.name = gpl->info;
item_tmp.value = i;
-
+
if (gpl->flag & GP_LAYER_ACTIVE)
item_tmp.icon = ICON_GREASEPENCIL;
- else
+ else
item_tmp.icon = ICON_NONE;
-
+
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
-
+
RNA_enum_item_end(&item, &totitem);
*r_free = true;
@@ -412,11 +413,11 @@ bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
const float mval_fl[2] = {mval[0], mval[1]};
const float screen_co_a[2] = {x0, y0};
const float screen_co_b[2] = {x1, y1};
-
+
if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
return true;
}
-
+
/* not inside */
return false;
}
@@ -469,7 +470,7 @@ bool ED_gpencil_stroke_color_use(const bGPDlayer *gpl, const bGPDstroke *gps)
if (((gpl->flag & GP_LAYER_UNLOCK_COLOR) == 0) && (palcolor->flag & PC_COLOR_LOCKED))
return false;
}
-
+
return true;
}
@@ -524,16 +525,16 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
-
+
/* zero out the storage (just in case) */
memset(r_gsc, 0, sizeof(GP_SpaceConversion));
unit_m4(r_gsc->mat);
-
+
/* store settings */
r_gsc->sa = sa;
r_gsc->ar = ar;
r_gsc->v2d = &ar->v2d;
-
+
/* init region-specific stuff */
if (sa->spacetype == SPACE_VIEW3D) {
wmWindow *win = CTX_wm_window(C);
@@ -541,13 +542,13 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
View3D *v3d = (View3D *)CTX_wm_space_data(C);
RegionView3D *rv3d = ar->regiondata;
-
+
/* init 3d depth buffers */
view3d_operator_needs_opengl(C);
-
+
view3d_region_operator_needs_opengl(win, ar);
ED_view3d_autodist_init(depsgraph, ar, v3d, 0);
-
+
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
ED_view3d_calc_camera_border(scene, CTX_data_depsgraph(C), ar, v3d, rv3d, &r_gsc->subrect_data, true); /* no shift */
@@ -563,7 +564,7 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
* \param diff_mat Matrix with the difference between original parent matrix
* \param[out] r_pt Pointer to new point after apply matrix
*/
-void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt)
+void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt)
{
float fpt[3];
@@ -626,12 +627,12 @@ void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
View2D *v2d = gsc->v2d;
rctf *subrect = gsc->subrect;
int xyval[2];
-
+
/* sanity checks */
BLI_assert(!(gps->flag & GP_STROKE_3DSPACE) || (gsc->sa->spacetype == SPACE_VIEW3D));
BLI_assert(!(gps->flag & GP_STROKE_2DSPACE) || (gsc->sa->spacetype != SPACE_VIEW3D));
-
-
+
+
if (gps->flag & GP_STROKE_3DSPACE) {
if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
*r_x = xyval[0];
@@ -679,12 +680,12 @@ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
View2D *v2d = gsc->v2d;
rctf *subrect = gsc->subrect;
float xyval[2];
-
+
/* sanity checks */
BLI_assert(!(gps->flag & GP_STROKE_3DSPACE) || (gsc->sa->spacetype == SPACE_VIEW3D));
BLI_assert(!(gps->flag & GP_STROKE_2DSPACE) || (gsc->sa->spacetype != SPACE_VIEW3D));
-
-
+
+
if (gps->flag & GP_STROKE_3DSPACE) {
if (ED_view3d_project_float_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
*r_x = xyval[0];
@@ -698,10 +699,10 @@ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
else if (gps->flag & GP_STROKE_2DSPACE) {
float vec[3] = {pt->x, pt->y, 0.0f};
int t_x, t_y;
-
+
mul_m4_v3(gsc->mat, vec);
UI_view2d_view_to_region_clip(v2d, vec[0], vec[1], &t_x, &t_y);
-
+
if ((t_x == t_y) && (t_x == V2D_IS_CLIPPED)) {
/* XXX: Or should we just always use the values as-is? */
*r_x = 0.0f;
@@ -748,22 +749,22 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen
float *rvec = ED_view3d_cursor3d_get(scene, v3d)->location;
float ref[3] = {rvec[0], rvec[1], rvec[2]};
float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL);
-
+
float mval_f[2], mval_prj[2];
float dvec[3];
-
+
copy_v2_v2(mval_f, screen_co);
-
+
if (ED_view3d_project_float_global(gsc->ar, ref, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
sub_v2_v2v2(mval_f, mval_prj, mval_f);
ED_view3d_win_to_delta(gsc->ar, mval_f, dvec, zfac);
sub_v3_v3v3(r_out, rvec, dvec);
-
+
return true;
}
else {
zero_v3(r_out);
-
+
return false;
}
}
@@ -780,19 +781,19 @@ bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure)
bGPDspoint *pt = &gps->points[i];
float pressure = 0.0f;
float sco[3] = {0.0f};
-
+
/* Do nothing if not enough points to smooth out */
if (gps->totpoints <= 2) {
return false;
}
-
+
/* Only affect endpoints by a fraction of the normal strength,
* to prevent the stroke from shrinking too much
*/
if ((i == 0) || (i == gps->totpoints - 1)) {
inf *= 0.1f;
}
-
+
/* Compute smoothed coordinate by taking the ones nearby */
/* XXX: This is potentially slow, and suffers from accumulation error as earlier points are handled before later ones */
{
@@ -800,14 +801,14 @@ bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure)
const int steps = 2;
const float average_fac = 1.0f / (float)(steps * 2 + 1);
int step;
-
+
/* add the point itself */
madd_v3_v3fl(sco, &pt->x, average_fac);
-
+
if (affect_pressure) {
pressure += pt->pressure * average_fac;
}
-
+
/* n-steps before/after current point */
// XXX: review how the endpoints are treated by this algorithm
// XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight
@@ -815,17 +816,17 @@ bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure)
bGPDspoint *pt1, *pt2;
int before = i - step;
int after = i + step;
-
+
CLAMP_MIN(before, 0);
CLAMP_MAX(after, gps->totpoints - 1);
-
+
pt1 = &gps->points[before];
pt2 = &gps->points[after];
-
+
/* add both these points to the average-sum (s += p[i]/n) */
madd_v3_v3fl(sco, &pt1->x, average_fac);
madd_v3_v3fl(sco, &pt2->x, average_fac);
-
+
#if 0
/* XXX: Disabled because get weird result */
/* do pressure too? */
@@ -836,17 +837,17 @@ bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure)
#endif
}
}
-
+
/* Based on influence factor, blend between original and optimal smoothed coordinate */
interp_v3_v3v3(&pt->x, &pt->x, sco, inf);
-
+
#if 0
/* XXX: Disabled because get weird result */
if (affect_pressure) {
pt->pressure = pressure;
}
#endif
-
+
return true;
}
@@ -939,22 +940,22 @@ void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints)
gps->points[new_totpoints - y] = gps->points[i];
y += 2;
}
-
+
/* Create interpolated points */
for (int i = 0; i < new_totpoints - 1; i += 2) {
bGPDspoint *prev = &gps->points[i];
bGPDspoint *pt = &gps->points[i + 1];
bGPDspoint *next = &gps->points[i + 2];
-
+
/* Interpolate all values */
interp_v3_v3v3(&pt->x, &prev->x, &next->x, 0.5f);
-
+
pt->pressure = interpf(prev->pressure, next->pressure, 0.5f);
pt->strength = interpf(prev->strength, next->strength, 0.5f);
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt->time = interpf(prev->time, next->time, 0.5f);
}
-
+
/* Update to new total number of points */
gps->totpoints = new_totpoints;
}
@@ -987,12 +988,12 @@ void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush)
float normal[3];
cross_v3_v3v3(normal, v1, v2);
normalize_v3(normal);
-
+
/* get orthogonal vector to plane to rotate random effect */
float ortho[3];
cross_v3_v3v3(ortho, v1, normal);
normalize_v3(ortho);
-
+
/* Read all points and apply shift vector (first and last point not modified) */
for (int i = 1; i < gps->totpoints - 1; ++i) {
bGPDspoint *pt = &gps->points[i];
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index a25b1b84cc5..943191c8892 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -36,6 +36,7 @@ struct ListBase;
struct AnimData;
struct bContext;
+struct Main;
struct wmKeyConfig;
struct ReportList;
struct ScrArea;
@@ -64,31 +65,32 @@ struct PropertyRNA;
/* --------------- Context --------------------- */
-/* This struct defines a structure used for animation-specific
+/* This struct defines a structure used for animation-specific
* 'context' information
*/
typedef struct bAnimContext {
void *data; /* data to be filtered for use in animation editor */
short datatype; /* type of data eAnimCont_Types */
-
+
short mode; /* editor->mode */
short spacetype; /* sa->spacetype */
short regiontype; /* active region -> type (channels or main) */
-
+
struct ScrArea *sa; /* editor host */
struct SpaceLink *sl; /* editor data */
struct ARegion *ar; /* region within editor */
-
+
struct bDopeSheet *ads; /* dopesheet data for editor (or which is being used) */
-
+
struct Depsgraph *depsgraph; /* active dependency graph */
+ struct Main *bmain; /* Current Main */
struct Scene *scene; /* active scene */
struct ViewLayer *view_layer; /* active scene layer */
struct Object *obact; /* active object */
ListBase *markers; /* active set of markers */
-
+
struct ReportList *reports; /* pointer to current reports list */
-
+
float yscale_fac; /* scale factor for height of channels (i.e. based on the size of keyframes) */
} bAnimContext;
@@ -109,24 +111,24 @@ typedef enum eAnimCont_Types {
/* --------------- Channels -------------------- */
-/* This struct defines a structure used for quick and uniform access for
+/* This struct defines a structure used for quick and uniform access for
* channels of animation data
*/
typedef struct bAnimListElem {
struct bAnimListElem *next, *prev;
-
+
void *data; /* source data this elem represents */
int type; /* (eAnim_ChannelType) one of the ANIMTYPE_* values */
int flag; /* copy of elem's flags for quick access */
int index; /* for un-named data, the index of the data in its collection */
-
+
char update; /* (eAnim_Update_Flags) tag the element for updating */
char tag; /* tag the included data. Temporary always */
short datatype; /* (eAnim_KeyType) type of motion data to expect */
void *key_data; /* motion data - mostly F-Curves, but can be other types too */
-
-
+
+
/* NOTE: id here is the "IdAdtTemplate"-style datablock (e.g. Object, Material, Texture, NodeTree)
* from which evaluation of the RNA-paths takes place. It's used to figure out how deep
* channels should be nested (e.g. for Textures/NodeTrees) in the tree, and allows property
@@ -138,12 +140,12 @@ typedef struct bAnimListElem {
*/
struct ID *id; /* ID block that channel is attached to */
struct AnimData *adt; /* source of the animation data attached to ID block (for convenience) */
-
+
void *owner; /* for per-element F-Curves (e.g. NLA Control Curves), the element that this represents (e.g. NlaStrip) */
} bAnimListElem;
-/* Some types for easier type-testing
+/* Some types for easier type-testing
* NOTE: need to keep the order of these synchronized with the channels define code
* which is used for drawing and handling channel lists for
*/
@@ -151,20 +153,20 @@ typedef enum eAnim_ChannelType {
ANIMTYPE_NONE = 0,
ANIMTYPE_ANIMDATA,
ANIMTYPE_SPECIALDATA,
-
+
ANIMTYPE_SUMMARY,
-
+
ANIMTYPE_SCENE,
ANIMTYPE_OBJECT,
ANIMTYPE_GROUP,
ANIMTYPE_FCURVE,
-
+
ANIMTYPE_NLACONTROLS,
ANIMTYPE_NLACURVE,
-
+
ANIMTYPE_FILLACTD,
ANIMTYPE_FILLDRIVERS,
-
+
ANIMTYPE_DSMAT,
ANIMTYPE_DSLAM,
ANIMTYPE_DSCAM,
@@ -183,18 +185,18 @@ typedef enum eAnim_ChannelType {
ANIMTYPE_DSSPK,
ANIMTYPE_DSGPENCIL,
ANIMTYPE_DSMCLIP,
-
+
ANIMTYPE_SHAPEKEY,
-
+
ANIMTYPE_GPDATABLOCK,
ANIMTYPE_GPLAYER,
-
+
ANIMTYPE_MASKDATABLOCK,
ANIMTYPE_MASKLAYER,
-
+
ANIMTYPE_NLATRACK,
ANIMTYPE_NLAACTION,
-
+
/* always as last item, the total number of channel types... */
ANIMTYPE_NUM_TYPES
} eAnim_ChannelType;
@@ -239,31 +241,31 @@ typedef enum eAnimFilter_Flags {
ANIMFILTER_LIST_VISIBLE = (1 << 1),
/* channel has specifically been tagged as visible in Graph Editor (* Graph Editor Only) */
ANIMFILTER_CURVE_VISIBLE = (1 << 2),
-
+
/* include summary channels and "expanders" (for drawing/mouse-selection in channel list) */
ANIMFILTER_LIST_CHANNELS = (1 << 3),
-
+
/* for its type, channel should be "active" one */
ANIMFILTER_ACTIVE = (1 << 4),
/* channel is a child of the active group (* Actions speciality) */
ANIMFILTER_ACTGROUPED = (1 << 5),
-
+
/* channel must be selected/not-selected, but both must not be set together */
ANIMFILTER_SEL = (1 << 6),
ANIMFILTER_UNSEL = (1 << 7),
-
+
/* editability status - must be editable to be included */
ANIMFILTER_FOREDIT = (1 << 8),
/* only selected animchannels should be considerable as editable - mainly for Graph Editor's option for keys on select curves only */
ANIMFILTER_SELEDIT = (1 << 9),
-
+
/* flags used to enforce certain data types */
// NOTE: the ones for curves and NLA tracks were redundant and have been removed for now...
ANIMFILTER_ANIMDATA = (1 << 10),
-
+
/* duplicate entries for animation data attached to multi-user blocks must not occur */
ANIMFILTER_NODUPLIS = (1 << 11),
-
+
/* for checking if we should keep some collapsed channel around (internal use only!) */
ANIMFILTER_TMP_PEEK = (1 << 30),
@@ -325,7 +327,7 @@ typedef enum eAnimFilter_Flags {
/* Grease Pencil only */
/* Grease Pencil datablock settings */
-#define EXPANDED_GPD(gpd) (gpd->flag & GP_DATA_EXPAND)
+#define EXPANDED_GPD(gpd) (gpd->flag & GP_DATA_EXPAND)
/* Grease Pencil Layer settings */
#define EDITABLE_GPL(gpl) ((gpl->flag & GP_LAYER_LOCKED) == 0)
#define SEL_GPL(gpl) (gpl->flag & GP_LAYER_SELECT)
@@ -391,7 +393,7 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F
*/
bool ANIM_animdata_get_context(const struct bContext *C, bAnimContext *ac);
-/* Obtain current anim-data context (from Animation Editor) given
+/* Obtain current anim-data context (from Animation Editor) given
* that Blender Context info has already been set.
* Returns whether the operation was successful.
*/
@@ -444,7 +446,7 @@ typedef struct bAnimChannelType {
const char *channel_type_name;
/* "level" or role in hierarchy - for finding the active channel */
eAnimChannel_Role channel_role;
-
+
/* -- Drawing -- */
/* get RGB color that is used to draw the majority of the backdrop */
void (*get_backdrop_color)(bAnimContext *ac, bAnimListElem *ale, float r_color[3]);
@@ -454,14 +456,14 @@ typedef struct bAnimChannelType {
short (*get_indent_level)(bAnimContext *ac, bAnimListElem *ale);
/* get offset in pixels for the start of the channel (in addition to the indent depth) */
short (*get_offset)(bAnimContext *ac, bAnimListElem *ale);
-
+
/* get name (for channel lists) */
void (*name)(bAnimListElem *ale, char *name);
/* get RNA property+pointer for editing the name */
bool (*name_prop)(bAnimListElem *ale, struct PointerRNA *ptr, struct PropertyRNA **prop);
/* get icon (for channel lists) */
int (*icon)(bAnimListElem *ale);
-
+
/* -- Settings -- */
/* check if the given setting is valid in the current context */
bool (*has_setting)(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting);
@@ -490,21 +492,21 @@ void ANIM_channel_draw_widgets(const struct bContext *C, bAnimContext *ac, bAnim
/* ------------------------ Editing API -------------------------- */
-/* Check if some setting for a channel is enabled
+/* Check if some setting for a channel is enabled
* Returns: 1 = On, 0 = Off, -1 = Invalid
*
* - setting: eAnimChannel_Settings
*/
short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting);
-/* Change value of some setting for a channel
+/* Change value of some setting for a channel
* - setting: eAnimChannel_Settings
* - mode: eAnimChannels_SetFlag
*/
void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode);
-/* Flush visibility (for Graph Editor) changes up/down hierarchy for changes in the given setting
+/* Flush visibility (for Graph Editor) changes up/down hierarchy for changes in the given setting
* - anim_data: list of the all the anim channels that can be chosen
* -> filtered using ANIMFILTER_CHANNELS only, since if we took VISIBLE too,
* then the channels under closed expanders get ignored...
@@ -579,7 +581,7 @@ void ANIM_fmodifiers_copybuf_free(void);
*/
bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active);
-/* 'Paste' the F-Modifier(s) from the buffer to the specified list
+/* 'Paste' the F-Modifier(s) from the buffer to the specified list
* - replace: free all the existing modifiers to leave only the pasted ones
*/
bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, struct FCurve *curve);
@@ -654,7 +656,7 @@ float ANIM_unit_mapping_get_factor(struct Scene *scene, struct ID *id, struct FC
*/
#define BEZKEYTYPE(bezt) ((bezt)->hide)
-/* set/clear/toggle macro
+/* set/clear/toggle macro
* - channel - channel with a 'flag' member that we're setting
* - smode - 0=clear, 1=set, 2=invert
* - sflag - bitflag to set
@@ -665,8 +667,8 @@ float ANIM_unit_mapping_get_factor(struct Scene *scene, struct ID *id, struct FC
else if (smode == ACHANNEL_SETFLAG_ADD) (channel)->flag |= (sflag); \
else (channel)->flag &= ~(sflag); \
}
-
-/* set/clear/toggle macro, where the flag is negative
+
+/* set/clear/toggle macro, where the flag is negative
* - channel - channel with a 'flag' member that we're setting
* - smode - 0=clear, 1=set, 2=invert
* - sflag - bitflag to set
@@ -682,7 +684,7 @@ float ANIM_unit_mapping_get_factor(struct Scene *scene, struct ID *id, struct FC
/* --------- anim_deps.c, animation updates -------- */
void ANIM_id_update(struct Scene *scene, struct ID *id);
-void ANIM_list_elem_update(struct Scene *scene, bAnimListElem *ale);
+void ANIM_list_elem_update(struct Main *bmain, struct Scene *scene, bAnimListElem *ale);
/* data -> channels syncing */
void ANIM_sync_animchannels_to_data(const struct bContext *C);
@@ -690,7 +692,7 @@ void ANIM_sync_animchannels_to_data(const struct bContext *C);
void ANIM_center_frame(struct bContext *C, int smooth_viewtx);
/* ************************************************* */
/* OPERATORS */
-
+
/* generic animation channels */
void ED_operatortypes_animchannels(void);
void ED_keymap_animchannels(struct wmKeyConfig *keyconf);
@@ -698,7 +700,7 @@ void ED_keymap_animchannels(struct wmKeyConfig *keyconf);
/* generic time editing */
void ED_operatortypes_anim(void);
void ED_keymap_anim(struct wmKeyConfig *keyconf);
-
+
/* space_graph */
void ED_operatormacros_graph(void);
/* space_action */
@@ -710,7 +712,7 @@ void ED_operatormacros_action(void);
/* Action Editor - Action Management */
struct AnimData *ED_actedit_animdata_from_context(struct bContext *C);
-void ED_animedit_unlink_action(struct bContext *C, struct ID *id,
+void ED_animedit_unlink_action(struct bContext *C, struct ID *id,
struct AnimData *adt, struct bAction *act,
struct ReportList *reports, bool force_delete);
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 2934745484a..cb422c2fb95 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -42,6 +42,7 @@ struct bPoseChannel;
struct Depsgraph;
struct IDProperty;
struct ListBase;
+struct Main;
struct MeshDeformModifierData;
struct Mesh;
struct Object;
@@ -73,7 +74,7 @@ typedef struct EditBone {
* animation are automatically relative to the bones' rest positions*/
int flag;
int layer;
-
+
float dist, weight;
float xwidth, length, zwidth; /* put them in order! transform uses this as scale */
float rad_head, rad_tail;
@@ -86,7 +87,7 @@ typedef struct EditBone {
float scaleIn, scaleOut;
float oldlength; /* for envelope scaling */
-
+
short segments;
/* Used for display */
@@ -135,7 +136,7 @@ void ED_operatormacros_armature(void);
void ED_keymap_armature(struct wmKeyConfig *keyconf);
/* editarmature.c */
-void ED_armature_from_edit(struct bArmature *arm);
+void ED_armature_from_edit(struct Main *bmain, struct bArmature *arm);
void ED_armature_to_edit(struct bArmature *arm);
void ED_armature_edit_free(struct bArmature *arm);
@@ -181,11 +182,11 @@ void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3]);
void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]);
void ED_armature_edit_transform_mirror_update(struct Object *obedit);
-void ED_armature_origin_set(struct Object *ob, float cursor[3], int centermode, int around);
+void ED_armature_origin_set(struct Main *bmain, struct Object *ob, float cursor[3], int centermode, int around);
void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props);
-void ED_armature_transform_apply(struct Object *ob, float mat[4][4], const bool do_props);
-void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do_props);
+void ED_armature_transform_apply(struct Main *bmain, struct Object *ob, float mat[4][4], const bool do_props);
+void ED_armature_transform(struct Main *bmain, struct bArmature *arm, float mat[4][4], const bool do_props);
#define ARM_GROUPS_NAME 1
#define ARM_GROUPS_ENVELOPE 2
@@ -197,8 +198,8 @@ void ED_object_vgroup_calc_from_armature(
/* if bone is already in list, pass it as param to ignore it */
void ED_armature_ebone_unique_name(struct ListBase *ebones, char *name, EditBone *bone);
-void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const char *newnamep);
-void ED_armature_bones_flip_names(struct bArmature *arm, struct ListBase *bones_names, const bool do_strip_numbers);
+void ED_armature_bone_rename(struct Main *bmain, struct bArmature *arm, const char *oldnamep, const char *newnamep);
+void ED_armature_bones_flip_names(struct Main *bmain, struct bArmature *arm, struct ListBase *bones_names, const bool do_strip_numbers);
/* low level selection functions which handle */
int ED_armature_ebone_selectflag_get(const EditBone *ebone);
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index 74c8334322f..8fcfb4743d5 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -32,15 +32,16 @@
#define __ED_CURVE_H__
struct bContext;
+struct BezTriple;
+struct BPoint;
+struct Curve;
+struct EditNurb;
+struct Main;
struct Nurb;
struct Object;
struct Text;
struct wmOperator;
struct wmKeyConfig;
-struct Curve;
-struct EditNurb;
-struct BezTriple;
-struct BPoint;
struct UndoType;
/* curve_ops.c */
@@ -51,7 +52,7 @@ void ED_keymap_curve(struct wmKeyConfig *keyconf);
/* editcurve.c */
struct ListBase *object_editcurve_get(struct Object *ob);
-void ED_curve_editnurb_load(struct Object *obedit);
+void ED_curve_editnurb_load(struct Main *bmain, struct Object *obedit);
void ED_curve_editnurb_make(struct Object *obedit);
void ED_curve_editnurb_free(struct Object *obedit);
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 57ca1f04c0a..f1f2ce29e7f 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -87,7 +87,7 @@ typedef struct tGPDinterpolate {
void *draw_handle_screen; /* handle for drawing strokes while operator is running screen stuff */
} tGPDinterpolate;
-/* Temporary 'Stroke Point' data
+/* Temporary 'Stroke Point' data
*
* Used as part of the 'stroke cache' used during drawing of new strokes
*/
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 62f1a617fcb..9b0b2c970b2 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -53,17 +53,17 @@ struct DLRBT_Tree;
typedef struct ActKeyColumn {
/* ListBase linkage */
struct ActKeyColumn *next, *prev;
-
+
/* sorting-tree linkage */
struct ActKeyColumn *left, *right; /* 'children' of this node, less than and greater than it (respectively) */
struct ActKeyColumn *parent; /* parent of this node in the tree */
char tree_col; /* DLRB_BLACK or DLRB_RED */
-
+
/* keyframe info */
char key_type; /* eBezTripe_KeyframeType */
short sel;
float cfra;
-
+
/* only while drawing - used to determine if long-keyframe needs to be drawn */
short modified;
short totcurve;
@@ -73,21 +73,21 @@ typedef struct ActKeyColumn {
typedef struct ActKeyBlock {
/* ListBase linkage */
struct ActKeyBlock *next, *prev;
-
+
/* sorting-tree linkage */
struct ActKeyBlock *left, *right; /* 'children' of this node, less than and greater than it (respectively) */
struct ActKeyBlock *parent; /* parent of this node in the tree */
char tree_col; /* DLRB_BLACK or DLRB_RED */
-
+
/* key-block info */
char sel;
short flag;
float val;
float start, end;
-
+
/* only while drawing - used to determine if block needs to be drawn */
short modified;
- short totcurve;
+ short totcurve;
} ActKeyBlock;
/* ActKeyBlock - Flag */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index 189cc36c134..5787a63d324 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -141,12 +141,12 @@ typedef enum eKeyframeVertOk {
typedef enum eKeyframeIterFlags {
/* consider handles in addition to key itself */
KEYFRAME_ITER_INCL_HANDLES = (1 << 0),
-
+
/* Perform NLA time remapping (global -> strip) for the "f1" parameter
* (e.g. used for selection tools on summary tracks)
*/
KED_F1_NLA_UNMAP = (1 << 1),
-
+
/* Perform NLA time remapping (global -> strip) for the "f2" parameter */
KED_F2_NLA_UNMAP = (1 << 2),
} eKeyframeIterFlags;
@@ -165,7 +165,7 @@ typedef struct KeyframeEditData {
struct FCurve *fcu; /* F-Curve that is being iterated over */
int curIndex; /* index of current keyframe being iterated over */
float channel_y; /* y-position of midpoint of the channel (for the dopesheet) */
-
+
/* flags */
eKeyframeVertOk curflags; /* current flags for the keyframe we're reached in the iteration process */
eKeyframeIterFlags iterflags; /* settings for iteration process */
@@ -243,7 +243,7 @@ KeyframeEditFunc ANIM_editkeyframes_easing(short mode);
/* -------- BezTriple Callbacks (Selection Map) ---------- */
-/* Get a callback to populate the selection settings map
+/* Get a callback to populate the selection settings map
* requires: ked->custom = char[] of length fcurve->totvert
*/
KeyframeEditFunc ANIM_editkeyframes_buildselmap(short mode);
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 066fc600c76..5882c44a9b3 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -61,19 +61,19 @@ struct EnumPropertyItem;
/* ************ Keyframing Management **************** */
-/* Get the active settings for keyframing settings from context (specifically the given scene)
+/* Get the active settings for keyframing settings from context (specifically the given scene)
* - incl_mode: include settings from keyframing mode in the result (i.e. replace only)
*/
short ANIM_get_keyframing_flags(struct Scene *scene, short incl_mode);
/* -------- */
-/* Get (or add relevant data to be able to do so) the Active Action for the given
+/* Get (or add relevant data to be able to do so) the Active Action for the given
* Animation Data block, given an ID block where the Animation Data should reside.
*/
-struct bAction *verify_adt_action(struct ID *id, short add);
+struct bAction *verify_adt_action(struct Main *bmain, struct ID *id, short add);
-/* Get (or add relevant data to be able to do so) F-Curve from the given Action.
+/* Get (or add relevant data to be able to do so) F-Curve from the given Action.
* This assumes that all the destinations are valid.
*/
struct FCurve *verify_fcurve(struct bAction *act, const char group[], struct PointerRNA *ptr,
@@ -96,7 +96,7 @@ void update_autoflags_fcurve(struct FCurve *fcu, struct bContext *C, struct Repo
*/
int insert_bezt_fcurve(struct FCurve *fcu, const struct BezTriple *bezt, eInsertKeyFlags flag);
-/* Main Keyframing API call:
+/* Main Keyframing API call:
* Use this when validation of necessary animation data isn't necessary as it
* already exists. It will insert a keyframe using the current value being keyframed.
* Returns the index at which a keyframe was added (or -1 if failed)
@@ -105,7 +105,7 @@ int insert_vert_fcurve(struct FCurve *fcu, float x, float y, eBezTriple_Keyframe
/* -------- */
-/* Secondary Keyframing API calls:
+/* Secondary Keyframing API calls:
* Use this to insert a keyframe using the current value being keyframed, in the
* nominated F-Curve (no creation of animation data performed). Returns success.
*/
@@ -113,13 +113,15 @@ bool insert_keyframe_direct(struct Depsgraph *depsgraph, struct ReportList *repo
/* -------- */
-/* Main Keyframing API calls:
+/* Main Keyframing API calls:
* Use this to create any necessary animation data, and then insert a keyframe
* using the current value being keyframed, in the relevant place. Returns success.
*/
-short insert_keyframe(struct Depsgraph *depsgraph, struct ReportList *reports, struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag);
+short insert_keyframe(
+ struct Main *bmain, struct Depsgraph *depsgraph, struct ReportList *reports, struct ID *id, struct bAction *act,
+ const char group[], const char rna_path[], int array_index, float cfra, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag);
-/* Main Keyframing API call:
+/* Main Keyframing API call:
* Use this to delete keyframe on current frame for relevant channel. Will perform checks just in case.
*/
short delete_keyframe(struct ReportList *reports, struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, eInsertKeyFlags flag);
@@ -135,13 +137,13 @@ typedef int (*cbKeyingSet_Poll)(struct KeyingSetInfo *ksi, struct bContext *C);
/* Context Iterator Callback for KeyingSets */
typedef void (*cbKeyingSet_Iterator)(struct KeyingSetInfo *ksi, struct bContext *C, struct KeyingSet *ks);
/* Property Specifier Callback for KeyingSets (called from iterators) */
-typedef void (*cbKeyingSet_Generate)(struct KeyingSetInfo *ksi, struct bContext *C, struct KeyingSet *ks, struct PointerRNA *ptr);
+typedef void (*cbKeyingSet_Generate)(struct KeyingSetInfo *ksi, struct bContext *C, struct KeyingSet *ks, struct PointerRNA *ptr);
/* Callback info for 'Procedural' KeyingSets to use */
typedef struct KeyingSetInfo {
struct KeyingSetInfo *next, *prev;
-
+
/* info */
/* identifier used for class name, which KeyingSet instances reference as "Typeinfo Name" */
char idname[64];
@@ -151,11 +153,11 @@ typedef struct KeyingSetInfo {
char description[240]; /* RNA_DYN_DESCR_MAX */
/* keying settings */
short keyingflag;
-
+
/* polling callbacks */
/* callback for polling the context for whether the right data is available */
cbKeyingSet_Poll poll;
-
+
/* generate callbacks */
/* iterator to use to go through collections of data in context
* - this callback is separate from the 'adding' stage, allowing
@@ -164,7 +166,7 @@ typedef struct KeyingSetInfo {
cbKeyingSet_Iterator iter;
/* generator to use to add properties based on the data found by iterator */
cbKeyingSet_Generate generate;
-
+
/* RNA integration */
struct ExtensionRNA ext;
} KeyingSetInfo;
@@ -243,7 +245,7 @@ typedef enum eCreateDriver_MappingTypes {
CREATEDRIVER_MAPPING_1_N = 0, /* 1 to Many - Use the specified index, and drive all elements with it */
CREATEDRIVER_MAPPING_1_1 = 1, /* 1 to 1 - Only for the specified index on each side */
CREATEDRIVER_MAPPING_N_N = 2, /* Many to Many - Match up the indices one by one (only for drivers on vectors/arrays) */
-
+
CREATEDRIVER_MAPPING_NONE = 3, /* None (Single Prop) - Do not create driver with any targets; these will get added later instead */
CREATEDRIVER_MAPPING_NONE_ALL = 4, /* None (All Properties) - Do not create driver with any targets; these will get added later instead */
} eCreateDriver_MappingTypes;
@@ -272,7 +274,7 @@ struct FCurve *verify_driver_fcurve(struct ID *id, const char rna_path[], const
* - mapping_type: eCreateDriver_MappingTypes
*/
int ANIM_add_driver_with_target(
- struct ReportList *reports,
+ struct ReportList *reports,
struct ID *dst_id, const char dst_path[], int dst_index,
struct ID *src_id, const char src_path[], int src_index,
short flag, int driver_type, short mapping_type);
@@ -364,7 +366,7 @@ bool fcurve_frame_has_keyframe(struct FCurve *fcu, float frame, short filter);
*/
bool id_frame_has_keyframe(struct ID *id, float frame, short filter);
-/* filter flags for id_cfra_has_keyframe
+/* filter flags for id_cfra_has_keyframe
*
* WARNING: do not alter order of these, as also stored in files
* (for v3d->keyflags)
diff --git a/source/blender/editors/include/ED_markers.h b/source/blender/editors/include/ED_markers.h
index 8c720ddea95..a95e283f218 100644
--- a/source/blender/editors/include/ED_markers.h
+++ b/source/blender/editors/include/ED_markers.h
@@ -68,7 +68,7 @@ struct TimeMarker *ED_markers_get_first_selected(ListBase *markers);
/* Operators ------------------------------ */
/* called in screen_ops.c:ED_operatortypes_screen() */
-void ED_operatortypes_marker(void);
+void ED_operatortypes_marker(void);
/* called in screen_ops.c:ED_keymap_screen() */
void ED_keymap_marker(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 6828cedbd80..f959b7f53ba 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -86,7 +86,7 @@ float ED_node_grid_size(void);
/* node_relationships.c */
void ED_node_link_intersect_test(struct ScrArea *sa, int test);
-void ED_node_link_insert(struct ScrArea *sa);
+void ED_node_link_insert(struct Main *bmain, struct ScrArea *sa);
/* node_edit.c */
void ED_node_set_tree_type(struct SpaceNode *snode, struct bNodeTreeType *typeinfo);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index c793c0aad2b..71b713da0d0 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -126,7 +126,7 @@ enum {
EM_NO_CONTEXT = (1 << 4),
};
bool ED_object_editmode_exit_ex(
- struct Scene *scene, struct Object *obedit, int flag);
+ struct Main *bmain, struct Scene *scene, struct Object *obedit, int flag);
bool ED_object_editmode_exit(struct bContext *C, int flag);
bool ED_object_editmode_enter_ex(struct Main *bmain, struct Scene *scene, struct Object *ob, int flag);
@@ -151,7 +151,7 @@ void ED_object_wpaintmode_exit_ex(struct Object *ob);
void ED_object_wpaintmode_exit(struct bContext *C);
void ED_object_sculptmode_enter_ex(
- struct Depsgraph *depsgraph,
+ struct Main *bmain, struct Depsgraph *depsgraph,
struct Scene *scene, struct Object *ob,
struct ReportList *reports);
void ED_object_sculptmode_enter(struct bContext *C, struct ReportList *reports);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 63485800a9b..cd1fb1f91d8 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -160,7 +160,7 @@ ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
vert_name = (vert_name == (win)->global_areas.vertbase.last) ? (screen)->vertbase.first : vert_name->next)
/* screens */
-void ED_screens_initialize(struct wmWindowManager *wm);
+void ED_screens_initialize(struct Main *bmain, struct wmWindowManager *wm);
void ED_screen_draw_edges(struct wmWindow *win);
void ED_screen_draw_join_shape(struct ScrArea *sa1, struct ScrArea *sa2);
void ED_screen_draw_split_preview(struct ScrArea *sa, const int dir, const float fac);
@@ -211,10 +211,12 @@ void ED_workspace_view_layer_unset(
const struct Main *bmain, struct Scene *scene,
const ViewLayer *layer_unset, ViewLayer *layer_new) ATTR_NONNULL(1, 2);
struct WorkSpaceLayout *ED_workspace_layout_add(
+ struct Main *bmain,
struct WorkSpace *workspace,
struct wmWindow *win,
const char *name) ATTR_NONNULL();
struct WorkSpaceLayout *ED_workspace_layout_duplicate(
+ struct Main *bmain,
struct WorkSpace *workspace, const struct WorkSpaceLayout *layout_old,
struct wmWindow *win) ATTR_NONNULL();
bool ED_workspace_layout_delete(
diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
index 271e84e3ec2..8ef7fee0f32 100644
--- a/source/blender/editors/include/ED_screen_types.h
+++ b/source/blender/editors/include/ED_screen_types.h
@@ -63,7 +63,7 @@ enum {
#define REDRAW_FRAME_AVERAGE 8
-/* for playback framerate info
+/* for playback framerate info
* stored during runtime as scene->fps_info
*/
typedef struct ScreenFrameRateInfo {
diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h
index eedd5336fb8..ddd8b59c264 100644
--- a/source/blender/editors/include/ED_space_api.h
+++ b/source/blender/editors/include/ED_space_api.h
@@ -60,7 +60,7 @@ void ED_spacetype_clip(void);
void ED_spacetype_statusbar(void);
void ED_spacetype_topbar(void);
-/* calls for instancing and freeing spacetype static data
+/* calls for instancing and freeing spacetype static data
* called in WM_init_exit */
/* in space_file.c */
void ED_file_init(void);
@@ -70,7 +70,7 @@ void ED_file_exit(void);
#define REGION_DRAW_POST_PIXEL 1
#define REGION_DRAW_PRE_VIEW 2
-void *ED_region_draw_cb_activate(struct ARegionType *,
+void *ED_region_draw_cb_activate(struct ARegionType *,
void (*draw)(const struct bContext *, struct ARegion *, void *),
void *custumdata, int type);
void ED_region_draw_cb_draw(const struct bContext *, struct ARegion *, int);
diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h
index 18d5101ebf7..8ac7dfcf9d8 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -79,9 +79,9 @@ struct SnapObjectParams {
typedef struct SnapObjectContext SnapObjectContext;
SnapObjectContext *ED_transform_snap_object_context_create(
- struct Scene *scene, struct Depsgraph *depsgraph, int flag);
+ struct Main *bmain, struct Scene *scene, struct Depsgraph *depsgraph, int flag);
SnapObjectContext *ED_transform_snap_object_context_create_view3d(
- struct Scene *scene, struct Depsgraph *depsgraph, int flag,
+ struct Main *bmain, struct Scene *scene, struct Depsgraph *depsgraph, int flag,
/* extra args for view3d */
const struct ARegion *ar, const struct View3D *v3d);
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index ae59f6da14b..24e5b3e2662 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -75,6 +75,7 @@ enum eGPUFXFlags;
/* for derivedmesh drawing callbacks, for view3d_select, .... */
typedef struct ViewContext {
+ struct Main *bmain;
struct Depsgraph *depsgraph;
struct Scene *scene;
struct ViewLayer *view_layer;
@@ -93,7 +94,7 @@ typedef struct ViewDepths {
short x, y; /* only for temp use for sub-rects, added to ar->winx/y */
float *depths;
double depth_range[2];
-
+
bool damaged;
} ViewDepths;
@@ -331,7 +332,8 @@ bool ED_view3d_autodist(
const bool alphaoverride, const float fallback_depth_pt[3]);
/* only draw so ED_view3d_autodist_simple can be called many times after */
-void ED_view3d_autodist_init(struct Depsgraph *depsgraph, struct ARegion *ar, struct View3D *v3d, int mode);
+void ED_view3d_autodist_init(
+ struct Depsgraph *depsgraph, struct ARegion *ar, struct View3D *v3d, int mode);
bool ED_view3d_autodist_simple(struct ARegion *ar, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth);
bool ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin, float *depth);
bool ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index b168ca00747..3bc1255d23f 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -61,7 +61,7 @@ DEF_ICON(PLUG)
DEF_ICON(UI)
DEF_ICON(NODE)
DEF_ICON(NODE_SEL)
-
+
/* ui */
DEF_ICON(FULLSCREEN)
DEF_ICON(SPLITSCREEN)
@@ -89,7 +89,7 @@ DEF_ICON(DOTSDOWN)
DEF_ICON(LINK)
DEF_ICON(INLINK)
DEF_ICON(PLUGIN)
-
+
/* various ui */
DEF_ICON(HELP)
DEF_ICON(GHOST_ENABLED)
@@ -119,7 +119,7 @@ DEF_ICON(RECOVER_LAST)
DEF_ICON(FULLSCREEN_ENTER)
DEF_ICON(FULLSCREEN_EXIT)
DEF_ICON(BLANK1) // Not actually blank - this is used all over the place
-
+
/* BUTTONS */
DEF_ICON(LAMP)
DEF_ICON(MATERIAL)
@@ -208,7 +208,7 @@ DEF_ICON(GREASEPENCIL_STROKE_PAINT)
DEF_ICON(BLANK077)
DEF_ICON(BLANK077b)
#endif
-
+
/* DATA */
DEF_ICON(SCENE_DATA)
DEF_ICON(RENDERLAYERS)
@@ -298,7 +298,7 @@ DEF_ICON(RNA_ADD)
DEF_ICON(BLANK116)
DEF_ICON(BLANK116b)
#endif
-
+
/* OUTLINER */
DEF_ICON(OUTLINER_OB_EMPTY)
DEF_ICON(OUTLINER_OB_MESH)
@@ -360,7 +360,7 @@ DEF_ICON(OUTLINER_DATA_GREASEPENCIL)
DEF_ICON(BLANK142)
DEF_ICON(BLANK142b)
#endif
-
+
/* PRIMITIVES */
DEF_ICON(MESH_PLANE)
DEF_ICON(MESH_CUBE)
@@ -394,7 +394,7 @@ DEF_ICON(META_CAPSULE)
#ifndef DEF_ICON_BLANK_SKIP
DEF_ICON(BLANK625)
#endif
-
+
/* PRIMITIVES */
DEF_ICON(SURFACE_NCURVE)
DEF_ICON(SURFACE_NCIRCLE)
@@ -485,7 +485,7 @@ DEF_ICON(NODE_INSERT_OFF)
DEF_ICON(BLANK713)
DEF_ICON(BLANK714)
DEF_ICON(BLANK715)
-
+
/* EMPTY */
DEF_ICON(BLANK720)
DEF_ICON(BLANK721)
@@ -600,7 +600,7 @@ DEF_ICON(MOD_NORMALEDIT)
DEF_ICON(BLANK176)
DEF_ICON(BLANK177)
#endif
-
+
/* ANIMATION */
DEF_ICON(REC)
DEF_ICON(PLAY)
@@ -691,7 +691,7 @@ DEF_ICON(SCULPT_DYNTOPO) /* XXX Empty icon! */
DEF_ICON(PARTICLE_POINT)
DEF_ICON(PARTICLE_TIP)
DEF_ICON(PARTICLE_PATH)
-
+
/* EDITING */
DEF_ICON(MAN_TRANS)
DEF_ICON(MAN_ROT)
@@ -753,7 +753,7 @@ DEF_ICON(UV_SYNC_SELECT)
DEF_ICON(BLANK247)
DEF_ICON(BLANK247b)
#endif
-
+
/* 3D VIEW */
DEF_ICON(BBOX)
DEF_ICON(WIRE)
@@ -876,7 +876,7 @@ DEF_ICON(FORWARD)
DEF_ICON(FILE_HIDDEN)
DEF_ICON(FILE_BACKUP)
DEF_ICON(DISK_DRIVE)
-
+
/* SHADING / TEXT */
DEF_ICON(MATPLANE)
DEF_ICON(MATSPHERE)
@@ -908,7 +908,7 @@ DEF_ICON(SCRIPTPLUGINS) // XXX CREATE NEW
DEF_ICON(BLANK328)
DEF_ICON(BLANK328b)
#endif
-
+
/* SEQUENCE / IMAGE EDITOR */
DEF_ICON(SEQ_SEQUENCER)
DEF_ICON(SEQ_PREVIEW)
@@ -1002,7 +1002,7 @@ DEF_ICON(MATCAP_22)
DEF_ICON(MATCAP_23)
DEF_ICON(MATCAP_24)
-/* vector icons, VICO_ prefix added */
+/* vector icons, VICO_ prefix added */
DEF_VICO(SMALL_TRI_RIGHT_VEC)
DEF_VICO(KEYTYPE_KEYFRAME_VEC)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index e2432d914b2..dee3104e6f4 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -491,8 +491,6 @@ void UI_blocklist_update_window_matrix(const struct bContext *C, const struct Li
void UI_blocklist_draw(const struct bContext *C, const struct ListBase *lb);
void UI_block_update_from_old(const struct bContext *C, struct uiBlock *block);
-uiBlock *UI_block_find_in_region(const char *name, struct ARegion *ar);
-
void UI_block_emboss_set(uiBlock *block, char dt);
void UI_block_free(const struct bContext *C, uiBlock *block);
@@ -581,7 +579,7 @@ bool UI_but_online_manual_id_from_active(
* - R: RNA
* - O: operator */
-uiBut *uiDefBut(uiBlock *block,
+uiBut *uiDefBut(uiBlock *block,
int type, int retval, const char *str,
int x1, int y1,
short x2, short y2,
@@ -601,7 +599,7 @@ uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int
uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip);
uiBut *uiDefButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, const char *str, int x, int y, short width, short height, const char *tip);
-uiBut *uiDefIconBut(uiBlock *block,
+uiBut *uiDefIconBut(uiBlock *block,
int type, int retval, int icon,
int x1, int y1,
short x2, short y2,
@@ -665,7 +663,7 @@ enum {
typedef struct uiStringInfo {
int type;
char *strinfo;
-} uiStringInfo;
+} uiStringInfo;
/* Note: Expects pointers to uiStringInfo structs as parameters.
* Will fill them with translated strings, when possible.
@@ -824,11 +822,13 @@ void UI_panels_begin(const struct bContext *C, struct ARegion *ar);
void UI_panels_end(const struct bContext *C, struct ARegion *ar, int *x, int *y);
void UI_panels_draw(const struct bContext *C, struct ARegion *ar);
-struct Panel *UI_panel_find_by_type(struct ARegion *ar, struct PanelType *pt);
-struct Panel *UI_panel_begin(struct ScrArea *sa, struct ARegion *ar, uiBlock *block,
- struct PanelType *pt, struct Panel *pa, bool *r_open);
+struct Panel *UI_panel_find_by_type(struct ListBase *lb, struct PanelType *pt);
+struct Panel *UI_panel_begin(struct ScrArea *sa, struct ARegion *ar, struct ListBase *lb,
+ uiBlock *block, struct PanelType *pt, struct Panel *pa,
+ bool *r_open);
void UI_panel_end(uiBlock *block, int width, int height);
void UI_panels_scale(struct ARegion *ar, float new_width);
+void UI_panel_label_offset(struct uiBlock *block, int *x, int *y);
bool UI_panel_category_is_visible(struct ARegion *ar);
void UI_panel_category_add(struct ARegion *ar, const char *name);
@@ -860,7 +860,7 @@ void UI_popup_handlers_remove_all(struct bContext *C, struct ListBase *handlers)
* be used to reinitialize some internal state if user preferences change. */
void UI_init(void);
-void UI_init_userdef(void);
+void UI_init_userdef(struct Main *bmain);
void UI_reinit_font(void);
void UI_exit(void);
@@ -1006,7 +1006,7 @@ void uiTemplateIDTabs(
PointerRNA *ptr, const char *propname,
const char *newop, const char *openop, const char *unlinkop,
int filter);
-void uiTemplateAnyID(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
+void uiTemplateAnyID(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
const char *proptypename, const char *text);
void uiTemplateSearch(
uiLayout *layout, struct bContext *C,
@@ -1019,7 +1019,7 @@ void uiTemplateSearchPreview(
struct PointerRNA *searchptr, const char *searchpropname,
const char *newop, const char *unlinkop,
const int rows, const int cols);
-void uiTemplatePathBuilder(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
+void uiTemplatePathBuilder(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
struct PointerRNA *root_ptr, const char *text);
uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
@@ -1247,10 +1247,10 @@ void UI_widgetbase_draw_cache_flush(void);
void UI_widgetbase_draw_cache_end(void);
/* Special drawing for toolbar, mainly workarounds for inflexible icon sizing. */
-#define USE_TOOLBAR_HACK
+#define USE_UI_TOOLBAR_HACK
/* Support click-drag motion which presses the button and closes a popover (like a menu). */
-#define USE_POPOVER_ONCE
+#define USE_UI_POPOVER_ONCE
bool UI_but_is_tool(const uiBut *but);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index b89a57b02d1..cab0fa8645d 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -56,7 +56,7 @@ typedef enum ThemeColorID {
TH_THEMEUI,
// common colors among spaces
-
+
TH_BACK,
TH_TEXT,
TH_TEXT_HI,
@@ -65,22 +65,23 @@ typedef enum ThemeColorID {
TH_TAB_INACTIVE,
TH_TAB_BACK,
TH_TAB_OUTLINE,
-
+
TH_HEADER,
TH_HEADERDESEL,
TH_HEADER_TEXT,
TH_HEADER_TEXT_HI,
-
+
/* panels */
TH_PANEL_HEADER,
TH_PANEL_BACK,
+ TH_PANEL_SUB_BACK,
TH_PANEL_SHOW_HEADER,
TH_PANEL_SHOW_BACK,
-
+
TH_BUTBACK,
TH_BUTBACK_TEXT,
TH_BUTBACK_TEXT_HI,
-
+
TH_SHADE1,
TH_SHADE2,
TH_HILITE,
@@ -141,14 +142,14 @@ typedef enum ThemeColorID {
TH_SYNTAX_D,
TH_SYNTAX_N,
TH_SYNTAX_S,
-
+
TH_BONE_SOLID,
TH_BONE_POSE,
TH_BONE_POSE_ACTIVE,
-
+
TH_STRIP,
TH_STRIP_SELECT,
-
+
TH_KEYTYPE_KEYFRAME, /* KEYTYPES */
TH_KEYTYPE_KEYFRAME_SELECT,
TH_KEYTYPE_EXTREME,
@@ -157,15 +158,15 @@ typedef enum ThemeColorID {
TH_KEYTYPE_BREAKDOWN_SELECT,
TH_KEYTYPE_JITTER,
TH_KEYTYPE_JITTER_SELECT,
-
+
TH_KEYBORDER,
TH_KEYBORDER_SELECT,
-
+
TH_LAMP,
TH_SPEAKER,
TH_CAMERA,
TH_EMPTY,
-
+
TH_NODE,
TH_NODE_INPUT,
TH_NODE_OUTPUT,
@@ -183,14 +184,14 @@ typedef enum ThemeColorID {
TH_NODE_FRAME,
TH_NODE_MATTE,
TH_NODE_DISTORT,
-
+
TH_CONSOLE_OUTPUT,
TH_CONSOLE_INPUT,
TH_CONSOLE_INFO,
TH_CONSOLE_ERROR,
TH_CONSOLE_CURSOR,
TH_CONSOLE_SELECT,
-
+
TH_SEQ_MOVIE,
TH_SEQ_MOVIECLIP,
TH_SEQ_MASK,
@@ -205,20 +206,20 @@ typedef enum ThemeColorID {
TH_EDGE_SHARP,
TH_EDITMESH_ACTIVE,
-
+
TH_HANDLE_VERTEX,
TH_HANDLE_VERTEX_SELECT,
TH_HANDLE_VERTEX_SIZE,
-
+
TH_GP_VERTEX,
TH_GP_VERTEX_SELECT,
TH_GP_VERTEX_SIZE,
-
+
TH_DOPESHEET_CHANNELOB,
TH_DOPESHEET_CHANNELSUBOB,
-
+
TH_PREVIEW_BACK,
-
+
TH_EDGE_CREASE,
TH_DRAWEXTRA_EDGELEN,
@@ -259,20 +260,20 @@ typedef enum ThemeColorID {
TH_SELECT_HIGHLIGHT, /* highlight color for selected outliner item */
TH_SKIN_ROOT,
-
+
TH_ANIM_ACTIVE, /* active action */
TH_ANIM_INACTIVE, /* no active action */
-
+
TH_NLA_TWEAK, /* 'tweaking' track in NLA */
TH_NLA_TWEAK_DUPLI, /* error/warning flag for other strips referencing dupli strip */
-
+
TH_NLA_TRANSITION,
TH_NLA_TRANSITION_SEL,
TH_NLA_META,
TH_NLA_META_SEL,
TH_NLA_SOUND,
TH_NLA_SOUND_SEL,
-
+
TH_WIDGET_EMBOSS,
TH_EDITOR_OUTLINE,
@@ -302,7 +303,7 @@ typedef enum ThemeColorID {
TH_INFO_DEBUG,
TH_INFO_DEBUG_TEXT,
TH_VIEW_OVERLAY,
-
+
TH_V3D_CLIPPING_BORDER,
TH_METADATA_BG,
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index e5d105f0d94..d407878d063 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -44,7 +44,7 @@
/* generic value to use when coordinate lies out of view when converting */
#define V2D_IS_CLIPPED 12000
-/* Common View2D view types
+/* Common View2D view types
* NOTE: only define a type here if it completely sets all (+/- a few) of the relevant flags
* and settings for a View2D region, and that set of settings is used in more
* than one specific place
@@ -75,7 +75,7 @@ enum eView2D_Units {
V2D_UNIT_SECONDS = 0,
V2D_UNIT_FRAMES,
V2D_UNIT_FRAMESCALE,
-
+
/* for drawing values */
V2D_UNIT_VALUES,
V2D_UNIT_DEGREES,
@@ -95,7 +95,7 @@ enum eView2D_Gridlines {
V2D_HORIZONTAL_AXIS = (1 << 2),
V2D_VERTICAL_AXIS = (1 << 3),
V2D_HORIZONTAL_FINELINES = (1 << 4),
-
+
V2D_GRIDLINES_MAJOR = (V2D_VERTICAL_LINES | V2D_VERTICAL_AXIS | V2D_HORIZONTAL_LINES | V2D_HORIZONTAL_AXIS),
V2D_GRIDLINES_ALL = (V2D_GRIDLINES_MAJOR | V2D_HORIZONTAL_FINELINES),
};
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index a9995001659..28f4c40469a 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -53,10 +53,11 @@
#include "BKE_animsys.h"
#include "BKE_context.h"
-#include "BKE_unit.h"
+#include "BKE_idprop.h"
+#include "BKE_main.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_idprop.h"
+#include "BKE_unit.h"
#include "GPU_glew.h"
#include "GPU_matrix.h"
@@ -2814,11 +2815,6 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
return block;
}
-uiBlock *UI_block_find_in_region(const char *name, ARegion *ar)
-{
- return BLI_findstring(&ar->uiblocks, name, offsetof(uiBlock, name));
-}
-
void UI_block_emboss_set(uiBlock *block, char dt)
{
block->dt = dt;
@@ -4699,10 +4695,10 @@ void UI_init(void)
}
/* after reading userdef file */
-void UI_init_userdef(void)
+void UI_init_userdef(Main *bmain)
{
/* fix saved themes */
- init_userdef_do_versions();
+ init_userdef_do_versions(bmain);
uiStyleInit();
}
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index ea1b58107bd..fc0ad7e5dce 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -41,6 +41,7 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_nla.h"
#include "DEG_depsgraph.h"
@@ -226,6 +227,7 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str)
void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
{
+ Main *bmain = CTX_data_main(C);
ID *id;
bAction *action;
FCurve *fcu;
@@ -277,7 +279,7 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
* because a button may control all items of an array at once.
* E.g., color wheels (see T42567). */
BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1));
- insert_keyframe(depsgraph, reports, id, action,
+ insert_keyframe(bmain, depsgraph, reports, id, action,
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path, but->rnaindex, cfra, ts->keyframe_type, flag);
diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c
index bd23fbb961d..df09c327da1 100644
--- a/source/blender/editors/interface/interface_eyedropper_depth.c
+++ b/source/blender/editors/interface/interface_eyedropper_depth.c
@@ -41,6 +41,7 @@
#include "BLI_math_vector.h"
#include "BKE_context.h"
+#include "BKE_main.h"
#include "BKE_screen.h"
#include "BKE_unit.h"
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 0ebe079703b..b05dbe9c3b0 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -506,7 +506,7 @@ bool ui_but_is_toggle(const uiBut *but)
);
}
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
bool ui_but_is_popover_once_compat(const uiBut *but)
{
return (
@@ -1400,7 +1400,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void
switch (event->type) {
case LEFTMOUSE:
{
- if (event->val != KM_PRESS) {
+ if (event->val == KM_RELEASE) {
done = true;
}
break;
@@ -3594,7 +3594,7 @@ static int ui_do_but_BUT(
button_activate_state(C, but, BUTTON_STATE_WAIT_RELEASE);
return WM_UI_HANDLER_BREAK;
}
- else if (event->type == LEFTMOUSE && but->block->handle) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE && but->block->handle) {
/* regular buttons will be 'UI_SELECT', menu items 'UI_ACTIVE' */
if (!(but->flag & (UI_SELECT | UI_ACTIVE)))
data->cancel = true;
@@ -3607,7 +3607,7 @@ static int ui_do_but_BUT(
}
}
else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
- if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (!(but->flag & UI_SELECT))
data->cancel = true;
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -4317,7 +4317,7 @@ static int ui_do_but_NUM(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (data->dragchange) {
#ifdef USE_DRAG_MULTINUM
/* if we started multibutton but didnt drag, then edit */
@@ -4625,7 +4625,7 @@ static int ui_do_but_SLI(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (data->dragchange) {
#ifdef USE_DRAG_MULTINUM
/* if we started multibutton but didnt drag, then edit */
@@ -4778,7 +4778,7 @@ static int ui_do_but_SCROLL(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (event->type == MOUSEMOVE) {
@@ -4830,7 +4830,7 @@ static int ui_do_but_GRIP(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (event->type == MOUSEMOVE) {
@@ -5216,7 +5216,7 @@ static int ui_do_but_UNITVEC(
ui_numedit_apply(C, block, but, data);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
@@ -5550,7 +5550,7 @@ static int ui_do_but_HSVCUBE(
ui_numedit_apply(C, block, but, data);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
@@ -5828,7 +5828,7 @@ static int ui_do_but_HSVCIRCLE(
}
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
return WM_UI_HANDLER_BREAK;
@@ -5918,7 +5918,7 @@ static int ui_do_but_COLORBAND(
ui_numedit_apply(C, block, but, data);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (ELEM(event->type, ESCKEY, RIGHTMOUSE)) {
@@ -6169,7 +6169,7 @@ static int ui_do_but_CURVE(
ui_numedit_apply(C, block, but, data);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if (data->dragsel != -1) {
CurveMapping *cumap = (CurveMapping *)but->poin;
CurveMap *cuma = cumap->cm + cumap->cur;
@@ -6267,7 +6267,7 @@ static int ui_do_but_HISTOGRAM(
ui_numedit_apply(C, block, but, data);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
return WM_UI_HANDLER_BREAK;
@@ -6342,7 +6342,7 @@ static int ui_do_but_WAVEFORM(
ui_numedit_apply(C, block, but, data);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
return WM_UI_HANDLER_BREAK;
@@ -6426,7 +6426,7 @@ static int ui_do_but_TRACKPREVIEW(
ui_numedit_apply(C, block, but, data);
}
}
- else if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
return WM_UI_HANDLER_BREAK;
@@ -8362,7 +8362,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
data->cancel = true;
button_activate_state(C, but, BUTTON_STATE_EXIT);
break;
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
case LEFTMOUSE:
{
if (event->val == KM_RELEASE) {
@@ -9527,7 +9527,7 @@ static int ui_handle_menu_event(
retval = ui_handle_menu_button(C, event, menu);
}
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
if (block->flag & UI_BLOCK_POPOVER_ONCE) {
if ((event->type == LEFTMOUSE) && (event->val == KM_RELEASE)) {
UI_popover_once_clear(menu->popup_create_vars.arg);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 2c813d152e9..c2ada1e3733 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1252,7 +1252,7 @@ static void icon_draw_size(
/* We need to flush widget base first to ensure correct ordering. */
UI_widgetbase_draw_cache_flush();
-#ifdef USE_TOOLBAR_HACK
+#ifdef USE_UI_TOOLBAR_HACK
/* TODO(campbell): scale icons up for toolbar, we need a way to detect larger buttons and do this automatic. */
{
float scale = (float)ICON_DEFAULT_HEIGHT_TOOLBAR / (float)ICON_DEFAULT_HEIGHT;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index c7cf03a44dd..b5bf9be737b 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -784,7 +784,7 @@ void ui_icon_ensure_deferred(const struct bContext *C, const int icon_id, const
int ui_id_icon_get(const struct bContext *C, struct ID *id, const bool big);
/* resources.c */
-void init_userdef_do_versions(void);
+void init_userdef_do_versions(struct Main *bmain);
void ui_theme_init_default(void);
void ui_style_init_default(void);
void ui_resources_init(void);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index d9c2879dfb1..0208e27a823 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -720,6 +720,7 @@ static uiBut *ui_item_with_label(
PropertyType type;
PropertySubType subtype;
int prop_but_width = w_hint;
+ const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
sub = uiLayoutRow(layout, layout->align);
UI_block_layout_set_current(block, sub);
@@ -727,15 +728,25 @@ static uiBut *ui_item_with_label(
if (name[0]) {
int w_label;
- if (ui_layout_vary_direction(layout) == UI_ITEM_VARY_X) {
- /* w_hint is width for label in this case. Use a default width for property button(s) */
- prop_but_width = UI_UNIT_X * 5;
- w_label = w_hint;
+ if (use_prop_sep) {
+ w_label = (int)((w_hint * 2) * UI_ITEM_PROP_SEP_DIVIDE);
}
else {
- w_label = w_hint / 3;
+ if (ui_layout_vary_direction(layout) == UI_ITEM_VARY_X) {
+ /* w_hint is width for label in this case. Use a default width for property button(s) */
+ prop_but_width = UI_UNIT_X * 5;
+ w_label = w_hint;
+ }
+ else {
+ w_label = w_hint / 3;
+ }
+ }
+
+ uiBut *but_label = uiDefBut(block, UI_BTYPE_LABEL, 0, name, x, y, w_label, h, NULL, 0.0, 0.0, 0, 0, "");
+ if (use_prop_sep) {
+ but_label->drawflag |= UI_BUT_TEXT_RIGHT;
+ but_label->drawflag &= ~UI_BUT_TEXT_LEFT;
}
- uiDefBut(block, UI_BTYPE_LABEL, 0, name, x, y, w_label, h, NULL, 0.0, 0.0, 0, 0, "");
}
type = RNA_property_type(prop);
@@ -1870,6 +1881,7 @@ void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propna
StructRNA *icontype;
int w, h;
char namestr[UI_MAX_NAME_STR];
+ const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
/* validate arguments */
prop = RNA_struct_find_property(ptr, propname);
@@ -1912,7 +1924,9 @@ void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propna
if (!name)
name = RNA_property_ui_name(prop);
- name = ui_item_name_add_colon(name, namestr);
+ if (use_prop_sep == false) {
+ name = ui_item_name_add_colon(name, namestr);
+ }
/* create button */
block = uiLayoutGetBlock(layout);
@@ -2080,10 +2094,12 @@ void uiItemPopoverPanelFromGroup(
for (PanelType *pt = art->paneltypes.first; pt; pt = pt->next) {
/* Causes too many panels, check context. */
- if (/* (*context == '\0') || */ STREQ(pt->context, context)) {
- if ((*category == '\0') || STREQ(pt->category, category)) {
- if (pt->poll == NULL || pt->poll(C, pt)) {
- uiItemPopoverPanel_ptr(layout, C, pt, NULL, ICON_NONE);
+ if (pt->parent_id[0] == '\0') {
+ if (/* (*context == '\0') || */ STREQ(pt->context, context)) {
+ if ((*category == '\0') || STREQ(pt->category, category)) {
+ if (pt->poll == NULL || pt->poll(C, pt)) {
+ uiItemPopoverPanel_ptr(layout, C, pt, NULL, ICON_NONE);
+ }
}
}
}
@@ -4215,18 +4231,11 @@ void UI_menutype_draw(bContext *C, MenuType *mt, struct uiLayout *layout)
}
}
-/**
- * Used for popup panels only.
- */
-void UI_paneltype_draw(bContext *C, PanelType *pt, uiLayout *layout)
+
+static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout)
{
Panel *panel = MEM_callocN(sizeof(Panel), "popover panel");
panel->type = pt;
-
- if (layout->context) {
- CTX_store_set(C, layout->context);
- }
-
if (pt->draw_header) {
panel->layout = uiLayoutRow(layout, false);
pt->draw_header(C, panel);
@@ -4237,9 +4246,36 @@ void UI_paneltype_draw(bContext *C, PanelType *pt, uiLayout *layout)
pt->draw(C, panel);
panel->layout = NULL;
+ MEM_freeN(panel);
+
+ PanelType *pt_iter = pt;
+ while (pt_iter->prev) {
+ pt_iter = pt_iter->prev;
+ }
+ do {
+ if (pt_iter != pt && STREQ(pt_iter->parent_id, pt->idname)) {
+ if (pt_iter->poll == NULL || pt_iter->poll(C, pt_iter)) {
+ uiItemS(layout);
+ uiItemL(layout, pt_iter->label, ICON_NONE);
+ ui_paneltype_draw_impl(C, pt_iter, layout);
+ }
+ }
+ } while ((pt_iter = pt_iter->next));
+}
+
+/**
+ * Used for popup panels only.
+ */
+void UI_paneltype_draw(bContext *C, PanelType *pt, uiLayout *layout)
+{
+ if (layout->context) {
+ CTX_store_set(C, layout->context);
+ }
+
+ ui_paneltype_draw_impl(C, pt, layout);
+
if (layout->context) {
CTX_store_set(C, NULL);
}
- MEM_freeN(panel);
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 5c2fb0e7aaa..6fcede58737 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -957,7 +957,7 @@ static int editsource_text_edit(
}
if (text == NULL) {
- text = BKE_text_load(bmain, filepath, bmain->name);
+ text = BKE_text_load(bmain, filepath, BKE_main_blendfile_path(bmain));
id_us_ensure_real(&text->id);
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 5711f76e3e9..dbdf2a0863c 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -110,6 +110,7 @@ typedef struct uiHandlePanelData {
int startsizex, startsizey;
} uiHandlePanelData;
+static int get_panel_real_size_y(Panel *pa);
static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelState state);
/*********************** space specific code ************************/
@@ -133,45 +134,80 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
return 0;
}
-static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
+static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, bool *no_animation)
{
- Panel *pa;
- int active = 0;
+ for (Panel *pa = lb->first; pa; pa = pa->next) {
+ /* Detect panel active flag changes. */
+ if (!(pa->type && pa->type->parent)) {
+ if ((pa->runtime_flag & PNL_WAS_ACTIVE) && !(pa->runtime_flag & PNL_ACTIVE)) {
+ return true;
+ }
+ if (!(pa->runtime_flag & PNL_WAS_ACTIVE) && (pa->runtime_flag & PNL_ACTIVE)) {
+ return true;
+ }
+ }
- *r_pa = NULL;
+ if ((pa->runtime_flag & PNL_ACTIVE) && !(pa->flag & PNL_CLOSED)) {
+ if (panel_active_animation_changed(&pa->children, pa_animation, no_animation)) {
+ return true;
+ }
+ }
+
+ /* Detect animation. */
+ if (pa->activedata) {
+ uiHandlePanelData *data = pa->activedata;
+ if (data->state == PANEL_STATE_ANIMATION) {
+ *pa_animation = pa;
+ }
+ else {
+ /* Don't animate while handling other interaction. */
+ *no_animation = true;
+ }
+ }
+ if ((pa->runtime_flag & PNL_ANIM_ALIGN) && !(*pa_animation)) {
+ *pa_animation = pa;
+ }
+ }
+
+ return false;
+}
+
+static bool panels_need_realign(ScrArea *sa, ARegion *ar, Panel **pa_animate)
+{
+ *pa_animate = NULL;
if (sa->spacetype == SPACE_BUTS && ar->regiontype == RGN_TYPE_WINDOW) {
SpaceButs *sbuts = sa->spacedata.first;
- if (sbuts->align)
- if (sbuts->re_align || sbuts->mainbo != sbuts->mainb)
- return 1;
+ if (sbuts->align) {
+ if (sbuts->re_align || sbuts->mainbo != sbuts->mainb) {
+ return true;
+ }
+ }
+ }
+ else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW) {
+ return true;
+ }
+ else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS) {
+ return true;
}
- else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
- return 1;
- else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
- return 1;
- /* in case panel is added or disappears */
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if ((pa->runtime_flag & PNL_WAS_ACTIVE) && !(pa->runtime_flag & PNL_ACTIVE))
- return 1;
- if (!(pa->runtime_flag & PNL_WAS_ACTIVE) && (pa->runtime_flag & PNL_ACTIVE))
- return 1;
- if (pa->activedata)
- active = 1;
+ /* Detect if a panel was added or removed. */
+ Panel *pa_animation = NULL;
+ bool no_animation = false;
+ if (panel_active_animation_changed(&ar->panels, &pa_animation, &no_animation)) {
+ return true;
}
- /* in case we need to do an animation (size changes) */
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if (pa->runtime_flag & PNL_ANIM_ALIGN) {
- if (!active)
- *r_pa = pa;
- return 1;
+ /* Detect panel marked for animation, if we're not already animating. */
+ if (pa_animation) {
+ if (!no_animation) {
+ *pa_animate = pa_animation;
}
+ return true;
}
- return 0;
+ return false;
}
/****************************** panels ******************************/
@@ -215,14 +251,14 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar)
*/
/* #define UI_USE_PANELTAB */
-Panel *UI_panel_find_by_type(ARegion *ar, PanelType *pt)
+Panel *UI_panel_find_by_type(ListBase *lb, PanelType *pt)
{
Panel *pa;
const char *idname = pt->idname;
#ifdef UI_USE_PANELTAB
const char *tabname = pt->idname;
- for (pa = ar->panels.first; pa; pa = pa->next) {
+ for (pa = lb->first; pa; pa = pa->next) {
if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
if (STREQLEN(pa->tabname, tabname, sizeof(pa->tabname))) {
return pa;
@@ -230,7 +266,7 @@ Panel *UI_panel_find_by_type(ARegion *ar, PanelType *pt)
}
}
#else
- for (pa = ar->panels.first; pa; pa = pa->next) {
+ for (pa = lb->first; pa; pa = pa->next) {
if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
return pa;
}
@@ -243,7 +279,7 @@ Panel *UI_panel_find_by_type(ARegion *ar, PanelType *pt)
/**
* \note \a pa should be return value from #UI_panel_find_by_type and can be NULL.
*/
-Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open)
+Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, ListBase *lb, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open)
{
Panel *palast, *panext;
const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
@@ -275,9 +311,11 @@ Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, P
pa->ofsy = 0;
pa->sizex = 0;
pa->sizey = 0;
+ pa->blocksizex = 0;
+ pa->blocksizey = 0;
pa->runtime_flag |= PNL_NEW_ADDED;
- BLI_addtail(&ar->panels, pa);
+ BLI_addtail(lb, pa);
#ifdef UI_USE_PANELTAB
BLI_strncpy(pa->tabname, tabname, sizeof(pa->tabname));
@@ -285,7 +323,7 @@ Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, P
/* make new Panel tabbed? */
if (hookname) {
Panel *patab;
- for (patab = ar->panels.first; patab; patab = patab->next) {
+ for (patab = lb->first; patab; patab = patab->next) {
if ((patab->runtime_flag & PNL_ACTIVE) && patab->paneltab == NULL) {
if (STREQLEN(hookname, patab->panelname, sizeof(patab->panelname))) {
if (STREQLEN(tabname, patab->tabname, sizeof(patab->tabname))) {
@@ -308,6 +346,8 @@ Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, P
/* Force update of panels' positions! */
pa->sizex = 0;
pa->sizey = 0;
+ pa->blocksizex = 0;
+ pa->blocksizey = 0;
}
BLI_strncpy(pa->drawname, drawname, sizeof(pa->drawname));
@@ -315,14 +355,18 @@ Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, P
/* if a new panel is added, we insert it right after the panel
* that was last added. this way new panels are inserted in the
* right place between versions */
- for (palast = ar->panels.first; palast; palast = palast->next)
- if (palast->runtime_flag & PNL_LAST_ADDED)
+ for (palast = lb->first; palast; palast = palast->next) {
+ if (palast->runtime_flag & PNL_LAST_ADDED) {
+ BLI_remlink(lb, pa);
+ BLI_insertlinkafter(lb, palast, pa);
break;
+ }
+ }
if (newpanel) {
pa->sortorder = (palast) ? palast->sortorder + 1 : 0;
- for (panext = ar->panels.first; panext; panext = panext->next)
+ for (panext = lb->first; panext; panext = panext->next)
if (panext != pa && panext->sortorder >= pa->sortorder)
panext->sortorder++;
}
@@ -348,6 +392,19 @@ void UI_panel_end(uiBlock *block, int width, int height)
{
Panel *pa = block->panel;
+ /* Set panel size excluding children. */
+ pa->blocksizex = width;
+ pa->blocksizey = height;
+
+ /* Compute total panel size including children. */
+ for (Panel *pachild = pa->children.first; pachild; pachild = pachild->next) {
+ if (pachild->runtime_flag & PNL_ACTIVE) {
+ width = max_ii(width, pachild->sizex);
+ height += get_panel_real_size_y(pachild);
+ }
+ }
+
+ /* Update total panel size. */
if (pa->runtime_flag & PNL_NEW_ADDED) {
pa->runtime_flag &= ~PNL_NEW_ADDED;
pa->sizex = width;
@@ -372,15 +429,13 @@ void UI_panel_end(uiBlock *block, int width, int height)
static void ui_offset_panel_block(uiBlock *block)
{
uiStyle *style = UI_style_get_dpi();
- uiBut *but;
- int ofsy;
/* compute bounds and offset */
ui_block_bounds_calc(block);
- ofsy = block->panel->sizey - style->panelspace;
+ int ofsy = block->panel->sizey - style->panelspace;
- for (but = block->buttons.first; but; but = but->next) {
+ for (uiBut *but = block->buttons.first; but; but = but->next) {
but->rect.ymin += ofsy;
but->rect.ymax += ofsy;
}
@@ -557,6 +612,20 @@ static void ui_draw_panel_dragwidget(unsigned int pos, unsigned int col, const r
immEnd();
}
+/* For button layout next to label. */
+void UI_panel_label_offset(uiBlock *block, int *x, int *y)
+{
+ Panel *panel = block->panel;
+ uiStyle *style = UI_style_get_dpi();
+ const bool is_subpanel = (panel->type && panel->type->parent);
+
+ *x = UI_UNIT_X * 1.1f;
+ *y = (UI_UNIT_Y * 1.1f) + style->panelspace;
+
+ if (is_subpanel) {
+ *x += 5.0f / block->aspect;
+ }
+}
static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, const rcti *rect, char dir)
{
@@ -564,6 +633,8 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, const r
rcti hrect;
int pnl_icons;
const char *activename = panel->drawname[0] ? panel->drawname : panel->panelname;
+ const bool is_subpanel = (panel->type && panel->type->parent);
+ uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle;
unsigned char col_title[4];
/* + 0.001f to avoid flirting with float inaccuracy */
@@ -580,14 +651,14 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, const r
if (dir == 'h') {
hrect.xmin = rect->xmin + pnl_icons;
hrect.ymin += 2.0f / block->aspect;
- UI_fontstyle_draw(&style->paneltitle, &hrect, activename, col_title);
+ UI_fontstyle_draw(fontstyle, &hrect, activename, col_title);
}
else {
/* ignore 'pnl_icons', otherwise the text gets offset horizontally
* + 0.001f to avoid flirting with float inaccuracy
*/
hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f;
- UI_fontstyle_draw_rotated(&style->paneltitle, &hrect, activename, col_title);
+ UI_fontstyle_draw_rotated(fontstyle, &hrect, activename, col_title);
}
}
@@ -600,6 +671,8 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
float color[4];
const bool is_closed_x = (panel->flag & PNL_CLOSEDX) ? true : false;
const bool is_closed_y = (panel->flag & PNL_CLOSEDY) ? true : false;
+ const bool is_subpanel = (panel->type && panel->type->parent);
+ const bool show_drag = !is_subpanel;
if (panel->paneltab) return;
if (panel->type && (panel->type->flag & PNL_NO_HEADER)) return;
@@ -610,10 +683,15 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
headrect.ymin = headrect.ymax;
headrect.ymax = headrect.ymin + floor(PNL_HEADER / block->aspect + 0.001f);
+ rcti titlerect = headrect;
+ if (is_subpanel) {
+ titlerect.xmin += 5.0f / block->aspect;
+ }
+
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- {
+ if (!is_subpanel) {
float minx = rect->xmin;
float maxx = is_closed_x ? (minx + PNL_HEADER / block->aspect) : rect->xmax;
float y = headrect.ymax;
@@ -681,25 +759,28 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
/* horizontal title */
if (is_closed_x == false) {
- unsigned int col;
- ui_draw_aligned_panel_header(style, block, &headrect, 'h');
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
-
- /* itemrect smaller */
- itemrect.xmax = headrect.xmax - 5.0f / block->aspect;
- itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
- itemrect.ymin = headrect.ymin;
- itemrect.ymax = headrect.ymax;
-
- BLI_rctf_scale(&itemrect, 0.7f);
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- ui_draw_panel_dragwidget(pos, col, &itemrect);
- immUnbindProgram();
+ ui_draw_aligned_panel_header(style, block, &titlerect, 'h');
+
+ if (show_drag) {
+ unsigned int col;
+ Gwn_VertFormat *format = immVertexFormat();
+ pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+
+ /* itemrect smaller */
+ itemrect.xmax = headrect.xmax - 5.0f / block->aspect;
+ itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
+ itemrect.ymin = headrect.ymin;
+ itemrect.ymax = headrect.ymax;
+
+ BLI_rctf_scale(&itemrect, 0.7f);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ ui_draw_panel_dragwidget(pos, col, &itemrect);
+ immUnbindProgram();
- /* Restore format for the following draws. */
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ /* Restore format for the following draws. */
+ pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ }
}
/* if the panel is minimized vertically:
@@ -727,8 +808,12 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* panel backdrop */
- if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) {
- /* draw with background color */
+ if (is_subpanel) {
+ glEnable(GL_BLEND);
+ immUniformThemeColor(TH_PANEL_SUB_BACK);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ }
+ else if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) {
glEnable(GL_BLEND);
immUniformThemeColor(TH_PANEL_BACK);
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
@@ -753,10 +838,10 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
/* draw collapse icon */
/* itemrect smaller */
- itemrect.xmin = headrect.xmin + 3.0f / block->aspect;
- itemrect.xmax = itemrect.xmin + BLI_rcti_size_y(&headrect);
- itemrect.ymin = headrect.ymin;
- itemrect.ymax = headrect.ymax;
+ itemrect.xmin = titlerect.xmin + 3.0f / block->aspect;
+ itemrect.xmax = itemrect.xmin + BLI_rcti_size_y(&titlerect);
+ itemrect.ymin = titlerect.ymin;
+ itemrect.ymax = titlerect.ymax;
BLI_rctf_scale(&itemrect, 0.25f);
@@ -786,6 +871,16 @@ static int get_panel_size_y(Panel *pa)
return PNL_HEADER + pa->sizey;
}
+static int get_panel_real_size_y(Panel *pa)
+{
+ int sizey = (pa->flag & PNL_CLOSED) ? 0 : pa->sizey;
+
+ if (pa->type && (pa->type->flag & PNL_NO_HEADER))
+ return sizey;
+
+ return PNL_HEADER + sizey;
+}
+
/* this function is needed because uiBlock and Panel itself don't
* change sizey or location when closed */
static int get_panel_real_ofsy(Panel *pa)
@@ -858,6 +953,24 @@ static int compare_panel(const void *a1, const void *a2)
return 0;
}
+static void align_sub_panels(Panel *pa)
+{
+ /* Position sub panels. */
+ int ofsy = get_panel_real_ofsy(pa) + pa->sizey - pa->blocksizey;
+
+ for (Panel *pachild = pa->children.first; pachild; pachild = pachild->next) {
+ if (pachild->runtime_flag & PNL_ACTIVE) {
+ pachild->ofsx = pa->ofsx;
+ pachild->ofsy = ofsy - get_panel_size_y(pachild);
+ ofsy -= get_panel_real_size_y(pachild);
+
+ if (pachild->children.first) {
+ align_sub_panels(pachild);
+ }
+ }
+ }
+}
+
/* this doesnt draw */
/* returns 1 when it did something */
static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bool drag)
@@ -949,10 +1062,17 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bo
}
}
- /* copy locations to tabs */
- for (pa = ar->panels.first; pa; pa = pa->next)
- if (pa->paneltab && (pa->runtime_flag & PNL_ACTIVE))
- ui_panel_copy_offset(pa, pa->paneltab);
+ /* set locations for tabbed and sub panels */
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
+ if (pa->paneltab) {
+ ui_panel_copy_offset(pa, pa->paneltab);
+ }
+ if (pa->children.first) {
+ align_sub_panels(pa);
+ }
+ }
+ }
/* free panelsort array */
for (ps = panelsort, a = 0; a < tot; a++, ps++) {
@@ -1022,20 +1142,27 @@ static void ui_do_animate(const bContext *C, Panel *panel)
}
}
-void UI_panels_begin(const bContext *UNUSED(C), ARegion *ar)
+static void panel_list_clear_active(ListBase *lb)
{
- Panel *pa;
-
/* set all panels as inactive, so that at the end we know
* which ones were used */
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if (pa->runtime_flag & PNL_ACTIVE)
+ for (Panel *pa = lb->first; pa; pa = pa->next) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
pa->runtime_flag = PNL_WAS_ACTIVE;
- else
+ }
+ else {
pa->runtime_flag = 0;
+ }
+
+ panel_list_clear_active(&pa->children);
}
}
+void UI_panels_begin(const bContext *UNUSED(C), ARegion *ar)
+{
+ panel_list_clear_active(&ar->panels);
+}
+
/* only draws blocks with panels */
void UI_panels_end(const bContext *C, ARegion *ar, int *x, int *y)
{
@@ -1074,8 +1201,7 @@ void UI_panels_end(const bContext *C, ARegion *ar, int *x, int *y)
}
/* re-align, possibly with animation */
- if (panels_re_align(sa, ar, &pa)) {
- /* XXX code never gets here... PNL_ANIM_ALIGN flag is never set */
+ if (panels_need_realign(sa, ar, &pa)) {
if (pa)
panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
else
@@ -1102,14 +1228,16 @@ void UI_panels_draw(const bContext *C, ARegion *ar)
UI_ThemeClearColor(TH_BACK);
- /* draw panels, selected on top */
- for (block = ar->uiblocks.first; block; block = block->next) {
+ /* Draw panels, selected on top. Also in reverse order, because
+ * UI blocks are added in reverse order and we need child panels
+ * to draw on top. */
+ for (block = ar->uiblocks.last; block; block = block->prev) {
if (block->active && block->panel && !(block->panel->flag & PNL_SELECT)) {
UI_block_draw(C, block);
}
}
- for (block = ar->uiblocks.first; block; block = block->next) {
+ for (block = ar->uiblocks.last; block; block = block->prev) {
if (block->active && block->panel && (block->panel->flag & PNL_SELECT)) {
UI_block_draw(C, block);
}
@@ -1371,6 +1499,8 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
#else
const bool show_pin = UI_panel_category_is_visible(ar);
#endif
+ const bool is_subpanel = (block->panel->type && block->panel->type->parent);
+ const bool show_drag = !is_subpanel;
int align = panel_aligned(sa, ar), button = 0;
@@ -1465,7 +1595,7 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
else
ED_region_tag_redraw(ar);
}
- else if (BLI_rctf_isect_x(&rect_drag, mx)) {
+ else if (show_drag && BLI_rctf_isect_x(&rect_drag, mx)) {
panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
}
else if (show_pin && BLI_rctf_isect_x(&rect_pin, mx)) {
@@ -2175,7 +2305,7 @@ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata)
uiHandlePanelData *data = panel->activedata;
/* verify if we can stop */
- if (event->type == LEFTMOUSE && event->val != KM_PRESS) {
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
int align = panel_aligned(sa, ar);
diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.c
index 0c43b787a84..504e1807a8f 100644
--- a/source/blender/editors/interface/interface_region_menu_pie.c
+++ b/source/blender/editors/interface/interface_region_menu_pie.c
@@ -150,8 +150,16 @@ uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, co
}
pie->layout = UI_block_layout(pie->block_radial, UI_LAYOUT_VERTICAL, UI_LAYOUT_PIEMENU, 0, 0, 200, 0, 0, style);
- pie->mx = event->x;
- pie->my = event->y;
+
+ /* Open from where we started dragging. */
+ if (event->val == KM_CLICK_DRAG) {
+ pie->mx = event->prevclickx;
+ pie->my = event->prevclicky;
+ }
+ else {
+ pie->mx = event->x;
+ pie->my = event->y;
+ }
/* create title button */
if (title[0]) {
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c
index 9d10713c868..c681cfe776f 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.c
@@ -87,7 +87,7 @@ struct uiPopover {
uiMenuCreateFunc menu_func;
void *menu_arg;
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
bool is_once;
#endif
};
@@ -136,7 +136,7 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
UI_block_region_set(block, handle->region);
UI_block_layout_resolve(block, &width, &height);
UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_KEEP_OPEN | UI_BLOCK_POPOVER);
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
if (pup->is_once) {
UI_block_flag_enable(block, UI_BLOCK_POPOVER_ONCE);
}
@@ -231,7 +231,7 @@ uiPopupBlockHandle *ui_popover_panel_create(
pup->menu_func = menu_func;
pup->menu_arg = arg;
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
pup->is_once = true;
#endif
@@ -365,7 +365,7 @@ uiLayout *UI_popover_layout(uiPopover *pup)
return pup->layout;
}
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
void UI_popover_once_clear(uiPopover *pup)
{
pup->is_once = false;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index d934d4dd1e4..9978726fa74 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -3970,7 +3970,9 @@ eAutoPropButsReturn uiTemplateOperatorPropertyButs(
#endif
/* set various special settings for buttons */
- {
+
+ /* Only do this if we're not refreshing an existing UI. */
+ if (block->oldblock == NULL) {
const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0;
uiBut *but;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 928ac8c9171..3188bc847a7 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2008,11 +2008,20 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if (but->flag & UI_HAS_ICON || show_menu_icon) {
const bool is_tool = UI_but_is_tool(but);
+ /* XXX add way to draw icons at a different size!
+ * Use small icons for popup. */
+#ifdef USE_UI_TOOLBAR_HACK
+ const float aspect_orig = but->block->aspect;
+ if (is_tool && (but->block->flag & UI_BLOCK_POPOVER)) {
+ but->block->aspect *= 2.0f;
+ }
+#endif
+
const BIFIconID icon = (but->flag & UI_HAS_ICON) ? but->icon + but->iconadd : ICON_NONE;
int icon_size_init = is_tool ? ICON_DEFAULT_HEIGHT_TOOLBAR : ICON_DEFAULT_HEIGHT;
const float icon_size = icon_size_init / (but->block->aspect / UI_DPI_FAC);
-#ifdef USE_TOOLBAR_HACK
+#ifdef USE_UI_TOOLBAR_HACK
if (is_tool) {
/* pass (even if its a menu toolbar) */
but->drawflag |= UI_BUT_TEXT_LEFT;
@@ -2034,6 +2043,10 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
widget_draw_icon(but, icon, alpha, rect, show_menu_icon);
+#ifdef USE_UI_TOOLBAR_HACK
+ but->block->aspect = aspect_orig;
+#endif
+
rect->xmin += icon_size;
/* without this menu keybindings will overlap the arrow icon [#38083] */
if (show_menu_icon) {
@@ -4359,7 +4372,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
uiFontStyle *fstyle = &style->widget;
uiWidgetType *wt = NULL;
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
const rcti rect_orig = *rect;
#endif
@@ -4413,7 +4426,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
case UI_BTYPE_BUT:
-#ifdef USE_TOOLBAR_HACK
+#ifdef USE_UI_TOOLBAR_HACK
if (UI_but_is_tool(but)) {
wt = widget_type(UI_WTYPE_TOOLBAR_ITEM);
}
@@ -4639,7 +4652,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
if (disabled)
glEnable(GL_BLEND);
-#ifdef USE_POPOVER_ONCE
+#ifdef USE_UI_POPOVER_ONCE
if (but->block->flag & UI_BLOCK_POPOVER_ONCE) {
if ((state & UI_ACTIVE) && ui_but_is_popover_once_compat(but)) {
uiWidgetType wt_back = *wt;
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 8e5bf8f0323..2a61be21589 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -254,6 +254,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->panelcolors.header; break;
case TH_PANEL_BACK:
cp = ts->panelcolors.back; break;
+ case TH_PANEL_SUB_BACK:
+ cp = ts->panelcolors.sub_back; break;
case TH_PANEL_SHOW_HEADER:
cp = &setting;
setting = ts->panelcolors.show_header;
@@ -821,6 +823,7 @@ static void ui_theme_init_new_do(ThemeSpace *ts)
ts->panelcolors.show_header = false;
rgba_char_args_set(ts->panelcolors.back, 114, 114, 114, 128);
rgba_char_args_set(ts->panelcolors.header, 0, 0, 0, 25);
+ rgba_char_args_set(ts->panelcolors.sub_back, 0, 0, 0, 25);
rgba_char_args_set(ts->button, 145, 145, 145, 245);
rgba_char_args_set(ts->button_title, 0, 0, 0, 255);
@@ -1815,10 +1818,8 @@ void UI_make_axis_color(const unsigned char src_col[3], unsigned char dst_col[3]
/* ************************************************************* */
/* patching UserDef struct and Themes */
-void init_userdef_do_versions(void)
+void init_userdef_do_versions(Main *bmain)
{
- Main *bmain = G.main;
-
#define USER_VERSION_ATLEAST(ver, subver) MAIN_VERSION_ATLEAST(bmain, ver, subver)
/* the UserDef struct is not corrected with do_versions() .... ugh! */
@@ -3022,6 +3023,16 @@ void init_userdef_do_versions(void)
}
}
+ if (!USER_VERSION_ATLEAST(280, 17)) {
+ for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
+ ThemeSpace *ts;
+
+ for (ts = UI_THEMESPACE_START(btheme); ts != UI_THEMESPACE_END(btheme); ts++) {
+ rgba_char_args_set(ts->panelcolors.sub_back, 0, 0, 0, 25);
+ }
+ }
+ }
+
/**
* Include next version bump.
*/
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index b584782e183..4440b99f211 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -79,11 +79,11 @@ static int wm_alembic_export_invoke(bContext *C, wmOperator *op, const wmEvent *
Main *bmain = CTX_data_main(C);
char filepath[FILE_MAX];
- if (bmain->name[0] == '\0') {
+ if (BKE_main_blendfile_path(bmain)[0] == '\0') {
BLI_strncpy(filepath, "untitled", sizeof(filepath));
}
else {
- BLI_strncpy(filepath, bmain->name, sizeof(filepath));
+ BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
}
BLI_replace_extension(filepath, sizeof(filepath), ".abc");
@@ -422,12 +422,12 @@ static int get_sequence_len(char *filename, int *ofs)
}
char path[FILE_MAX];
- BLI_path_abs(filename, G.main->name);
+ BLI_path_abs(filename, BKE_main_blendfile_path_from_global());
BLI_split_dir_part(filename, path, FILE_MAX);
if (path[0] == '\0') {
/* The filename had no path, so just use the blend file path. */
- BLI_split_dir_part(G.main->name, path, FILE_MAX);
+ BLI_split_dir_part(BKE_main_blendfile_path_from_global(), path, FILE_MAX);
}
DIR *dir = opendir(path);
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index eb79d0bec13..b13eaced843 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -60,7 +60,7 @@ static int cachefile_open_invoke(bContext *C, wmOperator *op, const wmEvent *eve
char filepath[FILE_MAX];
Main *bmain = CTX_data_main(C);
- BLI_strncpy(filepath, bmain->name, sizeof(filepath));
+ BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
BLI_replace_extension(filepath, sizeof(filepath), ".abc");
RNA_string_set(op->ptr, "filepath", filepath);
}
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 0f402083b6d..aca380c3123 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -60,14 +60,17 @@
#include "io_collada.h"
static int wm_collada_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
-{
+{
+ Main *bmain = CTX_data_main(C);
+
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
char filepath[FILE_MAX];
+ const char *blendfile_path = BKE_main_blendfile_path(bmain);
- if (G.main->name[0] == 0)
+ if (blendfile_path[0] == '\0')
BLI_strncpy(filepath, "untitled", sizeof(filepath));
else
- BLI_strncpy(filepath, G.main->name, sizeof(filepath));
+ BLI_strncpy(filepath, blendfile_path, sizeof(filepath));
BLI_replace_extension(filepath, sizeof(filepath), ".dae");
RNA_string_set(op->ptr, "filepath", filepath);
@@ -202,9 +205,11 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
if (export_settings.include_armatures) includeFilter |= OB_REL_MOD_ARMATURE;
if (export_settings.include_children) includeFilter |= OB_REL_CHILDREN_RECURSIVE;
- export_count = collada_export(CTX_data_depsgraph(C),
- scene,
- &export_settings
+ export_count = collada_export(
+ C,
+ CTX_data_depsgraph(C),
+ scene,
+ &export_settings
);
if (export_count == 0) {
@@ -586,8 +591,8 @@ void WM_OT_collada_import(wmOperatorType *ot)
0,
INT_MAX);
- RNA_def_boolean(ot->srna,
- "keep_bind_info", 0, "Keep Bind Info",
+ RNA_def_boolean(ot->srna,
+ "keep_bind_info", 0, "Keep Bind Info",
"Store Bindpose information in custom bone properties for later use during Collada export");
}
diff --git a/source/blender/editors/io/io_ops.c b/source/blender/editors/io/io_ops.c
index 6df4b0f4783..26414661f52 100644
--- a/source/blender/editors/io/io_ops.c
+++ b/source/blender/editors/io/io_ops.c
@@ -42,7 +42,7 @@
#include "io_cache.h"
-void ED_operatortypes_io(void)
+void ED_operatortypes_io(void)
{
#ifdef WITH_COLLADA
/* Collada operators: */
diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c
index 16147bdc7f8..364800ed1a2 100644
--- a/source/blender/editors/mask/mask_editaction.c
+++ b/source/blender/editors/mask/mask_editaction.c
@@ -205,21 +205,21 @@ void ED_masklayer_frames_select_border(MaskLayer *masklay, float min, float max,
void ED_masklayer_frames_select_region(KeyframeEditData *ked, MaskLayer *masklay, short tool, short select_mode)
{
MaskLayerShape *masklay_shape;
-
+
if (masklay == NULL)
return;
-
+
/* only select frames which are within the region */
for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
/* construct a dummy point coordinate to do this testing with */
float pt[2] = {0};
-
+
pt[0] = masklay_shape->frame;
pt[1] = ked->channel_y;
-
+
/* check the necessary regions */
if (tool == BEZT_OK_CHANNEL_LASSO) {
- /* Lasso */
+ /* Lasso */
if (keyframe_region_lasso_test(ked->data, pt))
masklayshape_select(masklay_shape, select_mode);
}
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 6d1f478249a..7e31b6a3774 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -64,7 +64,7 @@ void paintface_flush_flags(Object *ob, short flag)
const int *index_array = NULL;
int totpoly;
int i;
-
+
BLI_assert((flag & ~(SELECT | ME_HIDE)) == 0);
if (me == NULL)
@@ -106,7 +106,7 @@ void paintface_hide(Object *ob, const bool unselected)
Mesh *me;
MPoly *mpoly;
int a;
-
+
me = BKE_mesh_from_object(ob);
if (me == NULL || me->totpoly == 0) return;
@@ -122,10 +122,10 @@ void paintface_hide(Object *ob, const bool unselected)
if (mpoly->flag & ME_HIDE) {
mpoly->flag &= ~ME_FACE_SEL;
}
-
+
mpoly++;
}
-
+
BKE_mesh_flush_hidden_from_polys(me);
paintface_flush_flags(ob, SELECT | ME_HIDE);
@@ -258,7 +258,7 @@ void paintface_deselect_all_visible(Object *ob, int action, bool flush_flags)
me = BKE_mesh_from_object(ob);
if (me == NULL) return;
-
+
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
@@ -311,7 +311,7 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
if (!me || !me->mloopuv) {
return ok;
}
-
+
copy_m3_m4(bmat, ob->obmat);
mvert = me->mvert;
@@ -338,19 +338,19 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b
Mesh *me;
MPoly *mpoly, *mpoly_sel;
unsigned int a, index;
-
+
/* Get the face under the cursor */
me = BKE_mesh_from_object(ob);
if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE))
return false;
-
+
if (index >= me->totpoly)
return false;
mpoly_sel = me->mpoly + index;
if (mpoly_sel->flag & ME_HIDE) return false;
-
+
/* clear flags */
mpoly = me->mpoly;
a = me->totpoly;
@@ -360,7 +360,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b
mpoly++;
}
}
-
+
me->act_face = (int)index;
if (extend) {
@@ -378,7 +378,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b
else {
mpoly_sel->flag |= ME_FACE_SEL;
}
-
+
/* image window redraw */
paintface_flush_flags(ob, SELECT);
@@ -399,7 +399,7 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, bool select, bool exten
const int size[2] = {
BLI_rcti_size_x(rect) + 1,
BLI_rcti_size_y(rect) + 1};
-
+
me = BKE_mesh_from_object(ob);
if ((me == NULL) || (me->totpoly == 0) || (size[0] * size[1] <= 0)) {
@@ -455,7 +455,7 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, bool select, bool exten
IMB_freeImBuf(ibuf);
MEM_freeN(selar);
-#ifdef __APPLE__
+#ifdef __APPLE__
glReadBuffer(GL_BACK);
#endif
@@ -520,7 +520,7 @@ void paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
me = BKE_mesh_from_object(ob);
if (me == NULL) return;
-
+
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index e75b133b5bd..c51a57e27b3 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -85,7 +85,7 @@ typedef struct {
typedef struct {
float initial_length[NUM_VALUE_KINDS];
float scale[NUM_VALUE_KINDS];
- NumInput num_input[NUM_VALUE_KINDS];
+ NumInput num_input[NUM_VALUE_KINDS];
float shift_value[NUM_VALUE_KINDS]; /* The current value when shift is pressed. Negative when shift not active. */
bool is_modal;
@@ -174,7 +174,7 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
opdata->shift_value[i] = -1.0f;
opdata->initial_length[i] = -1.0f;
/* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
- opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch;
+ opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch;
initNumInput(&opdata->num_input[i]);
opdata->num_input[i].idx_max = 0;
@@ -338,7 +338,7 @@ static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event,
len = len_v2(mlen);
vmode = opdata->value_mode;
if (mode_changed || opdata->initial_length[vmode] == -1.0f) {
- /* If current value is not default start value, adjust len so that
+ /* If current value is not default start value, adjust len so that
* the scaling and offset in edbm_bevel_mouse_set_value will
* start at current value */
value = (vmode == SEGMENTS_VALUE) ?
@@ -552,7 +552,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
(opdata->value_mode == OFFSET_VALUE || opdata->value_mode == OFFSET_VALUE_PERCENT))
{
edbm_bevel_mouse_set_value(op, event);
- }
+ }
edbm_bevel_calc(op);
edbm_bevel_update_header(C, op);
handled = true;
@@ -594,7 +594,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
case VKEY:
if (event->val == KM_RELEASE)
break;
-
+
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "vertex_only");
RNA_property_boolean_set(op->ptr, prop, !RNA_property_boolean_get(op->ptr, prop));
@@ -603,7 +603,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
edbm_bevel_update_header(C, op);
handled = true;
break;
-
+
}
/* Modal numinput inactive, try to handle numeric inputs last... */
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 67e2a67c852..be54bba7aa4 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1806,7 +1806,7 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2],
ED_view3d_unproject(kcd->vc.ar, mval[0], mval[1], ofs, r_origin_ofs);
/* transform into object space */
- invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
+ invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
mul_m4_v3(kcd->ob->imat, r_origin);
mul_m4_v3(kcd->ob->imat, r_origin_ofs);
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index 5a61c5aab48..5ccbcf063ad 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -40,6 +40,7 @@
#include "BKE_curve.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_editmesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 26bac996381..3e787b2055a 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -77,7 +77,7 @@
typedef struct RingSelOpData {
ARegion *ar; /* region that ringsel was activated in */
void *draw_handle; /* for drawing preview loop */
-
+
float (*edges)[2][3];
int totedge;
@@ -109,7 +109,7 @@ static void ringsel_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
{
View3D *v3d = CTX_wm_view3d(C);
RingSelOpData *lcd = arg;
-
+
if ((lcd->totedge > 0) || (lcd->totpoint > 0)) {
if (v3d && v3d->zbuf)
glDisable(GL_DEPTH_TEST);
@@ -172,7 +172,7 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed,
break;
}
}
-
+
/* this should never happen */
if (!l) {
v[0][0] = eed->v1;
@@ -181,7 +181,7 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed,
v[1][1] = lasteed->v2;
return;
}
-
+
l2 = BM_loop_other_edge_loop(l, eed->v1);
rev = (l2 == l->prev);
while (l2->v != lasteed->v1 && l2->v != lasteed->v2) {
@@ -446,7 +446,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
BMVert *v_eed_orig[2] = {lcd->eed->v1, lcd->eed->v2};
edgering_select(lcd);
-
+
if (lcd->do_cut) {
const bool is_macro = (op->opm != NULL);
/* a single edge (rare, but better support) */
@@ -494,7 +494,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
BM_select_history_store(em->bm, lcd->eed->v1); /* low priority TODO, get vertrex close to mouse */
if (em->selectmode & SCE_SELECT_EDGE)
BM_select_history_store(em->bm, lcd->eed);
-
+
EDBM_selectmode_flush(lcd->em);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, lcd->ob->data);
}
@@ -508,7 +508,7 @@ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op)
/* deactivate the extra drawing stuff in 3D-View */
ED_region_draw_cb_exit(lcd->ar->type, lcd->draw_handle);
-
+
edgering_preview_free(lcd);
MEM_freeN(lcd->objects);
@@ -776,7 +776,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
case LEFTMOUSE: /* confirm */ // XXX hardcoded
if (event->val == KM_PRESS)
return loopcut_finish(lcd, C, op);
-
+
ED_region_tag_redraw(lcd->ar);
handled = true;
break;
@@ -791,11 +791,11 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* cancel */
ED_region_tag_redraw(lcd->ar);
ED_area_headerprint(CTX_wm_area(C), NULL);
-
+
ringcut_cancel(C, op);
return OPERATOR_CANCELLED;
}
-
+
ED_region_tag_redraw(lcd->ar);
handled = true;
break;
@@ -897,7 +897,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
str_rep, str_rep + NUM_STR_REP_LEN);
ED_area_headerprint(CTX_wm_area(C), buf);
}
-
+
/* keep going until the user confirms */
return OPERATOR_RUNNING_MODAL;
}
@@ -911,11 +911,11 @@ void MESH_OT_edgering_select(wmOperatorType *ot)
ot->name = "Edge Ring Select";
ot->idname = "MESH_OT_edgering_select";
ot->description = "Select an edge ring";
-
+
/* callbacks */
ot->invoke = ringsel_invoke;
- ot->poll = ED_operator_editmesh_region_view3d;
-
+ ot->poll = ED_operator_editmesh_region_view3d;
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -932,14 +932,14 @@ void MESH_OT_loopcut(wmOperatorType *ot)
ot->name = "Loop Cut";
ot->idname = "MESH_OT_loopcut";
ot->description = "Add a new loop between existing loops";
-
+
/* callbacks */
ot->invoke = ringcut_invoke;
ot->exec = loopcut_exec;
ot->modal = loopcut_modal;
ot->cancel = ringcut_cancel;
ot->poll = ED_operator_editmesh_region_view3d;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index fd8efcd84e3..634c65485e9 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -678,10 +678,10 @@ BMEdge *EDBM_edge_find_nearest_ex(
{
FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_EDGE);
ED_view3d_backbuf_validate_with_select_mode(vc, select_mode);
-
+
index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test);
eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL;
-
+
FAKE_SELECT_MODE_END(vc, fake_select_mode);
}
@@ -1061,7 +1061,7 @@ static bool unified_findnearest(
mval_prev[0] = vc->mval[0];
mval_prev[1] = vc->mval[1];
-
+
/* Only one element type will be non-null. */
BLI_assert(((hit.v.ele != NULL) + (hit.e.ele != NULL) + (hit.f.ele != NULL)) <= 1);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 3a67abdb9a0..17f643636cf 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -359,6 +359,7 @@ void MESH_OT_unsubdivide(wmOperatorType *ot)
void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
{
+ Main *bmain = CTX_data_main(C);
Object *obedit = em->ob;
BMIter iter;
BMVert *eve;
@@ -366,7 +367,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
ED_view3d_init_mats_rv3d(obedit, ar->regiondata);
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_scene(C), CTX_data_depsgraph(C), 0,
+ bmain, CTX_data_scene(C), CTX_data_depsgraph(C), 0,
ar, CTX_wm_view3d(C));
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
@@ -5310,7 +5311,7 @@ static int edbm_dissolve_degenerate_exec(bContext *C, wmOperator *op)
} /* objects */
const float thresh = RNA_float_get(op->ptr, "threshold");
-
+
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 28481bbbee3..d2410c7d97b 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -255,7 +255,7 @@ void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me)
CustomData *ldata = GET_CD_DATA(me, ldata);
const int layernum = CustomData_get_active_layer(ldata, CD_MLOOPUV);
ED_mesh_uv_loop_reset_ex(me, layernum);
-
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
@@ -301,7 +301,7 @@ int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set)
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, name);
CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, name);
}
-
+
if (active_set || layernum_dst == 0) {
CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst);
CustomData_set_layer_active(&me->fdata, CD_MTFACE, layernum_dst);
@@ -517,7 +517,7 @@ static int mesh_uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -527,7 +527,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
ot->name = "Add UV Map";
ot->description = "Add UV Map";
ot->idname = "MESH_OT_uv_texture_add";
-
+
/* api callbacks */
ot->poll = layers_poll;
ot->exec = mesh_uv_texture_add_exec;
@@ -545,7 +545,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e
Mesh *me;
Object *obedit;
int exitmode = 0;
-
+
if (v3d == NULL) {
BKE_report(op->reports, RPT_ERROR, "No 3D View Available");
return OPERATOR_CANCELLED;
@@ -558,7 +558,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e
BKE_report(op->reports, RPT_ERROR, "Not an object or mesh");
return OPERATOR_CANCELLED;
}
-
+
ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
if (!ima) {
return OPERATOR_CANCELLED;
@@ -576,7 +576,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e
}
if (me->edit_btmesh == NULL)
return OPERATOR_CANCELLED;
-
+
if (exitmode) {
EDBM_mesh_load(obedit);
EDBM_mesh_free(me->edit_btmesh);
@@ -591,9 +591,9 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e
/* dummie drop support; ensure view shows a result :) */
if (v3d)
v3d->flag2 |= V3D_SOLID_TEX;
-
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
-
+
return OPERATOR_FINISHED;
}
@@ -603,14 +603,14 @@ void MESH_OT_drop_named_image(wmOperatorType *ot)
ot->name = "Drop Image to Mesh UV Map";
ot->description = "Assign Image to active UV Map, or create an UV Map";
ot->idname = "MESH_OT_drop_named_image";
-
+
/* api callbacks */
ot->poll = layers_poll;
ot->invoke = drop_named_image_invoke;
-
+
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
-
+
/* properties */
RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign");
RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
@@ -630,7 +630,7 @@ static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -640,7 +640,7 @@ void MESH_OT_uv_texture_remove(wmOperatorType *ot)
ot->name = "Remove UV Map";
ot->description = "Remove UV Map";
ot->idname = "MESH_OT_uv_texture_remove";
-
+
/* api callbacks */
ot->poll = layers_poll;
ot->exec = mesh_uv_texture_remove_exec;
@@ -668,7 +668,7 @@ void MESH_OT_vertex_color_add(wmOperatorType *ot)
ot->name = "Add Vertex Color";
ot->description = "Add vertex color layer";
ot->idname = "MESH_OT_vertex_color_add";
-
+
/* api callbacks */
ot->poll = layers_poll;
ot->exec = mesh_vertex_color_add_exec;
@@ -694,7 +694,7 @@ void MESH_OT_vertex_color_remove(wmOperatorType *ot)
ot->name = "Remove Vertex Color";
ot->description = "Remove vertex color layer";
ot->idname = "MESH_OT_vertex_color_remove";
-
+
/* api callbacks */
ot->exec = mesh_vertex_color_remove_exec;
ot->poll = layers_poll;
diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c
index 0d6c7320a95..5cfb269cbc3 100644
--- a/source/blender/editors/mesh/mesh_navmesh.c
+++ b/source/blender/editors/mesh/mesh_navmesh.c
@@ -383,7 +383,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
/* create custom data layer to save polygon idx */
CustomData_add_layer_named(&em->bm->pdata, CD_RECAST, CD_CALLOC, NULL, 0, "createRepresentation recastData");
CustomData_bmesh_init_pool(&em->bm->pdata, 0, BM_FACE);
-
+
/* create verts and faces for detailed mesh */
meshes = recast_polyMeshDetailGetMeshes(dmesh, &nmeshes);
polys = recast_polyMeshGetPolys(pmesh, NULL, &nvp);
@@ -445,7 +445,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh,
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- ED_object_editmode_exit(C, EM_FREEDATA);
+ ED_object_editmode_exit(C, EM_FREEDATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
if (createob) {
@@ -616,14 +616,14 @@ static int navmesh_face_add_exec(bContext *C, wmOperator *UNUSED(op))
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *ef;
BMIter iter;
-
+
if (CustomData_has_layer(&em->bm->pdata, CD_RECAST)) {
int targetPolyIdx = findFreeNavPolyIndex(em);
if (targetPolyIdx > 0) {
/* set target poly idx to selected faces */
/*XXX this originally went last to first, but that isn't possible anymore*/
-
+
BM_ITER_MESH (ef, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(ef, BM_ELEM_SELECT)) {
int *recastDataBlock = (int *)CustomData_bmesh_get(&em->bm->pdata, ef->head.data, CD_RECAST);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 2a86b8caacc..f5c5a85d5ca 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -98,12 +98,12 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_loop_to_region);
WM_operatortype_append(MESH_OT_region_to_loop);
WM_operatortype_append(MESH_OT_select_axis);
-
+
WM_operatortype_append(MESH_OT_uvs_rotate);
WM_operatortype_append(MESH_OT_uvs_reverse);
WM_operatortype_append(MESH_OT_colors_rotate);
WM_operatortype_append(MESH_OT_colors_reverse);
-
+
WM_operatortype_append(MESH_OT_fill);
WM_operatortype_append(MESH_OT_fill_grid);
WM_operatortype_append(MESH_OT_fill_holes);
@@ -220,7 +220,7 @@ void ED_operatormacros_mesh(void)
{
wmOperatorType *ot;
wmOperatorTypeMacro *otmacro;
-
+
ot = WM_operatortype_append_macro("MESH_OT_loopcut_slide", "Loop Cut and Slide", "Cut mesh loop and slide it",
OPTYPE_UNDO | OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MESH_OT_loopcut");
@@ -317,14 +317,14 @@ void ED_operatormacros_mesh(void)
/* note mesh keymap also for other space? */
void ED_keymap_mesh(wmKeyConfig *keyconf)
-{
+{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
int i;
-
+
keymap = WM_keymap_find(keyconf, "Mesh", 0, 0);
keymap->poll = ED_operator_editmesh;
-
+
WM_keymap_add_item(keymap, "MESH_OT_loopcut_slide", RKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_offset_edge_loops_slide", RKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "MESH_OT_inset", IKEY, KM_PRESS, 0, 0);
@@ -335,6 +335,24 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "vertex_only", true);
/* selecting */
+
+ kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", ONEKEY, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX);
+ kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", TWOKEY, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "type", SCE_SELECT_EDGE);
+ kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", THREEKEY, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "type", SCE_SELECT_FACE);
+
+ kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", ONEKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX);
+ RNA_boolean_set(kmi->ptr, "use_extend", true);
+ kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", TWOKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "type", SCE_SELECT_EDGE);
+ RNA_boolean_set(kmi->ptr, "use_extend", true);
+ kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", THREEKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "type", SCE_SELECT_FACE);
+ RNA_boolean_set(kmi->ptr, "use_extend", true);
+
/* standard mouse selection goes via space_view3d */
kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
@@ -372,13 +390,13 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MESH_OT_select_prev_item", PADMINUS, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_non_manifold", MKEY, KM_PRESS, (KM_CTRL | KM_SHIFT | KM_ALT), 0);
-
+
WM_keymap_add_item(keymap, "MESH_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "MESH_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "MESH_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
-
+
WM_keymap_add_item(keymap, "MESH_OT_faces_select_linked_flat", FKEY, KM_PRESS, (KM_CTRL | KM_SHIFT | KM_ALT), 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0);
@@ -395,14 +413,14 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "inside", false);
kmi = WM_keymap_add_item(keymap, "MESH_OT_normals_make_consistent", NKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "inside", true);
-
+
WM_keymap_add_item(keymap, "VIEW3D_OT_edit_mesh_extrude_move_normal", EKEY, KM_PRESS, 0, 0); /* python operator */
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_extrude", EKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "TRANSFORM_OT_edge_crease", EKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "MESH_OT_spin", RKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "MESH_OT_fill", FKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "MESH_OT_beautify_fill", FKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0);
@@ -436,9 +454,9 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0);
// WM_keymap_add_item(keymap, "MESH_OT_skin", FKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); /* python, removed */
WM_keymap_add_item(keymap, "MESH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_menu(keymap, "INFO_MT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_split", YKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_vert_connect_path", JKEY, KM_PRESS, 0, 0);
@@ -456,7 +474,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MESH_OT_dissolve_mode", XKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_dissolve_mode", DELKEY, KM_PRESS, KM_CTRL, 0);
-
+
kmi = WM_keymap_add_item(keymap, "MESH_OT_knife_tool", KKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_occlude_geometry", true);
RNA_boolean_set(kmi->ptr, "only_selected", false);
@@ -464,7 +482,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "MESH_OT_knife_tool", KKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "use_occlude_geometry", false);
RNA_boolean_set(kmi->ptr, "only_selected", true);
-
+
WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
/* menus */
@@ -475,13 +493,13 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_uv_map", UKEY, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_vertex_group", GKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* useful stuff from object-mode */
for (i = 0; i <= 5; i++) {
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", ZEROKEY + i, KM_PRESS, KM_CTRL, 0);
RNA_int_set(kmi->ptr, "level", i);
}
-
+
ED_keymap_proportional_cycle(keyconf, keymap);
ED_keymap_proportional_editmode(keyconf, keymap, true);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 802922ab799..41e1ca13b79 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -54,6 +54,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_material.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
@@ -286,7 +287,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Cannot join while in edit mode");
return OPERATOR_CANCELLED;
}
-
+
/* ob is the object we are adding geometry to */
if (!ob || ob->type != OB_MESH) {
BKE_report(op->reports, RPT_WARNING, "Active object is not a mesh");
@@ -306,23 +307,23 @@ int join_mesh_exec(bContext *C, wmOperator *op)
totloop += me->totloop;
totpoly += me->totpoly;
totmat += base->object->totcol;
-
+
if (base->object == ob)
ok = true;
-
+
/* check for shapekeys */
if (me->key)
haskey++;
}
}
CTX_DATA_END;
-
- /* that way the active object is always selected */
+
+ /* that way the active object is always selected */
if (ok == false) {
BKE_report(op->reports, RPT_WARNING, "Active object is not a selected mesh");
return OPERATOR_CANCELLED;
}
-
+
/* only join meshes if there are verts to join, there aren't too many, and we only had one mesh selected */
me = (Mesh *)ob->data;
key = me->key;
@@ -331,7 +332,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No mesh data to join");
return OPERATOR_CANCELLED;
}
-
+
if (totvert > MESH_MAX_VERTS) {
BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is %ld", totvert, MESH_MAX_VERTS);
return OPERATOR_CANCELLED;
@@ -346,23 +347,23 @@ int join_mesh_exec(bContext *C, wmOperator *op)
matmap = MEM_callocN(sizeof(*matmap) * totmat, "join_mesh matmap");
}
totcol = ob->totcol;
-
+
/* obact materials in new main array, is nicer start! */
for (a = 0; a < ob->totcol; a++) {
matar[a] = give_current_material(ob, a + 1);
id_us_plus((ID *)matar[a]);
/* increase id->us : will be lowered later */
}
-
+
/* - if destination mesh had shapekeys, move them somewhere safe, and set up placeholders
* with arrays that are large enough to hold shapekey data for all meshes
- * - if destination mesh didn't have shapekeys, but we encountered some in the meshes we're
+ * - if destination mesh didn't have shapekeys, but we encountered some in the meshes we're
* joining, set up a new keyblock and assign to the mesh
*/
if (key) {
/* make a duplicate copy that will only be used here... (must remember to free it!) */
nkey = BKE_key_copy(bmain, key);
-
+
/* for all keys in old block, clear data-arrays */
for (kb = key->block.first; kb; kb = kb->next) {
if (kb->data) MEM_freeN(kb->data);
@@ -375,14 +376,14 @@ int join_mesh_exec(bContext *C, wmOperator *op)
key = me->key = BKE_key_add((ID *)me);
key->type = KEY_RELATIVE;
}
-
+
/* first pass over objects - copying materials and vertexgroups across */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
/* only act if a mesh, and not the one we're joining to */
if ((ob != base->object) && (base->object->type == OB_MESH)) {
me = base->object->data;
-
+
/* Join this object's vertex groups to the base one's */
for (dg = base->object->defbase.first; dg; dg = dg->next) {
/* See if this group exists in the object (if it doesn't, add it to the end) */
@@ -394,8 +395,8 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
if (ob->defbase.first && ob->actdef == 0)
ob->actdef = 1;
-
-
+
+
if (me->totvert) {
/* Add this object's materials to the base one's if they don't exist already (but only if limits not exceeded yet) */
if (totcol < MAXMAT) {
@@ -419,7 +420,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* if this mesh has shapekeys, check if destination mesh already has matching entries too */
if (me->key && key) {
/* for remapping KeyBlock.relative */
@@ -481,7 +482,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
edgeofs = 0;
loopofs = 0;
polyofs = 0;
-
+
/* inverse transform for all selected meshes in this object */
invert_m4_m4(imat, ob->obmat);
@@ -522,10 +523,10 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
/* return to mesh we're merging to */
me = ob->data;
-
+
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
CustomData_free(&me->ldata, me->totloop);
@@ -546,7 +547,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/* update normals in case objects with non-uniform scale are joined */
BKE_mesh_calc_normals(me);
-
+
/* old material array */
for (a = 1; a <= ob->totcol; a++) {
ma = ob->mat[a - 1];
@@ -573,13 +574,13 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/* other mesh users */
test_all_objects_materials(bmain, (ID *)me);
-
+
/* free temp copy of destination shapekeys (if applicable) */
if (nkey) {
/* We can assume nobody is using that ID currently. */
BKE_libblock_free_ex(bmain, nkey, false, false);
}
-
+
/* ensure newly inserted keys are time sorted */
if (key && (key->type != KEY_RELATIVE)) {
BKE_key_sort(key);
@@ -599,7 +600,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/*********************** JOIN AS SHAPES ***************************/
-/* Append selected meshes vertex locations as shapes of the active mesh,
+/* Append selected meshes vertex locations as shapes of the active mesh,
* return 0 if no join is made (error) and 1 of the join is done */
int join_mesh_shapes_exec(bContext *C, wmOperator *op)
@@ -613,14 +614,14 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
Key *key = me->key;
KeyBlock *kb;
bool ok = false, nonequal_verts = false;
-
+
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
if (base->object == ob) continue;
-
+
if (base->object->type == OB_MESH) {
selme = (Mesh *)base->object->data;
-
+
if (selme->totvert == me->totvert)
ok = true;
else
@@ -628,7 +629,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
if (!ok) {
if (nonequal_verts)
BKE_report(op->reports, RPT_WARNING, "Selected meshes must have equal numbers of vertices");
@@ -636,7 +637,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No additional selected meshes with equal vertex count to join");
return OPERATOR_CANCELLED;
}
-
+
if (key == NULL) {
key = me->key = BKE_key_add((ID *)me);
key->type = KEY_RELATIVE;
@@ -645,32 +646,32 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
kb = BKE_keyblock_add(key, NULL);
BKE_keyblock_convert_from_mesh(me, kb);
}
-
+
/* now ready to add new keys from selected meshes */
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
if (base->object == ob) continue;
-
+
if (base->object->type == OB_MESH) {
selme = (Mesh *)base->object->data;
-
+
if (selme->totvert == me->totvert) {
dm = mesh_get_derived_deform(depsgraph, scene, base->object, CD_MASK_BAREMESH);
-
+
if (!dm) continue;
-
+
kb = BKE_keyblock_add(key, base->object->id.name + 2);
-
+
DM_to_meshkey(dm, me, kb);
-
+
dm->release(dm);
}
}
}
CTX_DATA_END;
-
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -739,12 +740,12 @@ static int mesh_get_x_mirror_vert_spatial(Object *ob, DerivedMesh *dm, int index
Mesh *me = ob->data;
MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert;
float vec[3];
-
+
mvert = &mvert[index];
vec[0] = -mvert->co[0];
vec[1] = mvert->co[1];
vec[2] = mvert->co[2];
-
+
return ED_mesh_mirror_spatial_table(ob, NULL, dm, vec, 'u');
}
@@ -802,7 +803,7 @@ static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, c
{
float vec[3];
int i;
-
+
/* ignore nan verts */
if ((isfinite(co[0]) == false) ||
(isfinite(co[1]) == false) ||
@@ -810,11 +811,11 @@ static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, c
{
return NULL;
}
-
+
vec[0] = -co[0];
vec[1] = co[1];
vec[2] = co[2];
-
+
i = ED_mesh_mirror_spatial_table(ob, em, NULL, vec, 'u');
if (i != -1) {
return BM_vert_at_index(em->bm, i);
@@ -831,14 +832,14 @@ static BMVert *editbmesh_get_x_mirror_vert_topo(Object *ob, struct BMEditMesh *e
if (index == -1) {
BMIter iter;
BMVert *v;
-
+
index = 0;
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
if (v == eve)
break;
index++;
}
-
+
if (index == em->bm->totvert) {
return NULL;
}
@@ -849,7 +850,7 @@ static BMVert *editbmesh_get_x_mirror_vert_topo(Object *ob, struct BMEditMesh *e
if (poinval != -1)
return (BMVert *)(poinval);
return NULL;
-}
+}
BMVert *editbmesh_get_x_mirror_vert(Object *ob, struct BMEditMesh *em, BMVert *eve, const float co[3], int index, const bool use_topology)
{
@@ -921,19 +922,19 @@ static float *editmesh_get_mirror_uv(BMEditMesh *em, int axis, float *uv, float
{
BMIter iter;
BMFace *efa;
-
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
uv_poly_center(efa, cent, cd_loop_uv_offset);
-
+
if ( (fabsf(cent[0] - cent_vec[0]) < 0.001f) && (fabsf(cent[1] - cent_vec[1]) < 0.001f) ) {
BMIter liter;
BMLoop *l;
-
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
if ( (fabsf(luv->uv[0] - vec[0]) < 0.001f) && (fabsf(luv->uv[1] - vec[1]) < 0.001f) ) {
return luv->uv;
-
+
}
}
}
@@ -982,7 +983,7 @@ static int mirror_facerotation(MFace *a, MFace *b)
else if (a->v2 == b->v1 && a->v3 == b->v2 && a->v1 == b->v3)
return 2;
}
-
+
return -1;
}
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 0835618043d..65bf258f334 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -19,7 +19,7 @@
* All rights reserved.
*
* The Original Code is: all of this file.
-
+
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
@@ -79,7 +79,7 @@ void ED_mball_editmball_make(Object *obedit)
MetaElem *ml; /*, *newml;*/
ml = mb->elems.first;
-
+
while (ml) {
if (ml->flag & SELECT) mb->lastelem = ml;
ml = ml->next;
@@ -107,7 +107,7 @@ MetaElem *ED_mball_add_primitive(bContext *UNUSED(C), Object *obedit, float mat[
ml->flag &= ~SELECT;
ml = ml->next;
}
-
+
ml = BKE_mball_element_add(mball, type);
ml->rad *= dia;
mball->wiresize *= dia;
@@ -371,7 +371,7 @@ 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 int seed = WM_operator_properties_select_random_seed_increment_get(op);
-
+
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
@@ -415,14 +415,14 @@ void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot)
ot->name = "Select Random";
ot->description = "Randomly select metaelements";
ot->idname = "MBALL_OT_select_random_metaelems";
-
+
/* callback functions */
ot->exec = select_random_metaelems_exec;
ot->poll = ED_operator_editmball;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_select_random(ot);
}
@@ -435,7 +435,7 @@ static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op))
Object *obedit = CTX_data_edit_object(C);
MetaBall *mb = (MetaBall *)obedit->data;
MetaElem *ml, *newml;
-
+
ml = mb->editelems->last;
if (ml) {
while (ml) {
@@ -477,7 +477,7 @@ static int delete_metaelems_exec(bContext *C, wmOperator *UNUSED(op))
Object *obedit = CTX_data_edit_object(C);
MetaBall *mb = (MetaBall *)obedit->data;
MetaElem *ml, *next;
-
+
ml = mb->editelems->first;
if (ml) {
while (ml) {
@@ -549,7 +549,7 @@ void MBALL_OT_hide_metaelems(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_boolean(ot->srna, "unselected", false, "Unselected", "Hide unselected rather than selected");
}
@@ -575,7 +575,7 @@ static int reveal_metaelems_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_GEOM | ND_DATA, mb);
DEG_id_tag_update(obedit->data, 0);
}
-
+
return OPERATOR_FINISHED;
}
@@ -585,11 +585,11 @@ void MBALL_OT_reveal_metaelems(wmOperatorType *ot)
ot->name = "Reveal";
ot->description = "Reveal all hidden metaelements";
ot->idname = "MBALL_OT_reveal_metaelems";
-
+
/* callback functions */
ot->exec = reveal_metaelems_exec;
ot->poll = ED_operator_editmball;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -624,7 +624,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
}
if (ml == NULL) startelem = mb->editelems->first;
-
+
if (hits > 0) {
ml = startelem;
while (ml) {
@@ -644,7 +644,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
if (ml == NULL) ml = mb->editelems->first;
if (ml == startelem) break;
}
-
+
/* When some metaelem was found, then it is necessary to select or
* deselect it. */
if (ml_act) {
@@ -667,9 +667,9 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
/* Select only metaelem clicked on */
ml_act->flag |= SELECT;
}
-
+
mb->lastelem = ml_act;
-
+
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb);
return true;
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index 6bf49187483..2e1b7299295 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -45,10 +45,10 @@ void ED_operatortypes_metaball(void)
{
WM_operatortype_append(MBALL_OT_delete_metaelems);
WM_operatortype_append(MBALL_OT_duplicate_metaelems);
-
+
WM_operatortype_append(MBALL_OT_hide_metaelems);
WM_operatortype_append(MBALL_OT_reveal_metaelems);
-
+
WM_operatortype_append(MBALL_OT_select_all);
WM_operatortype_append(MBALL_OT_select_similar);
WM_operatortype_append(MBALL_OT_select_random_metaelems);
@@ -71,22 +71,22 @@ void ED_keymap_metaball(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
keymap = WM_keymap_find(keyconf, "Metaball", 0, 0);
keymap->poll = ED_operator_editmball;
WM_keymap_add_item(keymap, "OBJECT_OT_metaball_add", AKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "MBALL_OT_reveal_metaelems", HKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "MBALL_OT_hide_metaelems", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
-
+
WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MBALL_OT_delete_metaelems", DELKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MBALL_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
-
+
kmi = WM_keymap_add_item(keymap, "MBALL_OT_select_all", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
kmi = WM_keymap_add_item(keymap, "MBALL_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index d9ba12d1183..37589177037 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -82,6 +82,7 @@
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_nla.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -1055,13 +1056,13 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
Collection *collection;
unsigned int layer;
float loc[3], rot[3];
-
+
if (RNA_struct_property_is_set(op->ptr, "name")) {
char name[MAX_ID_NAME - 2];
-
+
RNA_string_get(op->ptr, "name", name);
collection = (Collection *)BKE_libblock_find_name(bmain, ID_GR, name);
-
+
if (0 == RNA_struct_property_is_set(op->ptr, "location")) {
const wmEvent *event = CTX_wm_window(C)->eventstate;
ARegion *ar = CTX_wm_region(C);
@@ -1216,7 +1217,7 @@ static int object_delete_exec(bContext *C, wmOperator *op)
const bool use_global = RNA_boolean_get(op->ptr, "use_global");
bool changed = false;
- if (CTX_data_edit_object(C))
+ if (CTX_data_edit_object(C))
return OPERATOR_CANCELLED;
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
@@ -1290,7 +1291,7 @@ static int object_delete_exec(bContext *C, wmOperator *op)
if (scene->id.tag & LIB_TAG_DOIT) {
scene->id.tag &= ~LIB_TAG_DOIT;
-
+
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
@@ -2046,7 +2047,7 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/**************************** Duplicate ************************/
-/*
+/*
* dupflag: a flag made from constants declared in DNA_userdef_types.h
* The flag tells adduplicate() whether to copy data linked to the object, or to reference the existing data.
* U.dupflag for default operations or you can construct a flag as python does
@@ -2424,7 +2425,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
ED_object_location_from_view(C, basen->object->loc);
ED_view3d_cursor3d_position(C, basen->object->loc, mval);
}
-
+
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 6dd6a76f129..5210182510f 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -276,7 +276,7 @@ static void refresh_images(BakeImages *bake_images)
Image *ima = bake_images->data[i].image;
if (ima->ok == IMA_OK_LOADED) {
GPU_free_image(ima);
- DEG_id_tag_update(&ima->id, 0);
+ DEG_id_tag_update(&ima->id, 0);
}
}
}
@@ -1021,7 +1021,8 @@ cage_cleanup:
BakeData *bake = &scene->r.bake;
char name[FILE_MAX];
- BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false, NULL);
+ BKE_image_path_from_imtype(name, filepath, BKE_main_blendfile_path(bmain),
+ 0, bake->im_format.imtype, true, false, NULL);
if (is_automatic_name) {
BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_");
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 6c4a79ec4b4..3b5a8d190ff 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -91,17 +91,17 @@ ListBase *get_active_constraints(Object *ob)
{
if (ob == NULL)
return NULL;
-
+
if (ob->mode & OB_MODE_POSE) {
bPoseChannel *pchan;
-
+
pchan = BKE_pose_channel_active(ob);
if (pchan)
return &pchan->constraints;
}
- else
+ else
return &ob->constraints;
-
+
return NULL;
}
@@ -110,33 +110,33 @@ ListBase *get_constraint_lb(Object *ob, bConstraint *con, bPoseChannel **r_pchan
{
if (r_pchan)
*r_pchan = NULL;
-
+
if (ELEM(NULL, ob, con))
return NULL;
-
+
/* try object constraints first */
if ((BLI_findindex(&ob->constraints, con) != -1)) {
return &ob->constraints;
}
-
+
/* if armature, try pose bones too */
if (ob->pose) {
bPoseChannel *pchan;
-
- /* try each bone in order
+
+ /* try each bone in order
* NOTE: it's not possible to directly look up the active bone yet, so this will have to do
*/
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if ((BLI_findindex(&pchan->constraints, con) != -1)) {
-
+
if (r_pchan)
*r_pchan = pchan;
-
+
return &pchan->constraints;
}
}
}
-
+
/* done */
return NULL;
}
@@ -152,59 +152,59 @@ bConstraint *get_active_constraint(Object *ob)
/* ------------- PyConstraints ------------------ */
/* this callback sets the text-file to be used for selected menu item */
-static void validate_pyconstraint_cb(void *arg1, void *arg2)
+static void validate_pyconstraint_cb(Main *bmain, void *arg1, void *arg2)
{
bPythonConstraint *data = arg1;
Text *text = NULL;
int index = *((int *)arg2);
int i;
-
+
/* exception for no script */
if (index) {
/* innovative use of a for...loop to search */
- for (text = G.main->text.first, i = 1; text && index != i; i++, text = text->id.next) ;
+ for (text = bmain->text.first, i = 1; text && index != i; i++, text = text->id.next) ;
}
data->text = text;
}
/* this returns a string for the list of usable pyconstraint script names */
-static char *buildmenu_pyconstraints(Text *con_text, int *pyconindex)
+static char *buildmenu_pyconstraints(Main *bmain, Text *con_text, int *pyconindex)
{
DynStr *pupds = BLI_dynstr_new();
Text *text;
char *str;
char buf[64];
int i;
-
+
/* add title first */
sprintf(buf, "Scripts: %%t|[None]%%x0|");
BLI_dynstr_append(pupds, buf);
-
+
/* init active-index first */
if (con_text == NULL)
*pyconindex = 0;
-
+
/* loop through markers, adding them */
- for (text = G.main->text.first, i = 1; text; i++, text = text->id.next) {
+ for (text = bmain->text.first, i = 1; text; i++, text = text->id.next) {
/* this is important to ensure that right script is shown as active */
if (text == con_text) *pyconindex = i;
-
+
/* only include valid pyconstraint scripts */
if (BPY_is_pyconstraint(text)) {
BLI_dynstr_append(pupds, text->id.name + 2);
-
+
sprintf(buf, "%%x%d", i);
BLI_dynstr_append(pupds, buf);
-
+
if (text->id.next)
BLI_dynstr_append(pupds, "|");
}
}
-
+
/* convert to normal MEM_malloc'd string */
str = BLI_dynstr_get_cstring(pupds);
BLI_dynstr_free(pupds);
-
+
return str;
}
#endif /* WITH_PYTHON */
@@ -232,11 +232,11 @@ static void set_constraint_nth_target(bConstraint *con, Object *target, const ch
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
int num_targets, i;
-
+
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
num_targets = BLI_listbase_count(&targets);
-
+
if (index < 0) {
if (abs(index) < num_targets)
index = num_targets - abs(index);
@@ -246,7 +246,7 @@ static void set_constraint_nth_target(bConstraint *con, Object *target, const ch
else if (index >= num_targets) {
index = num_targets - 1;
}
-
+
for (ct = targets.first, i = 0; ct; ct = ct->next, i++) {
if (i == index) {
ct->tar = target;
@@ -254,7 +254,7 @@ static void set_constraint_nth_target(bConstraint *con, Object *target, const ch
break;
}
}
-
+
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 0);
}
@@ -508,7 +508,7 @@ static void test_constraints(Main *bmain, Object *owner, bPoseChannel *pchan)
bConstraint *curcon;
ListBase *conlist = NULL;
int type;
-
+
if (owner == NULL) return;
type = constraint_type_get(owner, pchan);
@@ -522,7 +522,7 @@ static void test_constraints(Main *bmain, Object *owner, bPoseChannel *pchan)
conlist = &pchan->constraints;
break;
}
-
+
/* Check all constraints - is constraint valid? */
if (conlist) {
for (curcon = conlist->first; curcon; curcon = curcon->next) {
@@ -535,10 +535,10 @@ void object_test_constraints(Main *bmain, Object *owner)
{
if (owner->constraints.first)
test_constraints(bmain, owner, NULL);
-
+
if (owner->type == OB_ARMATURE && owner->pose) {
bPoseChannel *pchan;
-
+
for (pchan = owner->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->constraints.first)
test_constraints(bmain, owner, pchan);
@@ -623,24 +623,24 @@ static int edit_constraint_invoke_properties(bContext *C, wmOperator *op)
Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
bConstraint *con;
ListBase *list;
-
+
if (RNA_struct_property_is_set(op->ptr, "constraint") && RNA_struct_property_is_set(op->ptr, "owner"))
return 1;
-
+
if (ptr.data) {
con = ptr.data;
RNA_string_set(op->ptr, "constraint", con->name);
-
+
list = get_constraint_lb(ob, con, NULL);
-
+
if (&ob->constraints == list)
RNA_enum_set(op->ptr, "owner", EDIT_CONSTRAINT_OWNER_OBJECT);
else
RNA_enum_set(op->ptr, "owner", EDIT_CONSTRAINT_OWNER_BONE);
-
+
return 1;
}
-
+
return 0;
}
@@ -650,9 +650,9 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
int owner = RNA_enum_get(op->ptr, "owner");
bConstraint *con;
ListBase *list = NULL;
-
+
RNA_string_get(op->ptr, "constraint", constraint_name);
-
+
if (owner == EDIT_CONSTRAINT_OWNER_OBJECT) {
list = &ob->constraints;
}
@@ -671,14 +671,14 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
//printf("edit_constraint_property_get: defaulting to getting list in the standard way\n");
list = get_active_constraints(ob);
}
-
+
con = BKE_constraints_find_name(list, constraint_name);
//if (G.debug & G_DEBUG)
//printf("constraint found = %p, %s\n", (void *)con, (con) ? con->name : "<Not found>");
if (con && (type != 0) && (con->type != type))
con = NULL;
-
+
return con;
}
@@ -693,15 +693,15 @@ static int stretchto_reset_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_STRETCHTO);
bStretchToConstraint *data = (con) ? (bStretchToConstraint *)con->data : NULL;
-
+
/* despite 3 layers of checks, we may still not be able to find a constraint */
if (data == NULL)
return OPERATOR_CANCELLED;
-
+
/* just set original length to 0.0, which will cause a reset on next recalc */
data->orglength = 0.0f;
ED_object_constraint_update(bmain, ob);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL);
return OPERATOR_FINISHED;
}
@@ -720,15 +720,15 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot)
ot->name = "Reset Original Length";
ot->idname = "CONSTRAINT_OT_stretchto_reset";
ot->description = "Reset original length of bone for Stretch To Constraint";
-
+
/* callbacks */
ot->invoke = stretchto_reset_invoke;
ot->exec = stretchto_reset_exec;
ot->poll = edit_constraint_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
edit_constraint_properties(ot);
}
@@ -740,15 +740,15 @@ static int limitdistance_reset_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_DISTLIMIT);
bDistLimitConstraint *data = (con) ? (bDistLimitConstraint *)con->data : NULL;
-
+
/* despite 3 layers of checks, we may still not be able to find a constraint */
if (data == NULL)
return OPERATOR_CANCELLED;
-
+
/* just set original length to 0.0, which will cause a reset on next recalc */
data->dist = 0.0f;
ED_object_constraint_update(bmain, ob);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL);
return OPERATOR_FINISHED;
}
@@ -767,15 +767,15 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot)
ot->name = "Reset Distance";
ot->idname = "CONSTRAINT_OT_limitdistance_reset";
ot->description = "Reset limiting distance for Limit Distance Constraint";
-
+
/* callbacks */
ot->invoke = limitdistance_reset_invoke;
ot->exec = limitdistance_reset_exec;
ot->poll = edit_constraint_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
edit_constraint_properties(ot);
}
@@ -788,7 +788,7 @@ static void child_get_inverse_matrix(const bContext *C, Scene *scene, Object *ob
/* nullify inverse matrix first */
unit_m4(invmat);
-
+
if (owner == EDIT_CONSTRAINT_OWNER_BONE) {
bPoseChannel *pchan;
/* try to find a pose channel - assume that this is the constraint owner */
@@ -883,11 +883,11 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Could not find constraint data for Child-Of Set Inverse");
return OPERATOR_CANCELLED;
}
-
+
child_get_inverse_matrix(C, scene, ob, con, data->invmat, owner);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -905,15 +905,15 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot)
ot->name = "Set Inverse";
ot->idname = "CONSTRAINT_OT_childof_set_inverse";
ot->description = "Set inverse correction for ChildOf constraint";
-
+
/* callbacks */
ot->invoke = childof_set_inverse_invoke;
ot->exec = childof_set_inverse_exec;
ot->poll = edit_constraint_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
edit_constraint_properties(ot);
}
@@ -924,17 +924,17 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL;
-
+
if (data == NULL) {
BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found");
return OPERATOR_CANCELLED;
}
-
+
/* simply clear the matrix */
unit_m4(data->invmat);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -952,15 +952,15 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot)
ot->name = "Clear Inverse";
ot->idname = "CONSTRAINT_OT_childof_clear_inverse";
ot->description = "Clear inverse correction for ChildOf constraint";
-
+
/* callbacks */
ot->invoke = childof_clear_inverse_invoke;
ot->exec = childof_clear_inverse_exec;
ot->poll = edit_constraint_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
edit_constraint_properties(ot);
}
@@ -969,33 +969,34 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot)
static int followpath_path_animate_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_FOLLOWPATH);
bFollowPathConstraint *data = (con) ? (bFollowPathConstraint *)con->data : NULL;
-
+
bAction *act = NULL;
FCurve *fcu = NULL;
int sfra = RNA_int_get(op->ptr, "frame_start");
int len = RNA_int_get(op->ptr, "length");
float standardRange = 1.0;
-
+
/* nearly impossible sanity check */
if (data == NULL) {
BKE_report(op->reports, RPT_ERROR, "Follow Path constraint not found");
return OPERATOR_CANCELLED;
}
-
+
/* add F-Curve as appropriate */
if (data->tar) {
Curve *cu = (Curve *)data->tar->data;
-
+
if (ELEM(NULL, cu->adt, cu->adt->action) ||
(list_find_fcurve(&cu->adt->action->curves, "eval_time", 0) == NULL))
{
/* create F-Curve for path animation */
- act = verify_adt_action(&cu->id, 1);
+ act = verify_adt_action(bmain, &cu->id, 1);
fcu = verify_fcurve(act, NULL, NULL, "eval_time", 0, 1);
-
+
/* standard vertical range - 1:1 = 100 frames */
standardRange = 100.0f;
}
@@ -1010,46 +1011,46 @@ static int followpath_path_animate_exec(bContext *C, wmOperator *op)
PointerRNA ptr;
PropertyRNA *prop;
char *path;
-
+
/* get RNA pointer to constraint's "offset_factor" property - to build RNA path */
RNA_pointer_create(&ob->id, &RNA_FollowPathConstraint, con, &ptr);
prop = RNA_struct_find_property(&ptr, "offset_factor");
-
+
path = RNA_path_from_ID_to_property(&ptr, prop);
-
+
/* create F-Curve for constraint */
- act = verify_adt_action(&ob->id, 1);
+ act = verify_adt_action(bmain, &ob->id, 1);
fcu = verify_fcurve(act, NULL, NULL, path, 0, 1);
-
+
/* standard vertical range - 0.0 to 1.0 */
standardRange = 1.0f;
-
+
/* enable "Use Fixed Position" so that animating this has effect */
data->followflag |= FOLLOWPATH_STATIC;
-
+
/* path needs to be freed */
- if (path)
+ if (path)
MEM_freeN(path);
}
-
+
/* setup dummy 'generator' modifier here to get 1-1 correspondence still working
* and define basic slope of this curve based on the properties
*/
if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) {
FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu);
FMod_Generator *gen = fcm->data;
-
+
/* Assume that we have the following equation:
* y = Ax + B
* 1 0 <-- coefficients array indices
*/
float A = standardRange / (float)(len);
float B = (float)(-sfra) * A;
-
+
gen->coefficients[1] = A;
gen->coefficients[0] = B;
}
-
+
/* updates... */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
return OPERATOR_FINISHED;
@@ -1072,20 +1073,20 @@ void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot)
ot->name = "Auto Animate Path";
ot->idname = "CONSTRAINT_OT_followpath_path_animate";
ot->description = "Add default animation for path used by constraint if it isn't animated already";
-
+
/* callbacks */
ot->invoke = followpath_path_animate_invoke;
ot->exec = followpath_path_animate_exec;
ot->poll = edit_constraint_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
edit_constraint_properties(ot);
- RNA_def_int(ot->srna, "frame_start", 1, MINAFRAME, MAXFRAME, "Start Frame",
+ RNA_def_int(ot->srna, "frame_start", 1, MINAFRAME, MAXFRAME, "Start Frame",
"First frame of path animation", MINAFRAME, MAXFRAME);
- RNA_def_int(ot->srna, "length", 100, 0, MAXFRAME, "Length",
+ RNA_def_int(ot->srna, "length", 100, 0, MAXFRAME, "Length",
"Number of frames that path animation should take", 0, MAXFRAME);
}
@@ -1127,7 +1128,7 @@ void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot)
ot->name = "Set Inverse";
ot->idname = "CONSTRAINT_OT_objectsolver_set_inverse";
ot->description = "Set inverse correction for ObjectSolver constraint";
-
+
/* callbacks */
ot->invoke = objectsolver_set_inverse_invoke;
ot->exec = objectsolver_set_inverse_exec;
@@ -1135,7 +1136,7 @@ void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
edit_constraint_properties(ot);
}
@@ -1173,7 +1174,7 @@ void CONSTRAINT_OT_objectsolver_clear_inverse(wmOperatorType *ot)
ot->name = "Clear Inverse";
ot->idname = "CONSTRAINT_OT_objectsolver_clear_inverse";
ot->description = "Clear inverse correction for ObjectSolver constraint";
-
+
/* callbacks */
ot->invoke = objectsolver_clear_inverse_invoke;
ot->exec = objectsolver_clear_inverse_exec;
@@ -1181,7 +1182,7 @@ void CONSTRAINT_OT_objectsolver_clear_inverse(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
edit_constraint_properties(ot);
}
@@ -1189,14 +1190,14 @@ void CONSTRAINT_OT_objectsolver_clear_inverse(wmOperatorType *ot)
/***************************** BUTTONS ****************************/
void ED_object_constraint_set_active(Object *ob, bConstraint *con)
-{
+{
ListBase *lb = get_constraint_lb(ob, con, NULL);
-
+
/* lets be nice and escape if its active already */
/* NOTE: this assumes that the stack doesn't have other active ones set... */
if ((lb && con) && (con->flag & CONSTRAINT_ACTIVE))
return;
-
+
BKE_constraints_active_set(lb, con);
}
@@ -1206,9 +1207,9 @@ void ED_object_constraint_update(Main *bmain, Object *ob)
object_test_constraints(bmain, ob);
- if (ob->type == OB_ARMATURE)
+ if (ob->type == OB_ARMATURE)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB);
- else
+ else
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
}
@@ -1290,7 +1291,7 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op))
/* notifiers */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
-
+
return OPERATOR_FINISHED;
}
else {
@@ -1305,11 +1306,11 @@ void CONSTRAINT_OT_delete(wmOperatorType *ot)
ot->name = "Delete Constraint";
ot->idname = "CONSTRAINT_OT_delete";
ot->description = "Remove constraint from constraint stack";
-
+
/* callbacks */
ot->exec = constraint_delete_exec;
ot->poll = constraint_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1319,20 +1320,20 @@ static int constraint_move_down_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, 0);
-
+
if (con && con->next) {
ListBase *conlist = get_constraint_lb(ob, con, NULL);
bConstraint *nextCon = con->next;
-
+
/* insert the nominated constraint after the one that used to be after it */
BLI_remlink(conlist, con);
BLI_insertlinkafter(conlist, nextCon, con);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
-
+
return OPERATOR_FINISHED;
}
-
+
return OPERATOR_CANCELLED;
}
@@ -1350,15 +1351,15 @@ void CONSTRAINT_OT_move_down(wmOperatorType *ot)
ot->name = "Move Constraint Down";
ot->idname = "CONSTRAINT_OT_move_down";
ot->description = "Move constraint down in constraint stack";
-
+
/* callbacks */
ot->invoke = constraint_move_down_invoke;
ot->exec = constraint_move_down_exec;
ot->poll = edit_constraint_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
edit_constraint_properties(ot);
}
@@ -1368,20 +1369,20 @@ static int constraint_move_up_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
bConstraint *con = edit_constraint_property_get(op, ob, 0);
-
+
if (con && con->prev) {
ListBase *conlist = get_constraint_lb(ob, con, NULL);
bConstraint *prevCon = con->prev;
-
+
/* insert the nominated constraint before the one that used to be before it */
BLI_remlink(conlist, con);
BLI_insertlinkbefore(conlist, prevCon, con);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
-
+
return OPERATOR_FINISHED;
}
-
+
return OPERATOR_CANCELLED;
}
@@ -1399,12 +1400,12 @@ void CONSTRAINT_OT_move_up(wmOperatorType *ot)
ot->name = "Move Constraint Up";
ot->idname = "CONSTRAINT_OT_move_up";
ot->description = "Move constraint up in constraint stack";
-
+
/* callbacks */
ot->exec = constraint_move_up_exec;
ot->invoke = constraint_move_up_invoke;
ot->poll = edit_constraint_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
edit_constraint_properties(ot);
@@ -1418,7 +1419,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-
+
/* free constraints for all selected bones */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
@@ -1426,16 +1427,16 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_SPLINEIK | PCHAN_HAS_CONST);
}
CTX_DATA_END;
-
+
/* force depsgraph to get recalculated since relationships removed */
DEG_relations_tag_update(bmain);
-
+
/* note, calling BIK_clear_data() isn't needed here */
/* do updates */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1445,7 +1446,7 @@ void POSE_OT_constraints_clear(wmOperatorType *ot)
ot->name = "Clear Pose Constraints";
ot->idname = "POSE_OT_constraints_clear";
ot->description = "Clear all the constraints for the selected bones";
-
+
/* callbacks */
ot->exec = pose_constraints_clear_exec;
ot->poll = ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected bones too?
@@ -1455,7 +1456,7 @@ void POSE_OT_constraints_clear(wmOperatorType *ot)
static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
-
+
/* do freeing */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
@@ -1463,13 +1464,13 @@ static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
}
CTX_DATA_END;
-
+
/* force depsgraph to get recalculated since relationships removed */
DEG_relations_tag_update(bmain);
-
+
/* do updates */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1479,7 +1480,7 @@ void OBJECT_OT_constraints_clear(wmOperatorType *ot)
ot->name = "Clear Object Constraints";
ot->idname = "OBJECT_OT_constraints_clear";
ot->description = "Clear all the constraints for the active Object only";
-
+
/* callbacks */
ot->exec = object_constraints_clear_exec;
ot->poll = ED_operator_object_active_editable;
@@ -1493,19 +1494,19 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
bPoseChannel *pchan = CTX_data_active_pose_bone(C);
ListBase lb;
CollectionPointerLink *link;
-
+
/* don't do anything if bone doesn't exist or doesn't have any constraints */
if (ELEM(NULL, pchan, pchan->constraints.first)) {
BKE_report(op->reports, RPT_ERROR, "No active bone with constraints for copying");
return OPERATOR_CANCELLED;
}
-
+
/* copy all constraints from active posebone to all selected posebones */
CTX_data_selected_pose_bones(C, &lb);
for (link = lb.first; link; link = link->next) {
Object *ob = link->ptr.id.data;
bPoseChannel *chan = link->ptr.data;
-
+
/* if we're not handling the object we're copying from, copy all constraints over */
if (pchan != chan) {
BKE_constraints_copy(&chan->constraints, &pchan->constraints, true);
@@ -1517,12 +1518,12 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
}
}
BLI_freelistN(&lb);
-
+
/* force depsgraph to get recalculated since new relationships added */
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1532,7 +1533,7 @@ void POSE_OT_constraints_copy(wmOperatorType *ot)
ot->name = "Copy Constraints to Selected Bones";
ot->idname = "POSE_OT_constraints_copy";
ot->description = "Copy constraints to other selected bones";
-
+
/* api callbacks */
ot->exec = pose_constraint_copy_exec;
ot->poll = ED_operator_posemode_exclusive;
@@ -1545,7 +1546,7 @@ static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
Object *obact = ED_object_active_context(C);
-
+
/* copy all constraints from active object to all selected objects */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
@@ -1556,13 +1557,13 @@ static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
}
}
CTX_DATA_END;
-
+
/* force depsgraph to get recalculated since new relationships added */
DEG_relations_tag_update(bmain);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_ADDED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1572,7 +1573,7 @@ void OBJECT_OT_constraints_copy(wmOperatorType *ot)
ot->name = "Copy Constraints to Selected Objects";
ot->idname = "OBJECT_OT_constraints_copy";
ot->description = "Copy constraints to other selected objects";
-
+
/* api callbacks */
ot->exec = object_constraint_copy_exec;
ot->poll = ED_operator_object_active_editable;
@@ -1590,15 +1591,15 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
bPoseChannel *pchanact = BKE_pose_channel_active(obact);
bool only_curve = false, only_mesh = false, only_ob = false;
bool found = false;
-
- /* clear tar_ob and tar_pchan fields before use
+
+ /* clear tar_ob and tar_pchan fields before use
* - assume for now that both always exist...
*/
*tar_ob = NULL;
*tar_pchan = NULL;
-
+
/* check if constraint type doesn't requires a target
- * - if so, no need to get any targets
+ * - if so, no need to get any targets
*/
switch (con_type) {
/* no-target constraints --------------------------- */
@@ -1610,7 +1611,7 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
case CONSTRAINT_TYPE_SIZELIMIT:
case CONSTRAINT_TYPE_SAMEVOL:
return false;
-
+
/* restricted target-type constraints -------------- */
/* NOTE: for these, we cannot try to add a target object if no valid ones are found, since that doesn't work */
/* curve-based constraints - set the only_curve and only_ob flags */
@@ -1621,7 +1622,7 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
only_ob = true;
add = false;
break;
-
+
/* mesh only? */
case CONSTRAINT_TYPE_SHRINKWRAP:
only_mesh = true;
@@ -1629,7 +1630,7 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
add = false;
break;
}
-
+
/* if the active Object is Armature, and we can search for bones, do so... */
if ((obact->type == OB_ARMATURE) && (only_ob == false)) {
/* search in list of selected Pose-Channels for target */
@@ -1640,20 +1641,20 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
*tar_ob = obact;
*tar_pchan = pchan;
found = true;
-
+
break;
}
}
CTX_DATA_END;
}
-
+
/* if not yet found, try selected Objects... */
if (found == false) {
/* search in selected objects context */
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
- /* just use the first object we encounter (that isn't the active object)
- * and which fulfills the criteria for the object-target that we've got
+ /* just use the first object we encounter (that isn't the active object)
+ * and which fulfills the criteria for the object-target that we've got
*/
if (ob != obact) {
/* for armatures in pose mode, look inside the armature for the active bone
@@ -1666,7 +1667,7 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
*tar_ob = ob;
*tar_pchan = BKE_pose_channel_active(ob);
found = true;
-
+
break;
}
else if (((!only_curve) || (ob->type == OB_CURVE)) &&
@@ -1675,21 +1676,21 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
/* set target */
*tar_ob = ob;
found = true;
-
+
/* perform some special operations on the target */
if (only_curve) {
/* Curve-Path option must be enabled for follow-path constraints to be able to work */
Curve *cu = (Curve *)ob->data;
cu->flag |= CU_PATH;
}
-
+
break;
}
}
}
CTX_DATA_END;
}
-
+
/* if still not found, add a new empty to act as a target (if allowed) */
if ((found == false) && (add)) {
Main *bmain = CTX_data_main(C);
@@ -1697,18 +1698,18 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
ViewLayer *view_layer = CTX_data_view_layer(C);
Base *base = BASACT(view_layer), *newbase = NULL;
Object *obt;
-
+
/* add new target object */
obt = BKE_object_add(bmain, scene, view_layer, OB_EMPTY, NULL);
-
+
/* set layers OK */
newbase = BASACT(view_layer);
newbase->lay = base->lay;
obt->lay = newbase->lay;
-
+
/* transform cent to global coords for loc */
if (pchanact) {
- /* since by default, IK targets the tip of the last bone, use the tip of the active PoseChannel
+ /* since by default, IK targets the tip of the last bone, use the tip of the active PoseChannel
* if adding a target for an IK Constraint
*/
if (con_type == CONSTRAINT_TYPE_KINEMATIC)
@@ -1723,12 +1724,12 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
/* restore, BKE_object_add sets active */
BASACT(view_layer) = base;
base->flag |= BASE_SELECTED;
-
+
/* make our new target the new object */
*tar_ob = obt;
found = true;
}
-
+
/* return whether there's any target */
return found;
}
@@ -1739,13 +1740,13 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
Main *bmain = CTX_data_main(C);
bPoseChannel *pchan;
bConstraint *con;
-
+
if (list == &ob->constraints) {
pchan = NULL;
}
else {
pchan = BKE_pose_channel_active(ob);
-
+
/* ensure not to confuse object/pose adding */
if (pchan == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active pose bone to add a constraint to");
@@ -1764,23 +1765,23 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
BKE_report(op->reports, RPT_ERROR, "Spline IK constraint can only be added to bones");
return OPERATOR_CANCELLED;
}
-
+
/* create a new constraint of the type requried, and add it to the active/given constraints list */
if (pchan)
con = BKE_constraint_add_for_pose(ob, pchan, NULL, type);
else
con = BKE_constraint_add_for_object(ob, NULL, type);
-
+
/* get the first selected object/bone, and make that the target
* - apart from the buttons-window add buttons, we shouldn't add in this way
*/
if (setTarget) {
Object *tar_ob = NULL;
bPoseChannel *tar_pchan = NULL;
-
+
/* get the target objects, adding them as need be */
if (get_new_constraint_target(C, type, &tar_ob, &tar_pchan, 1)) {
- /* method of setting target depends on the type of target we've got
+ /* method of setting target depends on the type of target we've got
* - by default, just set the first target (distinction here is only for multiple-targeted constraints)
*/
if (tar_pchan)
@@ -1789,7 +1790,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
set_constraint_nth_target(con, tar_ob, "", 0);
}
}
-
+
/* do type-specific tweaking to the constraint settings */
switch (type) {
case CONSTRAINT_TYPE_PYTHON: /* FIXME: this code is not really valid anymore */
@@ -1798,15 +1799,15 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
char *menustr;
int scriptint = 0;
/* popup a list of usable scripts */
- menustr = buildmenu_pyconstraints(NULL, &scriptint);
+ menustr = buildmenu_pyconstraints(bmain, NULL, &scriptint);
/* XXX scriptint = pupmenu(menustr); */
MEM_freeN(menustr);
/* only add constraint if a script was chosen */
if (scriptint) {
/* add constraint */
- validate_pyconstraint_cb(con->data, &scriptint);
-
+ validate_pyconstraint_cb(bmain, con->data, &scriptint);
+
/* make sure target allowance is set correctly */
BPY_pyconstraint_update(ob, con);
}
@@ -1817,7 +1818,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
default:
break;
}
-
+
/* make sure all settings are valid - similar to above checks, but sometimes can be wrong */
object_test_constraints(bmain, ob);
@@ -1827,7 +1828,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
/* force depsgraph to get recalculated since new relationships added */
DEG_relations_tag_update(bmain);
-
+
if ((ob->type == OB_ARMATURE) && (pchan)) {
BKE_pose_tag_recalc(bmain, ob->pose); /* sort pose channels */
if (BKE_constraints_proxylocked_owner(ob, pchan) && ob->adt) {
@@ -1840,10 +1841,10 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
}
else
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_ADDED, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1855,12 +1856,12 @@ static int object_constraint_add_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
int type = RNA_enum_get(op->ptr, "type");
short with_targets = 0;
-
+
if (!ob) {
BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to");
return OPERATOR_CANCELLED;
}
-
+
/* hack: set constraint targets from selected objects in context is allowed when
* operator name included 'with_targets', since the menu doesn't allow multiple properties
*/
@@ -1876,18 +1877,18 @@ static int pose_constraint_add_exec(bContext *C, wmOperator *op)
Object *ob = BKE_object_pose_armature_get(ED_object_active_context(C));
int type = RNA_enum_get(op->ptr, "type");
short with_targets = 0;
-
+
if (!ob) {
BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to");
return OPERATOR_CANCELLED;
}
-
+
/* hack: set constraint targets from selected objects in context is allowed when
* operator name included 'with_targets', since the menu doesn't allow multiple properties
*/
if (strstr(op->idname, "with_targets"))
with_targets = 1;
-
+
return constraint_add_exec(C, op, ob, get_active_constraints(ob), type, with_targets);
}
@@ -1899,15 +1900,15 @@ void OBJECT_OT_constraint_add(wmOperatorType *ot)
ot->name = "Add Constraint";
ot->description = "Add a constraint to the active object";
ot->idname = "OBJECT_OT_constraint_add";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = object_constraint_add_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_constraint_type_items, 0, "Type", "");
}
@@ -1918,15 +1919,15 @@ void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot)
ot->name = "Add Constraint (with Targets)";
ot->description = "Add a constraint to the active object, with target (where applicable) set to the selected Objects/Bones";
ot->idname = "OBJECT_OT_constraint_add_with_targets";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = object_constraint_add_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_constraint_type_items, 0, "Type", "");
}
@@ -1937,15 +1938,15 @@ void POSE_OT_constraint_add(wmOperatorType *ot)
ot->name = "Add Constraint";
ot->description = "Add a constraint to the active bone";
ot->idname = "POSE_OT_constraint_add";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = pose_constraint_add_exec;
ot->poll = ED_operator_posemode_exclusive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_constraint_type_items, 0, "Type", "");
}
@@ -1956,15 +1957,15 @@ void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
ot->name = "Add Constraint (with Targets)";
ot->description = "Add a constraint to the active bone, with target (where applicable) set to the selected Objects/Bones";
ot->idname = "POSE_OT_constraint_add_with_targets";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = pose_constraint_add_exec;
ot->poll = ED_operator_posemode_exclusive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_constraint_type_items, 0, "Type", "");
}
@@ -1979,18 +1980,18 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bPoseChannel *pchan = BKE_pose_channel_active(ob);
bConstraint *con = NULL;
-
+
uiPopupMenu *pup;
uiLayout *layout;
Object *tar_ob = NULL;
bPoseChannel *tar_pchan = NULL;
-
+
/* must have active bone */
if (ELEM(NULL, ob, pchan)) {
BKE_report(op->reports, RPT_ERROR, "Must have an active bone to add IK constraint to");
return OPERATOR_CANCELLED;
}
-
+
/* bone must not have any constraints already */
for (con = pchan->constraints.first; con; con = con->next) {
if (con->type == CONSTRAINT_TYPE_KINEMATIC) break;
@@ -1999,14 +2000,14 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
BKE_report(op->reports, RPT_ERROR, "Bone already has an IK constraint");
return OPERATOR_CANCELLED;
}
-
+
/* prepare popup menu to choose targetting options */
pup = UI_popup_menu_begin(C, IFACE_("Add IK"), ICON_NONE);
layout = UI_popup_menu_layout(pup);
-
+
/* the type of targets we'll set determines the menu entries to show... */
if (get_new_constraint_target(C, CONSTRAINT_TYPE_KINEMATIC, &tar_ob, &tar_pchan, 0)) {
- /* bone target, or object target?
+ /* bone target, or object target?
* - the only thing that matters is that we want a target...
*/
if (tar_pchan)
@@ -2019,10 +2020,10 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
uiItemBooleanO(layout, IFACE_("To New Empty Object"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
uiItemBooleanO(layout, IFACE_("Without Targets"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 0);
}
-
+
/* finish building the menu, and process it (should result in calling self again) */
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -2031,7 +2032,7 @@ static int pose_ik_add_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
const bool with_targets = RNA_boolean_get(op->ptr, "with_targets");
-
+
/* add the constraint - all necessary checks should have been done by the invoke() callback already... */
return constraint_add_exec(C, op, ob, get_active_constraints(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets);
}
@@ -2042,15 +2043,15 @@ void POSE_OT_ik_add(wmOperatorType *ot)
ot->name = "Add IK to Bone";
ot->description = "Add IK Constraint to the active Bone";
ot->idname = "POSE_OT_ik_add";
-
+
/* api callbacks */
ot->invoke = pose_ik_add_invoke;
ot->exec = pose_ik_add_exec;
ot->poll = ED_operator_posemode_exclusive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "with_targets", 1, "With Targets", "Assign IK Constraint with targets derived from the select bones/objects");
}
@@ -2061,12 +2062,12 @@ void POSE_OT_ik_add(wmOperatorType *ot)
static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-
+
/* only remove IK Constraints */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
bConstraint *con, *next;
-
+
/* TODO: should we be checking if these contraints were local before we try and remove them? */
for (con = pchan->constraints.first; con; con = next) {
next = con->next;
@@ -2077,13 +2078,13 @@ static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET);
}
CTX_DATA_END;
-
+
/* refresh depsgraph */
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
/* note, notifier might evolve */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -2093,11 +2094,11 @@ void POSE_OT_ik_clear(wmOperatorType *ot)
ot->name = "Remove IK";
ot->description = "Remove all IK Constraints from selected bones";
ot->idname = "POSE_OT_ik_clear";
-
+
/* api callbacks */
ot->exec = pose_ik_clear_exec;
ot->poll = ED_operator_posemode_exclusive;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index d4e8955b38e..db81c51cc90 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -43,6 +43,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_object.h"
#include "BKE_report.h"
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 7b90a522d49..d47a2576a8a 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -209,7 +209,7 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
if (arm->edbo == NULL) {
return false;
}
- ED_armature_from_edit(obedit->data);
+ ED_armature_from_edit(bmain, obedit->data);
if (freedata) {
ED_armature_edit_free(obedit->data);
}
@@ -224,7 +224,7 @@ static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool f
if (cu->editnurb == NULL) {
return false;
}
- ED_curve_editnurb_load(obedit);
+ ED_curve_editnurb_load(bmain, obedit);
if (freedata) {
ED_curve_editnurb_free(obedit);
}
@@ -272,13 +272,13 @@ bool ED_object_editmode_load(Main *bmain, Object *obedit)
* \param flag:
* - If #EM_FREEDATA isn't in the flag, use ED_object_editmode_load directly.
*/
-bool ED_object_editmode_exit_ex(Scene *scene, Object *obedit, int flag)
+bool ED_object_editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int flag)
{
const bool freedata = (flag & EM_FREEDATA) != 0;
if (flag & EM_WAITCURSOR) waitcursor(1);
- if (ED_object_editmode_load_ex(G.main, obedit, freedata) == false) {
+ if (ED_object_editmode_load_ex(bmain, obedit, freedata) == false) {
/* in rare cases (background mode) its possible active object
* is flagged for editmode, without 'obedit' being set [#35489] */
if (UNLIKELY(obedit && obedit->mode & OB_MODE_EDIT)) {
@@ -318,9 +318,10 @@ bool ED_object_editmode_exit_ex(Scene *scene, Object *obedit, int flag)
bool ED_object_editmode_exit(bContext *C, int flag)
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
- return ED_object_editmode_exit_ex(scene, obedit, flag);
+ return ED_object_editmode_exit_ex(bmain, scene, obedit, flag);
}
bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag)
@@ -465,7 +466,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op)
FOREACH_OBJECT_BEGIN(view_layer, ob)
{
if ((ob != obact) && (ob->type == obact->type)) {
- ED_object_editmode_exit_ex(scene, ob, EM_FREEDATA | EM_WAITCURSOR);
+ ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA | EM_WAITCURSOR);
}
}
FOREACH_OBJECT_END;
@@ -499,16 +500,16 @@ static int editmode_toggle_poll(bContext *C)
void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Toggle Editmode";
ot->description = "Toggle object's editmode";
ot->idname = "OBJECT_OT_editmode_toggle";
-
+
/* api callbacks */
ot->exec = editmode_toggle_exec;
ot->poll = editmode_toggle_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -522,7 +523,7 @@ static int posemode_exec(bContext *C, wmOperator *op)
Object *obact = base->object;
const int mode_flag = OB_MODE_POSE;
bool is_mode_set = (obact->mode & mode_flag) != 0;
-
+
if (!is_mode_set) {
if (!ED_object_mode_compat_set(C, obact, mode_flag, op->reports)) {
return OPERATOR_CANCELLED;
@@ -581,17 +582,17 @@ static int posemode_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_posemode_toggle(wmOperatorType *ot)
+void OBJECT_OT_posemode_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Toggle Pose Mode";
ot->idname = "OBJECT_OT_posemode_toggle";
ot->description = "Enable or disable posing/selecting bones";
-
+
/* api callbacks */
ot->exec = posemode_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flag */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -601,7 +602,7 @@ static void copy_texture_space(Object *to, Object *ob)
{
float *poin1 = NULL, *poin2 = NULL;
short texflag = 0;
-
+
if (ob->type == OB_MESH) {
texflag = ((Mesh *)ob->data)->texflag;
poin2 = ((Mesh *)ob->data)->loc;
@@ -616,7 +617,7 @@ static void copy_texture_space(Object *to, Object *ob)
}
else
return;
-
+
if (to->type == OB_MESH) {
((Mesh *)to->data)->texflag = texflag;
poin1 = ((Mesh *)to->data)->loc;
@@ -631,9 +632,9 @@ static void copy_texture_space(Object *to, Object *ob)
}
else
return;
-
+
memcpy(poin1, poin2, 9 * sizeof(float)); /* this was noted in DNA_mesh, curve, mball */
-
+
if (to->type == OB_MESH) {
/* pass */
}
@@ -643,7 +644,7 @@ static void copy_texture_space(Object *to, Object *ob)
else {
BKE_curve_texspace_calc(to->data);
}
-
+
}
/* UNUSED, keep in case we want to copy functionality for use elsewhere */
@@ -654,11 +655,11 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
Curve *cu, *cu1;
Nurb *nu;
bool do_depgraph_update = false;
-
+
if (ID_IS_LINKED(scene)) return;
if (!(ob = OBACT(view_layer))) return;
-
+
if (BKE_object_is_in_editmode(ob)) {
/* obedit_copymenu(); */
return;
@@ -674,7 +675,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
if (base != BASACT(view_layer)) {
if (TESTBASELIB(base)) {
DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
-
+
if (event == 1) { /* loc */
copy_v3_v3(base->object->loc, ob->loc);
copy_v3_v3(base->object->dloc, ob->dloc);
@@ -704,7 +705,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
base->object->dupoff = ob->dupoff;
base->object->dupsta = ob->dupsta;
base->object->dupend = ob->dupend;
-
+
base->object->transflag &= ~OB_DUPLI;
base->object->transflag |= (ob->transflag & OB_DUPLI);
@@ -716,7 +717,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
copy_texture_space(base->object, ob);
}
else if (event == 18) { /* font settings */
-
+
if (base->object->type == ob->type) {
cu = ob->data;
cu1 = base->object->data;
@@ -749,25 +750,25 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
id_us_min(&cu1->vfontbi->id);
cu1->vfontbi = cu->vfontbi;
id_us_plus((ID *)cu1->vfontbi);
-
+
BLI_strncpy(cu1->family, cu->family, sizeof(cu1->family));
-
+
DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
}
else if (event == 19) { /* bevel settings */
-
+
if (ELEM(base->object->type, OB_CURVE, OB_FONT)) {
cu = ob->data;
cu1 = base->object->data;
-
+
cu1->bevobj = cu->bevobj;
cu1->taperobj = cu->taperobj;
cu1->width = cu->width;
cu1->bevresol = cu->bevresol;
cu1->ext1 = cu->ext1;
cu1->ext2 = cu->ext2;
-
+
DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
}
@@ -776,17 +777,17 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
if (ELEM(base->object->type, OB_CURVE, OB_FONT)) {
cu = ob->data;
cu1 = base->object->data;
-
+
cu1->resolu = cu->resolu;
cu1->resolu_ren = cu->resolu_ren;
-
+
nu = cu1->nurb.first;
-
+
while (nu) {
nu->resolu = cu1->resolu;
nu = nu->next;
}
-
+
DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
}
@@ -810,13 +811,13 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
else if (event == 22) {
/* Copy the constraint channels over */
BKE_constraints_copy(&base->object->constraints, &ob->constraints, true);
-
+
do_depgraph_update = true;
}
else if (event == 23) {
base->object->softflag = ob->softflag;
if (base->object->soft) sbFree(base->object->soft);
-
+
base->object->soft = copy_softbody(ob->soft, 0);
if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
@@ -843,7 +844,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
if (ELEM(base->object->type, OB_CURVE, OB_SURF)) {
cu = ob->data;
cu1 = base->object->data;
-
+
if (cu->flag & CU_UV_ORCO)
cu1->flag |= CU_UV_ORCO;
else
@@ -862,7 +863,7 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
}
}
}
-
+
if (do_depgraph_update)
DEG_relations_tag_update(bmain);
}
@@ -872,36 +873,36 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLaye
Object *ob;
short event;
char str[512];
-
+
if (!(ob = OBACT(view_layer))) return;
-
+
if (obedit) {
/* if (ob->type == OB_MESH) */
/* XXX mesh_copy_menu(); */
return;
}
-
+
/* Object Mode */
-
+
/* If you change this menu, don't forget to update the menu in header_view3d.c
* view3d_edit_object_copyattrmenu() and in toolbox.c
*/
-
+
strcpy(str,
"Copy Attributes %t|Location %x1|Rotation %x2|Size %x3|Draw Options %x4|"
"Time Offset %x5|Dupli %x6|Object Color %x31|%l|Mass %x7|Damping %x8|All Physical Attributes %x11|Properties %x9|"
"Logic Bricks %x10|Protected Transform %x29|%l");
-
+
strcat(str, "|Object Constraints %x22");
strcat(str, "|NLA Strips %x26");
-
+
/* XXX if (OB_TYPE_SUPPORT_MATERIAL(ob->type)) { */
/* strcat(str, "|Texture Space %x17"); */
/* } */
-
+
if (ob->type == OB_FONT) strcat(str, "|Font Settings %x18|Bevel Settings %x19");
if (ob->type == OB_CURVE) strcat(str, "|Bevel Settings %x19|UV Orco %x28");
-
+
if ((ob->type == OB_FONT) || (ob->type == OB_CURVE)) {
strcat(str, "|Curve Resolution %x25");
}
@@ -911,16 +912,16 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLaye
}
if (ob->soft) strcat(str, "|Soft Body Settings %x23");
-
+
strcat(str, "|Pass Index %x30");
-
+
if (ob->type == OB_MESH || ob->type == OB_CURVE || ob->type == OB_LATTICE || ob->type == OB_SURF) {
strcat(str, "|Modifiers ... %x24");
}
event = pupmenu(str);
if (event <= 0) return;
-
+
copy_attr(bmain, scene, view_layer, event);
}
@@ -966,16 +967,16 @@ static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op))
void OBJECT_OT_forcefield_toggle(wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Toggle Force Field";
ot->description = "Toggle object's force field";
ot->idname = "OBJECT_OT_forcefield_toggle";
-
+
/* api callbacks */
ot->exec = forcefield_toggle_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -993,7 +994,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene)
struct Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_depsgraph(C);
ListBase targets = {NULL, NULL};
-
+
/* loop over objects in scene */
CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
{
@@ -1002,11 +1003,11 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene)
animviz_get_object_motionpaths(ob, &targets);
}
CTX_DATA_END;
-
+
/* recalculate paths, then free */
animviz_calc_motionpaths(depsgraph, bmain, scene, &targets);
BLI_freelistN(&targets);
-
+
/* tag objects for copy on write - so paths will draw/redraw */
CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
{
@@ -1022,18 +1023,18 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene)
static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = CTX_data_active_object(C);
-
+
if (ob == NULL)
return OPERATOR_CANCELLED;
-
+
/* set default settings from existing/stored settings */
{
bAnimVizSettings *avs = &ob->avs;
-
+
RNA_int_set(op->ptr, "start_frame", avs->path_sf);
RNA_int_set(op->ptr, "end_frame", avs->path_ef);
}
-
+
/* show popup dialog to allow editing of range... */
/* FIXME: hardcoded dimensions here are just arbitrary */
return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 10 * UI_UNIT_Y);
@@ -1045,28 +1046,28 @@ static int object_calculate_paths_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
int start = RNA_int_get(op->ptr, "start_frame");
int end = RNA_int_get(op->ptr, "end_frame");
-
+
/* set up path data for bones being calculated */
CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
{
bAnimVizSettings *avs = &ob->avs;
-
+
/* grab baking settings from operator settings */
avs->path_sf = start;
avs->path_ef = end;
-
+
/* verify that the selected object has the appropriate settings */
animviz_verify_motionpaths(op->reports, scene, ob, NULL);
}
CTX_DATA_END;
-
+
/* calculate the paths for objects that have them (and are tagged to get refreshed) */
ED_objects_recalculate_paths(C, scene);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
- return OPERATOR_FINISHED;
+
+ return OPERATOR_FINISHED;
}
void OBJECT_OT_paths_calculate(wmOperatorType *ot)
@@ -1075,19 +1076,19 @@ void OBJECT_OT_paths_calculate(wmOperatorType *ot)
ot->name = "Calculate Object Paths";
ot->idname = "OBJECT_OT_paths_calculate";
ot->description = "Calculate motion paths for the selected objects";
-
+
/* api callbacks */
ot->invoke = object_calculate_paths_invoke;
ot->exec = object_calculate_paths_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
- RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start",
+ RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start",
"First frame to calculate object paths on", MINFRAME, MAXFRAME / 2.0);
- RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End",
+ RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End",
"Last frame to calculate object paths on", MINFRAME, MAXFRAME / 2.0);
}
@@ -1099,23 +1100,23 @@ static int object_update_paths_poll(bContext *C)
Object *ob = ED_object_active_context(C);
return (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
}
-
+
return false;
}
static int object_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
-
+
if (scene == NULL)
return OPERATOR_CANCELLED;
-
+
/* calculate the paths for objects that have them (and are tagged to get refreshed) */
ED_objects_recalculate_paths(C, scene);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1125,11 +1126,11 @@ void OBJECT_OT_paths_update(wmOperatorType *ot)
ot->name = "Update Object Paths";
ot->idname = "OBJECT_OT_paths_update";
ot->description = "Recalculate paths for selected objects";
-
+
/* api callbakcs */
ot->exec = object_update_paths_exec;
ot->poll = object_update_paths_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1171,14 +1172,14 @@ void ED_objects_clear_paths(bContext *C, bool only_selected)
static int object_clear_paths_exec(bContext *C, wmOperator *op)
{
bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
-
+
/* use the backend function for this */
ED_objects_clear_paths(C, only_selected);
-
+
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
- return OPERATOR_FINISHED;
+
+ return OPERATOR_FINISHED;
}
/* operator callback/wrapper */
@@ -1196,15 +1197,15 @@ void OBJECT_OT_paths_clear(wmOperatorType *ot)
ot->name = "Clear Object Paths";
ot->idname = "OBJECT_OT_paths_clear";
ot->description = "Clear path caches for all objects, hold Shift key for selected objects only";
-
+
/* api callbacks */
ot->invoke = object_clear_paths_invoke;
ot->exec = object_clear_paths_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_boolean(ot->srna, "only_selected", false, "Only Selected",
"Only clear paths from selected objects");
@@ -1273,7 +1274,7 @@ void OBJECT_OT_shade_flat(wmOperatorType *ot)
ot->name = "Shade Flat";
ot->description = "Render and display faces uniform, using Face Normals";
ot->idname = "OBJECT_OT_shade_flat";
-
+
/* api callbacks */
ot->poll = shade_poll;
ot->exec = shade_smooth_exec;
@@ -1288,11 +1289,11 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
ot->name = "Shade Smooth";
ot->description = "Render and display faces smooth, using interpolated Vertex Normals";
ot->idname = "OBJECT_OT_shade_smooth";
-
+
/* api callbacks */
ot->poll = shade_poll;
ot->exec = shade_smooth_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1333,7 +1334,7 @@ static const EnumPropertyItem *object_mode_set_itemsf(
/* We need at least this one! */
RNA_enum_items_add_value(&item, &totitem, input, OB_MODE_OBJECT);
}
-
+
/* On top of all the rest, GPencil Stroke Edit Mode
* is available if there's a valid gp datablock...
*/
@@ -1403,7 +1404,7 @@ static int object_mode_set_exec(bContext *C, wmOperator *op)
WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_EXEC_REGION_WIN, NULL);
}
}
-
+
if (!ob || !ED_object_mode_compat_test(ob, mode))
return OPERATOR_PASS_THROUGH;
@@ -1438,20 +1439,20 @@ static int object_mode_set_exec(bContext *C, wmOperator *op)
void OBJECT_OT_mode_set(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Set Object Mode";
ot->description = "Sets the object interaction mode";
ot->idname = "OBJECT_OT_mode_set";
-
+
/* api callbacks */
ot->exec = object_mode_set_exec;
-
+
ot->poll = object_mode_set_poll; //ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = 0; /* no register/undo here, leave it to operators being called */
-
+
ot->prop = RNA_def_enum(ot->srna, "mode", rna_enum_object_mode_items, OB_MODE_OBJECT, "Mode", "");
RNA_def_enum_funcs(ot->prop, object_mode_set_itemsf);
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 0a6a81d99da..8a52b6c5ef5 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -182,7 +182,7 @@ void COLLECTION_OT_objects_add_active(wmOperatorType *ot)
ot->name = "Add Selected To Active Collection";
ot->description = "Add the object to an object collection that contains the active object";
ot->idname = "COLLECTION_OT_objects_add_active";
-
+
/* api callbacks */
ot->exec = objects_add_active_exec;
ot->invoke = WM_menu_invoke;
@@ -207,10 +207,10 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
Collection *single_collection = collection_object_active_find_index(bmain, ob, single_collection_index);
Collection *collection;
bool ok = false;
-
+
if (ob == NULL)
return OPERATOR_CANCELLED;
-
+
/* linking to same collection requires its own loop so we can avoid
* looking up the active objects collections each time */
@@ -228,13 +228,13 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
}
}
-
+
if (!ok)
BKE_report(op->reports, RPT_ERROR, "Active object contains no collections");
-
+
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -246,12 +246,12 @@ void COLLECTION_OT_objects_remove_active(wmOperatorType *ot)
ot->name = "Remove Selected From Active Collection";
ot->description = "Remove the object from an object collection that contains the active object";
ot->idname = "COLLECTION_OT_objects_remove_active";
-
+
/* api callbacks */
ot->exec = objects_remove_active_exec;
ot->invoke = WM_menu_invoke;
ot->poll = ED_operator_objectmode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -274,7 +274,7 @@ static int collection_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -284,11 +284,11 @@ void COLLECTION_OT_objects_remove_all(wmOperatorType *ot)
ot->name = "Remove From All Unlinked Collections";
ot->description = "Remove selected objects from all collections not used in a scene";
ot->idname = "COLLECTION_OT_objects_remove_all";
-
+
/* api callbacks */
ot->exec = collection_objects_remove_all_exec;
ot->poll = ED_operator_objectmode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -357,11 +357,12 @@ static int collection_create_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
char name[MAX_ID_NAME - 2]; /* id name */
-
+
RNA_string_get(op->ptr, "name", name);
-
+
Collection *collection = BKE_collection_add(bmain, NULL, name);
-
+ id_fake_user_set(&collection->id);
+
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
BKE_collection_object_add(bmain, collection, base->object);
@@ -370,7 +371,7 @@ static int collection_create_exec(bContext *C, wmOperator *op)
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -380,14 +381,14 @@ void COLLECTION_OT_create(wmOperatorType *ot)
ot->name = "Create New Collection";
ot->description = "Create an object collection from selected objects";
ot->idname = "COLLECTION_OT_create";
-
+
/* api callbacks */
ot->exec = collection_create_exec;
ot->poll = ED_operator_objectmode;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_string(ot->srna, "name", "Collection", MAX_ID_NAME - 2, "Name", "Name of the new collection");
}
@@ -402,6 +403,7 @@ static int collection_add_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
Collection *collection = BKE_collection_add(bmain, NULL, "Collection");
+ id_fake_user_set(&collection->id);
BKE_collection_object_add(bmain, collection, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -415,7 +417,7 @@ void OBJECT_OT_collection_add(wmOperatorType *ot)
ot->name = "Add to Collection";
ot->idname = "OBJECT_OT_collection_add";
ot->description = "Add an object to a new collection";
-
+
/* api callbacks */
ot->exec = collection_add_exec;
ot->poll = ED_operator_objectmode;
@@ -466,7 +468,7 @@ void OBJECT_OT_collection_link(wmOperatorType *ot)
ot->name = "Link to Collection";
ot->idname = "OBJECT_OT_collection_link";
ot->description = "Add an object to an existing collection";
-
+
/* api callbacks */
ot->exec = collection_link_exec;
ot->invoke = WM_enum_search_invoke;
@@ -494,7 +496,7 @@ static int collection_remove_exec(bContext *C, wmOperator *UNUSED(op))
BKE_collection_object_remove(bmain, collection, ob, false);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -504,7 +506,7 @@ void OBJECT_OT_collection_remove(wmOperatorType *ot)
ot->name = "Remove Collection";
ot->idname = "OBJECT_OT_collection_remove";
ot->description = "Remove the active object from this collection";
-
+
/* api callbacks */
ot->exec = collection_remove_exec;
ot->poll = ED_operator_objectmode;
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 8c68431c19a..31e8685e323 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -82,17 +82,17 @@ static int return_editmesh_indexar(
BMVert *eve;
BMIter iter;
int *index, nr, totvert = 0;
-
+
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) totvert++;
}
if (totvert == 0) return 0;
-
+
*r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
*r_tot = totvert;
nr = 0;
zero_v3(r_cent);
-
+
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
*index = nr; index++;
@@ -100,9 +100,9 @@ static int return_editmesh_indexar(
}
nr++;
}
-
+
mul_v3_fl(r_cent, 1.0f / (float)totvert);
-
+
return totvert;
}
@@ -136,9 +136,9 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name,
return true;
}
}
-
+
return false;
-}
+}
static void select_editbmesh_hook(Object *ob, HookModifierData *hmd)
{
@@ -147,10 +147,10 @@ static void select_editbmesh_hook(Object *ob, HookModifierData *hmd)
BMVert *eve;
BMIter iter;
int index = 0, nr = 0;
-
+
if (hmd->indexar == NULL)
return;
-
+
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (nr == hmd->indexar[index]) {
BM_vert_select_set(em->bm, eve, true);
@@ -169,7 +169,7 @@ static int return_editlattice_indexar(
{
BPoint *bp;
int *index, nr, totvert = 0, a;
-
+
/* count */
a = editlatt->pntsu * editlatt->pntsv * editlatt->pntsw;
bp = editlatt->def;
@@ -181,12 +181,12 @@ static int return_editlattice_indexar(
}
if (totvert == 0) return 0;
-
+
*r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
*r_tot = totvert;
nr = 0;
zero_v3(r_cent);
-
+
a = editlatt->pntsu * editlatt->pntsv * editlatt->pntsw;
bp = editlatt->def;
while (a--) {
@@ -199,9 +199,9 @@ static int return_editlattice_indexar(
bp++;
nr++;
}
-
+
mul_v3_fl(r_cent, 1.0f / (float)totvert);
-
+
return totvert;
}
@@ -234,7 +234,7 @@ static int return_editcurve_indexar(
BPoint *bp;
BezTriple *bezt;
int *index, a, nr, totvert = 0;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
@@ -256,12 +256,12 @@ static int return_editcurve_indexar(
}
}
if (totvert == 0) return 0;
-
+
*r_indexar = index = MEM_mallocN(sizeof(*index) * totvert, "hook indexar");
*r_tot = totvert;
nr = 0;
zero_v3(r_cent);
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
@@ -298,19 +298,19 @@ static int return_editcurve_indexar(
}
}
}
-
+
mul_v3_fl(r_cent, 1.0f / (float)totvert);
-
+
return totvert;
}
-static bool object_hook_index_array(Scene *scene, Object *obedit,
+static bool object_hook_index_array(Main *bmain, Scene *scene, Object *obedit,
int *r_tot, int **r_indexar, char *r_name, float r_cent[3])
{
*r_indexar = NULL;
*r_tot = 0;
r_name[0] = 0;
-
+
switch (obedit->type) {
case OB_MESH:
{
@@ -336,7 +336,7 @@ static bool object_hook_index_array(Scene *scene, Object *obedit,
}
case OB_CURVE:
case OB_SURF:
- ED_curve_editnurb_load(obedit);
+ ED_curve_editnurb_load(bmain, obedit);
ED_curve_editnurb_make(obedit);
return return_editcurve_indexar(obedit, r_tot, r_indexar, r_cent);
case OB_LATTICE:
@@ -356,7 +356,7 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
BPoint *bp;
BezTriple *bezt;
int index = 0, a, nr = 0;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
@@ -377,7 +377,7 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
if (index < hmd->totindex - 1) index++;
}
nr++;
-
+
bezt++;
}
}
@@ -421,11 +421,11 @@ static void object_hook_from_context(bContext *C, PointerRNA *ptr, const int num
}
}
-static void object_hook_select(Object *ob, HookModifierData *hmd)
+static void object_hook_select(Object *ob, HookModifierData *hmd)
{
if (hmd->indexar == NULL)
return;
-
+
if (ob->type == OB_MESH) select_editbmesh_hook(ob, hmd);
else if (ob->type == OB_LATTICE) select_editlattice_hook(ob, hmd);
else if (ob->type == OB_CURVE) select_editcurve_hook(ob, hmd);
@@ -437,14 +437,14 @@ static void object_hook_select(Object *ob, HookModifierData *hmd)
static int hook_op_edit_poll(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
-
+
if (obedit) {
if (ED_operator_editmesh(C)) return 1;
if (ED_operator_editsurfcurve(C)) return 1;
if (ED_operator_editlattice(C)) return 1;
//if (ED_operator_editmball(C)) return 1;
}
-
+
return 0;
}
@@ -454,12 +454,12 @@ static Object *add_hook_object_new(Main *bmain, Scene *scene, ViewLayer *view_la
Object *ob;
ob = BKE_object_add(bmain, scene, view_layer, OB_EMPTY, NULL);
-
+
basedit = BKE_view_layer_base_find(view_layer, obedit);
base = view_layer->basact;
base->lay = ob->lay = obedit->lay;
BLI_assert(view_layer->basact->object == ob);
-
+
/* icky, BKE_object_add sets new base as active.
* so set it back to the original edit object */
view_layer->basact = basedit;
@@ -475,8 +475,8 @@ static int add_hook_object(const bContext *C, Main *bmain, Scene *scene, ViewLay
float pose_mat[4][4];
int tot, ok, *indexar;
char name[MAX_NAME];
-
- ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent);
+
+ ok = object_hook_index_array(bmain, scene, obedit, &tot, &indexar, name, cent);
if (!ok) {
BKE_report(reports, RPT_ERROR, "Requires selected vertices or active vertex group");
@@ -484,29 +484,29 @@ static int add_hook_object(const bContext *C, Main *bmain, Scene *scene, ViewLay
}
if (mode == OBJECT_ADDHOOK_NEWOB && !ob) {
-
+
ob = add_hook_object_new(bmain, scene, view_layer, obedit);
-
+
/* transform cent to global coords for loc */
mul_v3_m4v3(ob->loc, obedit->obmat, cent);
}
-
+
md = obedit->modifiers.first;
while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform) {
md = md->next;
}
-
+
hmd = (HookModifierData *) modifier_new(eModifierType_Hook);
BLI_insertlinkbefore(&obedit->modifiers, md, hmd);
BLI_snprintf(hmd->modifier.name, sizeof(hmd->modifier.name), "Hook-%s", ob->id.name + 2);
modifier_unique_name(&obedit->modifiers, (ModifierData *)hmd);
-
+
hmd->object = ob;
hmd->indexar = indexar;
copy_v3_v3(hmd->cent, cent);
hmd->totindex = tot;
BLI_strncpy(hmd->name, name, sizeof(hmd->name));
-
+
unit_m4(pose_mat);
invert_m4_m4(obedit->imat, obedit->obmat);
@@ -545,11 +545,11 @@ static int add_hook_object(const bContext *C, Main *bmain, Scene *scene, ViewLay
/* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
/* (parentinv ) */
BKE_object_where_is_calc(CTX_data_depsgraph(C), scene, ob);
-
+
invert_m4_m4(ob->imat, ob->obmat);
/* apparently this call goes from right to left... */
mul_m4_series(hmd->parentinv, pose_mat, ob->imat, obedit->obmat);
-
+
DEG_relations_tag_update(bmain);
return true;
@@ -564,7 +564,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
Object *obsel = NULL;
const bool use_bone = RNA_boolean_get(op->ptr, "use_bone");
const int mode = use_bone ? OBJECT_ADDHOOK_SELOB_BONE : OBJECT_ADDHOOK_SELOB;
-
+
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
if (ob != obedit) {
@@ -573,7 +573,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
if (!obsel) {
BKE_report(op->reports, RPT_ERROR, "Cannot add hook with no other selected objects");
return OPERATOR_CANCELLED;
@@ -583,7 +583,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Cannot add hook bone for a non armature object");
return OPERATOR_CANCELLED;
}
-
+
if (add_hook_object(C, bmain, scene, view_layer, obedit, obsel, mode, op->reports)) {
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
return OPERATOR_FINISHED;
@@ -599,11 +599,11 @@ void OBJECT_OT_hook_add_selob(wmOperatorType *ot)
ot->name = "Hook to Selected Object";
ot->description = "Hook selected vertices to the first selected object";
ot->idname = "OBJECT_OT_hook_add_selob";
-
+
/* api callbacks */
ot->exec = object_add_hook_selob_exec;
ot->poll = hook_op_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -634,11 +634,11 @@ void OBJECT_OT_hook_add_newob(wmOperatorType *ot)
ot->name = "Hook to New Object";
ot->description = "Hook selected vertices to a newly created object";
ot->idname = "OBJECT_OT_hook_add_newob";
-
+
/* api callbacks */
ot->exec = object_add_hook_newob_exec;
ot->poll = hook_op_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -654,29 +654,29 @@ static int object_hook_remove_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier");
return OPERATOR_CANCELLED;
}
-
+
/* remove functionality */
-
+
BLI_remlink(&ob->modifiers, (ModifierData *)hmd);
modifier_free((ModifierData *)hmd);
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
static const EnumPropertyItem *hook_mod_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
+{
Object *ob = CTX_data_edit_object(C);
EnumPropertyItem tmp = {0, "", 0, "", ""};
EnumPropertyItem *item = NULL;
ModifierData *md = NULL;
int a, totitem = 0;
-
+
if (!ob)
return DummyRNA_NULL_items;
-
+
for (a = 0, md = ob->modifiers.first; md; md = md->next, a++) {
if (md->type == eModifierType_Hook) {
tmp.value = a;
@@ -686,32 +686,32 @@ static const EnumPropertyItem *hook_mod_itemf(bContext *C, PointerRNA *UNUSED(pt
RNA_enum_item_add(&item, &totitem, &tmp);
}
}
-
+
RNA_enum_item_end(&item, &totitem);
*r_free = true;
-
+
return item;
}
void OBJECT_OT_hook_remove(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Remove Hook";
ot->idname = "OBJECT_OT_hook_remove";
ot->description = "Remove a hook from the active object";
-
+
/* api callbacks */
ot->exec = object_hook_remove_exec;
ot->invoke = WM_menu_invoke;
ot->poll = hook_op_edit_poll;
-
+
/* flags */
/* this operator removes modifier which isn't stored in local undo stack,
* so redoing it from redo panel gives totally weird results */
ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to remove");
RNA_def_enum_funcs(prop, hook_mod_itemf);
@@ -736,26 +736,26 @@ static int object_hook_reset_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_hook_reset(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Reset Hook";
ot->description = "Recalculate and clear offset transformation";
ot->idname = "OBJECT_OT_hook_reset";
-
+
/* callbacks */
ot->exec = object_hook_reset_exec;
ot->poll = hook_op_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to");
RNA_def_enum_funcs(prop, hook_mod_itemf);
@@ -770,42 +770,42 @@ static int object_hook_recenter_exec(bContext *C, wmOperator *op)
HookModifierData *hmd = NULL;
Scene *scene = CTX_data_scene(C);
float bmat[3][3], imat[3][3];
-
+
object_hook_from_context(C, &ptr, num, &ob, &hmd);
if (hmd == NULL) {
BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier");
return OPERATOR_CANCELLED;
}
-
+
/* recenter functionality */
copy_m3_m4(bmat, ob->obmat);
invert_m3_m3(imat, bmat);
-
+
sub_v3_v3v3(hmd->cent, scene->cursor.location, ob->obmat[3]);
mul_m3_v3(imat, hmd->cent);
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_hook_recenter(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Recenter Hook";
ot->description = "Set hook center to cursor position";
ot->idname = "OBJECT_OT_hook_recenter";
-
+
/* callbacks */
ot->exec = object_hook_recenter_exec;
ot->poll = hook_op_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to");
RNA_def_enum_funcs(prop, hook_mod_itemf);
@@ -814,6 +814,7 @@ void OBJECT_OT_hook_recenter(wmOperatorType *ot)
static int object_hook_assign_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier);
int num = RNA_enum_get(op->ptr, "modifier");
@@ -822,50 +823,50 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op)
float cent[3];
char name[MAX_NAME];
int *indexar, tot;
-
+
object_hook_from_context(C, &ptr, num, &ob, &hmd);
if (hmd == NULL) {
BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier");
return OPERATOR_CANCELLED;
}
-
+
/* assign functionality */
-
- if (!object_hook_index_array(scene, ob, &tot, &indexar, name, cent)) {
+
+ if (!object_hook_index_array(bmain, scene, ob, &tot, &indexar, name, cent)) {
BKE_report(op->reports, RPT_WARNING, "Requires selected vertices or active vertex group");
return OPERATOR_CANCELLED;
}
if (hmd->indexar)
MEM_freeN(hmd->indexar);
-
+
copy_v3_v3(hmd->cent, cent);
hmd->indexar = indexar;
hmd->totindex = tot;
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_hook_assign(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Assign to Hook";
ot->description = "Assign the selected vertices to a hook";
ot->idname = "OBJECT_OT_hook_assign";
-
+
/* callbacks */
ot->exec = object_hook_assign_exec;
ot->poll = hook_op_edit_poll;
-
+
/* flags */
/* this operator changes data stored in modifier which doesn't get pushed to undo stack,
* so redoing it from redo panel gives totally weird results */
ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to assign to");
RNA_def_enum_funcs(prop, hook_mod_itemf);
@@ -878,37 +879,37 @@ static int object_hook_select_exec(bContext *C, wmOperator *op)
int num = RNA_enum_get(op->ptr, "modifier");
Object *ob = NULL;
HookModifierData *hmd = NULL;
-
+
object_hook_from_context(C, &ptr, num, &ob, &hmd);
if (hmd == NULL) {
BKE_report(op->reports, RPT_ERROR, "Could not find hook modifier");
return OPERATOR_CANCELLED;
}
-
+
/* select functionality */
object_hook_select(ob, hmd);
-
+
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
-
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_hook_select(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Select Hook";
ot->description = "Select affected vertices on mesh";
ot->idname = "OBJECT_OT_hook_select";
-
+
/* callbacks */
ot->exec = object_hook_select_exec;
ot->poll = hook_op_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_enum(ot->srna, "modifier", DummyRNA_NULL_items, 0, "Modifier", "Modifier number to remove");
RNA_def_enum_funcs(prop, hook_mod_itemf);
diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c
index 66c2ad5fa9b..e9bd6fbce8f 100644
--- a/source/blender/editors/object/object_modes.c
+++ b/source/blender/editors/object/object_modes.c
@@ -209,7 +209,7 @@ static bool ed_object_mode_generic_exit_ex(
if (only_test) {
return true;
}
- ED_object_editmode_exit_ex(scene, ob, EM_FREEDATA);
+ ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
}
}
else if (ob->mode & OB_MODE_VERTEX_PAINT) {
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 96d82d51e3f..1b9af3725ca 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -63,6 +63,7 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_report.h"
@@ -100,7 +101,7 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
{
ModifierData *md = NULL, *new_md = NULL;
const ModifierTypeInfo *mti = modifierType_getInfo(type);
-
+
/* Check compatibility of modifier [T25291, T50373]. */
if (!BKE_object_support_modifier_type_check(ob, type)) {
BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2);
@@ -113,23 +114,23 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
return NULL;
}
}
-
+
if (type == eModifierType_ParticleSystem) {
/* don't need to worry about the new modifier's name, since that is set to the number
- * of particle systems which shouldn't have too many duplicates
+ * of particle systems which shouldn't have too many duplicates
*/
new_md = object_add_particle_system(scene, ob, name);
}
else {
/* get new modifier data to add */
new_md = modifier_new(type);
-
+
if (mti->flags & eModifierTypeFlag_RequiresOriginalData) {
md = ob->modifiers.first;
-
+
while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
md = md->next;
-
+
BLI_insertlinkbefore(&ob->modifiers, md, new_md);
}
else
@@ -142,7 +143,7 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
/* make sure modifier data has unique name */
modifier_unique_name(&ob->modifiers, new_md);
-
+
/* special cases */
if (type == eModifierType_Softbody) {
if (!ob->soft) {
@@ -153,7 +154,7 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
else if (type == eModifierType_Collision) {
if (!ob->pd)
ob->pd = object_add_collision_fields(0);
-
+
ob->pd->deflect = 1;
}
else if (type == eModifierType_Surface) {
@@ -468,14 +469,14 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
/* add new mesh */
obn = BKE_object_add(bmain, scene, view_layer, OB_MESH, NULL);
me = obn->data;
-
+
me->totvert = totvert;
me->totedge = totedge;
-
+
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
-
+
mvert = me->mvert;
medge = me->medge;
@@ -550,18 +551,18 @@ static int modifier_apply_shape(ReportList *reports, Depsgraph *depsgraph, Scene
Mesh *me = ob->data;
Key *key = me->key;
KeyBlock *kb;
-
+
if (!modifier_isSameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
return 0;
}
-
+
mesh_applied = BKE_mesh_create_derived_for_modifier(depsgraph, scene, ob, md, 0);
if (!mesh_applied) {
BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
return 0;
}
-
+
if (key == NULL) {
key = me->key = BKE_key_add((ID *)me);
key->type = KEY_RELATIVE;
@@ -572,8 +573,8 @@ static int modifier_apply_shape(ReportList *reports, Depsgraph *depsgraph, Scene
}
kb = BKE_keyblock_add(key, md->name);
- BKE_nomain_mesh_to_meshkey(mesh_applied, me, kb);
-
+ BKE_mesh_nomain_to_meshkey(mesh_applied, me, kb);
+
BKE_id_free(NULL, mesh_applied);
}
else {
@@ -621,7 +622,7 @@ static int modifier_apply_obdata(ReportList *reports, Depsgraph *depsgraph, Scen
return 0;
}
- BKE_nomain_mesh_to_mesh(mesh_applied, me, ob, CD_MASK_MESH, true);
+ BKE_mesh_nomain_to_mesh(mesh_applied, me, ob, CD_MASK_MESH, true);
if (md->type == eModifierType_Multires)
multires_customdata_delete(me);
@@ -660,7 +661,7 @@ static int modifier_apply_obdata(ReportList *reports, Depsgraph *depsgraph, Scen
ParticleSystem *psys = ob->particlesystem.first;
for (; psys; psys = psys->next) {
-
+
if (psys->part->type != PART_HAIR)
continue;
@@ -724,7 +725,7 @@ int ED_object_modifier_apply(
int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
{
ModifierData *nmd;
-
+
nmd = modifier_new(md->type);
modifier_copyData(md, nmd);
BLI_insertlinkafter(&ob->modifiers, md, nmd);
@@ -746,19 +747,19 @@ static int modifier_add_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
static const EnumPropertyItem *modifier_add_itemf(
bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
+{
Object *ob = ED_object_active_context(C);
EnumPropertyItem *item = NULL;
const EnumPropertyItem *md_item, *group_item = NULL;
const ModifierTypeInfo *mti;
int totitem = 0, a;
-
+
if (!ob)
return rna_enum_object_modifier_type_items;
@@ -803,15 +804,15 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot)
ot->name = "Add Modifier";
ot->description = "Add a procedural operation/effect to the active object";
ot->idname = "OBJECT_OT_modifier_add";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = modifier_add_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_enum(ot->srna, "type", rna_enum_object_modifier_type_items, eModifierType_Subsurf, "Type", "");
RNA_def_enum_funcs(prop, modifier_add_itemf);
@@ -824,7 +825,7 @@ int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
-
+
if (!ptr.data) {
CTX_wm_operator_poll_msg_set(C, "Context missing 'modifier'");
return 0;
@@ -838,7 +839,7 @@ int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag
CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers comming from static override");
return (((ModifierData *)ptr.data)->flag & eModifierFlag_StaticOverride_Local) != 0;
}
-
+
return 1;
}
@@ -855,7 +856,7 @@ void edit_modifier_properties(wmOperatorType *ot)
int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
{
ModifierData *md;
-
+
if (RNA_struct_property_is_set(op->ptr, "modifier")) {
return true;
}
@@ -876,9 +877,9 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
char modifier_name[MAX_NAME];
ModifierData *md;
RNA_string_get(op->ptr, "modifier", modifier_name);
-
+
md = modifiers_findByName(ob, modifier_name);
-
+
if (md && type != 0 && md->type != type)
md = NULL;
@@ -894,7 +895,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int mode_orig = ob->mode;
-
+
if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md))
return OPERATOR_CANCELLED;
@@ -928,7 +929,7 @@ void OBJECT_OT_modifier_remove(wmOperatorType *ot)
ot->invoke = modifier_remove_invoke;
ot->exec = modifier_remove_exec;
ot->poll = edit_modifier_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -946,7 +947,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -967,7 +968,7 @@ void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
ot->invoke = modifier_move_up_invoke;
ot->exec = modifier_move_up_exec;
ot->poll = edit_modifier_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -985,7 +986,7 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1006,7 +1007,7 @@ void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
ot->invoke = modifier_move_down_invoke;
ot->exec = modifier_move_down_exec;
ot->poll = edit_modifier_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -1028,7 +1029,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1055,10 +1056,10 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
ot->invoke = modifier_apply_invoke;
ot->exec = modifier_apply_exec;
ot->poll = edit_modifier_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
-
+
RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
edit_modifier_properties(ot);
}
@@ -1072,13 +1073,13 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
-
+
if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, view_layer, ob, md))
return OPERATOR_CANCELLED;
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1099,7 +1100,7 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot)
ot->invoke = modifier_convert_invoke;
ot->exec = modifier_convert_exec;
ot->poll = edit_modifier_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -1117,7 +1118,7 @@ static int modifier_copy_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1138,7 +1139,7 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot)
ot->invoke = modifier_copy_invoke;
ot->exec = modifier_copy_exec;
ot->poll = edit_modifier_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -1155,18 +1156,18 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
-
+
if (!mmd)
return OPERATOR_CANCELLED;
-
+
multiresModifier_del_levels(mmd, ob, 1);
ED_object_iter_other(CTX_data_main(C), ob, true,
ED_object_multires_update_totlevels_cb,
&mmd->totlvl);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1187,7 +1188,7 @@ void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
ot->poll = multires_poll;
ot->invoke = multires_higher_levels_delete_invoke;
ot->exec = multires_higher_levels_delete_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -1199,10 +1200,10 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
-
+
if (!mmd)
return OPERATOR_CANCELLED;
-
+
multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
ED_object_iter_other(CTX_data_main(C), ob, true,
@@ -1216,7 +1217,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
/* ensure that grid paint mask layer is created */
BKE_sculpt_mask_layers_ensure(ob, mmd);
}
-
+
return OPERATOR_FINISHED;
}
@@ -1237,7 +1238,7 @@ void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
ot->poll = multires_poll;
ot->invoke = multires_subdivide_invoke;
ot->exec = multires_subdivide_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -1302,14 +1303,14 @@ void OBJECT_OT_multires_reshape(wmOperatorType *ot)
ot->poll = multires_poll;
ot->invoke = multires_reshape_invoke;
ot->exec = multires_reshape_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
}
-
+
/****************** multires save external operator *********************/
static int multires_external_save_exec(bContext *C, wmOperator *op)
@@ -1325,15 +1326,15 @@ static int multires_external_save_exec(bContext *C, wmOperator *op)
if (CustomData_external_test(&me->ldata, CD_MDISPS))
return OPERATOR_CANCELLED;
-
+
RNA_string_get(op->ptr, "filepath", path);
if (relative)
- BLI_path_rel(path, bmain->name);
+ BLI_path_rel(path, BKE_main_blendfile_path(bmain));
CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path);
CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH, me->totloop, 0);
-
+
return OPERATOR_FINISHED;
}
@@ -1346,23 +1347,23 @@ static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEv
if (!edit_modifier_invoke_properties(C, op))
return OPERATOR_CANCELLED;
-
+
mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
-
+
if (!mmd)
return OPERATOR_CANCELLED;
-
+
if (CustomData_external_test(&me->ldata, CD_MDISPS))
return OPERATOR_CANCELLED;
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return multires_external_save_exec(C, op);
-
+
op->customdata = me;
BLI_snprintf(path, sizeof(path), "//%s.btx", me->id.name + 2);
RNA_string_set(op->ptr, "filepath", path);
-
+
WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
@@ -1378,7 +1379,7 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot)
ot->exec = multires_external_save_exec;
ot->invoke = multires_external_save_invoke;
ot->poll = multires_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -1400,7 +1401,7 @@ static int multires_external_pack_exec(bContext *C, wmOperator *UNUSED(op))
/* XXX don't remove.. */
CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop);
-
+
return OPERATOR_FINISHED;
}
@@ -1412,7 +1413,7 @@ void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
ot->poll = multires_poll;
ot->exec = multires_external_pack_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1422,15 +1423,15 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
-
+
if (!mmd)
return OPERATOR_CANCELLED;
-
+
multiresModifier_base_apply(mmd, ob);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1452,7 +1453,7 @@ void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
ot->poll = multires_poll;
ot->invoke = multires_base_apply_invoke;
ot->exec = multires_base_apply_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -1465,7 +1466,7 @@ static void modifier_skin_customdata_delete(Object *ob)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
-
+
if (em)
BM_data_layer_free(em->bm, &em->bm->vdata, CD_MVERT_SKIN);
else
@@ -1488,7 +1489,7 @@ static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_sk
{
BMEdge *bm_edge;
BMIter bm_iter;
-
+
BM_ITER_ELEM (bm_edge, &bm_iter, bm_vert, BM_EDGES_OF_VERT) {
BMVert *v2 = BM_edge_other_vert(bm_edge, bm_vert);
@@ -1536,7 +1537,7 @@ static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1548,7 +1549,7 @@ void OBJECT_OT_skin_root_mark(wmOperatorType *ot)
ot->poll = skin_edit_poll;
ot->exec = skin_root_mark_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1591,7 +1592,7 @@ static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1609,7 +1610,7 @@ void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot)
ot->poll = skin_edit_poll;
ot->exec = skin_loose_mark_clear_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1641,7 +1642,7 @@ static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -1653,7 +1654,7 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
ot->poll = skin_edit_poll;
ot->exec = skin_radii_equalize_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1697,7 +1698,7 @@ static void skin_armature_bone_create(Object *skin_ob,
ED_vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE);
ED_vgroup_vert_add(skin_ob, dg, v, 1, WEIGHT_REPLACE);
}
-
+
skin_armature_bone_create(skin_ob,
mvert, medge,
arm,
@@ -1730,7 +1731,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
CD_CALLOC,
NULL,
me->totvert);
-
+
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
arm_ob = BKE_object_add(bmain, scene, view_layer, OB_ARMATURE, NULL);
BKE_object_transform_copy(arm_ob, skin_ob);
@@ -1764,7 +1765,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
bone->head[1] = 1.0f;
bone->rad_head = bone->rad_tail = 0.25;
}
-
+
if (emap[v].count >= 1) {
skin_armature_bone_create(skin_ob,
mvert, me->medge,
@@ -1781,7 +1782,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
MEM_freeN(emap);
MEM_freeN(emap_mem);
- ED_armature_from_edit(arm);
+ ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
return arm_ob;
@@ -1839,7 +1840,7 @@ void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
ot->poll = skin_poll;
ot->invoke = skin_armature_create_invoke;
ot->exec = skin_armature_create_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -1925,7 +1926,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
Depsgraph *depsgraph = CTX_data_depsgraph(C);
MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
-
+
if (!mmd)
return OPERATOR_CANCELLED;
@@ -1950,7 +1951,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
mmd->totvert = 0;
mmd->totcagevert = 0;
mmd->totinfluence = 0;
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
}
@@ -1979,7 +1980,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
mmd->bindfunc = NULL;
mmd->modifier.mode = mode;
}
-
+
return OPERATOR_FINISHED;
}
@@ -1987,7 +1988,7 @@ static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UN
{
if (edit_modifier_invoke_properties(C, op))
return meshdeform_bind_exec(C, op);
- else
+ else
return OPERATOR_CANCELLED;
}
@@ -1997,12 +1998,12 @@ void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
ot->name = "Mesh Deform Bind";
ot->description = "Bind mesh to cage in mesh deform modifier";
ot->idname = "OBJECT_OT_meshdeform_bind";
-
+
/* api callbacks */
ot->poll = meshdeform_poll;
ot->invoke = meshdeform_bind_invoke;
ot->exec = meshdeform_bind_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -2019,7 +2020,7 @@ static int explode_refresh_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
ExplodeModifierData *emd = (ExplodeModifierData *)edit_modifier_property_get(op, ob, eModifierType_Explode);
-
+
if (!emd)
return OPERATOR_CANCELLED;
@@ -2027,7 +2028,7 @@ static int explode_refresh_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -2049,7 +2050,7 @@ void OBJECT_OT_explode_refresh(wmOperatorType *ot)
ot->poll = explode_poll;
ot->invoke = explode_refresh_invoke;
ot->exec = explode_refresh_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
@@ -2067,14 +2068,14 @@ static int ocean_bake_poll(bContext *C)
static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData *omd)
{
int do_heightfield, do_chop, do_normals, do_jacobian;
-
- if (!omd || !oc) return;
-
+
+ if (!omd || !oc) return;
+
do_heightfield = true;
do_chop = (omd->chop_amount > 0);
do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
-
+
BKE_ocean_init(oc, omd->resolution * omd->resolution, omd->resolution * omd->resolution, omd->spatial_size, omd->spatial_size,
omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment,
omd->depth, omd->time,
@@ -2104,8 +2105,8 @@ static int oceanbake_breakjob(void *UNUSED(customdata))
{
//OceanBakeJob *ob = (OceanBakeJob *)customdata;
//return *(ob->stop);
-
- /* this is not nice yet, need to make the jobs list template better
+
+ /* this is not nice yet, need to make the jobs list template better
* for identifying/acting upon various different jobs */
/* but for now we'll reuse the render break... */
return (G.is_break);
@@ -2115,10 +2116,10 @@ static int oceanbake_breakjob(void *UNUSED(customdata))
static void oceanbake_update(void *customdata, float progress, int *cancel)
{
OceanBakeJob *oj = customdata;
-
+
if (oceanbake_breakjob(oj))
*cancel = 1;
-
+
*(oj->do_update) = true;
*(oj->progress) = progress;
}
@@ -2126,15 +2127,15 @@ static void oceanbake_update(void *customdata, float progress, int *cancel)
static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
OceanBakeJob *oj = customdata;
-
+
oj->stop = stop;
oj->do_update = do_update;
oj->progress = progress;
-
+
G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
-
+
BKE_ocean_bake(oj->ocean, oj->och, oceanbake_update, (void *)oj);
-
+
*do_update = true;
*stop = 0;
}
@@ -2142,12 +2143,12 @@ static void oceanbake_startjob(void *customdata, short *stop, short *do_update,
static void oceanbake_endjob(void *customdata)
{
OceanBakeJob *oj = customdata;
-
+
if (oj->ocean) {
BKE_ocean_free(oj->ocean);
oj->ocean = NULL;
}
-
+
oj->omd->oceancache = oj->och;
oj->omd->cached = true;
}
@@ -2162,13 +2163,13 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
struct Ocean *ocean;
int f, cfra, i = 0;
const bool free = RNA_boolean_get(op->ptr, "free");
-
+
wmJob *wm_job;
OceanBakeJob *oj;
-
+
if (!omd)
return OPERATOR_CANCELLED;
-
+
if (free) {
omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE;
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -2179,11 +2180,11 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
och = BKE_ocean_init_cache(omd->cachepath, modifier_path_relbase(bmain, ob),
omd->bakestart, omd->bakeend, omd->wave_scale,
omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
-
+
och->time = MEM_mallocN(och->duration * sizeof(float), "foam bake time");
-
+
cfra = scene->r.cfra;
-
+
/* precalculate time variable before baking */
for (f = omd->bakestart; f <= omd->bakeend; f++) {
/* from physics_fluid.c:
@@ -2194,41 +2195,41 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
* This doesn't work with drivers:
* --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
*/
-
- /* Modifying the global scene isn't nice, but we can do it in
+
+ /* Modifying the global scene isn't nice, but we can do it in
* this part of the process before a threaded job is created */
-
+
//scene->r.cfra = f;
//ED_update_for_newframe(bmain, scene);
-
- /* ok, this doesn't work with drivers, but is way faster.
+
+ /* ok, this doesn't work with drivers, but is way faster.
* let's use this for now and hope nobody wants to drive the time value... */
BKE_animsys_evaluate_animdata(CTX_data_depsgraph(C), scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM);
-
+
och->time[i] = omd->time;
i++;
}
-
+
/* make a copy of ocean to use for baking - threadsafety */
ocean = BKE_ocean_add();
init_ocean_modifier_bake(ocean, omd);
-
+
#if 0
BKE_ocean_bake(ocean, och);
-
+
omd->oceancache = och;
omd->cached = true;
-
+
scene->r.cfra = cfra;
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
#endif
-
+
/* job stuff */
-
+
scene->r.cfra = cfra;
-
+
/* setup job */
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation",
WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_SIM_OCEAN);
@@ -2236,15 +2237,15 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
oj->ocean = ocean;
oj->och = och;
oj->omd = omd;
-
+
WM_jobs_customdata_set(wm_job, oj, oceanbake_free);
WM_jobs_timer(wm_job, 0.1, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER);
WM_jobs_callbacks(wm_job, oceanbake_startjob, NULL, NULL, oceanbake_endjob);
-
+
WM_jobs_start(CTX_wm_manager(C), wm_job);
-
-
-
+
+
+
return OPERATOR_FINISHED;
}
@@ -2262,15 +2263,15 @@ void OBJECT_OT_ocean_bake(wmOperatorType *ot)
ot->name = "Bake Ocean";
ot->description = "Bake an image sequence of ocean data";
ot->idname = "OBJECT_OT_ocean_bake";
-
+
ot->poll = ocean_bake_poll;
ot->invoke = ocean_bake_invoke;
ot->exec = ocean_bake_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
-
+
RNA_def_boolean(ot->srna, "free", false, "Free", "Free the bake, rather than generating it");
}
@@ -2329,7 +2330,7 @@ static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEven
{
if (edit_modifier_invoke_properties(C, op))
return laplaciandeform_bind_exec(C, op);
- else
+ else
return OPERATOR_CANCELLED;
}
@@ -2339,12 +2340,12 @@ void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
ot->name = "Laplacian Deform Bind";
ot->description = "Bind mesh to system in laplacian deform modifier";
ot->idname = "OBJECT_OT_laplaciandeform_bind";
-
+
/* api callbacks */
ot->poll = laplaciandeform_poll;
ot->invoke = laplaciandeform_bind_invoke;
ot->exec = laplaciandeform_bind_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 10206ad8410..af572824068 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -65,7 +65,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_transform_apply);
WM_operatortype_append(OBJECT_OT_transform_axis_target);
WM_operatortype_append(OBJECT_OT_origin_set);
-
+
WM_operatortype_append(OBJECT_OT_mode_set);
WM_operatortype_append(OBJECT_OT_mode_set_or_submode);
WM_operatortype_append(OBJECT_OT_editmode_toggle);
@@ -150,7 +150,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_meshdeform_bind);
WM_operatortype_append(OBJECT_OT_explode_refresh);
WM_operatortype_append(OBJECT_OT_ocean_bake);
-
+
WM_operatortype_append(OBJECT_OT_constraint_add);
WM_operatortype_append(OBJECT_OT_constraint_add_with_targets);
WM_operatortype_append(POSE_OT_constraint_add);
@@ -253,7 +253,7 @@ void ED_operatormacros_object(void)
{
wmOperatorType *ot;
wmOperatorTypeMacro *otmacro;
-
+
ot = WM_operatortype_append_macro("OBJECT_OT_duplicate_move", "Duplicate Objects",
"Duplicate selected objects and move them", OPTYPE_UNDO | OPTYPE_REGISTER);
if (ot) {
@@ -271,7 +271,7 @@ void ED_operatormacros_object(void)
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
}
-
+
}
static int object_mode_poll(bContext *C)
@@ -289,23 +289,11 @@ void ED_keymap_object(wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Object Non-modal", 0, 0);
/* modes */
- {
- short key_mode_pair[][2] = {
- {ONEKEY, OB_MODE_OBJECT},
- {TWOKEY, OB_MODE_EDIT},
- {THREEKEY, OB_MODE_POSE},
- {THREEKEY, OB_MODE_WEIGHT_PAINT},
- {FOURKEY, OB_MODE_VERTEX_PAINT},
- {FIVEKEY, OB_MODE_TEXTURE_PAINT},
- {SIXKEY, OB_MODE_SCULPT},
- {SEVENKEY, OB_MODE_PARTICLE_EDIT},
- };
-
- for (uint i = 0; i < ARRAY_SIZE(key_mode_pair); i++) {
- kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set_or_submode", key_mode_pair[i][0], KM_PRESS, 0, 0);
- RNA_enum_set(kmi->ptr, "mode", key_mode_pair[i][1]);
- }
- }
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_mode_set", TABKEY, KM_RELEASE, 0, 0);
+ RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
+
+ kmi = WM_keymap_add_menu_pie(keymap, "VIEW3D_PIE_object_mode", TABKEY, KM_CLICK_DRAG, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_origin_set", CKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_CTRL, 0);
@@ -313,7 +301,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
/* Note: this keymap gets disabled in non-objectmode, */
keymap = WM_keymap_find(keyconf, "Object Mode", 0, 0);
keymap->poll = object_mode_poll;
-
+
/* object mode supports PET now */
ED_keymap_proportional_cycle(keyconf, keymap);
ED_keymap_proportional_obmode(keyconf, keymap);
@@ -329,7 +317,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
-
+
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set_identifier(NULL, kmi->ptr, "direction", "PARENT");
RNA_boolean_set(kmi->ptr, "extend", false);
@@ -351,20 +339,20 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_track_set", TKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_track_clear", TKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_verify_item(keymap, "OBJECT_OT_constraint_add_with_targets", CKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_constraints_clear", CKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
-
-
+
+
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_location_clear", GKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "clear_delta", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_rotation_clear", RKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "clear_delta", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "clear_delta", false);
-
+
WM_keymap_verify_item(keymap, "OBJECT_OT_origin_clear", OKEY, KM_PRESS, KM_ALT, 0);
-
+
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_global", false);
@@ -386,7 +374,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move_linked", DKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_convert", CKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_proxy_make", PKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
@@ -396,13 +384,13 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_insert_menu", IKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_delete_v3d", IKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_keying_set_active_set", IKEY, KM_PRESS, KM_CTRL | KM_SHIFT | KM_ALT, 0);
-
+
WM_keymap_verify_item(keymap, "COLLECTION_OT_create", GKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "COLLECTION_OT_objects_remove", GKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_verify_item(keymap, "COLLECTION_OT_objects_remove_all", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL | KM_ALT, 0);
WM_keymap_verify_item(keymap, "COLLECTION_OT_objects_add_active", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
WM_keymap_verify_item(keymap, "COLLECTION_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0);
-
+
WM_keymap_add_menu(keymap, "VIEW3D_MT_object_specials", WKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_data_transfer", TKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index d417437ad99..4f441826bfd 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -640,7 +640,7 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene,
/* if follow, add F-Curve for ctime (i.e. "eval_time") so that path-follow works */
if (partype == PAR_FOLLOW) {
/* get or create F-Curve */
- bAction *act = verify_adt_action(&cu->id, 1);
+ bAction *act = verify_adt_action(bmain, &cu->id, 1);
FCurve *fcu = verify_fcurve(act, NULL, NULL, "eval_time", 0, 1);
/* setup dummy 'generator' modifier here to get 1-1 correspondence still working */
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 9746e4af714..bac1ba0e37d 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -88,7 +88,7 @@
* this takes into account the 'restrict selection in 3d view' flag.
* deselect works always, the restriction just prevents selection */
-/* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or
+/* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or
* or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */
void ED_object_base_select(Base *base, eObjectSelect_Mode mode)
@@ -143,7 +143,7 @@ static int objects_selectable_poll(bContext *C)
return 0;
if (obact && obact->mode)
return 0;
-
+
return 1;
}
@@ -152,10 +152,10 @@ static int objects_selectable_poll(bContext *C)
static int object_select_by_type_exec(bContext *C, wmOperator *op)
{
short obtype, extend;
-
+
obtype = RNA_enum_get(op->ptr, "type");
extend = RNA_boolean_get(op->ptr, "extend");
-
+
if (extend == 0) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
@@ -163,7 +163,7 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
-
+
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
if (base->object->type == obtype) {
@@ -171,9 +171,9 @@ static int object_select_by_type_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
-
+
return OPERATOR_FINISHED;
}
@@ -183,15 +183,15 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot)
ot->name = "Select By Type";
ot->description = "Select all visible objects that are of a type";
ot->idname = "OBJECT_OT_select_by_type";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = object_select_by_type_exec;
ot->poll = objects_selectable_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_object_type_items, 1, "Type", "");
@@ -294,7 +294,7 @@ static bool object_select_all_by_particle(bContext *C, Object *ob)
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
/* loop through other particles*/
ParticleSystem *psys;
-
+
for (psys = base->object->particlesystem.first; psys; psys = psys->next) {
if (psys->part == psys_act->part) {
ED_object_base_select(base, BA_SELECT);
@@ -378,7 +378,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
bool changed = false, extend;
extend = RNA_boolean_get(op->ptr, "extend");
-
+
if (extend == 0) {
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
@@ -386,13 +386,13 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
}
-
+
ob = OBACT(view_layer);
if (ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active object");
return OPERATOR_CANCELLED;
}
-
+
if (nr == OBJECT_SELECT_LINKED_IPO) {
// XXX old animation system
//if (ob->ipo == 0) return OPERATOR_CANCELLED;
@@ -442,7 +442,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_FINISHED;
}
-
+
return OPERATOR_CANCELLED;
}
@@ -452,15 +452,15 @@ void OBJECT_OT_select_linked(wmOperatorType *ot)
ot->name = "Select Linked";
ot->description = "Select all visible objects that are linked";
ot->idname = "OBJECT_OT_select_linked";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = object_select_linked_exec;
ot->poll = objects_selectable_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_linked_types, 0, "Type", "");
@@ -694,7 +694,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
{
KeyingSet *ks = ANIM_scene_get_active_keyingset(CTX_data_scene(C));
bool changed = false;
-
+
/* firstly, validate KeyingSet */
if (ks == NULL) {
BKE_report(reports, RPT_ERROR, "No active Keying Set to use");
@@ -703,7 +703,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
else if (ANIM_validate_keyingset(C, NULL, ks) != 0) {
if (ks->paths.first == NULL) {
if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
- BKE_report(reports, RPT_ERROR,
+ BKE_report(reports, RPT_ERROR,
"Use another Keying Set, as the active one depends on the currently "
"selected objects or cannot find any targets due to unsuitable context");
}
@@ -713,7 +713,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
}
return false;
}
-
+
/* select each object that Keying Set refers to */
/* TODO: perhaps to be more in line with the rest of these, we should only take objects
* if the passed in object is included in this too */
@@ -722,8 +722,8 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
/* only check for this object if it isn't selected already, to limit time wasted */
if ((base->flag & BASE_SELECTED) == 0) {
KS_Path *ksp;
-
- /* this is the slow way... we could end up with > 500 items here,
+
+ /* this is the slow way... we could end up with > 500 items here,
* with none matching, but end up doing this on 1000 objects...
*/
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
@@ -737,7 +737,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
}
}
CTX_DATA_END;
-
+
return changed;
}
@@ -822,15 +822,15 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
ot->name = "Select Grouped";
ot->description = "Select all visible objects grouped by various properties";
ot->idname = "OBJECT_OT_select_grouped";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = object_select_grouped_exec;
ot->poll = objects_selectable_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
@@ -841,7 +841,7 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot)
static int object_select_all_exec(bContext *C, wmOperator *op)
{
int action = RNA_enum_get(op->ptr, "action");
-
+
/* passthrough if no objects are visible */
if (CTX_DATA_COUNT(C, visible_bases) == 0) return OPERATOR_PASS_THROUGH;
@@ -877,24 +877,24 @@ static int object_select_all_exec(bContext *C, wmOperator *op)
}
}
CTX_DATA_END;
-
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
-
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_select_all(wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "(De)select All";
ot->description = "Change selection of all visible objects in scene";
ot->idname = "OBJECT_OT_select_all";
-
+
/* api callbacks */
ot->exec = object_select_all_exec;
ot->poll = objects_selectable_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -931,22 +931,22 @@ static int object_select_same_collection_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
-
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_select_same_collection(wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Select Same Collection";
ot->description = "Select object in the same collection";
ot->idname = "OBJECT_OT_select_same_collection";
-
+
/* api callbacks */
ot->exec = object_select_same_collection_exec;
ot->poll = objects_selectable_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -960,15 +960,15 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
bool extend;
-
+
extend = RNA_boolean_get(op->ptr, "extend");
-
+
CTX_DATA_BEGIN (C, Base *, primbase, selected_bases)
{
char name_flip[MAXBONENAME];
BLI_string_flip_side_name(name_flip, primbase->object->id.name + 2, true, sizeof(name_flip));
-
+
if (!STREQ(name_flip, primbase->object->id.name + 2)) {
Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, name_flip);
if (ob) {
@@ -979,33 +979,33 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op)
}
}
}
-
+
if (extend == false) ED_object_base_select(primbase, BA_DESELECT);
-
+
}
CTX_DATA_END;
-
+
/* undo? */
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
-
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_select_mirror(wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Select Mirror";
ot->description = "Select the Mirror objects of the selected object eg. L.sword -> R.sword";
ot->idname = "OBJECT_OT_select_mirror";
-
+
/* api callbacks */
ot->exec = object_select_mirror_exec;
ot->poll = objects_selectable_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first");
}
@@ -1130,7 +1130,7 @@ void OBJECT_OT_select_less(wmOperatorType *ot)
/**************************** Select Random ****************************/
static int object_select_random_exec(bContext *C, wmOperator *op)
-{
+{
const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f;
const int seed = WM_operator_properties_select_random_seed_increment_get(op);
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
@@ -1148,7 +1148,7 @@ static int object_select_random_exec(bContext *C, wmOperator *op)
BLI_rng_free(rng);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
-
+
return OPERATOR_FINISHED;
}
@@ -1158,15 +1158,15 @@ void OBJECT_OT_select_random(wmOperatorType *ot)
ot->name = "Select Random";
ot->description = "Set select on random visible objects";
ot->idname = "OBJECT_OT_select_random";
-
+
/* api callbacks */
/*ot->invoke = object_select_random_invoke XXX - need a number popup ;*/
ot->exec = object_select_random_exec;
ot->poll = objects_selectable_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_select_random(ot);
}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 1f80cb5f0bc..03fe6e9de65 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -35,7 +35,7 @@
#include <unistd.h>
#else
#include <io.h>
-#endif
+#endif
#include "MEM_guardedalloc.h"
@@ -119,7 +119,7 @@ static bool object_shape_key_mirror(bContext *C, Object *ob,
key = BKE_key_from_object(ob);
if (key == NULL)
return 0;
-
+
kb = BLI_findlink(&key->block, ob->shapenr - 1);
if (kb) {
@@ -211,7 +211,7 @@ static bool object_shape_key_mirror(bContext *C, Object *ob,
MEM_freeN(tag_elem);
}
-
+
*r_totmirr = totmirr;
*r_totfail = totfail;
@@ -278,7 +278,7 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot)
ot->name = "Add Shape Key";
ot->idname = "OBJECT_OT_shape_key_add";
ot->description = "Add shape key to the object";
-
+
/* api callbacks */
ot->poll = shape_key_mode_poll;
ot->exec = shape_key_add_exec;
@@ -321,7 +321,7 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
ot->name = "Remove Shape Key";
ot->idname = "OBJECT_OT_shape_key_remove";
ot->description = "Remove shape key from the object";
-
+
/* api callbacks */
ot->poll = shape_key_mode_exists_poll;
ot->exec = shape_key_remove_exec;
@@ -341,13 +341,13 @@ static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
if (!key || !kb)
return OPERATOR_CANCELLED;
-
+
for (kb = key->block.first; kb; kb = kb->next)
kb->curval = 0.0f;
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -357,7 +357,7 @@ void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
ot->name = "Clear Shape Keys";
ot->description = "Clear weights for all shape keys";
ot->idname = "OBJECT_OT_shape_key_clear";
-
+
/* api callbacks */
ot->poll = shape_key_poll;
ot->exec = shape_key_clear_exec;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 77514ca1e8e..721d248ae4c 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -122,7 +122,7 @@ static void object_clear_rot(Object *ob, const bool clear_delta)
ob->rotAxis[2] = 0.0f;
if (clear_delta) ob->drotAxis[2] = 0.0f;
}
-
+
/* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
if (IS_EQF(ob->rotAxis[0], ob->rotAxis[1]) && IS_EQF(ob->rotAxis[1], ob->rotAxis[2]))
ob->rotAxis[1] = 1.0f;
@@ -168,7 +168,7 @@ static void object_clear_rot(Object *ob, const bool clear_delta)
/* perform clamping using euler form (3-components) */
/* FIXME: deltas are not handled for these cases yet... */
float eul[3], oldeul[3], quat1[4] = {0};
-
+
if (ob->rotmode == ROT_MODE_QUAT) {
copy_qt_qt(quat1, ob->quat);
quat_to_eul(oldeul, ob->quat);
@@ -179,16 +179,16 @@ static void object_clear_rot(Object *ob, const bool clear_delta)
else {
copy_v3_v3(oldeul, ob->rot);
}
-
+
eul[0] = eul[1] = eul[2] = 0.0f;
-
+
if (ob->protectflag & OB_LOCK_ROTX)
eul[0] = oldeul[0];
if (ob->protectflag & OB_LOCK_ROTY)
eul[1] = oldeul[1];
if (ob->protectflag & OB_LOCK_ROTZ)
eul[2] = oldeul[2];
-
+
if (ob->rotmode == ROT_MODE_QUAT) {
eul_to_quat(ob->quat, eul);
/* quaternions flip w sign to accumulate rotations correctly */
@@ -241,24 +241,24 @@ static void object_clear_scale(Object *ob, const bool clear_delta)
/* --------------- */
/* generic exec for clear-transform operators */
-static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
+static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
void (*clear_func)(Object *, const bool),
const char default_ksName[])
{
Scene *scene = CTX_data_scene(C);
KeyingSet *ks;
const bool clear_delta = RNA_boolean_get(op->ptr, "clear_delta");
-
+
/* sanity checks */
if (ELEM(NULL, clear_func, default_ksName)) {
BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or keying set name");
return OPERATOR_CANCELLED;
}
-
+
/* get KeyingSet to use */
ks = ANIM_get_keyingset_for_autokeying(scene, default_ksName);
-
- /* operate on selected objects only if they aren't in weight-paint mode
+
+ /* operate on selected objects only if they aren't in weight-paint mode
* (so that object-transform clearing won't be applied at same time as bone-clearing)
*/
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
@@ -266,15 +266,15 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
if (!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
/* run provided clearing function */
clear_func(ob, clear_delta);
-
+
ED_autokeyframe_object(C, scene, ob, ks);
-
+
/* tag for updates */
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
CTX_DATA_END;
-
+
/* this is needed so children are also updated */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
@@ -295,15 +295,15 @@ void OBJECT_OT_location_clear(wmOperatorType *ot)
ot->name = "Clear Location";
ot->description = "Clear the object's location";
ot->idname = "OBJECT_OT_location_clear";
-
+
/* api callbacks */
ot->exec = object_location_clear_exec;
ot->poll = ED_operator_scene_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
-
+
+
/* properties */
ot->prop = RNA_def_boolean(ot->srna, "clear_delta", false, "Clear Delta",
"Clear delta location in addition to clearing the normal location transform");
@@ -320,14 +320,14 @@ void OBJECT_OT_rotation_clear(wmOperatorType *ot)
ot->name = "Clear Rotation";
ot->description = "Clear the object's rotation";
ot->idname = "OBJECT_OT_rotation_clear";
-
+
/* api callbacks */
ot->exec = object_rotation_clear_exec;
ot->poll = ED_operator_scene_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_boolean(ot->srna, "clear_delta", false, "Clear Delta",
"Clear delta rotation in addition to clearing the normal rotation transform");
@@ -344,14 +344,14 @@ void OBJECT_OT_scale_clear(wmOperatorType *ot)
ot->name = "Clear Scale";
ot->description = "Clear the object's scale";
ot->idname = "OBJECT_OT_scale_clear";
-
+
/* api callbacks */
ot->exec = object_scale_clear_exec;
ot->poll = ED_operator_scene_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_boolean(ot->srna, "clear_delta", false, "Clear Delta",
"Clear delta scale in addition to clearing the normal scale transform");
@@ -370,7 +370,7 @@ static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op))
/* vectors pointed to by v1 and v3 will get modified */
v1 = ob->loc;
v3 = ob->parentinv[3];
-
+
copy_m3_m4(mat, ob->parentinv);
negate_v3_v3(v3, v1);
mul_m3_v3(mat, v3);
@@ -381,7 +381,7 @@ static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op))
CTX_DATA_END;
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -391,11 +391,11 @@ void OBJECT_OT_origin_clear(wmOperatorType *ot)
ot->name = "Clear Origin";
ot->description = "Clear the object's origin";
ot->idname = "OBJECT_OT_origin_clear";
-
+
/* api callbacks */
ot->exec = object_origin_clear_exec;
ot->poll = ED_operator_scene_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -409,7 +409,7 @@ static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Objec
Object workob;
Object *ob_child;
Depsgraph *depsgraph = CTX_data_depsgraph(C);
-
+
/* a change was made, adjust the children to compensate */
for (ob_child = bmain->object.first; ob_child; ob_child = ob_child->id.next) {
if (ob_child->parent == ob) {
@@ -493,7 +493,7 @@ static int apply_objects_internal(
}
}
CTX_DATA_END;
-
+
if (!changed)
return OPERATOR_CANCELLED;
@@ -545,15 +545,15 @@ static int apply_objects_internal(
if (apply_scale)
multiresModifier_scale_disp(depsgraph, scene, ob);
-
+
/* adjust data */
BKE_mesh_transform(me, mat, true);
-
+
/* update normals */
BKE_mesh_calc_normals(me);
}
else if (ob->type == OB_ARMATURE) {
- ED_armature_transform_apply(ob, mat, do_props);
+ ED_armature_transform_apply(bmain, ob, mat, do_props);
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
@@ -600,12 +600,12 @@ static int apply_objects_internal(
BKE_tracking_reconstruction_scale(&clip->tracking, ob->size);
}
else if (ob->type == OB_EMPTY) {
- /* It's possible for empties too, even though they don't
+ /* It's possible for empties too, even though they don't
* really have obdata, since we can simply apply the maximum
* scaling to the empty's drawsize.
*
* Core Assumptions:
- * 1) Most scaled empties have uniform scaling
+ * 1) Most scaled empties have uniform scaling
* (i.e. for visibility reasons), AND/OR
* 2) Preserving non-uniform scaling is not that important,
* and is something that many users would be willing to
@@ -690,7 +690,7 @@ static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
/* update for any children that may get moved */
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
-
+
changed = true;
}
CTX_DATA_END;
@@ -708,11 +708,11 @@ void OBJECT_OT_visual_transform_apply(wmOperatorType *ot)
ot->name = "Apply Visual Transform";
ot->description = "Apply the object's visual transformation to its data";
ot->idname = "OBJECT_OT_visual_transform_apply";
-
+
/* api callbacks */
ot->exec = visual_transform_apply_exec;
ot->poll = ED_operator_scene_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -803,7 +803,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
BMEditMesh *em = me->edit_btmesh;
BMVert *eve;
BMIter iter;
-
+
if (centermode == ORIGIN_TO_CURSOR) {
copy_v3_v3(cent, cursor);
invert_m4_m4(obedit->imat, obedit->obmat);
@@ -827,7 +827,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
mid_v3_v3v3(cent, min, max);
}
}
-
+
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
sub_v3_v3(eve->co, cent);
}
@@ -880,7 +880,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
invert_m4_m4(ob->imat, ob->obmat);
mul_m4_v3(ob->imat, cent);
}
-
+
if (ob->data == NULL) {
/* special support for dupligroups */
if ((ob->transflag & OB_DUPLICOLLECTION) && ob->dup_group && (ob->dup_group->id.tag & LIB_TAG_DOIT) == 0) {
@@ -900,7 +900,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
invert_m4_m4(ob->imat, ob->obmat);
mul_m4_v3(ob->imat, cent);
}
-
+
add_v3_v3(ob->dup_group->dupli_ofs, cent);
tot_change++;
@@ -1006,7 +1006,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
/* Function to recenter armatures in editarmature.c
* Bone + object locations are handled there.
*/
- ED_armature_origin_set(ob, cursor, centermode, around);
+ ED_armature_origin_set(bmain, ob, cursor, centermode, around);
tot_change++;
arm->id.tag |= LIB_TAG_DOIT;
@@ -1077,7 +1077,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
}
ignore_parent_tx(C, bmain, scene, ob);
-
+
/* other users? */
//CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects)
//{
@@ -1151,27 +1151,27 @@ void OBJECT_OT_origin_set(wmOperatorType *ot)
"Calculate the center of mass from the volume (must be manifold geometry with consistent normals)"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem prop_set_bounds_types[] = {
{V3D_AROUND_CENTER_MEAN, "MEDIAN", 0, "Median Center", ""},
{V3D_AROUND_CENTER_BOUNDS, "BOUNDS", 0, "Bounds Center", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Set Origin";
ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3D cursor";
ot->idname = "OBJECT_OT_origin_set";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = object_origin_set_exec;
-
+
ot->poll = ED_operator_scene_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
ot->prop = RNA_def_enum(ot->srna, "type", prop_set_center_types, 0, "Type", "");
RNA_def_enum(ot->srna, "center", prop_set_bounds_types, V3D_AROUND_CENTER_MEAN, "Center", "");
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index ff40aa07cd2..84786024160 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -58,6 +58,7 @@
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_modifier.h"
@@ -772,7 +773,7 @@ static void ED_vgroup_nr_vert_add(
/* get the vert */
BKE_object_defgroup_array_get(ob->data, &dvert, &tot);
-
+
if (dvert == NULL)
return;
@@ -937,7 +938,7 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
dv = &lt->dvert[vertnum];
}
}
-
+
if (dv) {
MDeformWeight *dw = defvert_find_index(dv, def_nr);
if (dw) {
@@ -1024,12 +1025,12 @@ static void vgroup_select_verts(Object *ob, int select)
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = vgroup_edit_lattice(ob);
-
+
if (lt->dvert) {
MDeformVert *dv;
BPoint *bp, *actbp = BKE_lattice_active_point_get(lt);
int a, tot;
-
+
dv = lt->dvert;
tot = lt->pntsu * lt->pntsv * lt->pntsw;
@@ -1057,7 +1058,7 @@ static void vgroup_duplicate(Object *ob)
dg = BLI_findlink(&ob->defbase, (ob->actdef - 1));
if (!dg)
return;
-
+
if (!strstr(dg->name, "_copy")) {
BLI_snprintf(name, sizeof(name), "%s_copy", dg->name);
}
@@ -1127,7 +1128,7 @@ static bool vgroup_normalize(Object *ob)
if (weight_max > 0.0f) {
for (i = 0; i < dvert_tot; i++) {
-
+
/* in case its not selected */
if (!(dv = dvert_array[i])) {
continue;
@@ -1136,7 +1137,7 @@ static bool vgroup_normalize(Object *ob)
dw = defvert_find_index(dv, def_nr);
if (dw) {
dw->weight /= weight_max;
-
+
/* in case of division errors with very low weights */
CLAMP(dw->weight, 0.0f, 1.0f);
}
@@ -1461,7 +1462,7 @@ static void moveCloserToDistanceFromPlane(
MEM_freeN(dwIndices);
}
-/* this is used to try to smooth a surface by only adjusting the nonzero weights of a vertex
+/* this is used to try to smooth a surface by only adjusting the nonzero weights of a vertex
* but it could be used to raise or lower an existing 'bump.' */
static void vgroup_fix(const bContext *C, Scene *scene, Object *ob, float distToBe, float strength, float cp)
{
@@ -1487,7 +1488,7 @@ static void vgroup_fix(const bContext *C, Scene *scene, Object *ob, float distTo
dm->getVert(dm, verts[k], &m);
p[k] = m;
}
-
+
if (count >= 3) {
float d /*, dist */ /* UNUSED */, mag;
float coord[3];
@@ -2642,7 +2643,7 @@ static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -2652,7 +2653,7 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot)
ot->name = "Add Vertex Group";
ot->idname = "OBJECT_OT_vertex_group_add";
ot->description = "Add a new vertex group to the active object";
-
+
/* api callbacks */
ot->poll = vertex_group_supported_poll;
ot->exec = vertex_group_add_exec;
@@ -2675,7 +2676,7 @@ static int vertex_group_remove_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -2685,7 +2686,7 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot)
ot->name = "Remove Vertex Group";
ot->idname = "OBJECT_OT_vertex_group_remove";
ot->description = "Delete the active or all vertex groups from the active object";
-
+
/* api callbacks */
ot->poll = vertex_group_poll;
ot->exec = vertex_group_remove_exec;
@@ -2705,11 +2706,11 @@ static int vertex_group_assign_exec(bContext *C, wmOperator *UNUSED(op))
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = ED_object_context(C);
-
+
vgroup_assign_verts(ob, ts->vgroup_weight);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
-
+
return OPERATOR_FINISHED;
}
@@ -2719,7 +2720,7 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot)
ot->name = "Assign to Vertex Group";
ot->idname = "OBJECT_OT_vertex_group_assign";
ot->description = "Assign the selected vertices to the active vertex group";
-
+
/* api callbacks */
ot->poll = vertex_group_vert_select_unlocked_poll;
ot->exec = vertex_group_assign_exec;
@@ -2737,7 +2738,7 @@ static int vertex_group_assign_new_exec(bContext *C, wmOperator *op)
/* create new group... */
Object *ob = ED_object_context(C);
BKE_object_defgroup_add(ob);
-
+
/* assign selection to new group */
return vertex_group_assign_exec(C, op);
}
@@ -2748,11 +2749,11 @@ void OBJECT_OT_vertex_group_assign_new(wmOperatorType *ot)
ot->name = "Assign to New Group";
ot->idname = "OBJECT_OT_vertex_group_assign_new";
ot->description = "Assign the selected vertices to a new vertex group";
-
+
/* api callbacks */
ot->poll = vertex_group_vert_select_poll;
ot->exec = vertex_group_assign_new_exec;
-
+
/* flags */
/* redo operator will fail in this case because vertex group assignment
* isn't stored in local edit mode stack and toggling "new" property will
@@ -2894,7 +2895,7 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
static int vertex_group_levels_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
-
+
float offset = RNA_float_get(op->ptr, "offset");
float gain = RNA_float_get(op->ptr, "gain");
eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
@@ -2904,11 +2905,11 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op)
const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_levels_subset(ob, vgroup_validmap, vgroup_tot, subset_count, offset, gain);
MEM_freeN((void *)vgroup_validmap);
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
-
+
return OPERATOR_FINISHED;
}
@@ -2918,14 +2919,14 @@ void OBJECT_OT_vertex_group_levels(wmOperatorType *ot)
ot->name = "Vertex Group Levels";
ot->idname = "OBJECT_OT_vertex_group_levels";
ot->description = "Add some offset and multiply with some gain the weights of the active vertex group";
-
+
/* api callbacks */
ot->poll = vertex_group_poll;
ot->exec = vertex_group_levels_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
vgroup_operator_subset_select_props(ot, true);
RNA_def_float(ot->srna, "offset", 0.f, -1.0, 1.0, "Offset", "Value to add to weights", -1.0f, 1.f);
RNA_def_float(ot->srna, "gain", 1.f, 0.f, FLT_MAX, "Gain", "Value to multiply weights by", 0.0f, 10.f);
@@ -3014,7 +3015,7 @@ static int vertex_group_fix_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
-
+
float distToBe = RNA_float_get(op->ptr, "dist");
float strength = RNA_float_get(op->ptr, "strength");
float cp = RNA_float_get(op->ptr, "accuracy");
@@ -3026,17 +3027,17 @@ static int vertex_group_fix_exec(bContext *C, wmOperator *op)
}
md = md->next;
}
-
+
if (md && md->type == eModifierType_Mirror) {
BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "This operator does not support an active mirror modifier");
return OPERATOR_CANCELLED;
}
vgroup_fix(C, scene, ob, distToBe, strength, cp);
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
-
+
return OPERATOR_FINISHED;
}
@@ -3047,11 +3048,11 @@ void OBJECT_OT_vertex_group_fix(wmOperatorType *ot)
ot->idname = "OBJECT_OT_vertex_group_fix";
ot->description = "Modify the position of selected vertices by changing only their respective "
"groups' weights (this tool may be slow for many vertices)";
-
+
/* api callbacks */
ot->poll = vertex_group_mesh_poll;
ot->exec = vertex_group_fix_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_float(ot->srna, "dist", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "The distance to move to", -10.0f, 10.0f);
@@ -3449,16 +3450,16 @@ static int set_active_group_exec(bContext *C, wmOperator *op)
}
static const EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
+{
Object *ob = ED_object_context(C);
EnumPropertyItem tmp = {0, "", 0, "", ""};
EnumPropertyItem *item = NULL;
bDeformGroup *def;
int a, totitem = 0;
-
+
if (!ob)
return DummyRNA_NULL_items;
-
+
for (a = 0, def = ob->defbase.first; def; def = def->next, a++) {
tmp.value = a;
tmp.icon = ICON_GROUP_VERTEX;
@@ -3583,7 +3584,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
BLI_assert(sort_map_update[ob->actdef] >= 0);
ob->actdef = sort_map_update[ob->actdef];
-
+
MEM_freeN(sort_map_update);
return OPERATOR_FINISHED;
@@ -3651,7 +3652,7 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op)
vgroup_sort_bone_hierarchy(ob, NULL);
break;
}
-
+
/*remap vgroup data to map to correct names*/
ret = vgroup_do_remap(ob, name_array, op);
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 868402c7b56..f45ee050ef9 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -102,7 +102,7 @@ void DPAINT_OT_surface_slot_add(wmOperatorType *ot)
ot->name = "Add Surface Slot";
ot->idname = "DPAINT_OT_surface_slot_add";
ot->description = "Add a new Dynamic Paint surface slot";
-
+
/* api callbacks */
ot->exec = surface_slot_add_exec;
ot->poll = ED_operator_object_active_editable;
@@ -150,7 +150,7 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot)
ot->name = "Remove Surface Slot";
ot->idname = "DPAINT_OT_surface_slot_remove";
ot->description = "Remove the selected surface slot";
-
+
/* api callbacks */
ot->exec = surface_slot_remove_exec;
ot->poll = ED_operator_object_active_editable;
@@ -181,7 +181,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op)
if (!dynamicPaint_createType(pmd, type, scene))
return OPERATOR_CANCELLED;
}
-
+
/* update dependency */
DEG_id_tag_update(&cObject->id, OB_RECALC_DATA);
DEG_relations_tag_update(CTX_data_main(C));
@@ -198,14 +198,14 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot)
ot->name = "Toggle Type Active";
ot->idname = "DPAINT_OT_type_toggle";
ot->description = "Toggle whether given type is active or not";
-
+
/* api callbacks */
ot->exec = type_toggle_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_enum(ot->srna, "type", rna_enum_prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", "");
ot->prop = prop;
@@ -225,7 +225,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op)
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
int exists = dynamicPaint_outputLayerExists(surface, ob, output);
const char *name;
-
+
if (output == 0)
name = surface->output_name;
else
@@ -235,7 +235,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op)
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
if (!exists)
ED_mesh_color_add(ob->data, name, true);
- else
+ else
ED_mesh_color_remove_named(ob->data, name);
}
/* Vertex Weight Layer */
@@ -265,14 +265,14 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot)
ot->name = "Toggle Output Layer";
ot->idname = "DPAINT_OT_output_toggle";
ot->description = "Add or remove Dynamic Paint output data layer";
-
+
/* api callbacks */
ot->exec = output_toggle_exec;
ot->poll = ED_operator_object_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "output", prop_output_toggle_types, 0, "Output Toggle", "");
}
@@ -509,7 +509,7 @@ void DPAINT_OT_bake(wmOperatorType *ot)
ot->name = "Dynamic Paint Bake";
ot->description = "Bake dynamic paint image sequence surface";
ot->idname = "DPAINT_OT_bake";
-
+
/* api callbacks */
ot->exec = dynamicpaint_bake_exec;
ot->poll = ED_operator_object_active_editable;
diff --git a/source/blender/editors/physics/particle_boids.c b/source/blender/editors/physics/particle_boids.c
index ff3c4605eee..57b22991f94 100644
--- a/source/blender/editors/physics/particle_boids.c
+++ b/source/blender/editors/physics/particle_boids.c
@@ -78,7 +78,7 @@ static int rule_add_exec(bContext *C, wmOperator *op)
BLI_addtail(&state->rules, rule);
DEG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
-
+
return OPERATOR_FINISHED;
}
@@ -88,14 +88,14 @@ void BOID_OT_rule_add(wmOperatorType *ot)
ot->name = "Add Boid Rule";
ot->description = "Add a boid rule to the current boid state";
ot->idname = "BOID_OT_rule_add";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = rule_add_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
-
+
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_boidrule_type_items, 0, "Type", "");
}
static int rule_del_exec(bContext *C, wmOperator *UNUSED(op))
@@ -135,7 +135,7 @@ void BOID_OT_rule_del(wmOperatorType *ot)
ot->name = "Remove Boid Rule";
ot->idname = "BOID_OT_rule_del";
ot->description = "Delete current boid rule";
-
+
/* api callbacks */
ot->exec = rule_del_exec;
@@ -153,7 +153,7 @@ static int rule_move_up_exec(bContext *C, wmOperator *UNUSED(op))
if (!part || part->phystype != PART_PHYS_BOIDS)
return OPERATOR_CANCELLED;
-
+
state = boid_get_current_state(part->boids);
for (rule = state->rules.first; rule; rule=rule->next) {
if (rule->flag & BOIDRULE_CURRENT && rule->prev) {
@@ -164,7 +164,7 @@ static int rule_move_up_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -175,7 +175,7 @@ void BOID_OT_rule_move_up(wmOperatorType *ot)
ot->idname = "BOID_OT_rule_move_up";
ot->exec = rule_move_up_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -189,7 +189,7 @@ static int rule_move_down_exec(bContext *C, wmOperator *UNUSED(op))
if (!part || part->phystype != PART_PHYS_BOIDS)
return OPERATOR_CANCELLED;
-
+
state = boid_get_current_state(part->boids);
for (rule = state->rules.first; rule; rule=rule->next) {
if (rule->flag & BOIDRULE_CURRENT && rule->next) {
@@ -200,7 +200,7 @@ static int rule_move_down_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -211,7 +211,7 @@ void BOID_OT_rule_move_down(wmOperatorType *ot)
ot->idname = "BOID_OT_rule_move_down";
ot->exec = rule_move_down_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -244,10 +244,10 @@ void BOID_OT_state_add(wmOperatorType *ot)
ot->name = "Add Boid State";
ot->description = "Add a boid state to the particle system";
ot->idname = "BOID_OT_state_add";
-
+
/* api callbacks */
ot->exec = state_add_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -281,7 +281,7 @@ static int state_del_exec(bContext *C, wmOperator *UNUSED(op))
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
-
+
return OPERATOR_FINISHED;
}
@@ -291,7 +291,7 @@ void BOID_OT_state_del(wmOperatorType *ot)
ot->name = "Remove Boid State";
ot->idname = "BOID_OT_state_del";
ot->description = "Delete current boid state";
-
+
/* api callbacks */
ot->exec = state_del_exec;
@@ -311,7 +311,7 @@ static int state_move_up_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
boids = part->boids;
-
+
for (state = boids->states.first; state; state=state->next) {
if (state->flag & BOIDSTATE_CURRENT && state->prev) {
BLI_remlink(&boids->states, state);
@@ -319,7 +319,7 @@ static int state_move_up_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -330,7 +330,7 @@ void BOID_OT_state_move_up(wmOperatorType *ot)
ot->idname = "BOID_OT_state_move_up";
ot->exec = state_move_up_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -346,7 +346,7 @@ static int state_move_down_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
boids = part->boids;
-
+
for (state = boids->states.first; state; state=state->next) {
if (state->flag & BOIDSTATE_CURRENT && state->next) {
BLI_remlink(&boids->states, state);
@@ -355,7 +355,7 @@ static int state_move_down_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -366,7 +366,7 @@ void BOID_OT_state_move_down(wmOperatorType *ot)
ot->idname = "BOID_OT_state_move_down";
ot->exec = state_move_down_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 288c216c1b6..359e9365ea7 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -57,9 +57,11 @@
#include "BKE_object.h"
#include "BKE_library.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_report.h"
+#include "BKE_scene.h"
#include "BKE_bvhutils.h"
#include "BKE_pointcache.h"
@@ -189,7 +191,7 @@ static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *br
// here we can enable unified brush size, needs more work...
// UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
// float size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
-
+
return brush->size * U.pixelsize;
}
@@ -260,8 +262,7 @@ static PTCacheEdit *pe_get_current(
}
else {
if (create && !psys->edit) {
- ParticleSystem *psys_eval = psys_eval_get(depsgraph, ob, psys);
- if (psys_eval->flag & PSYS_HAIR_DONE) {
+ if (psys->flag & PSYS_HAIR_DONE) {
PE_create_particle_edit(depsgraph, scene, ob, NULL, psys);
}
}
@@ -353,7 +354,7 @@ static int pe_x_mirror(Object *ob)
{
if (ob->type == OB_MESH)
return (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X);
-
+
return 0;
}
@@ -361,7 +362,7 @@ static int pe_x_mirror(Object *ob)
typedef struct PEData {
ViewContext vc;
-
+
const bContext *context;
Scene *scene;
ViewLayer *view_layer;
@@ -429,13 +430,13 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
static bool PE_create_shape_tree(PEData *data, Object *shapeob)
{
Mesh *mesh = BKE_object_get_evaluated_mesh(data->depsgraph, shapeob);
-
+
memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
-
+
if (!mesh) {
return false;
}
-
+
return (BKE_bvhtree_from_mesh_get(&data->shape_bvh, mesh, BVHTREE_FROM_LOOPTRI, 4) != NULL);
}
@@ -506,7 +507,7 @@ static bool key_inside_circle(PEData *data, float rad, const float co[3], float
return 1;
}
-
+
return 0;
}
@@ -545,7 +546,7 @@ static bool point_is_selected(PTCacheEditPoint *point)
LOOP_SELECTED_KEYS {
return 1;
}
-
+
return 0;
}
@@ -643,11 +644,9 @@ static void foreach_mouse_hit_point(PEData *data, ForPointFunc func, int selecte
static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected)
{
- Object *ob_eval = DEG_get_evaluated_object(data->depsgraph, data->ob);
PTCacheEdit *edit = data->edit;
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd = NULL;
- ParticleSystemModifierData *psmd_eval = NULL;
ParticleEditSettings *pset= PE_settings(data->scene);
POINT_P; KEY_K;
float mat[4][4], imat[4][4];
@@ -658,10 +657,6 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
if (edit->psys)
psmd= psys_get_modifier(data->ob, edit->psys);
- if (psmd != NULL) {
- psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name);
- }
-
/* all is selected in path mode */
if (pset->selectmode==SCE_SELECT_PATH)
selected= 0;
@@ -675,7 +670,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
if (selected==0 || key->flag & PEK_SELECT) {
if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
- psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat);
+ psys_mat_hair_to_global(data->ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat);
invert_m4_m4(imat, mat);
}
@@ -690,7 +685,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
if (selected==0 || key->flag & PEK_SELECT) {
if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
- psys_mat_hair_to_global(data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat);
+ psys_mat_hair_to_global(data->ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat);
invert_m4_m4(imat, mat);
}
@@ -796,7 +791,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
/* lookup particles and set in mirror cache */
if (!edit->mirror_cache)
edit->mirror_cache= MEM_callocN(sizeof(int)*totpart, "PE mirror cache");
-
+
LOOP_PARTICLES {
key = pa->hair;
psys_mat_hair_to_orco(ob, psmd->mesh_final, psys->part->from, pa, mat);
@@ -841,7 +836,7 @@ static void PE_mirror_particle(Object *ob, Mesh *mesh, ParticleSystem *psys, Par
if (!mpa) {
if (!edit->mirror_cache)
PE_update_mirror_cache(ob, psys);
-
+
if (!edit->mirror_cache)
return; /* something went wrong! */
@@ -967,7 +962,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
LOOP_EDITED_POINTS {
psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles + p, hairmat);
-
+
LOOP_KEYS {
mul_m4_v3(hairmat, key->co);
}
@@ -979,7 +974,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
}
else {
index= BLI_kdtree_find_nearest(edit->emitter_field, key->co, NULL);
-
+
vec=edit->emitter_cosnos +index*6;
nor=vec+3;
@@ -1004,7 +999,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
dist_1st*=1.3333f;
}
}
-
+
invert_m4_m4(hairimat, hairmat);
LOOP_KEYS {
@@ -1015,7 +1010,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
/* force set distances between neighboring keys */
static void PE_apply_lengths(Scene *scene, PTCacheEdit *edit)
{
-
+
ParticleEditSettings *pset=PE_settings(scene);
POINT_P; KEY_K;
float dv1[3];
@@ -1109,11 +1104,9 @@ void recalc_lengths(PTCacheEdit *edit)
}
/* calculate a tree for finding nearest emitter's vertice */
-void recalc_emitter_field(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys)
+void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *ob, ParticleSystem *psys)
{
- Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
- ParticleSystem *psys_eval = psys_eval_get(depsgraph, ob, psys);
- Mesh *mesh = psys_get_modifier(object_eval, psys_eval)->mesh_final;
+ Mesh *mesh = psys_get_modifier(ob, psys)->mesh_final;
PTCacheEdit *edit = psys->edit;
float *vec, *nor;
int i, totface /*, totvert*/;
@@ -1156,7 +1149,7 @@ void recalc_emitter_field(Depsgraph *depsgraph, Object *ob, ParticleSystem *psys
mvert = &mesh->mvert[mface->v4];
add_v3_v3v3(vec, vec, mvert->co);
VECADD(nor, nor, mvert->no);
-
+
mul_v3_fl(vec, 0.25);
}
else
@@ -1181,7 +1174,7 @@ static void PE_update_selection(Depsgraph *depsgraph, Scene *scene, Object *ob,
LOOP_POINTS
point->flag |= PEP_EDIT_RECALC;
- /* flush edit key flag to hair key flag to preserve selection
+ /* flush edit key flag to hair key flag to preserve selection
* on save */
if (edit->psys) LOOP_POINTS {
hkey = edit->psys->particles[p].hair;
@@ -1201,27 +1194,19 @@ static void PE_update_selection(Depsgraph *depsgraph, Scene *scene, Object *ob,
DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE);
}
-void update_world_cos(Depsgraph *depsgraph, Object *ob, PTCacheEdit *edit)
+void update_world_cos(Depsgraph *UNUSED(depsgraph), Object *ob, PTCacheEdit *edit)
{
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
ParticleSystem *psys = edit->psys;
- ParticleSystem *psys_eval = NULL;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
- ParticleSystemModifierData *psmd_eval = NULL;
POINT_P; KEY_K;
float hairmat[4][4];
- if (psmd != NULL) {
- psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name);
- psys_eval = psmd_eval->psys;
- }
-
- if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL)
+ if (psys == 0 || psys->edit == 0 || psmd->mesh_final == NULL)
return;
LOOP_POINTS {
if (!(psys->flag & PSYS_GLOBAL_HAIR))
- psys_mat_hair_to_global(ob_eval, psmd_eval->mesh_final, psys->part->from, psys_eval->particles+p, hairmat);
+ psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles+p, hairmat);
LOOP_KEYS {
copy_v3_v3(key->world_co, key->co);
@@ -1276,7 +1261,7 @@ static void update_velocities(PTCacheEdit *edit)
}
else {
dfra = *(key+1)->time - *(key-1)->time;
-
+
if (dfra <= 0.0f)
continue;
@@ -1464,7 +1449,7 @@ void PARTICLE_OT_select_all(wmOperatorType *ot)
ot->name = "(De)select All";
ot->idname = "PARTICLE_OT_select_all";
ot->description = "(De)select all particles' keys";
-
+
/* api callbacks */
ot->exec = pe_select_all_exec;
ot->poll = PE_poll;
@@ -1524,7 +1509,7 @@ static void select_root(PEData *data, int point_index)
if (point->flag & PEP_HIDE)
return;
-
+
if (data->select_action != SEL_TOGGLE)
select_action_apply(point, key, data->select_action);
else if (key->flag & PEK_SELECT)
@@ -1562,7 +1547,7 @@ void PARTICLE_OT_select_roots(wmOperatorType *ot)
ot->name = "Select Roots";
ot->idname = "PARTICLE_OT_select_roots";
ot->description = "Select roots of all visible particles";
-
+
/* api callbacks */
ot->exec = select_roots_exec;
ot->poll = PE_poll;
@@ -1586,10 +1571,10 @@ static void select_tip(PEData *data, int point_index)
}
key = &point->keys[point->totkey - 1];
-
+
if (point->flag & PEP_HIDE)
return;
-
+
if (data->select_action != SEL_TOGGLE)
select_action_apply(point, key, data->select_action);
else if (key->flag & PEK_SELECT)
@@ -1761,7 +1746,7 @@ void PARTICLE_OT_select_linked(wmOperatorType *ot)
ot->name = "Select Linked";
ot->idname = "PARTICLE_OT_select_linked";
ot->description = "Select nearest particle from mouse pointer";
-
+
/* api callbacks */
ot->exec = select_linked_exec;
ot->invoke = select_linked_invoke;
@@ -1969,7 +1954,7 @@ void PARTICLE_OT_hide(wmOperatorType *ot)
ot->name = "Hide Selected";
ot->idname = "PARTICLE_OT_hide";
ot->description = "Hide selected particles";
-
+
/* api callbacks */
ot->exec = hide_exec;
ot->poll = PE_poll;
@@ -2015,7 +2000,7 @@ void PARTICLE_OT_reveal(wmOperatorType *ot)
ot->name = "Reveal";
ot->idname = "PARTICLE_OT_reveal";
ot->description = "Show hidden particles";
-
+
/* api callbacks */
ot->exec = reveal_exec;
ot->poll = PE_poll;
@@ -2077,7 +2062,7 @@ void PARTICLE_OT_select_less(wmOperatorType *ot)
ot->name = "Select Less";
ot->idname = "PARTICLE_OT_select_less";
ot->description = "Deselect boundary selected keys of each particle";
-
+
/* api callbacks */
ot->exec = select_less_exec;
ot->poll = PE_poll;
@@ -2139,7 +2124,7 @@ void PARTICLE_OT_select_more(wmOperatorType *ot)
ot->name = "Select More";
ot->idname = "PARTICLE_OT_select_more";
ot->description = "Select keys linked to boundary selected keys of each particle";
-
+
/* api callbacks */
ot->exec = select_more_exec;
ot->poll = PE_poll;
@@ -2200,7 +2185,7 @@ static void rekey_particle(PEData *data, int pa_index)
if (point->keys)
MEM_freeN(point->keys);
ekey= point->keys= MEM_callocN(pa->totkey * sizeof(PTCacheEditKey), "Hair re-key edit keys");
-
+
for (k=0, key=pa->hair; k<pa->totkey; k++, key++, ekey++) {
ekey->co= key->co;
ekey->time= &key->time;
@@ -2223,7 +2208,7 @@ static int rekey_exec(bContext *C, wmOperator *op)
data.totrekey= RNA_int_get(op->ptr, "keys_number");
foreach_selected_point(&data, rekey_particle);
-
+
recalc_lengths(data.edit);
PE_update_object(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
@@ -2237,7 +2222,7 @@ void PARTICLE_OT_rekey(wmOperatorType *ot)
ot->name = "Rekey";
ot->idname = "PARTICLE_OT_rekey";
ot->description = "Change the number of keys of selected particles (root and tip keys included)";
-
+
/* api callbacks */
ot->exec = rekey_exec;
ot->invoke = WM_operator_props_popup;
@@ -2275,7 +2260,7 @@ static void rekey_particle_to_time(const bContext *C, Scene *scene, Object *ob,
pa->flag |= PARS_REKEY;
key= new_keys= MEM_dupallocN(pa->hair);
-
+
/* interpolate new keys from old ones (roots stay the same) */
for (k=1, key++; k < pa->totkey; k++, key++) {
state.time= path_time * (float)k / (float)(pa->totkey-1);
@@ -2434,7 +2419,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys)
nhkey->editflag = hkey->editflag;
nhkey->time= hkey->time;
nhkey->weight= hkey->weight;
-
+
nkey->co= nhkey->co;
nkey->time= &nhkey->time;
/* these can be copied from old edit keys */
@@ -2453,7 +2438,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys)
if (point->keys)
MEM_freeN(point->keys);
-
+
pa->hair= new_hkeys;
point->keys= new_keys;
@@ -2499,7 +2484,7 @@ static void subdivide_particle(PEData *data, int pa_index)
nkey= new_keys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(HairKey)), "Hair subdivide keys");
nekey= new_ekeys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(PTCacheEditKey)), "Hair subdivide edit keys");
-
+
key = pa->hair;
endtime= key[pa->totkey-1].time;
@@ -2556,7 +2541,7 @@ static int subdivide_exec(bContext *C, wmOperator *UNUSED(op))
PE_set_data(C, &data);
foreach_point(&data, subdivide_particle);
-
+
recalc_lengths(data.edit);
PE_update_object(data.depsgraph, data.scene, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
@@ -2570,7 +2555,7 @@ void PARTICLE_OT_subdivide(wmOperatorType *ot)
ot->name = "Subdivide";
ot->idname = "PARTICLE_OT_subdivide";
ot->description = "Subdivide selected particles segments (adds keys)";
-
+
/* api callbacks */
ot->exec = subdivide_exec;
ot->poll = PE_hair_poll;
@@ -2605,7 +2590,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
removed= 0;
tree=BLI_kdtree_new(psys->totpart);
-
+
/* insert particles into kd tree */
LOOP_SELECTED_POINTS {
psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat);
@@ -2659,7 +2644,7 @@ void PARTICLE_OT_remove_doubles(wmOperatorType *ot)
ot->name = "Remove Doubles";
ot->idname = "PARTICLE_OT_remove_doubles";
ot->description = "Remove selected particles close enough of others";
-
+
/* api callbacks */
ot->exec = remove_doubles_exec;
ot->poll = PE_hair_poll;
@@ -2820,7 +2805,7 @@ void PARTICLE_OT_delete(wmOperatorType *ot)
ot->name = "Delete";
ot->idname = "PARTICLE_OT_delete";
ot->description = "Delete selected particles or keys";
-
+
/* api callbacks */
ot->exec = delete_exec;
ot->invoke = WM_menu_invoke;
@@ -2914,7 +2899,7 @@ static void PE_mirror_x(
}
edit->totpoint= psys->totpart= newtotpart;
-
+
/* create new elements */
newpa= psys->particles + totpart;
newpoint= edit->points + totpart;
@@ -2989,7 +2974,7 @@ static int mirror_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene= CTX_data_scene(C);
Object *ob= CTX_data_active_object(C);
PTCacheEdit *edit= PE_get_current(scene, ob);
-
+
PE_mirror_x(scene, ob, 0);
update_world_cos(CTX_data_depsgraph(C), ob, edit);
@@ -3005,7 +2990,7 @@ void PARTICLE_OT_mirror(wmOperatorType *ot)
ot->name = "Mirror";
ot->idname = "PARTICLE_OT_mirror";
ot->description = "Duplicate and mirror the selected particles along the local X axis";
-
+
/* api callbacks */
ot->exec = mirror_exec;
ot->poll = PE_hair_poll;
@@ -3064,7 +3049,7 @@ static void brush_cut(PEData *data, int pa_index)
o0= (float)data->mval[0];
o1= (float)data->mval[1];
-
+
xo0= x0 - o0;
xo1= x1 - o1;
@@ -3094,7 +3079,7 @@ static void brush_cut(PEData *data, int pa_index)
dv= v0*v0 + v1*v1;
d= (v0*xo1 - v1*xo0);
-
+
d= dv * rad2 - d*d;
if (d > 0.0f) {
@@ -3327,7 +3312,7 @@ static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[4][4]), float UN
}
static void brush_smooth_get(PEData *data, float mat[4][4], float UNUSED(imat[4][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key)
-{
+{
if (key_index) {
float dvec[3];
@@ -3341,7 +3326,7 @@ static void brush_smooth_get(PEData *data, float mat[4][4], float UNUSED(imat[4]
static void brush_smooth_do(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key)
{
float vec[3], dvec[3];
-
+
if (key_index) {
copy_v3_v3(vec, data->vec);
mul_mat3_m4_v3(imat, vec);
@@ -3350,7 +3335,7 @@ static void brush_smooth_do(PEData *data, float UNUSED(mat[4][4]), float imat[4]
sub_v3_v3v3(dvec, vec, dvec);
mul_v3_fl(dvec, data->smoothfac);
-
+
add_v3_v3(key->co, dvec);
}
@@ -3388,7 +3373,7 @@ static int particle_intersect_mesh(const bContext *C, Scene *scene, Object *ob,
int i, totface, intersect=0;
float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3];
float cur_ipoint[3];
-
+
if (mesh == NULL) {
psys_disable_all(ob);
@@ -3408,7 +3393,7 @@ static int particle_intersect_mesh(const bContext *C, Scene *scene, Object *ob,
/* BMESH_ONLY, deform dm may not have tessface */
BKE_mesh_tessface_ensure(mesh);
-
+
if (pa_minmax==0) {
INIT_MINMAX(p_min, p_max);
@@ -3580,7 +3565,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
mul_m4_v3(imat, co1);
mul_m4_v3(imat, co2);
min_d=2.0;
-
+
/* warning, returns the derived mesh face */
if (particle_intersect_mesh(C, scene, ob, mesh, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) {
if (psys->part->use_modifier_stack && !psmd->mesh_final->runtime.deformed_only) {
@@ -3631,7 +3616,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
/* create tree for interpolation */
if (pset->flag & PE_INTERPOLATE_ADDED && psys->totpart) {
tree=BLI_kdtree_new(psys->totpart);
-
+
for (i=0, pa=psys->particles; i<totpart; i++, pa++) {
psys_particle_on_dm(psmd->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0);
BLI_kdtree_insert(tree, i, cur_co);
@@ -3659,14 +3644,14 @@ static int brush_add(const bContext *C, PEData *data, short number)
if (!(psys->flag & PSYS_GLOBAL_HAIR))
key->flag |= PEK_USE_WCO;
}
-
+
pa->size= 1.0f;
initialize_particle(&sim, pa);
reset_particle(&sim, pa, 0.0, 1.0);
point->flag |= PEP_EDIT_RECALC;
if (pe_x_mirror(ob))
point->flag |= PEP_TAG; /* signal for duplicate */
-
+
framestep= pa->lifetime/(float)(pset->totaddkey-1);
if (tree) {
@@ -3681,7 +3666,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3);
maxd= ptn[maxw-1].dist;
-
+
for (w=0; w<maxw; w++) {
weight[w] = (float)pow(2.0, (double)(-6.0f * ptn[w].dist / maxd));
totw += weight[w];
@@ -3708,10 +3693,10 @@ static int brush_add(const bContext *C, PEData *data, short number)
key3[0].time= thkey->time/ 100.0f;
psys_get_particle_on_path(&sim, ptn[0].index, key3, 0);
mul_v3_fl(key3[0].co, weight[0]);
-
+
/* TODO: interpolating the weight would be nicer */
thkey->weight= (ppa->hair+MIN2(k, ppa->totkey-1))->weight;
-
+
if (maxw>1) {
key3[1].time= key3[0].time;
psys_get_particle_on_path(&sim, ptn[1].index, &key3[1], 0);
@@ -3755,7 +3740,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
MEM_freeN(add_pars);
BLI_rng_free(rng);
-
+
return n;
}
@@ -3785,7 +3770,7 @@ static int brush_edit_init(bContext *C, wmOperator *op)
ARegion *ar= CTX_wm_region(C);
BrushEdit *bedit;
float min[3], max[3];
-
+
if (pset->brushtype < 0)
return 0;
@@ -3916,7 +3901,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
case PE_BRUSH_LENGTH:
{
data.mval= mval;
-
+
data.rad= pe_brush_size_get(scene, brush);
data.growfac= brush->strength / 50.0f;
@@ -4080,7 +4065,7 @@ static int brush_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!brush_edit_init(C, op))
return OPERATOR_CANCELLED;
-
+
brush_edit_apply_event(C, op, event);
WM_event_add_modal_handler(C, op);
@@ -4115,7 +4100,7 @@ void PARTICLE_OT_brush_edit(wmOperatorType *ot)
ot->name = "Brush Edit";
ot->idname = "PARTICLE_OT_brush_edit";
ot->description = "Apply a stroke of brush to the particles";
-
+
/* api callbacks */
ot->exec = brush_edit_exec;
ot->invoke = brush_edit_invoke;
@@ -4139,12 +4124,12 @@ static int shape_cut_poll(bContext *C)
if (PE_hair_poll(C)) {
Scene *scene = CTX_data_scene(C);
ParticleEditSettings *pset = PE_settings(scene);
-
+
if (pset->shape_object && (pset->shape_object->type == OB_MESH)) {
return true;
}
}
-
+
return false;
}
@@ -4156,9 +4141,9 @@ typedef struct PointInsideBVH {
static void point_inside_bvh_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
PointInsideBVH *data = userdata;
-
+
data->bvhdata.raycast_callback(&data->bvhdata, index, ray, hit);
-
+
if (hit->index != -1)
++data->num_hits;
}
@@ -4169,14 +4154,14 @@ static bool shape_cut_test_point(PEData *data, ParticleCacheKey *key)
BVHTreeFromMesh *shape_bvh = &data->shape_bvh;
const float dir[3] = {1.0f, 0.0f, 0.0f};
PointInsideBVH userdata;
-
+
userdata.bvhdata = data->shape_bvh;
userdata.num_hits = 0;
-
+
BLI_bvhtree_ray_cast_all(
shape_bvh->tree, key->co, dir, 0.0f, BVH_RAYCAST_DIST_MAX,
point_inside_bvh_cb, &userdata);
-
+
/* for any point inside a watertight mesh the number of hits is uneven */
return (userdata.num_hits % 2) == 1;
}
@@ -4187,17 +4172,17 @@ static void shape_cut(PEData *data, int pa_index)
Object *ob = data->ob;
ParticleEditSettings *pset = PE_settings(data->scene);
ParticleCacheKey *key;
-
+
bool cut;
float cut_time = 1.0;
int k, totkeys = 1 << pset->draw_step;
-
+
/* don't cut hidden */
if (edit->points[pa_index].flag & PEP_HIDE)
return;
-
+
cut = false;
-
+
/* check if root is inside the cut shape */
key = edit->pathcache[pa_index];
if (!shape_cut_test_point(data, key)) {
@@ -4209,10 +4194,10 @@ static void shape_cut(PEData *data, int pa_index)
BVHTreeRayHit hit;
float dir[3];
float len;
-
+
sub_v3_v3v3(dir, (key+1)->co, key->co);
len = normalize_v3(dir);
-
+
memset(&hit, 0, sizeof(hit));
hit.index = -1;
hit.dist = len;
@@ -4248,32 +4233,32 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
Object *shapeob = pset->shape_object;
int selected = count_selected_keys(scene, edit);
int lock_root = pset->flag & PE_LOCK_FIRST;
-
+
if (!PE_start_edit(edit))
return OPERATOR_CANCELLED;
-
+
/* disable locking temporatily for disconnected hair */
if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR)
pset->flag &= ~PE_LOCK_FIRST;
-
+
if (edit->psys && edit->pathcache) {
PEData data;
int removed;
-
+
PE_set_data(C, &data);
if (!PE_create_shape_tree(&data, shapeob)) {
/* shapeob may not have faces... */
return OPERATOR_CANCELLED;
}
-
+
if (selected)
foreach_selected_point(&data, shape_cut);
else
foreach_point(&data, shape_cut);
-
+
removed = remove_tagged_particles(ob, edit->psys, pe_x_mirror(ob));
recalc_lengths(edit);
-
+
if (removed) {
update_world_cos(depsgraph, ob, edit);
psys_free_path_cache(NULL, edit);
@@ -4282,7 +4267,7 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
else {
PE_update_object(data.depsgraph, scene, ob, 1);
}
-
+
if (edit->psys) {
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
BKE_particle_batch_cache_dirty(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
@@ -4292,12 +4277,12 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
}
-
+
PE_free_shape_tree(&data);
}
-
+
pset->flag |= lock_root;
-
+
return OPERATOR_FINISHED;
}
@@ -4307,7 +4292,7 @@ void PARTICLE_OT_shape_cut(wmOperatorType *ot)
ot->name = "Shape Cut";
ot->idname = "PARTICLE_OT_shape_cut";
ot->description = "Cut hair to conform to the set shape object";
-
+
/* api callbacks */
ot->exec = shape_cut_exec;
ot->poll = shape_cut_poll;
@@ -4362,20 +4347,14 @@ void PE_create_particle_edit(
Depsgraph *depsgraph, Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
{
PTCacheEdit *edit;
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL;
- ParticleSystemModifierData *psmd_eval = NULL;
POINT_P; KEY_K;
ParticleData *pa = NULL;
HairKey *hkey;
int totpoint;
- if (psmd != NULL) {
- psmd_eval = (ParticleSystemModifierData *)modifiers_findByName(ob_eval, psmd->modifier.name);
- }
-
/* no psmd->dm happens in case particle system modifier is not enabled */
- if (!(psys && psmd_eval && psmd_eval->mesh_final) && !cache)
+ if (!(psys && psmd && psmd->mesh_final) && !cache)
return;
if (cache && cache->flag & PTCACHE_DISK_CACHE)
@@ -4505,14 +4484,23 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
if (!is_mode_set) {
PTCacheEdit *edit;
+ /* Particle edit mode requires original object to have all strands
+ * cached. A bit annoying to do update here, but is simpler than
+ * rewriting the while edit mode code.
+ */
+ ob->id.recalc |= (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ BKE_scene_graph_update_tagged(depsgraph, CTX_data_main(C));
+ BKE_object_eval_transform_all(depsgraph, scene, ob);
+ BKE_object_handle_data_update(depsgraph, scene, ob);
ob->mode |= mode_flag;
+
edit= PE_create_current(depsgraph, scene, ob);
-
+
/* mesh may have changed since last entering editmode.
* note, this may have run before if the edit data was just created, so could avoid this and speed up a little */
if (edit && edit->psys)
recalc_emitter_field(depsgraph, ob, edit->psys);
-
+
toggle_particle_cursor(C, 1);
WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL);
}
@@ -4539,7 +4527,7 @@ void PARTICLE_OT_particle_edit_toggle(wmOperatorType *ot)
ot->name = "Particle Edit Toggle";
ot->idname = "PARTICLE_OT_particle_edit_toggle";
ot->description = "Toggle particle edit mode";
-
+
/* api callbacks */
ot->exec = particle_edit_toggle_exec;
ot->poll = particle_edit_toggle_poll;
@@ -4555,7 +4543,7 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob= CTX_data_active_object(C);
ParticleSystem *psys = psys_get_current(ob);
-
+
if (psys->edit) {
if (psys->edit->edited || 1) {
PE_free_ptcache_edit(psys->edit);
@@ -4594,7 +4582,7 @@ void PARTICLE_OT_edited_clear(wmOperatorType *ot)
ot->name = "Clear Edited";
ot->idname = "PARTICLE_OT_edited_clear";
ot->description = "Undo all edition performed on the particle system";
-
+
/* api callbacks */
ot->exec = clear_edited_exec;
ot->poll = particle_edit_toggle_poll;
diff --git a/source/blender/editors/physics/particle_edit_undo.c b/source/blender/editors/physics/particle_edit_undo.c
index 5199b1c54fa..6576d692f70 100644
--- a/source/blender/editors/physics/particle_edit_undo.c
+++ b/source/blender/editors/physics/particle_edit_undo.c
@@ -233,7 +233,7 @@ static bool particle_undosys_poll(struct bContext *C)
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
PTCacheEdit *edit = PE_get_current(scene, ob);
-
+
return (edit != NULL);
}
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 21edcdc9e00..fbccdcfcdba 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -50,6 +50,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -88,10 +89,10 @@ static int particle_system_add_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
object_add_particle_system(scene, ob, NULL);
-
+
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -101,11 +102,11 @@ void OBJECT_OT_particle_system_add(wmOperatorType *ot)
ot->name = "Add Particle System Slot";
ot->idname = "OBJECT_OT_particle_system_add";
ot->description = "Add a particle system";
-
+
/* api callbacks */
ot->poll = ED_operator_object_active_editable;
ot->exec = particle_system_add_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -136,7 +137,7 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -146,7 +147,7 @@ void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
ot->name = "Remove Particle System Slot";
ot->idname = "OBJECT_OT_particle_system_remove";
ot->description = "Remove the selected particle system";
-
+
/* api callbacks */
ot->poll = ED_operator_object_active_editable;
ot->exec = particle_system_remove_exec;
@@ -194,7 +195,7 @@ static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -204,7 +205,7 @@ void PARTICLE_OT_new(wmOperatorType *ot)
ot->name = "New Particle Settings";
ot->idname = "PARTICLE_OT_new";
ot->description = "Add new particle settings";
-
+
/* api callbacks */
ot->exec = new_particle_settings_exec;
ot->poll = psys_poll;
@@ -242,7 +243,7 @@ static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -252,7 +253,7 @@ void PARTICLE_OT_new_target(wmOperatorType *ot)
ot->name = "New Particle Target";
ot->idname = "PARTICLE_OT_new_target";
ot->description = "Add a new particle target";
-
+
/* api callbacks */
ot->exec = new_particle_target_exec;
@@ -290,7 +291,7 @@ static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -300,7 +301,7 @@ void PARTICLE_OT_target_remove(wmOperatorType *ot)
ot->name = "Remove Particle Target";
ot->idname = "PARTICLE_OT_target_remove";
ot->description = "Remove the selected particle target";
-
+
/* api callbacks */
ot->exec = remove_particle_target_exec;
@@ -319,7 +320,7 @@ static int target_move_up_exec(bContext *C, wmOperator *UNUSED(op))
if (!psys)
return OPERATOR_CANCELLED;
-
+
pt = psys->targets.first;
for (; pt; pt=pt->next) {
if (pt->flag & PTARGET_CURRENT && pt->prev) {
@@ -331,7 +332,7 @@ static int target_move_up_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -340,9 +341,9 @@ void PARTICLE_OT_target_move_up(wmOperatorType *ot)
ot->name = "Move Up Target";
ot->idname = "PARTICLE_OT_target_move_up";
ot->description = "Move particle target up in the list";
-
+
ot->exec = target_move_up_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -369,7 +370,7 @@ static int target_move_down_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -378,9 +379,9 @@ void PARTICLE_OT_target_move_down(wmOperatorType *ot)
ot->name = "Move Down Target";
ot->idname = "PARTICLE_OT_target_move_down";
ot->description = "Move particle target down in the list";
-
+
ot->exec = target_move_down_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -407,7 +408,7 @@ static int dupliob_move_up_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -416,9 +417,9 @@ void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot)
ot->name = "Move Up Dupli Object";
ot->idname = "PARTICLE_OT_dupliob_move_up";
ot->description = "Move dupli object up in the list";
-
+
ot->exec = dupliob_move_up_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -446,7 +447,7 @@ static int copy_particle_dupliob_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -456,7 +457,7 @@ void PARTICLE_OT_dupliob_copy(wmOperatorType *ot)
ot->name = "Copy Particle Dupliob";
ot->idname = "PARTICLE_OT_dupliob_copy";
ot->description = "Duplicate the current dupliobject";
-
+
/* api callbacks */
ot->exec = copy_particle_dupliob_exec;
@@ -489,7 +490,7 @@ static int remove_particle_dupliob_exec(bContext *C, wmOperator *UNUSED(op))
dw->flag |= PART_DUPLIW_CURRENT;
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -499,7 +500,7 @@ void PARTICLE_OT_dupliob_remove(wmOperatorType *ot)
ot->name = "Remove Particle Dupliobject";
ot->idname = "PARTICLE_OT_dupliob_remove";
ot->description = "Remove the selected dupliobject";
-
+
/* api callbacks */
ot->exec = remove_particle_dupliob_exec;
@@ -529,7 +530,7 @@ static int dupliob_move_down_exec(bContext *C, wmOperator *UNUSED(op))
break;
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -538,9 +539,9 @@ void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot)
ot->name = "Move Down Dupli Object";
ot->idname = "PARTICLE_OT_dupliob_move_down";
ot->description = "Move dupli object down in the list";
-
+
ot->exec = dupliob_move_down_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
@@ -566,7 +567,7 @@ static void disconnect_hair(
if (!psys->part || psys->part->type != PART_HAIR)
return;
-
+
edit = psys->edit;
point= edit ? edit->points : NULL;
@@ -580,7 +581,7 @@ static void disconnect_hair(
for (k=0, key=pa->hair; k<pa->totkey; k++, key++) {
mul_m4_v3(hairmat, key->co);
-
+
if (ekey) {
ekey->flag &= ~PEK_USE_WCO;
ekey++;
@@ -630,9 +631,9 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
ot->name = "Disconnect Hair";
ot->description = "Disconnect hair from the emitter mesh";
ot->idname = "PARTICLE_OT_disconnect_hair";
-
+
ot->exec = disconnect_hair_exec;
-
+
/* flags */
ot->flag = OPTYPE_UNDO; /* No REGISTER, redo does not work due to missing update, see T47750. */
@@ -667,14 +668,14 @@ static bool remap_hair_emitter(
return false;
if (!target_psys->part || target_psys->part->type != PART_HAIR)
return false;
-
+
edit_point = target_edit ? target_edit->points : NULL;
-
+
invert_m4_m4(from_ob_imat, ob->obmat);
invert_m4_m4(to_ob_imat, target_ob->obmat);
invert_m4_m4(from_imat, from_mat);
invert_m4_m4(to_imat, to_mat);
-
+
if (target_psmd->mesh_final->runtime.deformed_only) {
/* we don't want to mess up target_psmd->dm when converting to global coordinates below */
mesh = target_psmd->mesh_final;
@@ -744,7 +745,7 @@ static bool remap_hair_emitter(
if (mface) {
float v[4][3];
-
+
mf = &mface[nearest.index];
copy_v3_v3(v[0], mvert[mf->v1].co);
@@ -780,7 +781,7 @@ static bool remap_hair_emitter(
HairKey *key, *tkey;
float hairmat[4][4], imat[4][4];
float offset[3];
-
+
if (to_global)
copy_m4_m4(imat, target_ob->obmat);
else {
@@ -789,41 +790,41 @@ static bool remap_hair_emitter(
invert_m4_m4(imat, hairmat);
}
mul_m4_m4m4(imat, imat, to_imat);
-
+
/* offset in world space */
sub_v3_v3v3(offset, nearest.co, from_co);
-
+
if (edit_point) {
for (k=0, key=pa->hair, tkey=tpa->hair, ekey = edit_point->keys; k<tpa->totkey; k++, key++, tkey++, ekey++) {
float co_orig[3];
-
+
if (from_global)
mul_v3_m4v3(co_orig, from_ob_imat, key->co);
else
mul_v3_m4v3(co_orig, from_ob_imat, key->world_co);
mul_m4_v3(from_mat, co_orig);
-
+
add_v3_v3v3(tkey->co, co_orig, offset);
-
+
mul_m4_v3(imat, tkey->co);
-
+
ekey->flag |= PEK_USE_WCO;
}
-
+
edit_point++;
}
else {
for (k=0, key=pa->hair, tkey=tpa->hair; k<tpa->totkey; k++, key++, tkey++) {
float co_orig[3];
-
+
if (from_global)
mul_v3_m4v3(co_orig, from_ob_imat, key->co);
else
mul_v3_m4v3(co_orig, from_ob_imat, key->world_co);
mul_m4_v3(from_mat, co_orig);
-
+
add_v3_v3v3(tkey->co, co_orig, offset);
-
+
mul_m4_v3(imat, tkey->co);
}
}
@@ -845,15 +846,15 @@ static bool connect_hair(
Object *ob, ParticleSystem *psys)
{
bool ok;
-
+
if (!psys)
return false;
-
+
ok = remap_hair_emitter(
depsgraph, scene, ob, psys, ob, psys, psys->edit,
ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
psys->flag &= ~PSYS_GLOBAL_HAIR;
-
+
return ok;
}
@@ -896,9 +897,9 @@ void PARTICLE_OT_connect_hair(wmOperatorType *ot)
ot->name = "Connect Hair";
ot->description = "Connect hair to the emitter mesh";
ot->idname = "PARTICLE_OT_connect_hair";
-
+
ot->exec = connect_hair_exec;
-
+
/* flags */
ot->flag = OPTYPE_UNDO; /* No REGISTER, redo does not work due to missing update, see T47750. */
@@ -920,17 +921,17 @@ static void copy_particle_edit(
ParticleData *pa;
KEY_K;
POINT_P;
-
+
if (!edit_from)
return;
-
+
edit = MEM_dupallocN(edit_from);
edit->psys = psys;
psys->edit = edit;
-
+
edit->pathcache = NULL;
BLI_listbase_clear(&edit->pathcachebufs);
-
+
edit->emitter_field = NULL;
edit->emitter_cosnos = NULL;
@@ -938,7 +939,7 @@ static void copy_particle_edit(
pa = psys->particles;
LOOP_POINTS {
HairKey *hkey = pa->hair;
-
+
point->keys= MEM_dupallocN(point->keys);
LOOP_KEYS {
key->co = hkey->co;
@@ -948,17 +949,17 @@ static void copy_particle_edit(
key->flag |= PEK_USE_WCO;
hkey->editflag |= PEK_USE_WCO;
}
-
+
hkey++;
}
-
+
pa++;
}
update_world_cos(depsgraph, ob, edit);
-
+
UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col);
UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col);
-
+
recalc_lengths(edit);
recalc_emitter_field(depsgraph, ob, psys);
PE_update_object(depsgraph, scene, ob, true);
@@ -967,15 +968,15 @@ static void copy_particle_edit(
static void remove_particle_systems_from_object(Object *ob_to)
{
ModifierData *md, *md_next;
-
+
if (ob_to->type != OB_MESH)
return;
if (!ob_to->data || ID_IS_LINKED(ob_to->data))
return;
-
+
for (md = ob_to->modifiers.first; md; md = md_next) {
md_next = md->next;
-
+
/* remove all particle system modifiers as well,
* these need to sync to the particle system list
*/
@@ -984,7 +985,7 @@ static void remove_particle_systems_from_object(Object *ob_to)
modifier_free(md);
}
}
-
+
BKE_object_free_particlesystems(ob_to);
}
@@ -1010,7 +1011,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
return false;
if (!ob_to->data || ID_IS_LINKED(ob_to->data))
return false;
-
+
/* For remapping we need a valid DM.
* Because the modifiers are appended at the end it's safe to use
* the final DM of the object without particles.
@@ -1022,9 +1023,9 @@ static bool copy_particle_systems_to_object(const bContext *C,
#define PSYS_FROM_FIRST (single_psys_from ? single_psys_from : ob_from->particlesystem.first)
#define PSYS_FROM_NEXT(cur) (single_psys_from ? NULL : (cur)->next)
totpsys = single_psys_from ? 1 : BLI_listbase_count(&ob_from->particlesystem);
-
+
tmp_psys = MEM_mallocN(sizeof(ParticleSystem*) * totpsys, "temporary particle system array");
-
+
cdmask = 0;
for (psys_from = PSYS_FROM_FIRST, i = 0;
psys_from;
@@ -1032,17 +1033,17 @@ static bool copy_particle_systems_to_object(const bContext *C,
{
psys = BKE_object_copy_particlesystem(psys_from, 0);
tmp_psys[i] = psys;
-
+
if (psys_start == NULL)
psys_start = psys;
-
+
cdmask |= psys_emitter_customdata_mask(psys);
}
/* to iterate source and target psys in sync,
* we need to know where the newly added psys start
*/
psys_start = totpsys > 0 ? tmp_psys[0] : NULL;
-
+
/* get the DM (psys and their modifiers have not been appended yet) */
/* TODO(Sybren): use mesh_eval instead */
DerivedMesh *final_dm = mesh_get_derived_final(depsgraph, scene, ob_to, cdmask);
@@ -1055,21 +1056,21 @@ static bool copy_particle_systems_to_object(const bContext *C,
++i, psys_from = PSYS_FROM_NEXT(psys_from))
{
ParticleSystemModifierData *psmd;
-
+
psys = tmp_psys[i];
-
+
/* append to the object */
BLI_addtail(&ob_to->particlesystem, psys);
-
+
/* add a particle system modifier for each system */
md = modifier_new(eModifierType_ParticleSystem);
psmd = (ParticleSystemModifierData *)md;
/* push on top of the stack, no use trying to reproduce old stack order */
BLI_addtail(&ob_to->modifiers, md);
-
+
BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", i);
modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
-
+
psmd->psys = psys;
BKE_id_copy_ex(
NULL, &final_mesh->id, (ID **)&psmd->mesh_final,
@@ -1092,7 +1093,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
}
}
MEM_freeN(tmp_psys);
-
+
/* note: do this after creating DM copies for all the particle system modifiers,
* the remapping otherwise makes final_dm invalid!
*/
@@ -1101,7 +1102,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
psys = psys->next, psys_from = PSYS_FROM_NEXT(psys_from), ++i)
{
float (*from_mat)[4], (*to_mat)[4];
-
+
switch (space) {
case PAR_COPY_SPACE_OBJECT:
from_mat = I;
@@ -1122,14 +1123,14 @@ static bool copy_particle_systems_to_object(const bContext *C,
depsgraph, scene, ob_from, psys_from, ob_to, psys, psys->edit,
from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
}
-
+
/* tag for recalc */
// psys->recalc |= PSYS_RECALC_RESET;
}
-
+
#undef PSYS_FROM_FIRST
#undef PSYS_FROM_NEXT
-
+
DEG_id_tag_update(&ob_to->id, OB_RECALC_DATA);
WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to);
return true;
@@ -1140,11 +1141,11 @@ static int copy_particle_systems_poll(bContext *C)
Object *ob;
if (!ED_operator_object_active_editable(C))
return false;
-
+
ob = ED_object_active_context(C);
if (BLI_listbase_is_empty(&ob->particlesystem))
return false;
-
+
return true;
}
@@ -1156,10 +1157,10 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *ob_from = ED_object_active_context(C);
ParticleSystem *psys_from = use_active ? CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data : NULL;
-
+
int changed_tot = 0;
int fail = 0;
-
+
CTX_DATA_BEGIN (C, Object *, ob_to, selected_editable_objects)
{
if (ob_from != ob_to) {
@@ -1172,19 +1173,19 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op)
changed = true;
else
fail++;
-
+
if (changed)
changed_tot++;
}
}
CTX_DATA_END;
-
+
if ((changed_tot == 0 && fail == 0) || fail) {
BKE_reportf(op->reports, RPT_ERROR,
"Copy particle systems to selected: %d done, %d failed",
changed_tot, fail);
}
-
+
return OPERATOR_FINISHED;
}
@@ -1195,17 +1196,17 @@ void PARTICLE_OT_copy_particle_systems(wmOperatorType *ot)
{PAR_COPY_SPACE_WORLD, "WORLD", 0, "World", "Copy in world space"},
{0, NULL, 0, NULL, NULL}
};
-
+
ot->name = "Copy Particle Systems";
ot->description = "Copy particle systems from the active object to selected objects";
ot->idname = "PARTICLE_OT_copy_particle_systems";
-
+
ot->poll = copy_particle_systems_poll;
ot->exec = copy_particle_systems_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_enum(ot->srna, "space", space_items, PAR_COPY_SPACE_OBJECT, "Space", "Space transform for copying from one object to another");
RNA_def_boolean(ot->srna, "remove_target_particles", true, "Remove Target Particles", "Remove particle systems on the target objects");
RNA_def_boolean(ot->srna, "use_active", false, "Use Active", "Use the active particle system from the context");
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index df8b4432e8b..130dcba060d 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -39,7 +39,7 @@
/* types */
#include "DNA_action_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_fluidsim_types.h"
+#include "DNA_object_fluidsim_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
@@ -84,12 +84,12 @@ static float get_fluid_viscosity(FluidsimSettings *settings)
static float get_fluid_rate(FluidsimSettings *settings)
{
float rate = 1.0f; /* default rate if not animated... */
-
+
rate = settings->animRate;
-
+
if (rate < 0.0f)
rate = 0.0f;
-
+
return rate;
}
@@ -111,10 +111,10 @@ static float get_fluid_size_m(Scene *scene, Object *domainob, FluidsimSettings *
else {
float dim[3];
float longest_axis;
-
+
BKE_object_dimensions_get(domainob, dim);
longest_axis = max_fff(dim[0], dim[1], dim[2]);
-
+
return longest_axis * scene->unit.scale_length;
}
}
@@ -140,9 +140,9 @@ void fluidsimGetGeometryObjFilename(Object *ob, char *dst) //, char *srcname)
typedef struct FluidAnimChannels {
int length;
-
+
double aniFrameTime;
-
+
float *timeAtFrame;
float *DomainTime;
float *DomainGravity;
@@ -151,21 +151,21 @@ typedef struct FluidAnimChannels {
typedef struct FluidObject {
struct FluidObject *next, *prev;
-
+
struct Object *object;
-
+
float *Translation;
float *Rotation;
float *Scale;
float *Active;
-
+
float *InitialVelocity;
-
+
float *AttractforceStrength;
float *AttractforceRadius;
float *VelocityforceStrength;
float *VelocityforceRadius;
-
+
float *VertexCache;
int numVerts, numTris;
} FluidObject;
@@ -177,10 +177,10 @@ typedef struct FluidObject {
// simplify channels before printing
// for API this is done anyway upon init
#if 0
-static void fluidsimPrintChannel(FILE *file, float *channel, int paramsize, char *str, int entries)
-{
+static void fluidsimPrintChannel(FILE *file, float *channel, int paramsize, char *str, int entries)
+{
int i, j;
- int channelSize = paramsize;
+ int channelSize = paramsize;
if (entries == 3) {
elbeemSimplifyChannelVec3(channel, &channelSize);
@@ -222,11 +222,11 @@ static void fluidsimPrintChannel(FILE *file, float *channel, int paramsize, char
static void init_time(FluidsimSettings *domainSettings, FluidAnimChannels *channels)
{
int i;
-
+
channels->timeAtFrame = MEM_callocN((channels->length + 1) * sizeof(float), "timeAtFrame channel");
-
+
channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1
-
+
for (i=2; i <= channels->length; i++) {
channels->timeAtFrame[i] = channels->timeAtFrame[i - 1] + (float)channels->aniFrameTime;
}
@@ -256,25 +256,25 @@ static void set_vertex_channel(Depsgraph *depsgraph, float *channel, float time,
int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd);
int framesize = (3*fobj->numVerts) + 1;
int j;
-
+
if (channel == NULL)
return;
-
+
initElbeemMesh(depsgraph, scene, ob, &numVerts, &verts, &numTris, &tris, 1, modifierIndex);
-
+
/* don't allow mesh to change number of verts in anim sequence */
if (numVerts != fobj->numVerts) {
MEM_freeN(channel);
channel = NULL;
return;
}
-
+
/* fill frame of channel with vertex locations */
for (j=0; j < (3*numVerts); j++) {
channel[i*framesize + j] = verts[j];
}
channel[i*framesize + framesize-1] = time;
-
+
MEM_freeN(verts);
MEM_freeN(tris);
}
@@ -296,7 +296,7 @@ static void free_domain_channels(FluidAnimChannels *channels)
static void free_all_fluidobject_channels(ListBase *fobjects)
{
FluidObject *fobj;
-
+
for (fobj=fobjects->first; fobj; fobj=fobj->next) {
if (fobj->Translation) {
MEM_freeN(fobj->Translation);
@@ -310,7 +310,7 @@ static void free_all_fluidobject_channels(ListBase *fobjects)
MEM_freeN(fobj->InitialVelocity);
fobj->InitialVelocity = NULL;
}
-
+
if (fobj->AttractforceStrength) {
MEM_freeN(fobj->AttractforceStrength);
fobj->AttractforceStrength = NULL;
@@ -321,7 +321,7 @@ static void free_all_fluidobject_channels(ListBase *fobjects)
MEM_freeN(fobj->VelocityforceRadius);
fobj->VelocityforceRadius = NULL;
}
-
+
if (fobj->VertexCache) {
MEM_freeN(fobj->VertexCache);
fobj->VertexCache = NULL;
@@ -341,105 +341,105 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
/* init time values (assuming that time moves at a constant speed; may be overridden later) */
init_time(domainSettings, channels);
-
+
/* allocate domain animation channels */
channels->DomainGravity = MEM_callocN(length * (CHANNEL_VEC+1) * sizeof(float), "channel DomainGravity");
channels->DomainViscosity = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainViscosity");
channels->DomainTime = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime");
-
+
/* allocate fluid objects */
for (base = FIRSTBASE(view_layer); base; base = base->next) {
Object *ob = base->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
-
+
if (fluidmd) {
FluidObject *fobj = MEM_callocN(sizeof(FluidObject), "Fluid Object");
fobj->object = ob;
-
+
if (ELEM(fluidmd->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE)) {
BLI_addtail(fobjects, fobj);
continue;
}
-
+
fobj->Translation = MEM_callocN(length * (CHANNEL_VEC+1) * sizeof(float), "fluidobject Translation");
fobj->Rotation = MEM_callocN(length * (CHANNEL_VEC+1) * sizeof(float), "fluidobject Rotation");
fobj->Scale = MEM_callocN(length * (CHANNEL_VEC+1) * sizeof(float), "fluidobject Scale");
fobj->Active = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject Active");
fobj->InitialVelocity = MEM_callocN(length * (CHANNEL_VEC+1) * sizeof(float), "fluidobject InitialVelocity");
-
+
if (fluidmd->fss->type == OB_FLUIDSIM_CONTROL) {
fobj->AttractforceStrength = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject AttractforceStrength");
fobj->AttractforceRadius = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject AttractforceRadius");
fobj->VelocityforceStrength = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject VelocityforceStrength");
fobj->VelocityforceRadius = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "fluidobject VelocityforceRadius");
}
-
+
if (fluid_is_animated_mesh(fluidmd->fss)) {
float *verts=NULL;
int *tris=NULL, modifierIndex = BLI_findindex(&ob->modifiers, (ModifierData *)fluidmd);
initElbeemMesh(depsgraph, scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex);
fobj->VertexCache = MEM_callocN(length *((fobj->numVerts*CHANNEL_VEC)+1) * sizeof(float), "fluidobject VertexCache");
-
+
MEM_freeN(verts);
MEM_freeN(tris);
}
-
+
BLI_addtail(fobjects, fobj);
}
}
-
+
/* now we loop over the frames and fill the allocated channels with data */
for (i=0; i < channels->length; i++) {
FluidObject *fobj;
float viscosity, gravity[3];
float timeAtFrame, time;
-
+
eval_time = domainSettings->bakeStart + i;
-
+
/* XXX: This can't be used due to an anim sys optimization that ignores recalc object animation,
* leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
* --> BKE_animsys_evaluate_all_animation(G.main, eval_time);
* This doesn't work with drivers:
* --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
*/
-
- /* Modifying the global scene isn't nice, but we can do it in
+
+ /* Modifying the global scene isn't nice, but we can do it in
* this part of the process before a threaded job is created */
scene->r.cfra = (int)eval_time;
ED_update_for_newframe(CTX_data_main(C), depsgraph);
-
+
/* now scene data should be current according to animation system, so we fill the channels */
-
+
/* Domain time */
// TODO: have option for not running sim, time mangling, in which case second case comes in handy
if (channels->DomainTime) {
time = get_fluid_rate(domainSettings) * (float)channels->aniFrameTime;
timeAtFrame = channels->timeAtFrame[i] + time;
-
+
channels->timeAtFrame[i+1] = timeAtFrame;
set_channel(channels->DomainTime, i, &time, i, CHANNEL_FLOAT);
}
else {
timeAtFrame = channels->timeAtFrame[i+1];
}
-
+
/* Domain properties - gravity/viscosity */
get_fluid_gravity(gravity, scene, domainSettings);
set_channel(channels->DomainGravity, timeAtFrame, gravity, i, CHANNEL_VEC);
viscosity = get_fluid_viscosity(domainSettings);
set_channel(channels->DomainViscosity, timeAtFrame, &viscosity, i, CHANNEL_FLOAT);
-
+
/* object movement */
for (fobj=fobjects->first; fobj; fobj=fobj->next) {
Object *ob = fobj->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
float active= (float) ((fluidmd->fss->flag & OB_FLUIDSIM_ACTIVE) > 0 ? 1 : 0);
float rot_d[3] = {0.f, 0.f, 0.f}, old_rot[3] = {0.f, 0.f, 0.f};
-
+
if (ELEM(fluidmd->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE))
continue;
-
+
/* init euler rotation values and convert to elbeem format */
/* get the rotation from ob->obmat rather than ob->rot to account for parent animations */
if (i) {
@@ -449,7 +449,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
mat4_to_compatible_eulO(rot_d, old_rot, 0, ob->obmat);
mul_v3_fl(rot_d, -180.0f / (float)M_PI);
-
+
set_channel(fobj->Translation, timeAtFrame, ob->loc, i, CHANNEL_VEC);
set_channel(fobj->Rotation, timeAtFrame, rot_d, i, CHANNEL_VEC);
set_channel(fobj->Scale, timeAtFrame, ob->size, i, CHANNEL_VEC);
@@ -457,14 +457,14 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
set_channel(fobj->InitialVelocity, timeAtFrame, &fluidmd->fss->iniVelx, i, CHANNEL_VEC);
// printf("Active: %f, Frame: %f\n", active, timeAtFrame);
-
+
if (fluidmd->fss->type == OB_FLUIDSIM_CONTROL) {
set_channel(fobj->AttractforceStrength, timeAtFrame, &fluidmd->fss->attractforceStrength, i, CHANNEL_FLOAT);
set_channel(fobj->AttractforceRadius, timeAtFrame, &fluidmd->fss->attractforceRadius, i, CHANNEL_FLOAT);
set_channel(fobj->VelocityforceStrength, timeAtFrame, &fluidmd->fss->velocityforceStrength, i, CHANNEL_FLOAT);
set_channel(fobj->VelocityforceRadius, timeAtFrame, &fluidmd->fss->velocityforceRadius, i, CHANNEL_FLOAT);
}
-
+
if (fluid_is_animated_mesh(fluidmd->fss)) {
set_vertex_channel(depsgraph, fobj->VertexCache, timeAtFrame, scene, fobj, i);
}
@@ -476,72 +476,72 @@ static void export_fluid_objects(const bContext *C, ListBase *fobjects, Scene *s
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
FluidObject *fobj;
-
+
for (fobj=fobjects->first; fobj; fobj=fobj->next) {
Object *ob = fobj->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd);
-
+
float *verts=NULL;
int *tris=NULL;
int numVerts=0, numTris=0;
bool deform = fluid_is_animated_mesh(fluidmd->fss);
-
+
elbeemMesh fsmesh;
-
+
if (ELEM(fluidmd->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE))
continue;
-
+
elbeemResetMesh(&fsmesh);
-
+
fsmesh.type = fluidmd->fss->type;
fsmesh.name = ob->id.name;
-
+
initElbeemMesh(depsgraph, scene, ob, &numVerts, &verts, &numTris, &tris, 0, modifierIndex);
-
+
fsmesh.numVertices = numVerts;
fsmesh.numTriangles = numTris;
fsmesh.vertices = verts;
fsmesh.triangles = tris;
-
- fsmesh.channelSizeTranslation =
- fsmesh.channelSizeRotation =
- fsmesh.channelSizeScale =
- fsmesh.channelSizeInitialVel =
+
+ fsmesh.channelSizeTranslation =
+ fsmesh.channelSizeRotation =
+ fsmesh.channelSizeScale =
+ fsmesh.channelSizeInitialVel =
fsmesh.channelSizeActive = length;
-
+
fsmesh.channelTranslation = fobj->Translation;
fsmesh.channelRotation = fobj->Rotation;
fsmesh.channelScale = fobj->Scale;
fsmesh.channelActive = fobj->Active;
-
+
if ( ELEM(fsmesh.type, OB_FLUIDSIM_FLUID, OB_FLUIDSIM_INFLOW)) {
fsmesh.channelInitialVel = fobj->InitialVelocity;
fsmesh.localInivelCoords = ((fluidmd->fss->typeFlags & OB_FSINFLOW_LOCALCOORD) ? 1 : 0);
}
-
+
if (fluidmd->fss->typeFlags & OB_FSBND_NOSLIP)
fsmesh.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP;
else if (fluidmd->fss->typeFlags & OB_FSBND_PARTSLIP)
fsmesh.obstacleType = FLUIDSIM_OBSTACLE_PARTSLIP;
else if (fluidmd->fss->typeFlags & OB_FSBND_FREESLIP)
fsmesh.obstacleType = FLUIDSIM_OBSTACLE_FREESLIP;
-
+
fsmesh.obstaclePartslip = fluidmd->fss->partSlipValue;
fsmesh.volumeInitType = fluidmd->fss->volumeInitType;
fsmesh.obstacleImpactFactor = fluidmd->fss->surfaceSmoothing; // misused value
-
+
if (fsmesh.type == OB_FLUIDSIM_CONTROL) {
fsmesh.cpsTimeStart = fluidmd->fss->cpsTimeStart;
fsmesh.cpsTimeEnd = fluidmd->fss->cpsTimeEnd;
fsmesh.cpsQuality = fluidmd->fss->cpsQuality;
fsmesh.obstacleType = (fluidmd->fss->flag & OB_FLUIDSIM_REVERSE);
-
- fsmesh.channelSizeAttractforceRadius =
- fsmesh.channelSizeVelocityforceStrength =
- fsmesh.channelSizeVelocityforceRadius =
+
+ fsmesh.channelSizeAttractforceRadius =
+ fsmesh.channelSizeVelocityforceStrength =
+ fsmesh.channelSizeVelocityforceRadius =
fsmesh.channelSizeAttractforceStrength = length;
-
+
fsmesh.channelAttractforceStrength = fobj->AttractforceStrength;
fsmesh.channelAttractforceRadius = fobj->AttractforceRadius;
fsmesh.channelVelocityforceStrength = fobj->VelocityforceStrength;
@@ -549,28 +549,28 @@ static void export_fluid_objects(const bContext *C, ListBase *fobjects, Scene *s
}
else {
fsmesh.channelAttractforceStrength =
- fsmesh.channelAttractforceRadius =
- fsmesh.channelVelocityforceStrength =
- fsmesh.channelVelocityforceRadius = NULL;
+ fsmesh.channelAttractforceRadius =
+ fsmesh.channelVelocityforceStrength =
+ fsmesh.channelVelocityforceRadius = NULL;
}
-
+
/* animated meshes */
if (deform) {
fsmesh.channelSizeVertices = length;
fsmesh.channelVertices = fobj->VertexCache;
-
+
/* remove channels */
- fsmesh.channelTranslation =
- fsmesh.channelRotation =
+ fsmesh.channelTranslation =
+ fsmesh.channelRotation =
fsmesh.channelScale = NULL;
-
+
/* Override user settings, only noslip is supported here! */
if (fsmesh.type != OB_FLUIDSIM_CONTROL)
fsmesh.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP;
}
-
+
elbeemAddMesh(&fsmesh);
-
+
if (verts) MEM_freeN(verts);
if (tris) MEM_freeN(tris);
}
@@ -589,7 +589,7 @@ static int fluid_validate_scene(ReportList *reports, ViewLayer *view_layer, Obje
/* only find objects with fluid modifiers */
if (!fluidmdtmp || ob->type != OB_MESH) continue;
-
+
if (fluidmdtmp->fss->type == OB_FLUIDSIM_DOMAIN) {
/* if no initial domain object given, find another potential domain */
if (!fsDomain) {
@@ -601,11 +601,11 @@ static int fluid_validate_scene(ReportList *reports, ViewLayer *view_layer, Obje
return 0;
}
}
-
+
/* count number of objects needed for animation channels */
if ( !ELEM(fluidmdtmp->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE) )
channelObjCount++;
-
+
/* count number of fluid input objects */
if (ELEM(fluidmdtmp->fss->type, OB_FLUIDSIM_FLUID, OB_FLUIDSIM_INFLOW))
fluidInputCount++;
@@ -613,22 +613,22 @@ static int fluid_validate_scene(ReportList *reports, ViewLayer *view_layer, Obje
if (newdomain)
fsDomain = newdomain;
-
+
if (!fsDomain) {
BKE_report(reports, RPT_ERROR, "No domain object found");
return 0;
}
-
+
if (channelObjCount >= 255) {
BKE_report(reports, RPT_ERROR, "Cannot bake with more than 256 objects");
return 0;
}
-
+
if (fluidInputCount == 0) {
BKE_report(reports, RPT_ERROR, "No fluid input objects in the scene");
return 0;
}
-
+
return 1;
}
@@ -722,8 +722,8 @@ static int fluidbake_breakjob(void *customdata)
if (fb->stop && *(fb->stop))
return 1;
-
- /* this is not nice yet, need to make the jobs list template better
+
+ /* this is not nice yet, need to make the jobs list template better
* for identifying/acting upon various different jobs */
/* but for now we'll reuse the render break... */
return (G.is_break);
@@ -733,7 +733,7 @@ static int fluidbake_breakjob(void *customdata)
static void fluidbake_updatejob(void *customdata, float progress)
{
FluidBakeJob *fb= (FluidBakeJob *)customdata;
-
+
*(fb->do_update) = true;
*(fb->progress) = progress;
}
@@ -741,13 +741,13 @@ static void fluidbake_updatejob(void *customdata, float progress)
static void fluidbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
FluidBakeJob *fb= (FluidBakeJob *)customdata;
-
+
fb->stop= stop;
fb->do_update = do_update;
fb->progress = progress;
-
+
G.is_break = false; /* XXX shared with render - replace with job 'stop' switch */
-
+
elbeemSimulate();
*do_update = true;
*stop = 0;
@@ -756,7 +756,7 @@ static void fluidbake_startjob(void *customdata, short *stop, short *do_update,
static void fluidbake_endjob(void *customdata)
{
FluidBakeJob *fb= (FluidBakeJob *)customdata;
-
+
if (fb->settings) {
MEM_freeN(fb->settings);
fb->settings = NULL;
@@ -767,16 +767,16 @@ static int runSimulationCallback(void *data, int status, int frame)
{
FluidBakeJob *fb = (FluidBakeJob *)data;
elbeemSimulationSettings *settings = fb->settings;
-
+
if (status == FLUIDSIM_CBSTATUS_NEWFRAME) {
fluidbake_updatejob(fb, frame / (float)settings->noOfFrames);
//printf("elbeem blender cb s%d, f%d, domainid:%d noOfFrames: %d\n", status, frame, settings->domainId, settings->noOfFrames ); // DEBUG
}
-
+
if (fluidbake_breakjob(fb)) {
return FLUIDSIM_CBRET_ABORT;
}
-
+
return FLUIDSIM_CBRET_CONTINUE;
}
@@ -790,12 +790,12 @@ static void fluidbake_free_data(FluidAnimChannels *channels, ListBase *fobjects,
BLI_freelistN(fobjects);
MEM_freeN(fobjects);
fobjects = NULL;
-
+
if (fsset) {
MEM_freeN(fsset);
fsset = NULL;
}
-
+
if (fb) {
MEM_freeN(fb);
fb = NULL;
@@ -849,7 +849,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
FluidsimSettings *domainSettings;
char debugStrBuffer[256];
-
+
int gridlevels = 0;
const char *relbase= modifier_path_relbase(bmain, fsDomain);
const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp
@@ -864,7 +864,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
int noFrames;
int origFrame = scene->r.cfra;
-
+
FluidAnimChannels *channels = MEM_callocN(sizeof(FluidAnimChannels), "fluid domain animation channels");
ListBase *fobjects = MEM_callocN(sizeof(ListBase), "fluid objects");
FluidsimModifierData *fluidmd = NULL;
@@ -874,14 +874,14 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
elbeemSimulationSettings *fsset= MEM_callocN(sizeof(elbeemSimulationSettings), "Fluid sim settings");
fb= MEM_callocN(sizeof(FluidBakeJob), "fluid bake job");
-
+
if (getenv(strEnvName)) {
int dlevel = atoi(getenv(strEnvName));
elbeemSetDebugLevel(dlevel);
BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer), "fluidsimBake::msg: Debug messages activated due to envvar '%s'\n", strEnvName);
elbeemDebugOut(debugStrBuffer);
}
-
+
/* make sure it corresponds to startFrame setting (old: noFrames = scene->r.efra - scene->r.sfra +1) */;
noFrames = scene->r.efra - 0;
if (noFrames<=0) {
@@ -889,30 +889,30 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
fluidbake_free_data(channels, fobjects, fsset, fb);
return 0;
}
-
+
/* check scene for sane object/modifier settings */
if (!fluid_validate_scene(reports, view_layer, fsDomain)) {
fluidbake_free_data(channels, fobjects, fsset, fb);
return 0;
}
-
+
/* these both have to be valid, otherwise we wouldn't be here */
fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim);
domainSettings = fluidmd->fss;
mesh = fsDomain->data;
-
+
domainSettings->bakeStart = 1;
domainSettings->bakeEnd = scene->r.efra;
-
+
// calculate bounding box
fluid_get_bb(mesh->mvert, mesh->totvert, fsDomain->obmat, domainSettings->bbStart, domainSettings->bbSize);
-
+
// reset last valid frame
domainSettings->lastgoodframe = -1;
/* delete old baked files */
fluidsim_delete_until_lastframe(domainSettings, relbase);
-
+
/* rough check of settings... */
if (domainSettings->previewresxyz > domainSettings->resolutionxyz) {
BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer), "fluidsimBake::warning - Preview (%d) >= Resolution (%d)... setting equal.\n", domainSettings->previewresxyz, domainSettings->resolutionxyz);
@@ -939,9 +939,9 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
}
BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer), "fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name, gridlevels);
elbeemDebugOut(debugStrBuffer);
-
-
-
+
+
+
/* ******** prepare output file paths ******** */
if (!fluid_init_filepaths(bmain, reports, domainSettings, fsDomain, targetDir, targetFile)) {
fluidbake_free_data(channels, fobjects, fsset, fb);
@@ -950,20 +950,20 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
channels->length = scene->r.efra; // DG TODO: why using endframe and not "noFrames" here? .. because "noFrames" is buggy too? (not using sfra)
channels->aniFrameTime = (double)((double)domainSettings->animEnd - (double)domainSettings->animStart) / (double)noFrames;
-
+
/* ******** initialize and allocate animation channels ******** */
fluid_init_all_channels(C, fsDomain, domainSettings, channels, fobjects);
/* reset to original current frame */
scene->r.cfra = origFrame;
ED_update_for_newframe(CTX_data_main(C), depsgraph);
-
+
/* ******** init domain object's matrix ******** */
copy_m4_m4(domainMat, fsDomain->obmat);
if (!invert_m4_m4(invDomMat, domainMat)) {
BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer), "fluidsimBake::error - Invalid obj matrix?\n");
elbeemDebugOut(debugStrBuffer);
- BKE_report(reports, RPT_ERROR, "Invalid object matrix");
+ BKE_report(reports, RPT_ERROR, "Invalid object matrix");
fluidbake_free_data(channels, fobjects, fsset, fb);
return 0;
@@ -980,7 +980,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
// setup global settings
copy_v3_v3(fsset->geoStart, domainSettings->bbStart);
copy_v3_v3(fsset->geoSize, domainSettings->bbSize);
-
+
// simulate with 50^3
fsset->resolutionxyz = (int)domainSettings->resolutionxyz;
fsset->previewresxyz = (int)domainSettings->previewresxyz;
@@ -999,21 +999,21 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
// defaults for compressibility and adaptive grids
fsset->gstar = domainSettings->gstar;
fsset->maxRefine = domainSettings->maxRefine; // check <-> gridlevels
- fsset->generateParticles = domainSettings->generateParticles;
- fsset->numTracerParticles = domainSettings->generateTracers;
- fsset->surfaceSmoothing = domainSettings->surfaceSmoothing;
- fsset->surfaceSubdivs = domainSettings->surfaceSubdivs;
- fsset->farFieldSize = domainSettings->farFieldSize;
+ fsset->generateParticles = domainSettings->generateParticles;
+ fsset->numTracerParticles = domainSettings->generateTracers;
+ fsset->surfaceSmoothing = domainSettings->surfaceSmoothing;
+ fsset->surfaceSubdivs = domainSettings->surfaceSubdivs;
+ fsset->farFieldSize = domainSettings->farFieldSize;
BLI_strncpy(fsset->outputPath, targetFile, sizeof(fsset->outputPath));
// domain channels
- fsset->channelSizeFrameTime =
- fsset->channelSizeViscosity =
+ fsset->channelSizeFrameTime =
+ fsset->channelSizeViscosity =
fsset->channelSizeGravity = channels->length;
fsset->channelFrameTime = channels->DomainTime;
fsset->channelViscosity = channels->DomainViscosity;
fsset->channelGravity = channels->DomainGravity;
-
+
fsset->runsimCallback = &runSimulationCallback;
fsset->runsimUserData = fb;
@@ -1041,13 +1041,13 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
/* ******** init solver with settings ******** */
elbeemInit();
elbeemAddDomain(fsset);
-
+
/* ******** export all fluid objects to elbeem ******** */
export_fluid_objects(C, fobjects, scene, channels->length);
-
+
/* custom data for fluid bake job */
fb->settings = fsset;
-
+
if (do_job) {
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Fluid Simulation",
WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_SIM_FLUID);
@@ -1119,7 +1119,7 @@ void FLUID_OT_bake(wmOperatorType *ot)
ot->name = "Fluid Simulation Bake";
ot->description = "Bake fluid simulation";
ot->idname = "FLUID_OT_bake";
-
+
/* api callbacks */
ot->invoke = fluid_bake_invoke;
ot->exec = fluid_bake_exec;
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index f37c263adc8..ffa73b41bd9 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -111,10 +111,10 @@ static void keymap_particle(wmKeyConfig *keyconf)
{
wmKeyMapItem *kmi;
wmKeyMap *keymap;
-
+
keymap = WM_keymap_find(keyconf, "Particle", 0, 0);
keymap->poll = PE_poll;
-
+
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_all", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
@@ -149,7 +149,7 @@ static void keymap_particle(wmKeyConfig *keyconf)
RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.particle_edit.brush.strength");
WM_keymap_add_menu(keymap, "VIEW3D_MT_particle_specials", WKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "PARTICLE_OT_weight_set", KKEY, KM_PRESS, KM_SHIFT, 0);
ED_keymap_proportional_cycle(keyconf, keymap);
@@ -205,7 +205,7 @@ static void operatortypes_dynamicpaint(void)
//static void keymap_pointcache(wmWindowManager *wm)
//{
// wmKeyMap *keymap = WM_keymap_find(wm, "Pointcache", 0, 0);
-//
+//
// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0);
// WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
// WM_keymap_add_item(keymap, "PHYSICS_OT_bake_particle_system", PADMINUS, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index fdafd6c28ed..45172774d55 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -256,9 +256,9 @@ static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op))
for (pid = pidlist.first; pid; pid = pid->next) {
ptcache_free_bake(pid->cache);
}
-
+
BLI_freelistN(&pidlist);
-
+
WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
}
FOREACH_SCENE_OBJECT_END;
@@ -274,7 +274,7 @@ void PTCACHE_OT_bake_all(wmOperatorType *ot)
ot->name = "Bake All Physics";
ot->description = "Bake all physics";
ot->idname = "PTCACHE_OT_bake_all";
-
+
/* api callbacks */
ot->exec = ptcache_bake_exec;
ot->invoke = ptcache_bake_invoke;
@@ -293,7 +293,7 @@ void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
ot->name = "Free All Physics Bakes";
ot->idname = "PTCACHE_OT_free_bake_all";
ot->description = "Free all baked caches of all objects in the current scene";
-
+
/* api callbacks */
ot->exec = ptcache_free_bake_all_exec;
ot->poll = ptcache_bake_all_poll;
@@ -309,7 +309,7 @@ static int ptcache_free_bake_exec(bContext *C, wmOperator *UNUSED(op))
Object *ob= ptr.id.data;
ptcache_free_bake(cache);
-
+
WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
return OPERATOR_FINISHED;
@@ -319,9 +319,9 @@ static int ptcache_bake_from_cache_exec(bContext *C, wmOperator *UNUSED(op))
PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
PointCache *cache= ptr.data;
Object *ob= ptr.id.data;
-
+
cache->flag |= PTCACHE_BAKED;
-
+
WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
return OPERATOR_FINISHED;
@@ -332,7 +332,7 @@ void PTCACHE_OT_bake(wmOperatorType *ot)
ot->name = "Bake Physics";
ot->description = "Bake physics";
ot->idname = "PTCACHE_OT_bake";
-
+
/* api callbacks */
ot->exec = ptcache_bake_exec;
ot->invoke = ptcache_bake_invoke;
@@ -351,7 +351,7 @@ void PTCACHE_OT_free_bake(wmOperatorType *ot)
ot->name = "Free Physics Bake";
ot->description = "Free physics bake";
ot->idname = "PTCACHE_OT_free_bake";
-
+
/* api callbacks */
ot->exec = ptcache_free_bake_exec;
ot->poll = ptcache_poll;
@@ -365,7 +365,7 @@ void PTCACHE_OT_bake_from_cache(wmOperatorType *ot)
ot->name = "Bake From Cache";
ot->description = "Bake from cache";
ot->idname = "PTCACHE_OT_bake_from_cache";
-
+
/* api callbacks */
ot->exec = ptcache_bake_from_cache_exec;
ot->poll = ptcache_poll;
@@ -418,7 +418,7 @@ void PTCACHE_OT_add(wmOperatorType *ot)
ot->name = "Add New Cache";
ot->description = "Add new cache";
ot->idname = "PTCACHE_OT_add";
-
+
/* api callbacks */
ot->exec = ptcache_add_new_exec;
ot->poll = ptcache_poll;
@@ -432,7 +432,7 @@ void PTCACHE_OT_remove(wmOperatorType *ot)
ot->name = "Delete Current Cache";
ot->description = "Delete current cache";
ot->idname = "PTCACHE_OT_remove";
-
+
/* api callbacks */
ot->exec = ptcache_remove_exec;
ot->poll = ptcache_poll;
diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c
index 008ab4c0554..8d5258a7522 100644
--- a/source/blender/editors/physics/rigidbody_world.c
+++ b/source/blender/editors/physics/rigidbody_world.c
@@ -24,7 +24,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-
+
/** \file rigidbody_world.c
* \ingroup editor_physics
* \brief Rigid Body world editing operators
@@ -174,7 +174,7 @@ static int rigidbody_world_export_invoke(bContext *C, wmOperator *op, const wmEv
// TODO: use the actual rigidbody world's name + .bullet instead of this temp crap
RNA_string_set(op->ptr, "filepath", "rigidbodyworld_export.bullet");
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 9c56f4f7754..2d65b361f99 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -272,7 +272,7 @@ static void screen_render_single_layer_set(wmOperator *op, Main *mainp, WorkSpac
RNA_string_get(op->ptr, "scene", scene_name);
scn = (Scene *)BLI_findstring(&mainp->scene, scene_name, offsetof(ID, name) + 2);
-
+
if (scn) {
/* camera switch wont have updated */
scn->r.cfra = (*scene)->r.cfra;
@@ -288,7 +288,7 @@ static void screen_render_single_layer_set(wmOperator *op, Main *mainp, WorkSpac
RNA_string_get(op->ptr, "layer", rl_name);
rl = (ViewLayer *)BLI_findstring(&(*scene)->view_layers, rl_name, offsetof(ViewLayer, name));
-
+
if (rl)
*single_layer = rl;
}
@@ -445,7 +445,7 @@ static void make_renderinfo_string(const RenderStats *rs,
/* full sample */
if (rs->curfsa)
spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa);
-
+
/* extra info */
if (rs->infostr && rs->infostr[0]) {
spos += sprintf(spos, "| %s ", rs->infostr);
@@ -487,7 +487,7 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
static void render_progress_update(void *rjv, float progress)
{
RenderJob *rj = rjv;
-
+
if (rj->progress && *rj->progress != progress) {
*rj->progress = progress;
@@ -574,10 +574,10 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
*(rj->do_update) = true;
return;
}
-
+
if (rr == NULL)
return;
-
+
/* update part of render */
render_image_update_pass_and_layer(rj, rr, &rj->iuser);
ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
@@ -596,7 +596,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
{
image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect, viewname);
}
-
+
/* make jobs timer to send notifier */
*(rj->do_update) = true;
}
@@ -683,13 +683,13 @@ static void render_endjob(void *rjv)
ED_update_for_newframe(G.main, rj->depsgraph);
}
}
-
+
/* XXX above function sets all tags in nodes */
ntreeCompositClearTags(rj->scene->nodetree);
-
+
/* potentially set by caller */
rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
-
+
if (rj->single_layer) {
nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
@@ -902,14 +902,14 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected");
return OPERATOR_CANCELLED;
}
-
+
/* stop all running jobs, except screen one. currently previews frustrate Render */
WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C));
/* cancel animation playback */
if (ED_screen_animation_playing(CTX_wm_manager(C)))
ED_screen_animation_play(C, 0, 0);
-
+
/* handle UI stuff */
WM_cursor_wait(1);
@@ -930,7 +930,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
sa = render_view_open(C, event->x, event->y, op->reports);
jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS;
-
+
if (RNA_struct_property_is_set(op->ptr, "layer"))
jobflag |= WM_JOB_SUSPEND;
@@ -1075,10 +1075,10 @@ Scene *ED_render_job_get_scene(const bContext *C)
{
wmWindowManager *wm = CTX_wm_manager(C);
RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
-
+
if (rj)
return rj->scene;
-
+
return NULL;
}
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index c2bc6170137..7e33549c5ac 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -404,7 +404,7 @@ static void screen_opengl_render_write(OGLRender *oglrender)
rr = RE_AcquireResultRead(oglrender->re);
BKE_image_path_from_imformat(
- name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
+ name, scene->r.pic, BKE_main_blendfile_path(oglrender->bmain), scene->r.cfra,
&scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false, NULL);
/* write images as individual images or stereo */
@@ -455,7 +455,7 @@ static void add_gpencil_renderpass(const bContext *C, OGLRender *oglrender, Rend
short oldalphamode = scene->r.alphamode;
/* set alpha transparent for gp */
scene->r.alphamode = R_ALPHAPREMUL;
-
+
/* saves layer status */
short *oldsts = MEM_mallocN(BLI_listbase_count(&gpd->layers) * sizeof(short), "temp_gplayers_flag");
int i = 0;
@@ -477,7 +477,7 @@ static void add_gpencil_renderpass(const bContext *C, OGLRender *oglrender, Rend
/* render this gp layer */
screen_opengl_render_doit(C, oglrender, rr);
-
+
/* add RendePass composite */
RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name);
@@ -943,7 +943,7 @@ static void write_result_func(TaskPool * __restrict pool,
char name[FILE_MAX];
BKE_image_path_from_imformat(name,
scene->r.pic,
- oglrender->bmain->name,
+ BKE_main_blendfile_path(oglrender->bmain),
cfra,
&scene->r.im_format,
(scene->r.scemode & R_EXTENSION) != 0,
@@ -1030,7 +1030,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
if (!is_movie) {
BKE_image_path_from_imformat(
- name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
+ name, scene->r.pic, BKE_main_blendfile_path(oglrender->bmain), scene->r.cfra,
&scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true, NULL);
if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
@@ -1108,7 +1108,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent
/* run first because screen_opengl_render_anim_step can free oglrender */
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
-
+
if (anim == 0) {
screen_opengl_render_apply(C, op->customdata);
screen_opengl_render_end(C, op->customdata);
@@ -1138,16 +1138,16 @@ static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEven
if (!screen_opengl_render_anim_initialize(C, op))
return OPERATOR_CANCELLED;
}
-
+
oglrender = op->customdata;
render_view_open(C, event->x, event->y, op->reports);
-
+
/* view may be changed above (R_OUTPUT_WINDOW) */
oglrender->win = CTX_wm_window(C);
WM_event_add_modal_handler(C, op);
oglrender->timer = WM_event_add_timer(oglrender->wm, oglrender->win, TIMER, 0.01f);
-
+
return OPERATOR_RUNNING_MODAL;
}
diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c
index 799264ce74e..dd5ed5b78f1 100644
--- a/source/blender/editors/render/render_ops.c
+++ b/source/blender/editors/render/render_ops.c
@@ -52,7 +52,7 @@ void ED_operatortypes_render(void)
WM_operatortype_append(MATERIAL_OT_new);
WM_operatortype_append(TEXTURE_OT_new);
WM_operatortype_append(WORLD_OT_new);
-
+
WM_operatortype_append(MATERIAL_OT_copy);
WM_operatortype_append(MATERIAL_OT_paste);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 946da6f1ed8..4a3c7a3fd4b 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -40,7 +40,7 @@
#include <unistd.h>
#else
#include <io.h>
-#endif
+#endif
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
@@ -122,7 +122,7 @@ ImBuf *get_brush_icon(Brush *brush)
// first use the path directly to try and load the file
BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath));
- BLI_path_abs(path, G.main->name);
+ BLI_path_abs(path, BKE_main_blendfile_path_from_global());
/* use default colorspaces for brushes */
brush->icon_imbuf = IMB_loadiffname(path, flags, NULL);
@@ -131,7 +131,7 @@ ImBuf *get_brush_icon(Brush *brush)
if (!(brush->icon_imbuf)) {
folder = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons");
- BLI_make_file_string(G.main->name, path, folder, brush->icon_filepath);
+ BLI_make_file_string(BKE_main_blendfile_path_from_global(), path, folder, brush->icon_filepath);
if (path[0]) {
/* use fefault color spaces */
@@ -155,21 +155,21 @@ typedef struct ShaderPreview {
/* from wmJob */
void *owner;
short *stop, *do_update;
-
+
Scene *scene;
Depsgraph *depsgraph;
ID *id;
ID *parent;
MTex *slot;
-
+
/* datablocks with nodes need full copy during preview render, glsl uses it too */
Material *matcopy;
Tex *texcopy;
Lamp *lampcopy;
World *worldcopy;
-
+
float col[4]; /* active object color */
-
+
int sizex, sizey;
unsigned int *pr_rect;
int pr_method;
@@ -249,7 +249,7 @@ void ED_preview_free_dbase(void)
static Scene *preview_get_scene(Main *pr_main)
{
if (pr_main == NULL) return NULL;
-
+
return pr_main->scene.first;
}
@@ -319,7 +319,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
Scene *sce;
Main *pr_main = sp->pr_main;
- memcpy(pr_main->name, bmain->name, sizeof(pr_main->name));
+ memcpy(pr_main->name, BKE_main_blendfile_path(bmain), sizeof(pr_main->name));
sce = preview_get_scene(pr_main);
if (sce) {
@@ -334,13 +334,13 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
sce->world->exp = scene->world->exp;
sce->world->range = scene->world->range;
}
-
+
sce->r.color_mgt_flag = scene->r.color_mgt_flag;
BKE_color_managed_display_settings_copy(&sce->display_settings, &scene->display_settings);
BKE_color_managed_view_settings_free(&sce->view_settings);
BKE_color_managed_view_settings_copy(&sce->view_settings, &scene->view_settings);
-
+
/* prevent overhead for small renders and icons (32) */
if (id && sp->sizex < 40) {
sce->r.tilex = sce->r.tiley = 64;
@@ -349,7 +349,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
sce->r.tilex = sce->r.xsch / 4;
sce->r.tiley = sce->r.ysch / 4;
}
-
+
if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO)
sce->r.alphamode = R_ALPHAPREMUL;
else
@@ -367,16 +367,16 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
else {
BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine));
}
-
+
if (id_type == ID_MA) {
Material *mat = NULL, *origmat = (Material *)id;
-
+
if (origmat) {
/* work on a copy */
mat = BKE_material_localize(origmat);
sp->matcopy = mat;
BLI_addtail(&pr_main->mat, mat);
-
+
/* use current scene world to light sphere */
if (mat->pr_type == MA_SPHERE_A && sp->pr_method == PR_BUTS_RENDER) {
/* Use current scene world to light sphere. */
@@ -390,7 +390,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
sce->world->horg = 0.5f;
sce->world->horb = 0.5f;
}
-
+
if (sp->pr_method == PR_ICON_RENDER) {
set_preview_collection(sce, view_layer, MA_SPHERE_A);
}
@@ -406,14 +406,14 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
}
else {
sce->r.mode &= ~(R_OSA);
-
+
}
-
+
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
if (base->object->id.name[2] == 'p') {
/* copy over object color, in case material uses it */
copy_v4_v4(base->object->col, sp->col);
-
+
if (OB_TYPE_SUPPORT_MATERIAL(base->object->type)) {
/* don't use assign_material, it changed mat->id.us, which shows in the UI */
Material ***matar = give_matarar(base->object);
@@ -430,14 +430,14 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
}
else if (id_type == ID_TE) {
Tex *tex = NULL, *origtex = (Tex *)id;
-
+
if (origtex) {
tex = BKE_texture_localize(origtex);
sp->texcopy = tex;
BLI_addtail(&pr_main->tex, tex);
}
set_preview_collection(sce, view_layer, MA_TEXTURE);
-
+
if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) {
/* two previews, they get copied by wmJob */
BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true);
@@ -463,7 +463,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
sce->world->horg = 0.0f;
sce->world->horb = 0.0f;
}
-
+
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
if (base->object->id.name[2] == 'p') {
if (base->object->type == OB_LAMP)
@@ -498,7 +498,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
return sce;
}
-
+
return NULL;
}
@@ -547,7 +547,7 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
}
if (rv && rv->rectf) {
-
+
if (ABS(rres.rectx - newx) < 2 && ABS(rres.recty - newy) < 2) {
newrect->xmax = max_ii(newrect->xmax, rect->xmin + rres.rectx + offx);
@@ -565,9 +565,9 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
immDrawPixelsTex(&state, fx, fy, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, rect_byte,
1.0f, 1.0f, NULL);
-
+
MEM_freeN(rect_byte);
-
+
ok = 1;
}
}
@@ -629,7 +629,7 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
static void shader_preview_update(void *spv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
{
ShaderPreview *sp = spv;
-
+
*(sp->do_update) = true;
}
@@ -645,30 +645,30 @@ static int shader_preview_break(void *spv)
static void shader_preview_updatejob(void *spv)
{
ShaderPreview *sp = spv;
-
+
if (sp->id) {
if (sp->pr_method == PR_NODE_RENDER) {
if (GS(sp->id->name) == ID_MA) {
Material *mat = (Material *)sp->id;
-
+
if (sp->matcopy && mat->nodetree && sp->matcopy->nodetree)
ntreeLocalSync(sp->matcopy->nodetree, mat->nodetree);
}
else if (GS(sp->id->name) == ID_TE) {
Tex *tex = (Tex *)sp->id;
-
+
if (sp->texcopy && tex->nodetree && sp->texcopy->nodetree)
ntreeLocalSync(sp->texcopy->nodetree, tex->nodetree);
}
else if (GS(sp->id->name) == ID_WO) {
World *wrld = (World *)sp->id;
-
+
if (sp->worldcopy && wrld->nodetree && sp->worldcopy->nodetree)
ntreeLocalSync(sp->worldcopy->nodetree, wrld->nodetree);
}
else if (GS(sp->id->name) == ID_LA) {
Lamp *la = (Lamp *)sp->id;
-
+
if (sp->lampcopy && la->nodetree && sp->lampcopy->nodetree)
ntreeLocalSync(sp->lampcopy->nodetree, la->nodetree);
}
@@ -686,7 +686,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
int sizex;
Main *pr_main = sp->pr_main;
ID *id_eval = DEG_get_evaluated_id(sp->depsgraph, id);
-
+
/* in case of split preview, use border render */
if (split) {
if (first) sizex = sp->sizex / 2;
@@ -703,19 +703,19 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
sce->r.ysch = sp->sizey;
sce->r.size = 100;
}
-
+
/* get the stuff from the builtin preview dbase */
sce = preview_prepare_scene(sp->bmain, sp->scene, id_eval, idtype, sp);
if (sce == NULL) return;
-
+
if (!split || first) sprintf(name, "Preview %p", sp->owner);
else sprintf(name, "SecondPreview %p", sp->owner);
re = RE_GetRender(name);
-
+
/* full refreshed render from first tile */
if (re == NULL)
re = RE_NewRender(name);
-
+
/* sce->r gets copied in RE_InitState! */
sce->r.scemode &= ~(R_MATNODE_PREVIEW | R_TEXNODE_PREVIEW);
sce->r.scemode &= ~R_NO_IMAGE_LOAD;
@@ -740,7 +740,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
}
/* set this for all previews, default is react to G.is_break still */
RE_test_break_cb(re, sp, shader_preview_break);
-
+
/* lens adjust */
oldlens = ((Camera *)sce->camera->data)->lens;
if (sizex > sp->sizey)
@@ -754,14 +754,14 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
/* handle results */
if (sp->pr_method == PR_ICON_RENDER) {
// char *rct= (char *)(sp->pr_rect + 32*16 + 16);
-
+
if (sp->pr_rect)
RE_ResultGet32(re, sp->pr_rect);
}
/* unassign the pointers, reset vars */
preview_prepare_scene(sp->bmain, sp->scene, NULL, GS(id->name), sp);
-
+
/* XXX bad exception, end-exec is not being called in render, because it uses local main */
// if (idtype == ID_TE) {
// Tex *tex= (Tex *)id;
@@ -793,16 +793,16 @@ static void shader_preview_free(void *customdata)
{
ShaderPreview *sp = customdata;
Main *pr_main = sp->pr_main;
-
+
if (sp->matcopy) {
struct IDProperty *properties;
-
+
/* node previews */
shader_preview_updatejob(sp);
-
+
/* get rid of copied material */
BLI_remlink(&pr_main->mat, sp->matcopy);
-
+
BKE_material_free(sp->matcopy);
properties = IDP_GetProperties((ID *)sp->matcopy, false);
@@ -816,11 +816,11 @@ static void shader_preview_free(void *customdata)
struct IDProperty *properties;
/* node previews */
shader_preview_updatejob(sp);
-
+
/* get rid of copied texture */
BLI_remlink(&pr_main->tex, sp->texcopy);
BKE_texture_free(sp->texcopy);
-
+
properties = IDP_GetProperties((ID *)sp->texcopy, false);
if (properties) {
IDP_FreeProperty(properties);
@@ -832,11 +832,11 @@ static void shader_preview_free(void *customdata)
struct IDProperty *properties;
/* node previews */
shader_preview_updatejob(sp);
-
+
/* get rid of copied world */
BLI_remlink(&pr_main->world, sp->worldcopy);
BKE_world_free(sp->worldcopy);
-
+
properties = IDP_GetProperties((ID *)sp->worldcopy, false);
if (properties) {
IDP_FreeProperty(properties);
@@ -848,11 +848,11 @@ static void shader_preview_free(void *customdata)
struct IDProperty *properties;
/* node previews */
shader_preview_updatejob(sp);
-
+
/* get rid of copied lamp */
BLI_remlink(&pr_main->lamp, sp->lampcopy);
BKE_lamp_free(sp->lampcopy);
-
+
properties = IDP_GetProperties((ID *)sp->lampcopy, false);
if (properties) {
IDP_FreeProperty(properties);
@@ -860,7 +860,7 @@ static void shader_preview_free(void *customdata)
}
MEM_freeN(sp->lampcopy);
}
-
+
MEM_freeN(sp);
}
@@ -876,13 +876,13 @@ static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned
/* paranoia test */
if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL))
return;
-
+
/* waste of cpu cyles... but the imbuf API has no other way to scale fast (ton) */
ima = IMB_dupImBuf(ibuf);
-
- if (!ima)
+
+ if (!ima)
return;
-
+
if (ima->x > ima->y) {
scaledx = (float)w;
scaledy = ( (float)ima->y / (float)ima->x) * (float)w;
@@ -891,15 +891,15 @@ static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned
scaledx = ( (float)ima->x / (float)ima->y) * (float)h;
scaledy = (float)h;
}
-
+
ex = (short)scaledx;
ey = (short)scaledy;
-
+
dx = (w - ex) / 2;
dy = (h - ey) / 2;
-
+
IMB_scalefastImBuf(ima, ex, ey);
-
+
/* if needed, convert to 32 bits */
if (ima->rect == NULL)
IMB_rect_from_float(ima);
@@ -917,7 +917,7 @@ static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned
IMB_freeImBuf(ima);
}
-static void set_alpha(char *cp, int sizex, int sizey, char alpha)
+static void set_alpha(char *cp, int sizex, int sizey, char alpha)
{
int a, size = sizex * sizey;
@@ -1101,7 +1101,7 @@ static void icon_preview_endjob(void *customdata)
if (GS(ip->id->name) == ID_BR)
WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
-#if 0
+#if 0
if (GS(ip->id->name) == ID_MA) {
Material *ma = (Material *)ip->id;
PreviewImage *prv_img = ma->preview;
@@ -1246,12 +1246,12 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
if (ob && ob->totcol) copy_v4_v4(sp->col, ob->col);
else sp->col[0] = sp->col[1] = sp->col[2] = sp->col[3] = 1.0f;
-
+
/* setup job */
WM_jobs_customdata_set(wm_job, sp, shader_preview_free);
WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL);
WM_jobs_callbacks(wm_job, common_preview_startjob, NULL, shader_preview_updatejob, NULL);
-
+
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index e2c4335dca9..3f32242cd1b 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -105,7 +105,7 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
if (!ob)
return OPERATOR_CANCELLED;
-
+
BKE_object_material_slot_add(bmain, ob);
if (ob->mode & OB_MODE_TEXTURE_PAINT) {
@@ -113,11 +113,11 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -127,7 +127,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot)
ot->name = "Add Material Slot";
ot->idname = "OBJECT_OT_material_slot_add";
ot->description = "Add a new material slot";
-
+
/* api callbacks */
ot->exec = material_slot_add_exec;
ot->poll = ED_operator_object_active_editable;
@@ -148,7 +148,7 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
return OPERATOR_CANCELLED;
}
-
+
BKE_object_material_slot_remove(CTX_data_main(C), ob);
if (ob->mode & OB_MODE_TEXTURE_PAINT) {
@@ -156,12 +156,12 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op)
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
-
+
return OPERATOR_FINISHED;
}
@@ -171,7 +171,7 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
ot->name = "Remove Material Slot";
ot->idname = "OBJECT_OT_material_slot_remove";
ot->description = "Remove the selected material slot";
-
+
/* api callbacks */
ot->exec = material_slot_remove_exec;
ot->poll = ED_operator_object_active_editable;
@@ -225,7 +225,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
-
+
return OPERATOR_FINISHED;
}
@@ -235,7 +235,7 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
ot->name = "Assign Material Slot";
ot->idname = "OBJECT_OT_material_slot_assign";
ot->description = "Assign active material slot to selection";
-
+
/* api callbacks */
ot->exec = material_slot_assign_exec;
ot->poll = ED_operator_object_active_editable;
@@ -319,7 +319,7 @@ void OBJECT_OT_material_slot_select(wmOperatorType *ot)
ot->name = "Select Material Slot";
ot->idname = "OBJECT_OT_material_slot_select";
ot->description = "Select by active material slot";
-
+
/* api callbacks */
ot->exec = material_slot_select_exec;
@@ -338,7 +338,7 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
ot->name = "Deselect Material Slot";
ot->idname = "OBJECT_OT_material_slot_deselect";
ot->description = "Deselect by active material slot";
-
+
/* api callbacks */
ot->exec = material_slot_deselect_exec;
@@ -361,7 +361,7 @@ static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
if (ob != ob_iter && give_matarar(ob_iter)) {
if (ob->data != ob_iter->data)
assign_matarar(bmain, ob_iter, matar, ob->totcol);
-
+
if (ob_iter->totcol == ob->totcol) {
ob_iter->actcol = ob->actcol;
DEG_id_tag_update(&ob_iter->id, OB_RECALC_DATA);
@@ -492,7 +492,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
}
WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma);
-
+
return OPERATOR_FINISHED;
}
@@ -502,7 +502,7 @@ void MATERIAL_OT_new(wmOperatorType *ot)
ot->name = "New Material";
ot->idname = "MATERIAL_OT_new";
ot->description = "Add a new material";
-
+
/* api callbacks */
ot->exec = new_material_exec;
@@ -541,7 +541,7 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
}
WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex);
-
+
return OPERATOR_FINISHED;
}
@@ -551,7 +551,7 @@ void TEXTURE_OT_new(wmOperatorType *ot)
ot->name = "New Texture";
ot->idname = "TEXTURE_OT_new";
ot->description = "Add a new texture";
-
+
/* api callbacks */
ot->exec = new_texture_exec;
@@ -592,7 +592,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
}
WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo);
-
+
return OPERATOR_FINISHED;
}
@@ -602,7 +602,7 @@ void WORLD_OT_new(wmOperatorType *ot)
ot->name = "New World";
ot->idname = "WORLD_OT_new";
ot->description = "Create a new world Data-Block";
-
+
/* api callbacks */
ot->exec = new_world_exec;
@@ -625,7 +625,7 @@ static int view_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&scene->id, 0);
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -635,7 +635,7 @@ void SCENE_OT_view_layer_add(wmOperatorType *ot)
ot->name = "Add View Layer";
ot->idname = "SCENE_OT_view_layer_add";
ot->description = "Add a view layer";
-
+
/* api callbacks */
ot->exec = view_layer_add_exec;
@@ -664,7 +664,7 @@ void SCENE_OT_view_layer_remove(wmOperatorType *ot)
ot->name = "Remove View Layer";
ot->idname = "SCENE_OT_view_layer_remove";
ot->description = "Remove the selected view layer";
-
+
/* api callbacks */
ot->exec = view_layer_remove_exec;
@@ -1433,11 +1433,11 @@ static int texture_slot_move_exec(bContext *C, wmOperator *op)
mtexswap = mtex_ar[act];
mtex_ar[act] = mtex_ar[act - 1];
mtex_ar[act - 1] = mtexswap;
-
+
BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act - 1, -1, 0);
BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act - 1, 0);
BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
-
+
set_active_mtex(id, act - 1);
}
}
@@ -1446,11 +1446,11 @@ static int texture_slot_move_exec(bContext *C, wmOperator *op)
mtexswap = mtex_ar[act];
mtex_ar[act] = mtex_ar[act + 1];
mtex_ar[act + 1] = mtexswap;
-
+
BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act + 1, -1, 0);
BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act + 1, 0);
BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
-
+
set_active_mtex(id, act + 1);
}
}
@@ -1555,7 +1555,7 @@ void ED_render_clear_mtex_copybuf(void)
static void copy_mtex_copybuf(ID *id)
{
MTex **mtex = NULL;
-
+
switch (GS(id->name)) {
case ID_PA:
mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
@@ -1566,7 +1566,7 @@ static void copy_mtex_copybuf(ID *id)
default:
break;
}
-
+
if (mtex && *mtex) {
memcpy(&mtexcopybuf, *mtex, sizeof(MTex));
mtexcopied = 1;
@@ -1579,10 +1579,10 @@ static void copy_mtex_copybuf(ID *id)
static void paste_mtex_copybuf(ID *id)
{
MTex **mtex = NULL;
-
+
if (mtexcopied == 0 || mtexcopybuf.tex == NULL)
return;
-
+
switch (GS(id->name)) {
case ID_PA:
mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
@@ -1594,7 +1594,7 @@ static void paste_mtex_copybuf(ID *id)
BLI_assert(!"invalid id type");
return;
}
-
+
if (mtex) {
if (*mtex == NULL) {
*mtex = MEM_mallocN(sizeof(MTex), "mtex copy");
@@ -1602,9 +1602,9 @@ static void paste_mtex_copybuf(ID *id)
else if ((*mtex)->tex) {
id_us_min(&(*mtex)->tex->id);
}
-
+
memcpy(*mtex, &mtexcopybuf, sizeof(MTex));
-
+
id_us_plus((ID *)mtexcopybuf.tex);
}
}
@@ -1628,7 +1628,7 @@ static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op))
static int copy_mtex_poll(bContext *C)
{
ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
-
+
return (id != NULL);
}
@@ -1642,7 +1642,7 @@ void TEXTURE_OT_slot_copy(wmOperatorType *ot)
/* api callbacks */
ot->exec = copy_mtex_exec;
ot->poll = copy_mtex_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; /* no undo needed since no changes are made to the mtex */
}
@@ -1668,7 +1668,7 @@ static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
id = &psys->part->id;
else if (linestyle)
id = &linestyle->id;
-
+
if (id == NULL)
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index de731888e4b..b7e6508117e 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -111,12 +111,12 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update
CTX_wm_manager_set(C, bmain->wm.first);
wm = bmain->wm.first;
-
+
for (win = wm->windows.first; win; win = win->next) {
bScreen *sc = WM_window_get_active_screen(win);
ScrArea *sa;
ARegion *ar;
-
+
CTX_wm_window_set(C, win);
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -220,22 +220,22 @@ static void render_engine_flag_changed(Main *bmain, int update_flag)
bScreen *sc;
ScrArea *sa;
ARegion *ar;
-
+
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
for (sa = sc->areabase.first; sa; sa = sa->next) {
if (sa->spacetype != SPACE_VIEW3D)
continue;
-
+
for (ar = sa->regionbase.first; ar; ar = ar->next) {
RegionView3D *rv3d;
-
+
if (ar->regiontype != RGN_TYPE_WINDOW)
continue;
-
+
rv3d = ar->regiondata;
if (rv3d->render_engine)
rv3d->render_engine->update_flag |= update_flag;
-
+
}
}
}
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index e4bae9d78ea..a522817825a 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -104,7 +104,7 @@ static ScrArea *find_area_showing_r_result(bContext *C, Scene *scene, wmWindow *
break;
}
}
-
+
return sa;
}
@@ -139,7 +139,7 @@ ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
if (scene->r.displaymode == R_OUTPUT_NONE)
return NULL;
-
+
if (scene->r.displaymode == R_OUTPUT_WINDOW) {
int sizex = 30 * UI_DPI_FAC + (scene->r.xsch * scene->r.size) / 100;
int sizey = 60 * UI_DPI_FAC + (scene->r.ysch * scene->r.size) / 100;
@@ -177,7 +177,7 @@ ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
sa = find_area_showing_r_result(C, scene, &win);
if (sa == NULL)
sa = find_area_image_empty(C);
-
+
/* if area found in other window, we make that one show in front */
if (win && win != CTX_wm_window(C))
wm_window_raise(win);
@@ -292,7 +292,7 @@ void RENDER_OT_view_cancel(struct wmOperatorType *ot)
static int render_view_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *wincur = CTX_wm_window(C);
-
+
/* test if we have currently a temp screen active */
if (WM_window_is_temp_screen(wincur)) {
wm_window_lower(wincur);
@@ -300,7 +300,7 @@ static int render_view_show_invoke(bContext *C, wmOperator *op, const wmEvent *e
else {
wmWindow *win, *winshow;
ScrArea *sa = find_area_showing_r_result(C, CTX_data_scene(C), &winshow);
-
+
/* is there another window on current scene showing result? */
for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) {
const bScreen *sc = WM_window_get_active_screen(win);
@@ -312,7 +312,7 @@ static int render_view_show_invoke(bContext *C, wmOperator *op, const wmEvent *e
return OPERATOR_FINISHED;
}
}
-
+
/* determine if render already shows */
if (sa) {
/* but don't close it when rendering */
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 2491c9f57de..034ccdf2e7b 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -311,7 +311,7 @@ static void draw_azone_plus(float x1, float y1, float x2, float y2)
static void region_draw_azone_tab_plus(AZone *az)
{
glEnable(GL_BLEND);
-
+
/* add code to draw region hidden as 'too small' */
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
@@ -352,7 +352,7 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar)
gpuPushMatrix();
gpuTranslate2f(-ar->winrct.xmin, -ar->winrct.ymin);
-
+
for (az = sa->actionzones.first; az; az = az->next) {
/* test if action zone is over this region */
rcti azrct;
@@ -452,19 +452,19 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
return;
ar->do_draw |= RGN_DRAWING;
-
+
/* Set viewport, scissor, ortho and ar->drawrct. */
wmPartialViewport(&ar->drawrct, &ar->winrct, &ar->drawrct);
wmOrtho2_region_pixelspace(ar);
-
+
UI_SetTheme(sa ? sa->spacetype : 0, at->regionid);
-
+
/* optional header info instead? */
if (ar->headerstr) {
UI_ThemeClearColor(TH_HEADER);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_FontThemeColor(BLF_default(), TH_TEXT);
BLF_draw_default(UI_UNIT_X, 0.4f * UI_UNIT_Y, 0.0f, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX);
}
@@ -493,7 +493,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
#endif
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
-
+
UI_blocklist_free_inactive(C, &ar->uiblocks);
if (sa) {
@@ -602,7 +602,7 @@ void ED_region_tag_redraw_partial(ARegion *ar, const rcti *rct)
void ED_area_tag_redraw(ScrArea *sa)
{
ARegion *ar;
-
+
if (sa)
for (ar = sa->regionbase.first; ar; ar = ar->next)
ED_region_tag_redraw(ar);
@@ -620,7 +620,7 @@ void ED_area_tag_redraw_no_rebuild(ScrArea *sa)
void ED_area_tag_redraw_regiontype(ScrArea *sa, int regiontype)
{
ARegion *ar;
-
+
if (sa) {
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == regiontype) {
@@ -669,7 +669,7 @@ void ED_area_headerprint(ScrArea *sa, const char *str)
static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *sa)
{
AZone *az;
-
+
/* reinitalize entirely, regions and fullscreen add azones too */
BLI_freelistN(&sa->actionzones);
@@ -794,11 +794,11 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
{
AZone *azt;
int tot = 0, add;
-
+
for (azt = sa->actionzones.first; azt; azt = azt->next) {
if (azt->edge == az->edge) tot++;
}
-
+
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
add = (ar->winrct.ymax == sa->totrct.ymin) ? 1 : 0;
@@ -1032,20 +1032,20 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
rcti *remainder_prev = remainder;
int prefsizex, prefsizey;
int alignment;
-
+
if (ar == NULL)
return;
-
+
/* no returns in function, winrct gets set in the end again */
BLI_rcti_init(&ar->winrct, 0, 0, 0, 0);
-
+
/* for test; allow split of previously defined region */
if (ar->alignment & RGN_SPLIT_PREV)
if (ar->prev)
remainder = &ar->prev->winrct;
-
+
alignment = ar->alignment & ~RGN_SPLIT_PREV;
-
+
/* set here, assuming userpref switching forces to call this again */
ar->overlap = ED_region_is_overlap(sa->spacetype, ar->regiontype);
@@ -1089,7 +1089,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
}
else if (alignment == RGN_ALIGN_TOP || alignment == RGN_ALIGN_BOTTOM) {
rcti *winrct = (ar->overlap) ? overlap_remainder : remainder;
-
+
if (rct_fits(winrct, 'v', prefsizey) < 0) {
ar->flag |= RGN_FLAG_TOO_SMALL;
}
@@ -1098,9 +1098,9 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
if (fac < 0)
prefsizey += fac;
-
+
ar->winrct = *winrct;
-
+
if (alignment == RGN_ALIGN_TOP) {
ar->winrct.ymin = ar->winrct.ymax - prefsizey + 1;
winrct->ymax = ar->winrct.ymin - 1;
@@ -1113,18 +1113,18 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
}
else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
rcti *winrct = (ar->overlap) ? overlap_remainder : remainder;
-
+
if (rct_fits(winrct, 'h', prefsizex) < 0) {
ar->flag |= RGN_FLAG_TOO_SMALL;
}
else {
int fac = rct_fits(winrct, 'h', prefsizex);
-
+
if (fac < 0)
prefsizex += fac;
-
+
ar->winrct = *winrct;
-
+
if (alignment == RGN_ALIGN_RIGHT) {
ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1;
winrct->xmax = ar->winrct.xmin - 1;
@@ -1138,7 +1138,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
else if (alignment == RGN_ALIGN_VSPLIT || alignment == RGN_ALIGN_HSPLIT) {
/* percentage subdiv*/
ar->winrct = *remainder;
-
+
if (alignment == RGN_ALIGN_HSPLIT) {
if (rct_fits(remainder, 'h', prefsizex) > 4) {
ar->winrct.xmax = BLI_rcti_cent_x(remainder);
@@ -1160,18 +1160,18 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
}
else if (alignment == RGN_ALIGN_QSPLIT) {
ar->winrct = *remainder;
-
+
/* test if there's still 4 regions left */
if (quad == 0) {
ARegion *artest = ar->next;
int count = 1;
-
+
while (artest) {
artest->alignment = RGN_ALIGN_QSPLIT;
artest = artest->next;
count++;
}
-
+
if (count != 4) {
/* let's stop adding regions */
BLI_rcti_init(remainder, 0, 0, 0, 0);
@@ -1204,16 +1204,16 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
quad++;
}
}
-
+
/* for speedup */
ar->winx = BLI_rcti_size_x(&ar->winrct) + 1;
ar->winy = BLI_rcti_size_y(&ar->winrct) + 1;
-
+
/* if region opened normally, we store this for hide/reveal usage */
/* prevent rounding errors for UI_DPI_FAC mult and divide */
if (ar->winx > 1) ar->sizex = (ar->winx + 0.5f) / UI_DPI_FAC;
if (ar->winy > 1) ar->sizey = (ar->winy + 0.5f) / UI_DPI_FAC;
-
+
/* exception for multiple overlapping regions on same spot */
if (ar->overlap) {
region_overlap_fix(sa, ar);
@@ -1222,7 +1222,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
/* set winrect for azones */
if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) {
ar->winrct = (ar->overlap) ? *overlap_remainder : *remainder;
-
+
switch (alignment) {
case RGN_ALIGN_TOP:
ar->winrct.ymin = ar->winrct.ymax;
@@ -1328,7 +1328,7 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
if (flag & ED_KEYMAP_MARKERS) {
/* time-markers */
wmKeyMap *keymap = WM_keymap_find(wm->defaultconf, "Markers", 0, 0);
-
+
/* use a boundbox restricted map */
ARegion *ar;
/* same local check for all areas */
@@ -1351,16 +1351,16 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
}
if (flag & ED_KEYMAP_GPENCIL) {
/* grease pencil */
- /* NOTE: This is now 2 keymaps - One for basic functionality,
- * and one that only applies when "Edit Mode" is enabled
+ /* NOTE: This is now 2 keymaps - One for basic functionality,
+ * and one that only applies when "Edit Mode" is enabled
* for strokes.
*
- * For now, it's easier to just include both,
+ * For now, it's easier to just include both,
* since you hardly want one without the other.
*/
wmKeyMap *keymap_general = WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0);
wmKeyMap *keymap_edit = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0);
-
+
WM_event_add_keymap_handler(handlers, keymap_general);
WM_event_add_keymap_handler(handlers, keymap_edit);
}
@@ -1417,7 +1417,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
/* set typedefinitions */
sa->type = BKE_spacetype_from_id(sa->spacetype);
-
+
if (sa->type == NULL) {
sa->spacetype = SPACE_VIEW3D;
sa->type = BKE_spacetype_from_id(sa->spacetype);
@@ -1434,7 +1434,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
overlap_rect = rect;
region_rect_recursive(win, sa, sa->regionbase.first, &rect, &overlap_rect, 0);
sa->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE;
-
+
/* default area handlers */
ed_default_handlers(wm, sa, &sa->handlers, sa->type->keymapflag);
/* checks spacedata, adds own handlers */
@@ -1447,7 +1447,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
/* region windows, default and own handlers */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
region_subwindow(ar);
-
+
if (ar->visible) {
/* default region handlers */
ed_default_handlers(wm, sa, &ar->handlers, ar->type->keymapflag);
@@ -1511,10 +1511,10 @@ void ED_region_cursor_set(wmWindow *win, ScrArea *sa, ARegion *ar)
void ED_region_visibility_change_update(bContext *C, ARegion *ar)
{
ScrArea *sa = CTX_wm_area(C);
-
+
if (ar->flag & RGN_FLAG_HIDDEN)
WM_event_remove_handlers(C, &ar->handlers);
-
+
ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
ED_area_tag_redraw(sa);
}
@@ -1523,9 +1523,9 @@ void ED_region_visibility_change_update(bContext *C, ARegion *ar)
void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade)
{
ScrArea *sa = CTX_wm_area(C);
-
+
ar->flag ^= RGN_FLAG_HIDDEN;
-
+
if (do_fade && ar->overlap) {
/* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */
region_blend_start(C, sa, ar);
@@ -1550,7 +1550,7 @@ void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free)
ARegion *ar;
const char spacetype = sa_dst->spacetype;
const short flag_copy = HEADER_NO_PULLDOWN;
-
+
sa_dst->spacetype = sa_src->spacetype;
sa_dst->type = sa_src->type;
@@ -1608,7 +1608,7 @@ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(C);
-
+
ED_area_tag_redraw(sa1);
ED_area_tag_refresh(sa1);
ED_area_tag_redraw(sa2);
@@ -1657,7 +1657,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi
for (sl = sa->spacedata.first; sl; sl = sl->next)
if (sl->spacetype == type)
break;
-
+
/* old spacedata... happened during work on 2.50, remove */
if (sl && BLI_listbase_is_empty(&sl->regionbase)) {
st->free(sl);
@@ -1673,7 +1673,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi
slold->regionbase = sa->regionbase;
sa->regionbase = sl->regionbase;
BLI_listbase_clear(&sl->regionbase);
-
+
/* put in front of list */
BLI_remlink(&sa->spacedata, sl);
BLI_addhead(&sa->spacedata, sl);
@@ -1694,7 +1694,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi
Scene *scene = WM_window_get_active_scene(win);
sl = st->new(sa, scene);
BLI_addhead(&sa->spacedata, sl);
-
+
/* swap regions */
if (slold)
slold->regionbase = sa->regionbase;
@@ -1702,18 +1702,18 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exi
BLI_listbase_clear(&sl->regionbase);
}
}
-
+
ED_area_initialize(CTX_wm_manager(C), win, sa);
-
+
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(C);
-
+
/* send space change notifier */
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CHANGED, sa);
-
+
ED_area_tag_refresh(sa);
}
-
+
/* also redraw when re-used */
ED_area_tag_redraw(sa);
}
@@ -1806,6 +1806,86 @@ BLI_INLINE bool streq_array_any(const char *s, const char *arr[])
return false;
}
+static void ed_panel_draw(const bContext *C,
+ ScrArea *sa,
+ ARegion *ar,
+ ListBase *lb,
+ PanelType *pt,
+ Panel *panel,
+ int w,
+ int em,
+ bool vertical)
+{
+ uiStyle *style = UI_style_get_dpi();
+
+ /* draw panel */
+ uiBlock *block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS);
+
+ bool open;
+ panel = UI_panel_begin(sa, ar, lb, block, pt, panel, &open);
+
+ /* bad fixed values */
+ int xco, yco, h = 0;
+
+ if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
+ int labelx, labely;
+ UI_panel_label_offset(block, &labelx, &labely);
+
+ /* for enabled buttons */
+ panel->layout = UI_block_layout(
+ block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
+ labelx, labely, UI_UNIT_Y, 1, 0, style);
+
+ pt->draw_header(C, panel);
+
+ UI_block_layout_resolve(block, &xco, &yco);
+ panel->labelofs = xco - labelx;
+ panel->layout = NULL;
+ }
+ else {
+ panel->labelofs = 0;
+ }
+
+ if (open) {
+ short panelContext;
+
+ /* panel context can either be toolbar region or normal panels region */
+ if (ar->regiontype == RGN_TYPE_TOOLS)
+ panelContext = UI_LAYOUT_TOOLBAR;
+ else
+ panelContext = UI_LAYOUT_PANEL;
+
+ panel->layout = UI_block_layout(
+ block, UI_LAYOUT_VERTICAL, panelContext,
+ style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
+
+ pt->draw(C, panel);
+
+ UI_block_layout_resolve(block, &xco, &yco);
+ panel->layout = NULL;
+
+ if (yco != 0) {
+ h = -yco + 2 * style->panelspace;
+ }
+ }
+
+ UI_block_end(C, block);
+
+ /* Draw child panels. */
+ if (open) {
+ for (LinkData *link = pt->children.first; link; link = link->next) {
+ PanelType *child_pt = link->data;
+ Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt);
+
+ if (child_pt->draw && (!child_pt->poll || child_pt->poll(C, child_pt))) {
+ ed_panel_draw(C, sa, ar, &panel->children, child_pt, child_panel, w, em, vertical);
+ }
+ }
+ }
+
+ UI_panel_end(block, w, h);
+}
+
/**
* \param contexts: A NULL terminated array of context strings to match against.
* Matching against any of these strings will draw the panel.
@@ -1815,13 +1895,10 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
{
const WorkSpace *workspace = CTX_wm_workspace(C);
ScrArea *sa = CTX_wm_area(C);
- uiStyle *style = UI_style_get_dpi();
- uiBlock *block;
PanelType *pt;
- Panel *panel;
View2D *v2d = &ar->v2d;
View2DScrollers *scrollers;
- int x, y, xco, yco, w, em, triangle;
+ int x, y, w, em;
bool is_context_new = 0;
int scroll;
@@ -1836,7 +1913,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
if (contextnr != -1)
is_context_new = UI_view2d_tab_set(v2d, contextnr);
-
+
/* before setting the view */
if (vertical) {
/* only allow scrolling in vertical direction */
@@ -1859,6 +1936,11 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
/* collect panels to draw */
for (pt = ar->type->paneltypes.last; pt; pt = pt->prev) {
+ /* Only draw top level panels. */
+ if (pt->parent) {
+ continue;
+ }
+
/* verify context */
if (contexts && pt->context[0] && !streq_array_any(pt->context, contexts)) {
continue;
@@ -1920,9 +2002,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt)
{
- bool open;
-
- panel = UI_panel_find_by_type(ar, pt);
+ Panel *panel = UI_panel_find_by_type(&ar->panels, pt);
if (use_category_tabs && pt->category[0] && !STREQ(category, pt->category)) {
if ((panel == NULL) || ((panel->flag & PNL_PIN) == 0)) {
@@ -1930,56 +2010,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
}
}
- /* draw panel */
- block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS);
- panel = UI_panel_begin(sa, ar, block, pt, panel, &open);
-
- /* bad fixed values */
- triangle = (int)(UI_UNIT_Y * 1.1f);
-
- if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
- /* for enabled buttons */
- panel->layout = UI_block_layout(
- block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
- triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style);
-
- pt->draw_header(C, panel);
-
- UI_block_layout_resolve(block, &xco, &yco);
- panel->labelofs = xco - triangle;
- panel->layout = NULL;
- }
- else {
- panel->labelofs = 0;
- }
-
- if (open) {
- short panelContext;
-
- /* panel context can either be toolbar region or normal panels region */
- if (ar->regiontype == RGN_TYPE_TOOLS)
- panelContext = UI_LAYOUT_TOOLBAR;
- else
- panelContext = UI_LAYOUT_PANEL;
-
- panel->layout = UI_block_layout(
- block, UI_LAYOUT_VERTICAL, panelContext,
- style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
-
- pt->draw(C, panel);
-
- UI_block_layout_resolve(block, &xco, &yco);
- panel->layout = NULL;
-
- yco -= 2 * style->panelspace;
- UI_panel_end(block, w, -yco);
- }
- else {
- yco = 0;
- UI_panel_end(block, w, 0);
- }
-
- UI_block_end(C, block);
+ ed_panel_draw(C, sa, ar, &ar->panels, pt, panel, w, em, vertical);
}
BLI_SMALLSTACK_ITER_END;
@@ -2029,7 +2060,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
}
region_clear_color(C, ar, (ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK);
-
+
/* reset line width for drawing tabs */
glLineWidth(1.0f);
@@ -2041,7 +2072,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
/* restore view matrix */
UI_view2d_view_restore(C);
-
+
if (use_category_tabs) {
UI_panel_category_draw_all(ar, category);
}
@@ -2095,7 +2126,7 @@ void ED_region_header_layout(const bContext *C, ARegion *ar)
header.type = ht;
header.layout = layout;
ht->draw(C, &header);
-
+
/* for view2d */
xco = uiLayoutGetWidth(layout);
if (xco > maxco)
@@ -2103,7 +2134,7 @@ void ED_region_header_layout(const bContext *C, ARegion *ar)
}
UI_block_layout_resolve(block, &xco, &yco);
-
+
/* for view2d */
if (xco > maxco)
maxco = xco;
@@ -2402,7 +2433,7 @@ static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const
if (metadata_is_valid(ibuf, temp_str, i, len)) {
BLF_position(fontid, xmin + ofs_x, ymin, 0.0f);
BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
-
+
ofs_x += BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX) + UI_UNIT_X;
}
}
@@ -2542,7 +2573,7 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
-
+
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShade(TH_BACK, 20);
immRectf(pos, x1, y1, x2, y2);
@@ -2576,14 +2607,14 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
GWN_vertformat_clear(format);
pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
-
+
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
immBegin(GWN_PRIM_LINES, 4 * count_fine + 4 * count_large);
-
+
float theme_color[3];
UI_GetThemeColorShade3fv(TH_BACK, (int)(20.0f * (1.0f - blendfac)), theme_color);
fac = 0.0f;
-
+
/* the fine resolution level */
for (int i = 0; i < count_fine; i++) {
immAttrib3fv(color, theme_color);
@@ -2600,7 +2631,7 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
if (count_large > 0) {
UI_GetThemeColor3fv(TH_BACK, theme_color);
fac = 0.0f;
-
+
/* the large resolution level */
for (int i = 0; i < count_large; i++) {
immAttrib3fv(color, theme_color);
@@ -2625,13 +2656,13 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
void ED_region_visible_rect(ARegion *ar, rcti *rect)
{
ARegion *arn = ar;
-
+
/* allow function to be called without area */
while (arn->prev)
arn = arn->prev;
-
+
*rect = ar->winrct;
-
+
/* check if a region overlaps with the current one */
for (; arn; arn = arn->next) {
if (ar != arn && arn->overlap) {
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 5d6abea06dc..1d73566e5a8 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -62,7 +62,7 @@ void setlinestyle(int nr)
glDisable(GL_LINE_STIPPLE);
}
else {
-
+
glEnable(GL_LINE_STIPPLE);
if (U.pixelsize > 1.0f)
glLineStipple(nr, 0xCCCC);
@@ -72,10 +72,10 @@ void setlinestyle(int nr)
}
/* Invert line handling */
-
+
#define GL_TOGGLE(mode, onoff) (((onoff) ? glEnable : glDisable)(mode))
-void set_inverted_drawing(int enable)
+void set_inverted_drawing(int enable)
{
glLogicOp(enable ? GL_INVERT : GL_COPY);
GL_TOGGLE(GL_COLOR_LOGIC_OP, enable);
@@ -355,18 +355,18 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
void bglPolygonOffset(float viewdist, float dist)
{
static float winmat[16], offset = 0.0f;
-
+
if (dist != 0.0f) {
float offs;
-
+
// glEnable(GL_POLYGON_OFFSET_FILL);
// glPolygonOffset(-1.0, -1.0);
/* hack below is to mimic polygon offset */
gpuGetProjectionMatrix(winmat);
-
+
/* dist is from camera to center point */
-
+
if (winmat[15] > 0.5f) {
#if 1
offs = 0.00001f * dist * viewdist; // ortho tweaking
@@ -391,7 +391,7 @@ void bglPolygonOffset(float viewdist, float dist)
*/
offs = winmat[14] * -0.0025f * dist;
}
-
+
winmat[14] -= offs;
offset += offs;
}
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 847cd06f45d..864150be9da 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -80,7 +80,7 @@ const char *screen_context_dir[] = {
"sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */
"gpencil_data", "gpencil_data_owner", /* grease pencil data */
"visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes",
- "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_palette",
+ "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_palette",
"active_gpencil_palettecolor", "active_gpencil_brush",
"active_operator", "selected_editable_fcurves",
NULL};
@@ -208,7 +208,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
EditBone *ebone, *flipbone = NULL;
const bool editable_bones = CTX_data_equals(member, "editable_bones");
-
+
if (arm && arm->edbo) {
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
@@ -259,7 +259,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
EditBone *ebone, *flipbone = NULL;
const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones");
-
+
if (arm && arm->edbo) {
uint objects_len;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
@@ -364,7 +364,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "active_pose_bone")) {
bPoseChannel *pchan;
Object *obpose = BKE_object_pose_armature_get(obact);
-
+
pchan = BKE_pose_channel_active(obpose);
if (pchan) {
CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
@@ -393,7 +393,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
/* convenience for now, 1 object per scene in editmode */
if (obedit)
CTX_data_id_pointer_set(result, &obedit->id);
-
+
return 1;
}
else if (CTX_data_equals(member, "sculpt_object")) {
@@ -465,11 +465,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "gpencil_data")) {
/* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations
- * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when
+ * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when
* called from context. For that reason, we end up using an alternative where we pass everything in!
*/
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
CTX_data_id_pointer_set(result, &gpd->id);
return 1;
@@ -477,14 +477,14 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "gpencil_data_owner")) {
/* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data)
- * XXX: see comment for gpencil_data case...
+ * XXX: see comment for gpencil_data case...
*/
bGPdata **gpd_ptr = NULL;
PointerRNA ptr;
-
+
/* get pointer to Grease Pencil Data */
gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr);
-
+
if (gpd_ptr) {
CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data);
return 1;
@@ -493,10 +493,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "active_gpencil_layer")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
if (gpl) {
CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl);
return 1;
@@ -544,10 +544,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "active_gpencil_frame")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
if (gpl) {
CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe);
return 1;
@@ -557,10 +557,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "visible_gpencil_layers")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl;
-
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if ((gpl->flag & GP_LAYER_HIDE) == 0) {
CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
@@ -573,10 +573,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "editable_gpencil_layers")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl;
-
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpencil_layer_is_editable(gpl)) {
CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
@@ -589,15 +589,15 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "editable_gpencil_strokes")) {
/* XXX: see comment for gpencil_data case... */
bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
-
+
if (gpd) {
bGPDlayer *gpl;
-
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) {
bGPDframe *gpf = gpl->actframe;
bGPDstroke *gps;
-
+
for (gps = gpf->strokes.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
/* check if the color is editable */
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 06f45fa0d00..ac4ab3461a3 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -81,7 +81,7 @@ static ScrVert *screen_addvert_ex(ScrAreaMap *area_map, short x, short y)
ScrVert *sv = MEM_callocN(sizeof(ScrVert), "addscrvert");
sv->vec.x = x;
sv->vec.y = y;
-
+
BLI_addtail(&area_map->vertbase, sv);
return sv;
}
@@ -129,7 +129,7 @@ ScrEdge *screen_area_map_find_active_scredge(
short min, max;
min = MIN2(se->v1->vec.x, se->v2->vec.x);
max = MAX2(se->v1->vec.x, se->v2->vec.x);
-
+
if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max)
return se;
}
@@ -139,7 +139,7 @@ ScrEdge *screen_area_map_find_active_scredge(
short min, max;
min = MIN2(se->v1->vec.y, se->v2->vec.y);
max = MAX2(se->v1->vec.y, se->v2->vec.y);
-
+
if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max)
return se;
}
@@ -201,11 +201,11 @@ static ScrArea *screen_addarea(
static void screen_delarea(bContext *C, bScreen *sc, ScrArea *sa)
{
-
+
ED_area_exit(C, sa);
-
+
BKE_screen_area_free(sa);
-
+
BLI_remlink(&sc->areabase, sa);
MEM_freeN(sa);
}
@@ -217,14 +217,14 @@ static short testsplitpoint(ScrArea *sa, char dir, float fac)
short x, y;
const short area_min_x = AREAMINX;
const short area_min_y = ED_area_headersize();
-
+
// area big enough?
if (dir == 'v' && (sa->v4->vec.x - sa->v1->vec.x <= 2 * area_min_x)) return 0;
if (dir == 'h' && (sa->v2->vec.y - sa->v1->vec.y <= 2 * area_min_y)) return 0;
-
+
// to be sure
CLAMP(fac, 0.0f, 1.0f);
-
+
if (dir == 'h') {
y = sa->v1->vec.y +
round_fl_to_short(fac * (float)(sa->v2->vec.y - sa->v1->vec.y));
@@ -254,12 +254,12 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
ScrArea *newa = NULL;
ScrVert *sv1, *sv2;
short split;
-
+
if (sa == NULL) return NULL;
-
+
split = testsplitpoint(sa, dir, fac);
if (split == 0) return NULL;
-
+
/* note regarding (fac > 0.5f) checks below.
* normally it shouldn't matter which is used since the copy should match the original
* however with viewport rendering and python console this isn't the case. - campbell */
@@ -268,14 +268,14 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
/* new vertices */
sv1 = screen_addvert(sc, sa->v1->vec.x, split);
sv2 = screen_addvert(sc, sa->v4->vec.x, split);
-
+
/* new edges */
screen_addedge(sc, sa->v1, sv1);
screen_addedge(sc, sv1, sa->v2);
screen_addedge(sc, sa->v3, sv2);
screen_addedge(sc, sv2, sa->v4);
screen_addedge(sc, sv1, sv2);
-
+
if (fac > 0.5f) {
/* new areas: top */
newa = screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->spacetype);
@@ -294,20 +294,20 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
}
ED_area_data_copy(newa, sa, true);
-
+
}
else {
/* new vertices */
sv1 = screen_addvert(sc, split, sa->v1->vec.y);
sv2 = screen_addvert(sc, split, sa->v2->vec.y);
-
+
/* new edges */
screen_addedge(sc, sa->v1, sv1);
screen_addedge(sc, sv1, sa->v4);
screen_addedge(sc, sa->v2, sv2);
screen_addedge(sc, sv2, sa->v3);
screen_addedge(sc, sv1, sv2);
-
+
if (fac > 0.5f) {
/* new areas: right */
newa = screen_addarea(sc, sv1, sv2, sa->v3, sa->v4, sa->spacetype);
@@ -327,25 +327,25 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
ED_area_data_copy(newa, sa, true);
}
-
+
/* remove double vertices en edges */
if (merge)
BKE_screen_remove_double_scrverts(sc);
BKE_screen_remove_double_scredges(sc);
BKE_screen_remove_unused_scredges(sc);
-
+
return newa;
}
/**
* Empty screen, with 1 dummy area without spacedata. Uses window size.
*/
-bScreen *screen_add(const char *name, const rcti *rect)
+bScreen *screen_add(Main *bmain, const char *name, const rcti *rect)
{
bScreen *sc;
ScrVert *sv1, *sv2, *sv3, *sv4;
-
- sc = BKE_libblock_alloc(G.main, ID_SCR, name, 0);
+
+ sc = BKE_libblock_alloc(bmain, ID_SCR, name, 0);
sc->do_refresh = true;
sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN;
@@ -353,15 +353,15 @@ bScreen *screen_add(const char *name, const rcti *rect)
sv2 = screen_addvert(sc, rect->xmin, rect->ymax - 1);
sv3 = screen_addvert(sc, rect->xmax - 1, rect->ymax - 1);
sv4 = screen_addvert(sc, rect->xmax - 1, rect->ymin);
-
+
screen_addedge(sc, sv1, sv2);
screen_addedge(sc, sv2, sv3);
screen_addedge(sc, sv3, sv4);
screen_addedge(sc, sv4, sv1);
-
+
/* dummy type, no spacedata */
screen_addarea(sc, sv1, sv2, sv3, sv4, SPACE_EMPTY);
-
+
return sc;
}
@@ -370,26 +370,26 @@ void screen_data_copy(bScreen *to, bScreen *from)
ScrVert *s1, *s2;
ScrEdge *se;
ScrArea *sa, *saf;
-
+
/* free contents of 'to', is from blenkernel screen.c */
BKE_screen_free(to);
-
+
BLI_duplicatelist(&to->vertbase, &from->vertbase);
BLI_duplicatelist(&to->edgebase, &from->edgebase);
BLI_duplicatelist(&to->areabase, &from->areabase);
BLI_listbase_clear(&to->regionbase);
-
+
s2 = to->vertbase.first;
for (s1 = from->vertbase.first; s1; s1 = s1->next, s2 = s2->next) {
s1->newv = s2;
}
-
+
for (se = to->edgebase.first; se; se = se->next) {
se->v1 = se->v1->newv;
se->v2 = se->v2->newv;
BKE_screen_sort_scrvert(&(se->v1), &(se->v2));
}
-
+
saf = from->areabase.first;
for (sa = to->areabase.first; sa; sa = sa->next, saf = saf->next) {
sa->v1 = sa->v1->newv;
@@ -401,10 +401,10 @@ void screen_data_copy(bScreen *to, bScreen *from)
BLI_listbase_clear(&sa->regionbase);
BLI_listbase_clear(&sa->actionzones);
BLI_listbase_clear(&sa->handlers);
-
+
ED_area_data_copy(sa, saf, true);
}
-
+
/* put at zero (needed?) */
for (s1 = from->vertbase.first; s1; s1 = s1->next)
s1->newv = NULL;
@@ -439,7 +439,7 @@ int area_getorientation(ScrArea *sa, ScrArea *sb)
sbv2 = sb->v2;
sbv3 = sb->v3;
sbv4 = sb->v4;
-
+
if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */
return 0;
}
@@ -452,7 +452,7 @@ int area_getorientation(ScrArea *sa, ScrArea *sb)
else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/
return 3;
}
-
+
return -1;
}
@@ -462,14 +462,14 @@ int area_getorientation(ScrArea *sa, ScrArea *sb)
int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2)
{
int dir;
-
+
dir = area_getorientation(sa1, sa2);
/*printf("dir is : %i\n", dir);*/
-
+
if (dir == -1) {
return 0;
}
-
+
if (dir == 0) {
sa1->v1 = sa2->v1;
sa1->v2 = sa2->v2;
@@ -494,7 +494,7 @@ int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2)
screen_addedge(scr, sa1->v1, sa1->v2);
screen_addedge(scr, sa1->v3, sa1->v4);
}
-
+
screen_delarea(C, scr, sa2);
BKE_screen_remove_double_scrverts(scr);
/* Update preview thumbnail */
@@ -509,20 +509,20 @@ void select_connected_scredge(const wmWindow *win, ScrEdge *edge)
ScrEdge *se;
int oneselected;
char dir;
-
+
/* select connected, only in the right direction */
/* 'dir' is the direction of EDGE */
-
+
if (edge->v1->vec.x == edge->v2->vec.x) dir = 'v';
else dir = 'h';
-
+
ED_screen_verts_iter(win, sc, sv) {
sv->flag = 0;
}
edge->v1->flag = 1;
edge->v2->flag = 1;
-
+
oneselected = 1;
while (oneselected) {
se = sc->edgebase.first;
@@ -675,7 +675,7 @@ static void screen_vertices_scale(
/* test for collapsed areas. This could happen in some blender version... */
/* ton: removed option now, it needs Context... */
-
+
/* make each window at least ED_area_headersize() high */
for (sa = sc->areabase.first; sa; sa = sa->next) {
int headery = headery_init;
@@ -784,7 +784,7 @@ static void screen_refresh_headersizes(void)
{
const ListBase *lb = BKE_spacetypes_list();
SpaceType *st;
-
+
for (st = lb->first; st; st = st->next) {
ARegionType *art = BKE_regiontype_from_id(st, RGN_TYPE_HEADER);
if (art) art->prefsizey = ED_area_headersize();
@@ -815,7 +815,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
/* sets subwindows for regions, adds handlers */
ED_area_initialize(wm, win, area);
}
-
+
/* wake up animtimer */
if (screen->animtimer)
WM_event_timer_sleep(wm, win, screen->animtimer, false);
@@ -832,10 +832,10 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
}
/* file read, set all screens, ... */
-void ED_screens_initialize(wmWindowManager *wm)
+void ED_screens_initialize(Main *UNUSED(bmain), wmWindowManager *wm)
{
wmWindow *win;
-
+
for (win = wm->windows.first; win; win = win->next) {
if (WM_window_get_active_workspace(win) == NULL) {
WM_window_set_active_workspace(win, G.main->workspaces.first);
@@ -875,12 +875,12 @@ void ED_region_exit(bContext *C, ARegion *ar)
WM_event_remove_handlers(C, &ar->handlers);
WM_event_modal_handler_region_replace(win, ar, NULL);
WM_draw_region_free(ar);
-
+
if (ar->headerstr) {
MEM_freeN(ar->headerstr);
ar->headerstr = NULL;
}
-
+
if (ar->regiontimer) {
WM_event_remove_timer(wm, win, ar->regiontimer);
ar->regiontimer = NULL;
@@ -918,14 +918,14 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
wmWindow *prevwin = CTX_wm_window(C);
CTX_wm_window_set(C, window);
-
+
if (screen->animtimer)
WM_event_remove_timer(wm, window, screen->animtimer);
screen->animtimer = NULL;
screen->scrubbing = false;
screen->active_region = NULL;
-
+
for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) {
ED_region_exit(C, ar);
}
@@ -939,7 +939,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
/* mark it available for use for other windows */
screen->winid = 0;
-
+
if (!WM_window_is_temp_screen(prevwin)) {
/* use previous window if possible */
CTX_wm_window_set(C, prevwin);
@@ -948,7 +948,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
/* none otherwise */
CTX_wm_window_set(C, NULL);
}
-
+
}
/* *********************************** */
@@ -959,11 +959,11 @@ static void screen_cursor_set(wmWindow *win, const int xy[2])
const bScreen *screen = WM_window_get_active_screen(win);
AZone *az = NULL;
ScrArea *sa;
-
+
for (sa = screen->areabase.first; sa; sa = sa->next)
if ((az = is_in_area_actionzone(sa, xy)))
break;
-
+
if (sa) {
if (az->type == AZONE_AREA)
WM_cursor_set(win, CURSOR_EDIT);
@@ -1021,19 +1021,19 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
}
else
scr->active_region = NULL;
-
+
/* check for redraw headers */
if (old_ar != scr->active_region) {
ED_screen_areas_iter(win, scr, area_iter) {
bool do_draw = false;
-
+
for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
if (ar == old_ar || ar == scr->active_region) {
do_draw = true;
}
}
-
+
if (do_draw) {
for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_HEADER) {
@@ -1043,7 +1043,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
}
}
}
-
+
/* cursors, for time being set always on edges, otherwise aregion doesnt switch */
if (scr->active_region == NULL) {
screen_cursor_set(win, xy);
@@ -1075,10 +1075,10 @@ int ED_screen_area_active(const bContext *C)
if (win && sc && sa) {
AZone *az = is_in_area_actionzone(sa, &win->eventstate->x);
ARegion *ar;
-
+
if (az && az->type == AZONE_REGION)
return 1;
-
+
for (ar = sa->regionbase.first; ar; ar = ar->next)
if (ar == sc->active_region)
return 1;
@@ -1277,13 +1277,13 @@ static void screen_set_3dview_camera(Scene *scene, ViewLayer *view_layer, ScrAre
if (!v3d->camera) {
ARegion *ar;
ListBase *regionbase;
-
+
/* regionbase is in different place depending if space is active */
if (v3d == sa->spacedata.first)
regionbase = &sa->regionbase;
else
regionbase = &v3d->regionbase;
-
+
for (ar = regionbase->first; ar; ar = ar->next) {
if (ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = ar->regiondata;
@@ -1316,7 +1316,7 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
if (!sa || sa->full == NULL) {
newsa = ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED);
}
-
+
if (!newsa) {
newsa = sa;
}
@@ -1373,10 +1373,10 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa)
SpaceLink *sl = sa->spacedata.first;
bScreen *screen = CTX_wm_screen(C);
short state = (screen ? screen->state : SCREENMAXIMIZED);
-
+
/* if fullscreen area has a temporary space (such as a file browser or fullscreen render
* overlaid on top of an existing setup) then return to the previous space */
-
+
if (sl->next) {
if (sa->flag & AREA_FLAG_TEMP_TYPE) {
ED_screen_full_prevspace(C, sa);
@@ -1399,6 +1399,7 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa)
*/
ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const short state)
{
+ Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
WorkSpace *workspace = WM_window_get_active_workspace(win);
bScreen *sc, *oldscreen;
@@ -1489,7 +1490,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
oldscreen->state = state;
BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal");
- layout_new = ED_workspace_layout_add(workspace, win, newname);
+ layout_new = ED_workspace_layout_add(bmain, workspace, win, newname);
sc = BKE_workspace_layout_screen_get(layout_new);
sc->state = state;
@@ -1502,7 +1503,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
/* use random area when we have no active one, e.g. when the
* mouse is outside of the window and we open a file browser */
- if (!sa) {
+ if (!sa || sa->global) {
sa = oldscreen->areabase.first;
}
@@ -1544,15 +1545,15 @@ void ED_refresh_viewport_fps(bContext *C)
{
wmTimer *animtimer = CTX_wm_screen(C)->animtimer;
Scene *scene = CTX_data_scene(C);
-
+
/* is anim playback running? */
if (animtimer && (U.uiflag & USER_SHOW_FPS)) {
ScreenFrameRateInfo *fpsi = scene->fps_info;
-
+
/* if there isn't any info, init it first */
if (fpsi == NULL)
fpsi = scene->fps_info = MEM_callocN(sizeof(ScreenFrameRateInfo), "refresh_viewport_fps fps_info");
-
+
/* update the values */
fpsi->redrawtime = fpsi->lredrawtime;
fpsi->lredrawtime = animtimer->ltime;
@@ -1565,7 +1566,7 @@ void ED_refresh_viewport_fps(bContext *C)
}
}
-/* redraws: uses defines from stime->redraws
+/* redraws: uses defines from stime->redraws
* enable: 1 - forward on, -1 - backwards on, 0 - off
*/
void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync, int enable)
@@ -1575,17 +1576,17 @@ void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync,
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
bScreen *stopscreen = ED_screen_animation_playing(wm);
-
+
if (stopscreen) {
WM_event_remove_timer(wm, win, stopscreen->animtimer);
stopscreen->animtimer = NULL;
}
-
+
if (enable) {
ScreenAnimData *sad = MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData");
-
+
screen->animtimer = WM_event_add_timer(wm, win, TIMER0, (1.0 / FPS));
-
+
sad->ar = CTX_wm_region(C);
/* if startframe is larger than current frame, we put currentframe on startframe.
* note: first frame then is not drawn! (ton) */
@@ -1620,7 +1621,7 @@ void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync,
sad->from_anim_edit = (ELEM(spacetype, SPACE_IPO, SPACE_ACTION, SPACE_NLA));
screen->animtimer->customdata = sad;
-
+
}
/* notifier catched by top header, for button */
@@ -1633,7 +1634,7 @@ static ARegion *time_top_left_3dwindow(bScreen *screen)
ARegion *aret = NULL;
ScrArea *sa;
int min = 10000;
-
+
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->spacetype == SPACE_VIEW3D) {
ARegion *ar;
@@ -1656,7 +1657,7 @@ void ED_screen_animation_timer_update(bScreen *screen, int redraws, int refresh)
if (screen && screen->animtimer) {
wmTimer *wt = screen->animtimer;
ScreenAnimData *sad = wt->customdata;
-
+
sad->redraws = redraws;
sad->refresh = refresh;
sad->ar = NULL;
@@ -1681,7 +1682,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
}
}
#endif
-
+
ED_clip_update_frame(bmain, scene->r.cfra);
/* this function applies the changes too */
@@ -1690,7 +1691,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
/* composite */
if (scene->use_nodes && scene->nodetree)
ntreeCompositTagAnimated(scene->nodetree);
-
+
/* update animated texture nodes */
{
Tex *tex;
@@ -1700,7 +1701,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
}
}
}
-
+
}
/*
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index adfd7b185ab..b02198764e0 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -48,7 +48,7 @@ void screen_area_update_region_sizes(wmWindowManager *wm, wmWindow *win,
void region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade);
/* screen_edit.c */
-bScreen *screen_add(const char *name, const rcti *rect);
+bScreen *screen_add(struct Main *bmain, const char *name, const rcti *rect);
void screen_data_copy(bScreen *to, bScreen *from);
void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new);
void screen_change_update(struct bContext *C, wmWindow *win, bScreen *sc);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index dd808d122d2..f6bd238170d 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -171,11 +171,11 @@ int ED_operator_objectmode(bContext *C)
return 0;
if (CTX_data_edit_object(C))
return 0;
-
+
/* add a check for ob->mode too? */
if (obact && (obact->mode != OB_MODE_OBJECT))
return 0;
-
+
return 1;
}
@@ -252,20 +252,20 @@ int ED_operator_buttons_active(bContext *C)
int ED_operator_node_active(bContext *C)
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
if (snode && snode->edittree)
return 1;
-
+
return 0;
}
int ED_operator_node_editable(bContext *C)
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
if (snode && snode->edittree && !ID_IS_LINKED(snode->edittree))
return 1;
-
+
return 0;
}
@@ -451,15 +451,15 @@ int ED_operator_uvmap(bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = NULL;
-
+
if (obedit && obedit->type == OB_MESH) {
em = BKE_editmesh_from_object(obedit);
}
-
+
if (em && (em->bm->totface)) {
return true;
}
-
+
return false;
}
@@ -606,7 +606,7 @@ static ARegion *screen_find_region_type(bContext *C, int type)
/** \name Action Zone Operator
* \{ */
-/* operator state vars used:
+/* operator state vars used:
* none
*
* functions:
@@ -639,11 +639,11 @@ static int actionzone_area_poll(bContext *C)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
-
+
if (sa && win && win->eventstate) {
const int *xy = &win->eventstate->x;
AZone *az;
-
+
for (az = sa->actionzones.first; az; az = az->next)
if (BLI_rcti_isect_pt_v(&az->rect, xy))
return 1;
@@ -672,13 +672,13 @@ static void fullscreen_click_rcti_init(rcti *rect, const short x1, const short y
AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2])
{
AZone *az = NULL;
-
+
for (az = sa->actionzones.first; az; az = az->next) {
if (BLI_rcti_isect_pt_v(&az->rect, xy)) {
if (az->type == AZONE_AREA) {
/* no triangle intersect but a hotspot circle based on corner */
int radius = (xy[0] - az->x1) * (xy[0] - az->x1) + (xy[1] - az->y1) * (xy[1] - az->y1);
-
+
if (radius <= AZONESPOT * AZONESPOT)
break;
}
@@ -776,7 +776,7 @@ AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2])
}
}
}
-
+
return az;
}
@@ -794,9 +794,9 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
wmEvent event;
wmWindow *win = CTX_wm_window(C);
sActionzoneData *sad = op->customdata;
-
+
sad->modifier = RNA_int_get(op->ptr, "modifier");
-
+
wm_event_init_from_window(win, &event);
if (type == AZONE_AREA)
@@ -810,7 +810,7 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
event.customdata = op->customdata;
event.customdatafree = true;
op->customdata = NULL;
-
+
wm_event_add(win, &event);
}
@@ -819,17 +819,17 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ScrArea *sa = CTX_wm_area(C);
AZone *az = is_in_area_actionzone(sa, &event->x);
sActionzoneData *sad;
-
+
/* quick escape */
if (az == NULL)
return OPERATOR_PASS_THROUGH;
-
+
/* ok we do the actionzone */
sad = op->customdata = MEM_callocN(sizeof(sActionzoneData), "sActionzoneData");
sad->sa1 = sa;
sad->az = az;
sad->x = event->x; sad->y = event->y;
-
+
/* region azone directly reacts on mouse clicks */
if (ELEM(sad->az->type, AZONE_REGION, AZONE_FULLSCREEN)) {
actionzone_apply(C, op, sad->az->type);
@@ -842,7 +842,7 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else {
/* add modal handler */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
}
@@ -870,7 +870,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
sad->gesture_dir = 's';
else
sad->gesture_dir = 'w';
-
+
if (sad->az->type == AZONE_AREA) {
const wmWindow *win = CTX_wm_window(C);
rcti screen_rect;
@@ -894,7 +894,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* apply sends event */
actionzone_apply(C, op, sad->az->type);
actionzone_exit(op);
-
+
return OPERATOR_FINISHED;
}
break;
@@ -905,9 +905,9 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
case LEFTMOUSE:
actionzone_exit(op);
return OPERATOR_CANCELLED;
-
+
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -922,15 +922,15 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot)
ot->name = "Handle Area Action Zones";
ot->description = "Handle area action zones for mouse actions/gestures";
ot->idname = "SCREEN_OT_actionzone";
-
+
ot->invoke = actionzone_invoke;
ot->modal = actionzone_modal;
ot->poll = actionzone_area_poll;
ot->cancel = actionzone_cancel;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
+
RNA_def_int(ot->srna, "modifier", 0, 0, 2, "Modifier", "Modifier state", 0, 2);
}
@@ -968,15 +968,15 @@ static int area_swap_init(wmOperator *op, const wmEvent *event)
{
sAreaSwapData *sd = NULL;
sActionzoneData *sad = event->customdata;
-
+
if (sad == NULL || sad->sa1 == NULL)
return 0;
-
+
sd = MEM_callocN(sizeof(sAreaSwapData), "sAreaSwapData");
sd->sa1 = sad->sa1;
sd->sa2 = sad->sa2;
op->customdata = sd;
-
+
return 1;
}
@@ -996,22 +996,22 @@ static void area_swap_cancel(bContext *C, wmOperator *op)
static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
-
+
if (!area_swap_init(op, event))
return OPERATOR_PASS_THROUGH;
-
+
/* add modal handler */
WM_cursor_modal_set(CTX_wm_window(C), BC_SWAPAREA_CURSOR);
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
-
+
}
static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sActionzoneData *sad = op->customdata;
-
+
switch (event->type) {
case MOUSEMOVE:
/* second area, for join */
@@ -1028,15 +1028,15 @@ static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
ED_area_tag_redraw(sad->sa2);
ED_area_swapspace(C, sad->sa1, sad->sa2);
-
+
area_swap_exit(C, op);
-
+
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
break;
-
+
case ESCKEY:
area_swap_cancel(C, op);
return OPERATOR_CANCELLED;
@@ -1049,12 +1049,12 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
ot->name = "Swap Areas";
ot->description = "Swap selected areas screen positions";
ot->idname = "SCREEN_OT_area_swap";
-
+
ot->invoke = area_swap_invoke;
ot->modal = area_swap_modal;
ot->poll = ED_operator_areaactive;
ot->cancel = area_swap_cancel;
-
+
ot->flag = OPTYPE_BLOCKING;
}
@@ -1069,6 +1069,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
/* operator callback */
static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ Main *bmain = CTX_data_main(C);
wmWindow *newwin, *win = CTX_wm_window(C);
Scene *scene;
WorkSpace *workspace = WM_window_get_active_workspace(win);
@@ -1077,18 +1078,18 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bScreen *newsc;
ScrArea *sa;
rcti rect;
-
+
win = CTX_wm_window(C);
scene = CTX_data_scene(C);
sa = CTX_wm_area(C);
-
+
/* XXX hrmf! */
if (event->type == EVT_ACTIONZONE_AREA) {
sActionzoneData *sad = event->customdata;
-
+
if (sad == NULL)
return OPERATOR_PASS_THROUGH;
-
+
sa = sad->sa1;
}
@@ -1110,7 +1111,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
WM_window_set_active_workspace(newwin, workspace);
/* allocs new screen and adds to newly created window, using window size */
- layout_new = ED_workspace_layout_add(workspace, newwin, BKE_workspace_layout_name_get(layout_old));
+ layout_new = ED_workspace_layout_add(bmain, workspace, newwin, BKE_workspace_layout_name_get(layout_old));
newsc = BKE_workspace_layout_screen_get(layout_new);
WM_window_set_active_layout(newwin, workspace, layout_new);
@@ -1126,7 +1127,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
finally:
if (event->type == EVT_ACTIONZONE_AREA)
actionzone_exit(op);
-
+
if (newwin) {
return OPERATOR_FINISHED;
}
@@ -1140,7 +1141,7 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot)
ot->name = "Duplicate Area into New Window";
ot->description = "Duplicate selected area into new window";
ot->idname = "SCREEN_OT_area_dupli";
-
+
ot->invoke = area_dupli_invoke;
ot->poll = ED_operator_areaactive;
}
@@ -1151,7 +1152,7 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot)
/** \name Move Area Edge Operator
* \{ */
-/* operator state vars used:
+/* operator state vars used:
* x, y mouse coord near edge
* delta movement of edge
*
@@ -1252,14 +1253,14 @@ static void area_move_set_limits(
if (dir == 'h') {
int y1;
areamin = areaminy;
-
+
if (sa->v1->vec.y > screen_rect->ymin)
areamin += U.pixelsize;
if (sa->v2->vec.y < (screen_rect->ymax - 1))
areamin += U.pixelsize;
-
+
y1 = sa->v2->vec.y - sa->v1->vec.y + 1 - areamin;
-
+
/* if top or down edge selected, test height */
if (sa->v1->editflag && sa->v4->editflag)
*bigger = min_ii(*bigger, y1);
@@ -1269,14 +1270,14 @@ static void area_move_set_limits(
else {
int x1;
areamin = AREAMINX;
-
+
if (sa->v1->vec.x > screen_rect->xmin)
areamin += U.pixelsize;
if (sa->v4->vec.x < (screen_rect->xmax - 1))
areamin += U.pixelsize;
-
+
x1 = sa->v4->vec.x - sa->v1->vec.x + 1 - areamin;
-
+
/* if left or right edge selected, test width */
if (sa->v1->editflag && sa->v2->editflag)
*bigger = min_ii(*bigger, x1);
@@ -1296,22 +1297,22 @@ static int area_move_init(bContext *C, wmOperator *op)
sAreaMoveData *md;
rcti screen_rect;
int x, y;
-
+
/* required properties */
x = RNA_int_get(op->ptr, "x");
y = RNA_int_get(op->ptr, "y");
-
+
/* setup */
actedge = screen_find_active_scredge(win, sc, x, y);
if (actedge == NULL) return 0;
-
+
md = MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData");
op->customdata = md;
-
+
md->dir = scredge_is_horizontal(actedge) ? 'h' : 'v';
if (md->dir == 'h') md->origval = actedge->v1->vec.y;
else md->origval = actedge->v1->vec.x;
-
+
select_connected_scredge(win, actedge);
/* now all vertices with 'flag == 1' are the ones that can be moved. Move this to editflag */
ED_screen_verts_iter(win, sc, v1) {
@@ -1388,6 +1389,8 @@ static int area_snap_calc_location(
}
break;
}
+ case SNAP_NONE:
+ break;
}
return final_loc;
@@ -1468,7 +1471,7 @@ static void area_move_exit(bContext *C, wmOperator *op)
if (op->customdata)
MEM_freeN(op->customdata);
op->customdata = NULL;
-
+
/* this makes sure aligned edges will result in aligned grabbing */
BKE_screen_remove_double_scrverts(CTX_wm_screen(C));
BKE_screen_remove_double_scredges(CTX_wm_screen(C));
@@ -1478,10 +1481,10 @@ static int area_move_exec(bContext *C, wmOperator *op)
{
if (!area_move_init(C, op))
return OPERATOR_CANCELLED;
-
+
area_move_apply(C, op);
area_move_exit(C, op);
-
+
return OPERATOR_FINISHED;
}
@@ -1490,19 +1493,19 @@ static int area_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set(op->ptr, "x", event->x);
RNA_int_set(op->ptr, "y", event->y);
-
- if (!area_move_init(C, op))
+
+ if (!area_move_init(C, op))
return OPERATOR_PASS_THROUGH;
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
static void area_move_cancel(bContext *C, wmOperator *op)
{
-
+
RNA_int_set(op->ptr, "delta", 0);
area_move_apply(C, op);
area_move_exit(C, op);
@@ -1513,17 +1516,17 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sAreaMoveData *md = op->customdata;
int delta, x, y;
-
+
/* execute the events */
switch (event->type) {
case MOUSEMOVE:
{
x = RNA_int_get(op->ptr, "x");
y = RNA_int_get(op->ptr, "y");
-
+
delta = (md->dir == 'v') ? event->x - x : event->y - y;
RNA_int_set(op->ptr, "delta", delta);
-
+
area_move_apply(C, op);
break;
}
@@ -1533,7 +1536,7 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
case KM_MODAL_APPLY:
area_move_exit(C, op);
return OPERATOR_FINISHED;
-
+
case KM_MODAL_CANCEL:
area_move_cancel(C, op);
return OPERATOR_CANCELLED;
@@ -1553,7 +1556,7 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
}
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -1563,16 +1566,16 @@ static void SCREEN_OT_area_move(wmOperatorType *ot)
ot->name = "Move Area Edges";
ot->description = "Move selected area edges";
ot->idname = "SCREEN_OT_area_move";
-
+
ot->exec = area_move_exec;
ot->invoke = area_move_invoke;
ot->cancel = area_move_cancel;
ot->modal = area_move_modal;
ot->poll = ED_operator_screen_mainwinactive; /* when mouse is over area-edge */
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
+
/* rna */
RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
@@ -1631,7 +1634,7 @@ typedef struct sAreaSplitData {
ScrEdge *nedge; /* new edge */
ScrArea *sarea; /* start area */
ScrArea *narea; /* new area */
-
+
} sAreaSplitData;
static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdata)
@@ -1651,11 +1654,11 @@ static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdat
static int area_split_menu_init(bContext *C, wmOperator *op)
{
sAreaSplitData *sd;
-
+
/* custom data */
sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split");
op->customdata = sd;
-
+
sd->sarea = CTX_wm_area(C);
return 1;
@@ -1668,21 +1671,21 @@ static int area_split_init(bContext *C, wmOperator *op)
sAreaSplitData *sd;
int areaminy = ED_area_headersize();
int dir;
-
+
/* required context */
if (sa == NULL) return 0;
-
+
/* required properties */
dir = RNA_enum_get(op->ptr, "direction");
-
+
/* minimal size */
if (dir == 'v' && sa->winx < 2 * AREAMINX) return 0;
if (dir == 'h' && sa->winy < 2 * areaminy) return 0;
-
+
/* custom data */
sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split");
op->customdata = sd;
-
+
sd->sarea = sa;
if (dir == 'v') {
sd->origmin = sa->v1->vec.x;
@@ -1708,7 +1711,7 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb)
ScrVert *sbv2 = sb->v2;
ScrVert *sbv3 = sb->v3;
ScrVert *sbv4 = sb->v4;
-
+
if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */
return BKE_screen_find_edge(screen, sav1, sav2);
}
@@ -1721,7 +1724,7 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb)
else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/
return BKE_screen_find_edge(screen, sav1, sav4);
}
-
+
return NULL;
}
@@ -1733,24 +1736,24 @@ static int area_split_apply(bContext *C, wmOperator *op)
sAreaSplitData *sd = (sAreaSplitData *)op->customdata;
float fac;
int dir;
-
+
fac = RNA_float_get(op->ptr, "factor");
dir = RNA_enum_get(op->ptr, "direction");
-
+
sd->narea = area_split(sc, sd->sarea, dir, fac, 0); /* 0 = no merge */
-
+
if (sd->narea) {
ScrVert *sv;
-
+
sd->nedge = area_findsharededge(sc, sd->sarea, sd->narea);
-
+
/* select newly created edge, prepare for moving edge */
for (sv = sc->vertbase.first; sv; sv = sv->next)
sv->editflag = 0;
-
+
sd->nedge->v1->editflag = 1;
sd->nedge->v2->editflag = 1;
-
+
if (dir == 'h') sd->origval = sd->nedge->v1->vec.y;
else sd->origval = sd->nedge->v1->vec.x;
@@ -1763,7 +1766,7 @@ static int area_split_apply(bContext *C, wmOperator *op)
return 1;
}
-
+
return 0;
}
@@ -1780,10 +1783,10 @@ static void area_split_exit(bContext *C, wmOperator *op)
MEM_freeN(op->customdata);
op->customdata = NULL;
}
-
+
WM_cursor_modal_restore(CTX_wm_window(C));
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+
/* this makes sure aligned edges will result in aligned grabbing */
BKE_screen_remove_double_scrverts(CTX_wm_screen(C));
BKE_screen_remove_double_scredges(CTX_wm_screen(C));
@@ -1804,7 +1807,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
sAreaSplitData *sd;
rcti screen_rect;
int dir;
-
+
/* no full window splitting allowed */
if (sc->state != SCREENNORMAL)
return OPERATOR_CANCELLED;
@@ -1813,19 +1816,19 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == EVT_ACTIONZONE_AREA) {
sActionzoneData *sad = event->customdata;
-
+
if (sad == NULL || sad->modifier > 0) {
return OPERATOR_PASS_THROUGH;
}
-
+
/* verify *sad itself */
if (sad->sa1 == NULL || sad->az == NULL)
return OPERATOR_PASS_THROUGH;
-
+
/* is this our *sad? if areas not equal it should be passed on */
if (CTX_wm_area(C) != sad->sa1 || sad->sa1 != sad->sa2)
return OPERATOR_PASS_THROUGH;
-
+
/* prepare operator state vars */
if (sad->gesture_dir == 'n' || sad->gesture_dir == 's') {
dir = 'h';
@@ -1836,22 +1839,22 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
RNA_float_set(op->ptr, "factor", ((float)(event->y - sad->sa1->v1->vec.y)) / (float)sad->sa1->winy);
}
RNA_enum_set(op->ptr, "direction", dir);
-
+
/* general init, also non-UI case, adds customdata, sets area and defaults */
if (!area_split_init(C, op))
return OPERATOR_PASS_THROUGH;
-
+
}
else {
ScrEdge *actedge;
int x, y;
-
+
/* retrieve initial mouse coord, so we can find the active edge */
if (RNA_struct_property_is_set(op->ptr, "mouse_x"))
x = RNA_int_get(op->ptr, "mouse_x");
else
x = event->x;
-
+
if (RNA_struct_property_is_set(op->ptr, "mouse_y"))
y = RNA_int_get(op->ptr, "mouse_y");
else
@@ -1860,28 +1863,28 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
actedge = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &screen_rect, x, y);
if (actedge == NULL)
return OPERATOR_CANCELLED;
-
+
dir = scredge_is_horizontal(actedge) ? 'v' : 'h';
-
+
RNA_enum_set(op->ptr, "direction", dir);
-
+
/* special case, adds customdata, sets defaults */
if (!area_split_menu_init(C, op))
return OPERATOR_CANCELLED;
-
+
}
-
+
sd = (sAreaSplitData *)op->customdata;
-
+
if (event->type == EVT_ACTIONZONE_AREA) {
-
+
/* do the split */
if (area_split_apply(C, op)) {
area_move_set_limits(win, sc, dir, &screen_rect, &sd->bigger, &sd->smaller, NULL);
/* add temp handler for edge move or cancel */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
}
@@ -1893,22 +1896,22 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
area_split_preview_update_cursor(C, op);
return OPERATOR_RUNNING_MODAL;
-
+
}
-
+
return OPERATOR_PASS_THROUGH;
}
/* function to be called outside UI context, or for redo */
static int area_split_exec(bContext *C, wmOperator *op)
{
-
+
if (!area_split_init(C, op))
return OPERATOR_CANCELLED;
-
+
area_split_apply(C, op);
area_split_exit(C, op);
-
+
return OPERATOR_FINISHED;
}
@@ -1916,7 +1919,7 @@ static int area_split_exec(bContext *C, wmOperator *op)
static void area_split_cancel(bContext *C, wmOperator *op)
{
sAreaSplitData *sd = (sAreaSplitData *)op->customdata;
-
+
if (sd->previewmode) {
/* pass */
}
@@ -1957,7 +1960,7 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
break;
-
+
case MIDDLEMOUSE:
case TABKEY:
if (sd->previewmode == 0) {
@@ -1973,9 +1976,9 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
}
-
+
break;
-
+
case RIGHTMOUSE: /* cancel operation */
case ESCKEY:
area_split_cancel(C, op);
@@ -2054,17 +2057,17 @@ static void SCREEN_OT_area_split(wmOperatorType *ot)
ot->name = "Split Area";
ot->description = "Split selected area into new windows";
ot->idname = "SCREEN_OT_area_split";
-
+
ot->exec = area_split_exec;
ot->invoke = area_split_invoke;
ot->modal = area_split_modal;
ot->cancel = area_split_cancel;
-
+
ot->poll = screen_active_editable;
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
+
/* rna */
RNA_def_enum(ot->srna, "direction", prop_direction_items, 'h', "Direction", "");
RNA_def_float(ot->srna, "factor", 0.5f, 0.0, 1.0, "Factor", "", 0.0, 1.0);
@@ -2086,7 +2089,7 @@ typedef struct RegionMoveData {
int origx, origy;
int maxsize;
AZEdge edge;
-
+
} RegionMoveData;
@@ -2094,20 +2097,20 @@ static int area_max_regionsize(ScrArea *sa, ARegion *scalear, AZEdge edge)
{
ARegion *ar;
int dist;
-
+
if (edge == AE_RIGHT_TO_TOPLEFT || edge == AE_LEFT_TO_TOPRIGHT) {
dist = BLI_rcti_size_x(&sa->totrct);
}
else { /* AE_BOTTOM_TO_TOPLEFT, AE_TOP_TO_BOTTOMRIGHT */
dist = BLI_rcti_size_y(&sa->totrct);
}
-
- /* subtractwidth of regions on opposite side
+
+ /* subtractwidth of regions on opposite side
* prevents dragging regions into other opposite regions */
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar == scalear)
continue;
-
+
if (scalear->alignment == RGN_ALIGN_TOP && ar->alignment == RGN_ALIGN_BOTTOM)
dist -= ar->winy;
else if (scalear->alignment == RGN_ALIGN_BOTTOM && ar->alignment == RGN_ALIGN_TOP)
@@ -2116,7 +2119,7 @@ static int area_max_regionsize(ScrArea *sa, ARegion *scalear, AZEdge edge)
dist -= ar->winx;
else if (scalear->alignment == RGN_ALIGN_RIGHT && ar->alignment == RGN_ALIGN_LEFT)
dist -= ar->winx;
-
+
/* case of regions in regions, like operator properties panel */
/* these can sit on top of other regions such as headers, so account for this */
else if (edge == AE_BOTTOM_TO_TOPLEFT && scalear->alignment & RGN_ALIGN_TOP &&
@@ -2138,20 +2141,20 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event
{
sActionzoneData *sad = event->customdata;
AZone *az;
-
+
if (event->type != EVT_ACTIONZONE_REGION) {
BKE_report(op->reports, RPT_ERROR, "Can only scale region size from an action zone");
return OPERATOR_CANCELLED;
}
-
+
az = sad->az;
-
+
if (az->ar) {
RegionMoveData *rmd = MEM_callocN(sizeof(RegionMoveData), "RegionMoveData");
int maxsize;
-
+
op->customdata = rmd;
-
+
rmd->az = az;
rmd->ar = az->ar;
rmd->sa = sad->sa1;
@@ -2159,13 +2162,13 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event
rmd->origx = event->x;
rmd->origy = event->y;
rmd->maxsize = area_max_regionsize(rmd->sa, rmd->ar, rmd->edge);
-
+
/* if not set we do now, otherwise it uses type */
if (rmd->ar->sizex == 0)
rmd->ar->sizex = rmd->ar->winx;
if (rmd->ar->sizey == 0)
rmd->ar->sizey = rmd->ar->winy;
-
+
/* now copy to regionmovedata */
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
rmd->origval = rmd->ar->sizex;
@@ -2173,21 +2176,21 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event
else {
rmd->origval = rmd->ar->sizey;
}
-
+
/* limit headers to standard height for now */
if (rmd->ar->regiontype == RGN_TYPE_HEADER)
maxsize = ED_area_headersize();
else
maxsize = 1000;
-
+
CLAMP(rmd->maxsize, 0, maxsize);
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
-
+
return OPERATOR_FINISHED;
}
@@ -2243,7 +2246,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionMoveData *rmd = op->customdata;
int delta;
-
+
/* execute the events */
switch (event->type) {
case MOUSEMOVE:
@@ -2253,10 +2256,10 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) {
delta = event->x - rmd->origx;
if (rmd->edge == AE_LEFT_TO_TOPRIGHT) delta = -delta;
-
+
/* region sizes now get multiplied */
delta /= UI_DPI_FAC;
-
+
rmd->ar->sizex = rmd->origval + delta;
if (rmd->ar->type->snap_size) {
@@ -2279,7 +2282,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
int maxsize = region_scale_get_maxsize(rmd);
delta = event->y - rmd->origy;
if (rmd->edge == AE_BOTTOM_TO_TOPLEFT) delta = -delta;
-
+
/* region sizes now get multiplied */
delta /= UI_DPI_FAC;
@@ -2301,19 +2304,19 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (!(rmd->ar->flag & RGN_FLAG_HIDDEN))
region_scale_toggle_hidden(C, rmd);
}
- else if (maxsize > 0 && (rmd->ar->sizey > maxsize))
+ else if (maxsize > 0 && (rmd->ar->sizey > maxsize))
rmd->ar->sizey = maxsize;
else if (rmd->ar->flag & RGN_FLAG_HIDDEN)
region_scale_toggle_hidden(C, rmd);
}
ED_area_tag_redraw(rmd->sa);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+
break;
}
case LEFTMOUSE:
if (event->val == KM_RELEASE) {
-
+
if (ABS(event->x - rmd->origx) < 2 && ABS(event->y - rmd->origy) < 2) {
if (rmd->ar->flag & RGN_FLAG_HIDDEN) {
region_scale_toggle_hidden(C, rmd);
@@ -2327,15 +2330,15 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
MEM_freeN(op->customdata);
op->customdata = NULL;
-
+
return OPERATOR_FINISHED;
}
break;
-
+
case ESCKEY:
break;
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -2351,13 +2354,13 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot)
ot->name = "Scale Region Size";
ot->description = "Scale selected area";
ot->idname = "SCREEN_OT_region_scale";
-
+
ot->invoke = region_scale_invoke;
ot->modal = region_scale_modal;
ot->cancel = region_scale_cancel;
-
+
ot->poll = ED_operator_areaactive;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
}
@@ -2415,19 +2418,19 @@ static int frame_offset_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
int delta;
-
+
delta = RNA_int_get(op->ptr, "delta");
CFRA += delta;
FRAMENUMBER_MIN_CLAMP(CFRA);
SUBFRA = 0.f;
-
+
areas_do_frame_follow(C, false);
BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -2436,13 +2439,13 @@ static void SCREEN_OT_frame_offset(wmOperatorType *ot)
ot->name = "Frame Offset";
ot->idname = "SCREEN_OT_frame_offset";
ot->description = "Move current frame forward/backward by a given number";
-
+
ot->exec = frame_offset_exec;
-
+
ot->poll = ED_operator_screenactive_norender;
ot->flag = OPTYPE_UNDO_GROUPED;
ot->undo_group = "FRAME_CHANGE";
-
+
/* rna */
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
}
@@ -2466,9 +2469,9 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
*/
if (animtimer) {
ScreenAnimData *sad = animtimer->customdata;
-
+
sad->flag |= ANIMPLAY_FLAG_USE_NEXT_FRAME;
-
+
if (RNA_boolean_get(op->ptr, "end"))
sad->nextfra = PEFRA;
else
@@ -2479,14 +2482,14 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
CFRA = PEFRA;
else
CFRA = PSFRA;
-
+
areas_do_frame_follow(C, true);
BKE_sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
-
+
return OPERATOR_FINISHED;
}
@@ -2495,13 +2498,13 @@ static void SCREEN_OT_frame_jump(wmOperatorType *ot)
ot->name = "Jump to Endpoint";
ot->description = "Jump to first/last frame in frame range";
ot->idname = "SCREEN_OT_frame_jump";
-
+
ot->exec = frame_jump_exec;
-
+
ot->poll = ED_operator_screenactive_norender;
ot->flag = OPTYPE_UNDO_GROUPED;
ot->undo_group = "FRAME_CHANGE";
-
+
/* rna */
RNA_def_boolean(ot->srna, "end", 0, "Last Frame", "Jump to the last frame of the frame range");
}
@@ -2524,7 +2527,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
float cfra;
const bool next = RNA_boolean_get(op->ptr, "next");
bool done = false;
-
+
/* sanity checks */
if (scene == NULL)
return OPERATOR_CANCELLED;
@@ -2533,13 +2536,13 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
/* init binarytree-list for getting keyframes */
BLI_dlrbTree_init(&keys);
-
+
/* seed up dummy dopesheet context with flags to perform necessary filtering */
if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) {
/* only selected channels are included */
ads.filterflag |= ADS_FILTER_ONLYSEL;
}
-
+
/* populate tree with keyframe nodes */
scene_to_keylist(&ads, scene, &keys, NULL);
gpencil_to_keylist(&ads, scene->gpd, &keys);
@@ -2548,7 +2551,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
ob_to_keylist(&ads, ob, &keys, NULL);
gpencil_to_keylist(&ads, ob->gpd, &keys);
}
-
+
{
Mask *mask = CTX_data_edit_mask(C);
if (mask) {
@@ -2559,13 +2562,13 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
/* build linked-list for searching */
BLI_dlrbTree_linkedlist_sync(&keys);
-
+
/* find matching keyframe in the right direction */
if (next)
ak = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfra);
else
ak = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfra);
-
+
while ((ak != NULL) && (done == false)) {
if (CFRA != (int)ak->cfra) {
/* this changes the frame, so set the frame and we're done */
@@ -2582,7 +2585,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* free temp stuff */
BLI_dlrbTree_free(&keys);
@@ -2608,13 +2611,13 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
ot->name = "Jump to Keyframe";
ot->description = "Jump to previous/next keyframe";
ot->idname = "SCREEN_OT_keyframe_jump";
-
+
ot->exec = keyframe_jump_exec;
-
+
ot->poll = ED_operator_screenactive_norender;
ot->flag = OPTYPE_UNDO_GROUPED;
ot->undo_group = "FRAME_CHANGE";
-
+
/* properties */
RNA_def_boolean(ot->srna, "next", true, "Next Keyframe", "");
}
@@ -2710,7 +2713,7 @@ static void SCREEN_OT_screen_set(wmOperatorType *ot)
ot->name = "Set Screen";
ot->description = "Cycle through available screens";
ot->idname = "SCREEN_OT_screen_set";
-
+
ot->exec = screen_set_exec;
ot->poll = ED_operator_screenactive;
@@ -2730,17 +2733,17 @@ static int screen_maximize_area_exec(bContext *C, wmOperator *op)
bScreen *screen = CTX_wm_screen(C);
ScrArea *sa = NULL;
const bool hide_panels = RNA_boolean_get(op->ptr, "use_hide_panels");
-
+
/* search current screen for 'fullscreen' areas */
/* prevents restoring info header, when mouse is over it */
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->full) break;
}
-
+
if (sa == NULL) {
sa = CTX_wm_area(C);
}
-
+
if (hide_panels) {
if (!ELEM(screen->state, SCREENNORMAL, SCREENFULL)) {
return OPERATOR_CANCELLED;
@@ -2773,7 +2776,7 @@ static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
ot->name = "Toggle Maximize Area";
ot->description = "Toggle display selected area as fullscreen/maximized";
ot->idname = "SCREEN_OT_screen_full_area";
-
+
ot->exec = screen_maximize_area_exec;
ot->poll = screen_maximize_area_poll;
ot->flag = 0;
@@ -2788,7 +2791,7 @@ static void SCREEN_OT_screen_full_area(wmOperatorType *ot)
/** \name Screen Join-Area Operator
* \{ */
-/* operator state vars used:
+/* operator state vars used:
* x1, y1 mouse coord in first area, which will disappear
* x2, y2 mouse coord in 2nd area, which will become joined
*
@@ -2843,18 +2846,18 @@ static int area_join_init(bContext *C, wmOperator *op)
int x1, y1;
int x2, y2;
int shared = 0;
-
+
/* required properties, make negative to get return 0 if not set by caller */
x1 = RNA_int_get(op->ptr, "min_x");
y1 = RNA_int_get(op->ptr, "min_y");
x2 = RNA_int_get(op->ptr, "max_x");
y2 = RNA_int_get(op->ptr, "max_y");
-
+
sa1 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, x1, y1);
sa2 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, x2, y2);
if (sa1 == NULL || sa2 == NULL || sa1 == sa2)
return 0;
-
+
/* do areas share an edge? */
if (sa1->v1 == sa2->v1 || sa1->v1 == sa2->v2 || sa1->v1 == sa2->v3 || sa1->v1 == sa2->v4) shared++;
if (sa1->v2 == sa2->v1 || sa1->v2 == sa2->v2 || sa1->v2 == sa2->v3 || sa1->v2 == sa2->v4) shared++;
@@ -2864,7 +2867,7 @@ static int area_join_init(bContext *C, wmOperator *op)
printf("areas don't share edge\n");
return 0;
}
-
+
jd = (sAreaJoinData *)MEM_callocN(sizeof(sAreaJoinData), "op_area_join");
jd->sa1 = sa1;
@@ -2882,7 +2885,7 @@ static int area_join_apply(bContext *C, wmOperator *op)
{
sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
if (!jd) return 0;
-
+
if (!screen_area_join(C, CTX_wm_screen(C), jd->sa1, jd->sa2)) {
return 0;
}
@@ -2890,7 +2893,7 @@ static int area_join_apply(bContext *C, wmOperator *op)
CTX_wm_area_set(C, NULL);
CTX_wm_region_set(C, NULL);
}
-
+
return 1;
}
@@ -2906,7 +2909,7 @@ static void area_join_exit(bContext *C, wmOperator *op)
MEM_freeN(jd);
op->customdata = NULL;
}
-
+
/* this makes sure aligned edges will result in aligned grabbing */
BKE_screen_remove_double_scredges(CTX_wm_screen(C));
BKE_screen_remove_unused_scredges(CTX_wm_screen(C));
@@ -2915,55 +2918,55 @@ static void area_join_exit(bContext *C, wmOperator *op)
static int area_join_exec(bContext *C, wmOperator *op)
{
- if (!area_join_init(C, op))
+ if (!area_join_init(C, op))
return OPERATOR_CANCELLED;
-
+
area_join_apply(C, op);
area_join_exit(C, op);
-
+
return OPERATOR_FINISHED;
}
/* interaction callback */
static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
-
+
if (event->type == EVT_ACTIONZONE_AREA) {
sActionzoneData *sad = event->customdata;
-
+
if (sad == NULL || sad->modifier > 0) {
return OPERATOR_PASS_THROUGH;
}
-
+
/* verify *sad itself */
if (sad->sa1 == NULL || sad->sa2 == NULL)
return OPERATOR_PASS_THROUGH;
-
+
/* is this our *sad? if areas equal it should be passed on */
if (sad->sa1 == sad->sa2)
return OPERATOR_PASS_THROUGH;
-
+
/* prepare operator state vars */
RNA_int_set(op->ptr, "min_x", sad->x);
RNA_int_set(op->ptr, "min_y", sad->y);
RNA_int_set(op->ptr, "max_x", event->x);
RNA_int_set(op->ptr, "max_y", event->y);
}
-
-
- if (!area_join_init(C, op))
+
+
+ if (!area_join_init(C, op))
return OPERATOR_PASS_THROUGH;
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
static void area_join_cancel(bContext *C, wmOperator *op)
{
WM_event_add_notifier(C, NC_WINDOW, NULL);
-
+
area_join_exit(C, op);
}
@@ -2972,15 +2975,15 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
bScreen *sc = CTX_wm_screen(C);
sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
-
+
/* execute the events */
switch (event->type) {
-
- case MOUSEMOVE:
+
+ case MOUSEMOVE:
{
ScrArea *sa = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y);
int dir;
-
+
if (sa) {
if (jd->sa1 != sa) {
dir = area_getorientation(jd->sa1, sa);
@@ -2988,7 +2991,7 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
jd->sa2 = sa;
}
else {
- /* we are not bordering on the previously selected area
+ /* we are not bordering on the previously selected area
* we check if area has common border with the one marked for removal
* in this case we can swap areas.
*/
@@ -3004,7 +3007,7 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
WM_event_add_notifier(C, NC_WINDOW, NULL);
}
else {
- /* we are back in the area previously selected for keeping
+ /* we are back in the area previously selected for keeping
* we swap the areas if possible to allow user to choose */
if (jd->sa2 != NULL) {
jd->sa1 = jd->sa2;
@@ -3036,13 +3039,13 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
break;
-
+
case RIGHTMOUSE:
case ESCKEY:
area_join_cancel(C, op);
return OPERATOR_CANCELLED;
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -3053,17 +3056,17 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
ot->name = "Join Area";
ot->description = "Join selected areas into new window";
ot->idname = "SCREEN_OT_area_join";
-
+
/* api callbacks */
ot->exec = area_join_exec;
ot->invoke = area_join_invoke;
ot->modal = area_join_modal;
ot->poll = screen_active_editable;
ot->cancel = area_join_cancel;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
+
/* rna */
RNA_def_int(ot->srna, "min_x", -100, INT_MIN, INT_MAX, "X 1", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "min_y", -100, INT_MIN, INT_MAX, "Y 1", "", INT_MIN, INT_MAX);
@@ -3089,12 +3092,12 @@ static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent
WM_window_screen_rect_calc(win, &screen_rect);
actedge = screen_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y);
-
+
if (actedge == NULL) return OPERATOR_CANCELLED;
-
+
pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
layout = UI_popup_menu_layout(pup);
-
+
uiItemFullO(layout, "SCREEN_OT_area_split", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr);
/* store initial mouse cursor position */
RNA_int_set(&ptr, "mouse_x", event->x);
@@ -3106,9 +3109,9 @@ static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent
RNA_int_set(&ptr, "min_y", event->y + 4);
RNA_int_set(&ptr, "max_x", event->x - 4);
RNA_int_set(&ptr, "max_y", event->y - 4);
-
+
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -3118,10 +3121,10 @@ static void SCREEN_OT_area_options(wmOperatorType *ot)
ot->name = "Area Options";
ot->description = "Operations for splitting and merging";
ot->idname = "SCREEN_OT_area_options";
-
+
/* api callbacks */
ot->invoke = screen_area_options_invoke;
-
+
ot->poll = ED_operator_screen_mainwinactive;
/* flags */
@@ -3140,7 +3143,7 @@ static int spacedata_cleanup_exec(bContext *C, wmOperator *op)
bScreen *screen;
ScrArea *sa;
int tot = 0;
-
+
for (screen = bmain->screen.first; screen; screen = screen->id.next) {
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->spacedata.first != sa->spacedata.last) {
@@ -3154,7 +3157,7 @@ static int spacedata_cleanup_exec(bContext *C, wmOperator *op)
}
}
BKE_reportf(op->reports, RPT_INFO, "Removed amount of editors: %d", tot);
-
+
return OPERATOR_FINISHED;
}
@@ -3164,11 +3167,11 @@ static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot)
ot->name = "Clean-up Space-data";
ot->description = "Remove unused settings for invisible editors";
ot->idname = "SCREEN_OT_spacedata_cleanup";
-
+
/* api callbacks */
ot->exec = spacedata_cleanup_exec;
ot->poll = WM_operator_winactive;
-
+
}
/** \} */
@@ -3196,7 +3199,7 @@ static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op))
WM_operator_free_all_after(wm, lastop);
WM_operator_repeat(C, lastop);
}
-
+
return OPERATOR_CANCELLED;
}
@@ -3206,12 +3209,12 @@ static void SCREEN_OT_repeat_last(wmOperatorType *ot)
ot->name = "Repeat Last";
ot->description = "Repeat last action";
ot->idname = "SCREEN_OT_repeat_last";
-
+
/* api callbacks */
ot->exec = repeat_last_exec;
-
+
ot->poll = ED_operator_screenactive;
-
+
}
/** \} */
@@ -3227,37 +3230,37 @@ static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNU
uiPopupMenu *pup;
uiLayout *layout;
int items, i;
-
+
items = BLI_listbase_count(&wm->operators);
if (items == 0)
return OPERATOR_CANCELLED;
-
+
pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
layout = UI_popup_menu_layout(pup);
-
+
for (i = items - 1, lastop = wm->operators.last; lastop; lastop = lastop->prev, i--)
if ((lastop->type->flag & OPTYPE_REGISTER) && WM_operator_repeat_check(C, lastop)) {
uiItemIntO(layout, RNA_struct_ui_name(lastop->type->srna), ICON_NONE, op->type->idname, "index", i);
}
-
+
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
static int repeat_history_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
-
+
op = BLI_findlink(&wm->operators, RNA_int_get(op->ptr, "index"));
if (op) {
/* let's put it as last operator in list */
BLI_remlink(&wm->operators, op);
BLI_addtail(&wm->operators, op);
-
+
WM_operator_repeat(C, op);
}
-
+
return OPERATOR_FINISHED;
}
@@ -3267,13 +3270,13 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot)
ot->name = "Repeat History";
ot->description = "Display menu for previous actions performed";
ot->idname = "SCREEN_OT_repeat_history";
-
+
/* api callbacks */
ot->invoke = repeat_history_invoke;
ot->exec = repeat_history_exec;
-
+
ot->poll = ED_operator_screenactive;
-
+
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
}
@@ -3286,10 +3289,10 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot)
static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
wmOperator *lastop = WM_operator_last_redo(C);
-
+
if (lastop)
WM_operator_redo_popup(C, lastop);
-
+
return OPERATOR_CANCELLED;
}
@@ -3299,10 +3302,10 @@ static void SCREEN_OT_redo_last(wmOperatorType *ot)
ot->name = "Redo Last";
ot->description = "Display menu for last action performed";
ot->idname = "SCREEN_OT_redo_last";
-
+
/* api callbacks */
ot->invoke = redo_last_invoke;
-
+
ot->poll = ED_operator_screenactive;
}
@@ -3345,7 +3348,7 @@ static void region_quadview_init_rv3d(ScrArea *sa, ARegion *ar,
static int region_quadview_exec(bContext *C, wmOperator *op)
{
ARegion *ar = CTX_wm_region(C);
-
+
/* some rules... */
if (ar->regiontype != RGN_TYPE_WINDOW) {
BKE_report(op->reports, RPT_ERROR, "Only window region can be 4-splitted");
@@ -3354,10 +3357,10 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
/* Exit quad-view */
ScrArea *sa = CTX_wm_area(C);
ARegion *arn;
-
+
/* keep current region */
ar->alignment = 0;
-
+
if (sa->spacetype == SPACE_VIEW3D) {
ARegion *ar_iter;
RegionView3D *rv3d = ar->regiondata;
@@ -3387,7 +3390,7 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
}
}
}
-
+
for (ar = sa->regionbase.first; ar; ar = arn) {
arn = ar->next;
if (ar->alignment == RGN_ALIGN_QSPLIT) {
@@ -3408,14 +3411,14 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
ScrArea *sa = CTX_wm_area(C);
ARegion *newar;
int count;
-
+
ar->alignment = RGN_ALIGN_QSPLIT;
-
+
for (count = 0; count < 3; count++) {
newar = BKE_area_region_copy(sa->type, ar);
BLI_addtail(&sa->regionbase, newar);
}
-
+
/* lock views and set them */
if (sa->spacetype == SPACE_VIEW3D) {
View3D *v3d = sa->spacedata.first;
@@ -3445,8 +3448,8 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
ED_area_tag_redraw(sa);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
}
-
-
+
+
return OPERATOR_FINISHED;
}
@@ -3456,7 +3459,7 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot)
ot->name = "Toggle Quad View";
ot->description = "Split selected area into camera, front, right & top views";
ot->idname = "SCREEN_OT_region_quadview";
-
+
/* api callbacks */
ot->exec = region_quadview_exec;
ot->poll = ED_operator_region_view3d_active;
@@ -3473,10 +3476,10 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot)
static int region_flip_exec(bContext *C, wmOperator *UNUSED(op))
{
ARegion *ar = CTX_wm_region(C);
-
+
if (!ar)
return OPERATOR_CANCELLED;
-
+
if (ar->alignment == RGN_ALIGN_TOP)
ar->alignment = RGN_ALIGN_BOTTOM;
else if (ar->alignment == RGN_ALIGN_BOTTOM)
@@ -3488,7 +3491,7 @@ static int region_flip_exec(bContext *C, wmOperator *UNUSED(op))
ED_area_tag_redraw(CTX_wm_area(C));
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -3511,7 +3514,7 @@ static void SCREEN_OT_region_flip(wmOperatorType *ot)
ot->name = "Flip Region";
ot->idname = "SCREEN_OT_region_flip";
ot->description = "Toggle the region's alignment (left/right or top/bottom)";
-
+
/* api callbacks */
ot->exec = region_flip_exec;
ot->poll = region_flip_poll;
@@ -3578,7 +3581,7 @@ static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot)
ot->name = "Expand/Collapse Header Menus";
ot->idname = "SCREEN_OT_header_toggle_menus";
ot->description = "Expand or collapse the header pulldown menus";
-
+
/* api callbacks */
ot->exec = header_toggle_menus_exec;
ot->poll = ED_operator_areaactive;
@@ -3638,7 +3641,7 @@ static void SCREEN_OT_header_toolbox(wmOperatorType *ot)
ot->name = "Header Toolbox";
ot->description = "Display header region toolbox";
ot->idname = "SCREEN_OT_header_toolbox";
-
+
/* api callbacks */
ot->invoke = header_toolbox_invoke;
}
@@ -3659,14 +3662,14 @@ static int match_area_with_refresh(int spacetype, int refresh)
return 1;
break;
}
-
+
return 0;
}
static int match_region_with_redraws(int spacetype, int regiontype, int redraws, bool from_anim_edit)
{
if (regiontype == RGN_TYPE_WINDOW) {
-
+
switch (spacetype) {
case SPACE_VIEW3D:
if ((redraws & TIME_ALL_3D_WIN) || from_anim_edit)
@@ -3704,7 +3707,7 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws,
if ((redraws & TIME_CLIPS) || from_anim_edit)
return 1;
break;
-
+
}
}
else if (regiontype == RGN_TYPE_CHANNELS) {
@@ -3769,12 +3772,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
ScrArea *sa;
int sync;
float time;
-
+
/* sync, don't sync, or follow scene setting */
if (sad->flag & ANIMPLAY_FLAG_SYNC) sync = 1;
else if (sad->flag & ANIMPLAY_FLAG_NO_SYNC) sync = 0;
else sync = (scene->flag & SCE_FRAME_DROP);
-
+
if ((scene->audio.flag & AUDIO_SYNC) &&
(sad->flag & ANIMPLAY_FLAG_REVERSE) == false &&
isfinite(time = BKE_sound_sync_scene(scene)))
@@ -3820,12 +3823,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
scene->r.cfra++;
}
}
-
+
sad->last_duration = wt->duration;
/* reset 'jumped' flag before checking if we need to jump... */
sad->flag &= ~ANIMPLAY_FLAG_JUMPED;
-
+
if (sad->flag & ANIMPLAY_FLAG_REVERSE) {
/* jump back to end? */
if (PRVRANGEON) {
@@ -3863,14 +3866,14 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
sad->flag &= ~ANIMPLAY_FLAG_USE_NEXT_FRAME;
sad->flag |= ANIMPLAY_FLAG_JUMPED;
}
-
+
if (sad->flag & ANIMPLAY_FLAG_JUMPED) {
BKE_sound_seek_scene(bmain, scene);
#ifdef PROFILE_AUDIO_SYNCH
old_frame = CFRA;
#endif
}
-
+
/* since we follow drawflags, we can't send notifier but tag regions ourselves */
ED_update_for_newframe(bmain, depsgraph);
@@ -3909,24 +3912,24 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
}
}
}
-
+
if (match_area_with_refresh(sa->spacetype, sad->refresh))
ED_area_tag_refresh(sa);
}
}
-
- /* update frame rate info too
- * NOTE: this may not be accurate enough, since we might need this after modifiers/etc.
+
+ /* update frame rate info too
+ * NOTE: this may not be accurate enough, since we might need this after modifiers/etc.
* have been calculated instead of just before updates have been done?
*/
ED_refresh_viewport_fps(C);
-
+
/* recalculate the timestep for the timer now that we've finished calculating this,
* since the frames-per-second value may have been changed
*/
/* TODO: this may make evaluation a bit slower if the value doesn't change... any way to avoid this? */
wt->timestep = (1.0 / FPS);
-
+
return OPERATOR_FINISHED;
}
return OPERATOR_PASS_THROUGH;
@@ -3938,12 +3941,12 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot)
ot->name = "Animation Step";
ot->description = "Step through animation by position";
ot->idname = "SCREEN_OT_animation_step";
-
+
/* api callbacks */
ot->invoke = screen_animation_step;
-
+
ot->poll = ED_operator_screenactive_norender;
-
+
}
/** \} */
@@ -3997,16 +4000,16 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
}
else {
int refresh = SPACE_ACTION; /* these settings are currently only available from a menu in the TimeLine */
-
+
if (mode == 1) /* XXX only play audio forwards!? */
BKE_sound_play_scene(scene);
-
+
ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode);
-
+
if (screen->animtimer) {
wmTimer *wt = screen->animtimer;
ScreenAnimData *sad = wt->customdata;
-
+
sad->ar = CTX_wm_region(C);
}
}
@@ -4018,10 +4021,10 @@ static int screen_animation_play_exec(bContext *C, wmOperator *op)
{
int mode = (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
int sync = -1;
-
+
if (RNA_struct_property_is_set(op->ptr, "sync"))
sync = (RNA_boolean_get(op->ptr, "sync"));
-
+
return ED_screen_animation_play(C, sync, mode);
}
@@ -4033,12 +4036,12 @@ static void SCREEN_OT_animation_play(wmOperatorType *ot)
ot->name = "Play Animation";
ot->description = "Play animation";
ot->idname = "SCREEN_OT_animation_play";
-
+
/* api callbacks */
ot->exec = screen_animation_play_exec;
-
+
ot->poll = ED_operator_screenactive_norender;
-
+
prop = RNA_def_boolean(ot->srna, "reverse", 0, "Play in Reverse", "Animation is played backwards");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain framerate");
@@ -4081,10 +4084,10 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot)
ot->name = "Cancel Animation";
ot->description = "Cancel animation, returning to the original frame";
ot->idname = "SCREEN_OT_animation_cancel";
-
+
/* api callbacks */
ot->exec = screen_animation_cancel_exec;
-
+
ot->poll = ED_operator_screenactive;
RNA_def_boolean(ot->srna, "restore_frame", true, "Restore Frame", "Restore the frame when animation was initialized");
@@ -4096,7 +4099,7 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot)
/** \name Border Select Operator (Template)
* \{ */
-/* operator state vars used: (added by default WM callbacks)
+/* operator state vars used: (added by default WM callbacks)
* xmin, ymin
* xmax, ymax
*
@@ -4118,14 +4121,14 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot)
static int border_select_exec(bContext *C, wmOperator *op)
{
int event_type = RNA_int_get(op->ptr, "event_type");
-
+
if (event_type == LEFTMOUSE)
printf("border select do select\n");
else if (event_type == RIGHTMOUSE)
printf("border select deselect\n");
- else
+ else
printf("border select do something\n");
-
+
return 1;
}
@@ -4134,15 +4137,15 @@ static void SCREEN_OT_border_select(wmOperatorType *ot)
/* identifiers */
ot->name = "Border Select";
ot->idname = "SCREEN_OT_border_select";
-
+
/* api callbacks */
ot->exec = border_select_exec;
ot->invoke = WM_gesture_border_invoke;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = ED_operator_areaactive;
-
+
/* rna */
RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
WM_operator_properties_border(ot);
@@ -4162,7 +4165,7 @@ static int fullscreen_back_exec(bContext *C, wmOperator *op)
{
bScreen *screen = CTX_wm_screen(C);
ScrArea *sa = NULL;
-
+
/* search current screen for 'fullscreen' areas */
for (sa = screen->areabase.first; sa; sa = sa->next) {
if (sa->full) break;
@@ -4183,7 +4186,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
ot->name = "Back to Previous Screen";
ot->description = "Revert back to the original screen layout, before fullscreen area overlay";
ot->idname = "SCREEN_OT_back_to_previous";
-
+
/* api callbacks */
ot->exec = fullscreen_back_exec;
ot->poll = ED_operator_screenactive;
@@ -4199,7 +4202,7 @@ static int userpref_show_invoke(bContext *C, wmOperator *op, const wmEvent *even
{
int sizex = 800 * UI_DPI_FAC;
int sizey = 500 * UI_DPI_FAC;
-
+
/* changes context! */
if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_USERPREFS) != NULL) {
return OPERATOR_FINISHED;
@@ -4217,7 +4220,7 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
ot->name = "Show User Preferences";
ot->description = "Show user preferences";
ot->idname = "SCREEN_OT_userpref_show";
-
+
/* api callbacks */
ot->invoke = userpref_show_invoke;
ot->poll = ED_operator_screenactive;
@@ -4235,23 +4238,23 @@ static int drivers_editor_show_invoke(bContext *C, wmOperator *op, const wmEvent
PropertyRNA *prop = NULL;
int index = -1;
uiBut *but = NULL;
-
+
int sizex = 900 * UI_DPI_FAC;
int sizey = 580 * UI_DPI_FAC;
-
+
/* Get active property to show driver for
* - Need to grab it first, or else this info disappears
* after we've created the window
*/
but = UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
+
/* changes context! */
if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_DRIVERS) != NULL) {
/* activate driver F-Curve for the property under the cursor */
if (but) {
FCurve *fcu;
bool driven, special;
-
+
fcu = rna_get_fcurve_context_ui(C,
&ptr, prop, index,
NULL, NULL, &driven, &special);
@@ -4269,7 +4272,7 @@ static int drivers_editor_show_invoke(bContext *C, wmOperator *op, const wmEvent
}
}
}
-
+
return OPERATOR_FINISHED;
}
else {
@@ -4285,7 +4288,7 @@ static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot)
ot->name = "Show Drivers Editor";
ot->description = "Show drivers editor in a separate window";
ot->idname = "SCREEN_OT_drivers_editor_show";
-
+
/* api callbacks */
ot->invoke = drivers_editor_show_invoke;
ot->poll = ED_operator_screenactive;
@@ -4299,12 +4302,13 @@ static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot)
static int screen_new_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
wmWindow *win = CTX_wm_window(C);
WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
WorkSpaceLayout *layout_old = BKE_workspace_active_layout_get(win->workspace_hook);
WorkSpaceLayout *layout_new;
- layout_new = ED_workspace_layout_duplicate(workspace, layout_old, win);
+ layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_old, win);
WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTBROWSE, layout_new);
return OPERATOR_FINISHED;
@@ -4316,7 +4320,7 @@ static void SCREEN_OT_new(wmOperatorType *ot)
ot->name = "New Screen";
ot->description = "Add a new screen";
ot->idname = "SCREEN_OT_new";
-
+
/* api callbacks */
ot->exec = screen_new_exec;
ot->poll = WM_operator_winactive;
@@ -4345,7 +4349,7 @@ static void SCREEN_OT_delete(wmOperatorType *ot)
ot->name = "Delete Screen";
ot->description = "Delete active screen";
ot->idname = "SCREEN_OT_delete";
-
+
/* api callbacks */
ot->exec = screen_delete_exec;
}
@@ -4383,7 +4387,7 @@ float ED_region_blend_alpha(ARegion *ar)
alpha = (float)ar->regiontimer->duration / TIMEOUT;
/* makes sure the blend out works 100% - without area redraws */
if (rgi->hidden) alpha = 0.9f - TIMESTEP - alpha;
-
+
CLAMP(alpha, 0.0f, 1.0f);
return alpha;
}
@@ -4394,12 +4398,12 @@ float ED_region_blend_alpha(ARegion *ar)
static void region_blend_end(bContext *C, ARegion *ar, const bool is_running)
{
RegionAlphaInfo *rgi = ar->regiontimer->customdata;
-
+
/* always send redraw */
ED_region_tag_redraw(ar);
if (rgi->child_ar)
ED_region_tag_redraw(rgi->child_ar);
-
+
/* if running timer was hiding, the flag toggle went wrong */
if (is_running) {
if (rgi->hidden)
@@ -4423,14 +4427,14 @@ void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
RegionAlphaInfo *rgi;
-
+
/* end running timer */
if (ar->regiontimer) {
region_blend_end(C, ar, true);
}
rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo");
-
+
rgi->hidden = ar->flag & RGN_FLAG_HIDDEN;
rgi->sa = sa;
rgi->ar = ar;
@@ -4459,18 +4463,18 @@ static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven
{
RegionAlphaInfo *rgi;
wmTimer *timer = event->customdata;
-
+
/* event type is TIMERREGION, but we better check */
if (event->type != TIMERREGION || timer == NULL)
return OPERATOR_PASS_THROUGH;
-
+
rgi = timer->customdata;
-
+
/* always send redraws */
ED_region_tag_redraw(rgi->ar);
if (rgi->child_ar)
ED_region_tag_redraw(rgi->child_ar);
-
+
/* end timer? */
if (rgi->ar->regiontimer->duration > (double)TIMEOUT) {
region_blend_end(C, rgi->ar, false);
@@ -4486,13 +4490,13 @@ static void SCREEN_OT_region_blend(wmOperatorType *ot)
ot->name = "Region Alpha";
ot->idname = "SCREEN_OT_region_blend";
ot->description = "Blend in and out overlapping region";
-
+
/* api callbacks */
ot->invoke = region_blend_invoke;
-
+
/* flags */
ot->flag = OPTYPE_INTERNAL;
-
+
/* properties */
}
@@ -4594,7 +4598,7 @@ static int space_workspace_cycle_invoke(bContext *C, wmOperator *op, const wmEve
if (WM_window_is_temp_screen(win)) {
return OPERATOR_CANCELLED;
}
-
+
Main *bmain = CTX_data_main(C);
const int direction = RNA_enum_get(op->ptr, "direction");
WorkSpace *workspace_src = WM_window_get_active_workspace(win);
@@ -4641,7 +4645,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_repeat_last);
WM_operatortype_append(SCREEN_OT_repeat_history);
WM_operatortype_append(SCREEN_OT_redo_last);
-
+
/* screen tools */
WM_operatortype_append(SCREEN_OT_area_move);
WM_operatortype_append(SCREEN_OT_area_split);
@@ -4666,13 +4670,13 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_region_blend);
WM_operatortype_append(SCREEN_OT_space_context_cycle);
WM_operatortype_append(SCREEN_OT_workspace_cycle);
-
+
/*frame changes*/
WM_operatortype_append(SCREEN_OT_frame_offset);
WM_operatortype_append(SCREEN_OT_frame_jump);
WM_operatortype_append(SCREEN_OT_keyframe_jump);
WM_operatortype_append(SCREEN_OT_marker_jump);
-
+
WM_operatortype_append(SCREEN_OT_animation_step);
WM_operatortype_append(SCREEN_OT_animation_play);
WM_operatortype_append(SCREEN_OT_animation_cancel);
@@ -4689,7 +4693,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(ED_OT_undo_history);
WM_operatortype_append(ED_OT_flush_edits);
-
+
}
/** \} */
@@ -4707,20 +4711,20 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
{KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap off", ""},
{0, NULL, 0, NULL, NULL}};
wmKeyMap *keymap;
-
+
/* Standard Modal keymap ------------------------------------------------ */
keymap = WM_modalkeymap_add(keyconf, "Standard Modal Map", modal_items);
-
+
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, KM_MODAL_APPLY);
WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY);
WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, KM_MODAL_APPLY);
-
+
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, KM_MODAL_SNAP_ON);
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, KM_MODAL_SNAP_OFF);
-
+
WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move");
-
+
}
static int open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
@@ -4746,14 +4750,14 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
ListBase *lb;
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
/* Screen Editing ------------------------------------------------ */
keymap = WM_keymap_find(keyconf, "Screen Editing", 0, 0);
-
+
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "modifier", 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "modifier", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "modifier", 2);
-
+
/* screen tools */
WM_keymap_verify_item(keymap, "SCREEN_OT_area_split", EVT_ACTIONZONE_AREA, 0, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_area_join", EVT_ACTIONZONE_AREA, 0, 0, 0);
@@ -4764,7 +4768,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "use_hide_panels", true);
/* area move after action zones */
WM_keymap_verify_item(keymap, "SCREEN_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0);
-
+
WM_keymap_verify_item(keymap, "SCREEN_OT_area_options", RIGHTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_header", F9KEY, KM_PRESS, KM_ALT, 0);
@@ -4777,12 +4781,12 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
/* Screen General ------------------------------------------------ */
keymap = WM_keymap_find(keyconf, "Screen", 0, 0);
-
+
/* standard timers */
WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_region_blend", TIMERREGION, KM_ANY, KM_ANY, 0);
-
-
+
+
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_SHIFT, 0);
@@ -4809,12 +4813,12 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "SCRIPT_OT_reload", F8KEY, KM_PRESS, 0, 0);
-
+
/* files */
WM_keymap_add_item(keymap, "FILE_OT_execute", RETKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_execute", PADENTER, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_cancel", ESCKEY, KM_PRESS, 0, 0);
-
+
/* undo */
#ifdef __APPLE__
WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_OSKEY, 0);
@@ -4824,8 +4828,8 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ED_OT_redo", ZKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "ED_OT_undo_history", ZKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
-
-
+
+
/* render */
kmi = WM_keymap_add_item(keymap, "RENDER_OT_render", F12KEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_viewport", true);
@@ -4835,62 +4839,62 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "RENDER_OT_view_cancel", ESCKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "RENDER_OT_view_show", F11KEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "RENDER_OT_play_rendered_anim", F11KEY, KM_PRESS, KM_CTRL, 0);
-
+
/* user prefs */
#ifdef __APPLE__
WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", COMMAKEY, KM_PRESS, KM_OSKEY, 0);
#endif
WM_keymap_add_item(keymap, "SCREEN_OT_userpref_show", UKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
-
-
+
+
/* Anim Playback ------------------------------------------------ */
keymap = WM_keymap_find(keyconf, "Frames", 0, 0);
-
+
/* frame offsets */
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "delta", 10);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", DOWNARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "delta", -10);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", -1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
-
+
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELDOWNMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", WHEELUPMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "delta", -1);
-
+
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", UPARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "end", true);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", DOWNARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "end", false);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", true);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "end", false);
-
+
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", UPARROWKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "next", true);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", DOWNARROWKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "next", false);
-
+
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIALAST, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "next", true);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIAFIRST, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "next", false);
-
+
/* play (forward and backwards) */
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0)->ptr, "reverse", true);
WM_keymap_add_item(keymap, "SCREEN_OT_animation_cancel", ESCKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", MEDIAPLAY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_animation_cancel", MEDIASTOP, KM_PRESS, 0, 0);
-
+
/* Alternative keys for animation and sequencer playing */
#if 0 /* XXX: disabled for restoring later... bad implementation */
keymap = WM_keymap_find(keyconf, "Frames", 0, 0);
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "cycle_speed", true);
-
+
kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", LEFTARROWKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "reverse", true);
RNA_boolean_set(kmi->ptr, "cycle_speed", true);
-
+
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", DOWNARROWKEY, KM_PRESS, KM_ALT, 0);
#endif
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 2c1cbc3d21d..7e50f8d41c4 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -104,7 +104,7 @@ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy)
*dumpsy = WM_window_pixels_y(win);
if (*dumpsx && *dumpsy) {
-
+
dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect");
glReadBuffer(GL_FRONT);
screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char *)dumprect);
@@ -122,13 +122,13 @@ static int screenshot_data_create(bContext *C, wmOperator *op)
/* do redraw so we don't show popups/menus */
WM_redraw_windows(C);
-
+
dumprect = screenshot(C, &dumpsx, &dumpsy);
if (dumprect) {
ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
ScrArea *sa = CTX_wm_area(C);
-
+
scd->dumpsx = dumpsx;
scd->dumpsy = dumpsy;
scd->dumprect = dumprect;
@@ -194,7 +194,7 @@ static int screenshot_exec(bContext *C, wmOperator *op)
char path[FILE_MAX];
RNA_string_get(op->ptr, "filepath", path);
- BLI_path_abs(path, G.main->name);
+ BLI_path_abs(path, BKE_main_blendfile_path_from_global());
/* operator ensures the extension */
ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0);
@@ -233,13 +233,13 @@ static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
/* extension is added by 'screenshot_check' after */
char filepath[FILE_MAX] = "//screen";
if (G.relbase_valid) {
- BLI_strncpy(filepath, G.main->name, sizeof(filepath));
+ BLI_strncpy(filepath, BKE_main_blendfile_path_from_global(), sizeof(filepath));
BLI_replace_extension(filepath, sizeof(filepath), ""); /* strip '.blend' */
}
RNA_string_set(op->ptr, "filepath", filepath);
-
+
WM_event_add_fileselect(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_CANCELLED;
@@ -291,16 +291,16 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
ot->name = "Save Screenshot"; /* weak: opname starting with 'save' makes filewindow give save-over */
ot->idname = "SCREEN_OT_screenshot";
ot->description = "Capture a picture of the active area or whole Blender window";
-
+
ot->invoke = screenshot_invoke;
ot->check = screenshot_check;
ot->exec = screenshot_exec;
ot->cancel = screenshot_cancel;
ot->ui = screenshot_draw;
ot->poll = screenshot_poll;
-
+
ot->flag = 0;
-
+
WM_operator_properties_filesel(
ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
@@ -328,7 +328,7 @@ typedef struct ScreenshotJob {
static void screenshot_freejob(void *sjv)
{
ScreenshotJob *sj = sjv;
-
+
if (sj->dumprect)
MEM_freeN(sj->dumprect);
@@ -347,11 +347,11 @@ static void screenshot_updatejob(void *sjv)
{
ScreenshotJob *sj = sjv;
unsigned int *dumprect;
-
+
if (sj->dumprect == NULL) {
dumprect = MEM_mallocN(sizeof(int) * sj->dumpsx * sj->dumpsy, "dumprect");
screenshot_read_pixels(sj->x, sj->y, sj->dumpsx, sj->dumpsy, (unsigned char *)dumprect);
-
+
sj->dumprect = dumprect;
}
}
@@ -367,7 +367,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
/* we need this as local variables for renderdata */
rd.frs_sec = U.scrcastfps;
rd.frs_sec_base = 1.0f;
-
+
if (BKE_imtype_is_movie(rd.im_format.imtype)) {
mh = BKE_movie_handle_get(sj->scene->r.im_format.imtype);
if (mh == NULL) {
@@ -382,16 +382,16 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
return;
}
}
-
+
sj->stop = stop;
sj->do_update = do_update;
-
+
*do_update = true; /* wait for opengl rect */
-
+
while (*stop == 0) {
-
+
if (sj->dumprect) {
-
+
if (mh) {
if (mh->append_movie(sj->movie_ctx, &rd, rd.sfra, rd.cfra, (int *)sj->dumprect,
sj->dumpsx, sj->dumpsy, "", &sj->reports))
@@ -407,14 +407,14 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
ImBuf *ibuf = IMB_allocImBuf(sj->dumpsx, sj->dumpsy, rd.im_format.planes, 0);
char name[FILE_MAX];
int ok;
-
+
BKE_image_path_from_imformat(
- name, rd.pic, sj->bmain->name, rd.cfra,
+ name, rd.pic, BKE_main_blendfile_path(sj->bmain), rd.cfra,
&rd.im_format, (rd.scemode & R_EXTENSION) != 0, true, NULL);
-
+
ibuf->rect = sj->dumprect;
ok = BKE_imbuf_write(ibuf, name, &rd.im_format);
-
+
if (ok == 0) {
printf("Write error: cannot save %s\n", name);
BKE_reportf(&sj->reports, RPT_INFO, "Write error: cannot save %s", name);
@@ -424,23 +424,23 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
printf("Saved file: %s\n", name);
BKE_reportf(&sj->reports, RPT_INFO, "Saved file: %s", name);
}
-
+
/* imbuf knows which rects are not part of ibuf */
IMB_freeImBuf(ibuf);
}
-
+
MEM_freeN(sj->dumprect);
sj->dumprect = NULL;
-
+
*do_update = true;
-
+
rd.cfra++;
}
- else
+ else
PIL_sleep_ms(U.scrcastwait);
}
-
+
if (mh) {
mh->end_movie(sj->movie_ctx);
mh->context_free(sj->movie_ctx);
@@ -468,7 +468,7 @@ static void screencast_draw_cursor(bContext *UNUSED(C), int x, int y, void *UNUS
imm_draw_circle_wire_2d(pos, (float)x, (float)y, 20, 40);
immUnbindProgram();
-
+
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
}
@@ -477,7 +477,7 @@ static void screencast_draw_cursor(bContext *UNUSED(C), int x, int y, void *UNUS
static void screencast_cursor_toggle(wmWindowManager *wm, short enable)
{
static void *cursor = NULL;
-
+
if (cursor && !enable) {
/* clear cursor */
WM_paint_cursor_end(wm, cursor);
@@ -492,7 +492,7 @@ static void screencast_cursor_toggle(wmWindowManager *wm, short enable)
static void screenshot_endjob(void *sjv)
{
ScreenshotJob *sj = sjv;
-
+
screencast_cursor_toggle(sj->wm, 0);
}
@@ -508,10 +508,10 @@ static int screencast_exec(bContext *C, wmOperator *op)
/* if called again, stop the running job */
if (WM_jobs_test(wm, screen, WM_JOB_TYPE_SCREENCAST))
WM_jobs_stop(wm, screen, screenshot_startjob);
-
+
wm_job = WM_jobs_get(wm, win, screen, "Screencast", 0, WM_JOB_TYPE_SCREENCAST);
sj = MEM_callocN(sizeof(ScreenshotJob), "screenshot job");
-
+
/* setup sj */
if (RNA_boolean_get(op->ptr, "full")) {
sj->x = 0;
@@ -529,20 +529,20 @@ static int screencast_exec(bContext *C, wmOperator *op)
sj->bmain = CTX_data_main(C);
sj->scene = CTX_data_scene(C);
sj->wm = wm;
-
+
BKE_reports_init(&sj->reports, RPT_PRINT);
/* setup job */
WM_jobs_customdata_set(wm_job, sj, screenshot_freejob);
WM_jobs_timer(wm_job, 0.1, 0, NC_SCREEN | ND_SCREENCAST);
WM_jobs_callbacks(wm_job, screenshot_startjob, NULL, screenshot_updatejob, screenshot_endjob);
-
+
WM_jobs_start(sj->wm, wm_job);
-
+
screencast_cursor_toggle(sj->wm, 1);
-
+
WM_event_add_notifier(C, NC_SCREEN | ND_SCREENCAST, screen);
-
+
return OPERATOR_FINISHED;
}
@@ -551,13 +551,13 @@ void SCREEN_OT_screencast(wmOperatorType *ot)
ot->name = "Make Screencast";
ot->idname = "SCREEN_OT_screencast";
ot->description = "Capture a video of the active area or whole Blender window";
-
+
ot->invoke = WM_operator_confirm;
ot->exec = screencast_exec;
ot->poll = screenshot_poll; /* shared poll */
-
+
ot->flag = 0;
-
+
RNA_def_property(ot->srna, "filepath", PROP_STRING, PROP_FILEPATH);
RNA_def_boolean(ot->srna, "full", 1, "Full Screen",
"Capture the whole window (otherwise only capture the active area)");
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index d54996bad59..a044a7d377a 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -131,7 +131,7 @@ static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, v
}
static WorkSpaceLayout *workspace_change_get_new_layout(
- WorkSpace *workspace_new, wmWindow *win)
+ Main *bmain, WorkSpace *workspace_new, wmWindow *win)
{
/* ED_workspace_duplicate may have stored a layout to activate once the workspace gets activated. */
WorkSpaceLayout *layout_new;
@@ -155,7 +155,7 @@ static WorkSpaceLayout *workspace_change_get_new_layout(
NULL, false);
if (!layout_temp) {
/* fallback solution: duplicate layout */
- layout_temp = ED_workspace_layout_duplicate(workspace_new, layout_new, win);
+ layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_new, win);
}
layout_new = layout_temp;
}
@@ -177,7 +177,7 @@ bool ED_workspace_change(
{
Main *bmain = CTX_data_main(C);
WorkSpace *workspace_old = WM_window_get_active_workspace(win);
- WorkSpaceLayout *layout_new = workspace_change_get_new_layout(workspace_new, win);
+ WorkSpaceLayout *layout_new = workspace_change_get_new_layout(bmain, workspace_new, win);
bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new);
bScreen *screen_old = BKE_workspace_active_screen_get(win->workspace_hook);
@@ -228,7 +228,7 @@ WorkSpace *ED_workspace_duplicate(
/* TODO(campbell): tools */
for (WorkSpaceLayout *layout_old = layouts_old->first; layout_old; layout_old = layout_old->next) {
- WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(workspace_new, layout_old, win);
+ WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win);
if (layout_active_old == layout_old) {
win->workspace_hook->temp_layout_store = layout_new;
diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c
index 6285f031836..0c7431cb2e7 100644
--- a/source/blender/editors/screen/workspace_layout_edit.c
+++ b/source/blender/editors/screen/workspace_layout_edit.c
@@ -46,6 +46,7 @@
* Empty screen, with 1 dummy area without spacedata. Uses window size.
*/
WorkSpaceLayout *ED_workspace_layout_add(
+ Main *bmain,
WorkSpace *workspace,
wmWindow *win,
const char *name)
@@ -54,12 +55,13 @@ WorkSpaceLayout *ED_workspace_layout_add(
rcti screen_rect;
WM_window_screen_rect_calc(win, &screen_rect);
- screen = screen_add(name, &screen_rect);
+ screen = screen_add(bmain, name, &screen_rect);
return BKE_workspace_layout_add(workspace, screen, name);
}
WorkSpaceLayout *ED_workspace_layout_duplicate(
+ Main *bmain,
WorkSpace *workspace, const WorkSpaceLayout *layout_old,
wmWindow *win)
{
@@ -72,7 +74,7 @@ WorkSpaceLayout *ED_workspace_layout_duplicate(
return NULL; /* XXX handle this case! */
}
- layout_new = ED_workspace_layout_add(workspace, win, name);
+ layout_new = ED_workspace_layout_add(bmain, workspace, win, name);
screen_new = BKE_workspace_layout_screen_get(layout_new);
screen_data_copy(screen_new, screen_old);
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 8d941078c5f..848d12bcfaa 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -262,7 +262,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
target = (primary) ? &primary_snap : &secondary_snap;
- refresh =
+ refresh =
!target->overlay_texture ||
(invalid != 0) ||
!same_tex_snap(target, mtex, vc, col, zoom);
@@ -1001,7 +1001,7 @@ static void paint_cursor_on_hit(UnifiedPaintSettings *ups, Brush *brush, ViewCon
else
projected_radius = BKE_brush_size_get(vc->scene, brush);
}
-
+
/* convert brush radius from 2D to 3D */
unprojected_radius = paint_calc_object_space_radius(vc, location,
projected_radius);
diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c
index 049d8ff8c0b..af0b828ae39 100644
--- a/source/blender/editors/sculpt_paint/paint_curve.c
+++ b/source/blender/editors/sculpt_paint/paint_curve.c
@@ -697,17 +697,17 @@ void PAINTCURVE_OT_draw(wmOperatorType *ot)
static int paintcurve_cursor_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ePaintMode mode = BKE_paintmode_get_active_from_context(C);
-
+
switch (mode) {
case ePaintTexture2D:
{
ARegion *ar = CTX_wm_region(C);
SpaceImage *sima = CTX_wm_space_image(C);
float location[2];
-
+
if (!sima)
return OPERATOR_CANCELLED;
-
+
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
copy_v2_v2(sima->cursor, location);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL);
@@ -717,7 +717,7 @@ static int paintcurve_cursor_invoke(bContext *C, wmOperator *UNUSED(op), const w
ED_view3d_cursor3d_update(C, event->mval);
break;
}
-
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index 4dd770d79b9..ac5b0624d56 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -48,6 +48,7 @@
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_subsurf.h"
@@ -101,7 +102,7 @@ static void partialvis_update_mesh(Object *ob,
const int *vert_indices;
int totvert, i;
bool any_changed = false, any_visible = false;
-
+
BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
@@ -153,7 +154,7 @@ static void partialvis_update_grids(Object *ob,
&grids);
grid_hidden = BKE_pbvh_grid_hidden(pbvh);
BKE_pbvh_get_grid_key(pbvh, &key);
-
+
sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
for (i = 0; i < totgrid; i++) {
@@ -323,7 +324,7 @@ static void clip_planes_from_rect(bContext *C,
{
ViewContext vc;
BoundBox bb;
-
+
view3d_operator_needs_opengl(C);
ED_view3d_viewcontext_init(C, &vc);
ED_view3d_clipping_calc(&bb, clip_planes, vc.ar, vc.obact, rect);
@@ -354,7 +355,7 @@ static void get_pbvh_nodes(PBVH *pbvh,
case PARTIALVIS_MASKED:
break;
}
-
+
BKE_pbvh_search_gather(pbvh, cb, clip_planes, nodes, totnode);
}
@@ -368,7 +369,6 @@ static int hide_show_exec(bContext *C, wmOperator *op)
PartialVisArea area;
PBVH *pbvh;
PBVHNode **nodes;
- DerivedMesh *dm;
PBVHType pbvh_type;
float clip_planes[4][4];
rcti rect;
@@ -381,9 +381,9 @@ static int hide_show_exec(bContext *C, wmOperator *op)
clip_planes_from_rect(C, clip_planes, &rect);
- dm = mesh_get_derived_final(depsgraph, CTX_data_scene(C), ob, CD_MASK_BAREMESH);
- pbvh = dm->getPBVH(ob, dm);
- ob->sculpt->pbvh = pbvh;
+ Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, CTX_data_scene(C), ob, CD_MASK_BAREMESH);
+ pbvh = BKE_sculpt_object_pbvh_ensure(ob, me_eval_deform);
+ BLI_assert(ob->sculpt->pbvh == pbvh);
get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area);
pbvh_type = BKE_pbvh_type(pbvh);
@@ -414,7 +414,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
if (nodes)
MEM_freeN(nodes);
-
+
/* end undo */
sculpt_undo_push_end();
@@ -425,7 +425,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
}
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -454,7 +454,7 @@ void PAINT_OT_hide_show(struct wmOperatorType *ot)
{PARTIALVIS_MASKED, "MASKED", 0, "Masked", "Hide or show vertices that are masked (minimum mask value of 0.5)"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Hide/Show";
ot->idname = "PAINT_OT_hide_show";
@@ -474,6 +474,6 @@ void PAINT_OT_hide_show(struct wmOperatorType *ot)
"Action", "Whether to hide or show vertices");
RNA_def_enum(ot->srna, "area", area_items, PARTIALVIS_INSIDE,
"Area", "Which vertices to hide or show");
-
+
WM_operator_properties_border(ot);
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 9ecdc44cd10..2921faf8a5a 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -169,7 +169,7 @@ void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short te
IMB_partial_display_buffer_update_delayed(ibuf, imapaintpartial.x1, imapaintpartial.y1,
imapaintpartial.x2, imapaintpartial.y2);
}
-
+
if (ibuf->mipmap[0])
ibuf->userflags |= IB_MIPMAP_INVALID;
@@ -195,7 +195,7 @@ BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
if (proj) {
radius = 0.5f;
-
+
side = kernel->side = 2;
kernel->side_squared = kernel->side * kernel->side;
kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
@@ -204,15 +204,15 @@ BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
else {
if (br->blur_kernel_radius <= 0)
br->blur_kernel_radius = 1;
-
+
radius = br->blur_kernel_radius;
-
+
side = kernel->side = radius * 2 + 1;
kernel->side_squared = kernel->side * kernel->side;
kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
kernel->pixel_len = br->blur_kernel_radius;
}
-
+
switch (type) {
case KERNEL_BOX:
for (i = 0; i < kernel->side_squared; i++)
@@ -221,9 +221,9 @@ BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
case KERNEL_GAUSSIAN:
{
- /* at 3.0 standard deviations distance, kernel is about zero */
- float standard_dev = radius / 3.0f;
-
+ /* at 3.0 standard deviations distance, kernel is about zero */
+ float standard_dev = radius / 3.0f;
+
/* make the necessary adjustment to the value for use in the normal distribution formula */
standard_dev = -standard_dev * standard_dev * 2;
@@ -232,7 +232,7 @@ BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
float idist = radius - i;
float jdist = radius - j;
float value = exp((idist * idist + jdist * jdist) / standard_dev);
-
+
kernel->wdata[i + j * side] = value;
}
}
@@ -312,7 +312,7 @@ static int image_paint_2d_clone_poll(bContext *C)
if (brush && (brush->imagepaint_tool == PAINT_TOOL_CLONE))
if (brush->clone.image)
return 1;
-
+
return 0;
}
@@ -465,7 +465,7 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
BKE_paint_data_warning(op->reports, uvs, mat, tex, stencil);
MEM_freeN(pop);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
- return NULL;
+ return NULL;
}
pop->mode = PAINT_MODE_3D_PROJECT;
pop->custom_paint = paint_proj_new_stroke(C, ob, mouse, mode);
@@ -483,7 +483,7 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) {
pop->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), image_paint_poll, gradient_draw_line, pop);
}
-
+
settings->imapaint.flag |= IMAGEPAINT_DRAWING;
ED_image_undo_push_begin(op->type->name);
@@ -850,7 +850,7 @@ void PAINT_OT_grab_clone(wmOperatorType *ot)
ot->name = "Grab Clone";
ot->idname = "PAINT_OT_grab_clone";
ot->description = "Move the clone source image";
-
+
/* api callbacks */
ot->exec = grab_clone_exec;
ot->invoke = grab_clone_invoke;
@@ -915,7 +915,7 @@ static int sample_color_exec(bContext *C, wmOperator *op)
}
WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
-
+
return OPERATOR_FINISHED;
}
@@ -1017,7 +1017,7 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
ot->name = "Sample Color";
ot->idname = "PAINT_OT_sample_color";
ot->description = "Use the mouse to sample a color in the image";
-
+
/* api callbacks */
ot->exec = sample_color_exec;
ot->invoke = sample_color_invoke;
@@ -1086,7 +1086,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
BKE_texpaint_slots_refresh_object(scene, ob);
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
-
+
/* entering paint mode also sets image to editors */
if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
Material *ma = give_current_material(ob, ob->actcol); /* set the current material active paint slot on image editor */
@@ -1096,8 +1096,8 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
}
else if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) {
ima = imapaint->canvas;
- }
-
+ }
+
if (ima) {
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
@@ -1106,7 +1106,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
-
+
if (!sima->pin) {
Object *obedit = CTX_data_edit_object(C);
ED_space_image_set(sima, scene, obedit, ima);
@@ -1116,7 +1116,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
}
}
}
-
+
ob->mode |= mode_flag;
BKE_paint_init(scene, ePaintTextureProjective, PAINT_CURSOR_TEXTURE_PAINT);
@@ -1143,7 +1143,7 @@ void PAINT_OT_texture_paint_toggle(wmOperatorType *ot)
ot->name = "Texture Paint Toggle";
ot->idname = "PAINT_OT_texture_paint_toggle";
ot->description = "Toggle texture paint mode in 3D view";
-
+
/* api callbacks */
ot->exec = texture_paint_toggle_exec;
ot->poll = texture_paint_toggle_poll;
@@ -1163,7 +1163,7 @@ static int brush_colors_flip_exec(bContext *C, wmOperator *UNUSED(op))
br = image_paint_brush(C);
}
else {
- /* At the moment, wpaint does not support the color flipper.
+ /* At the moment, wpaint does not support the color flipper.
* So for now we're only handling vpaint */
ToolSettings *ts = CTX_data_tool_settings(C);
VPaint *vp = ts->vpaint;
@@ -1236,7 +1236,7 @@ static int texture_paint_poll(bContext *C)
if (texture_paint_toggle_poll(C))
if (CTX_data_active_object(C)->mode & OB_MODE_TEXTURE_PAINT)
return 1;
-
+
return 0;
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index c2ce9d83782..a75d6344849 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -582,7 +582,7 @@ static void brush_painter_imbuf_partial_update(BrushPainter *painter, const floa
destx = desty = 0;
w = h = 0;
}
-
+
x1 = min_ii(destx, ibuf->x);
y1 = min_ii(desty, ibuf->y);
x2 = min_ii(destx + w, ibuf->x);
@@ -1132,13 +1132,13 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
tot = 1;
}
-
+
/* blend into canvas */
for (a = 0; a < tot; a++) {
ED_imapaint_dirty_region(s->image, s->canvas,
region[a].destx, region[a].desty,
region[a].width, region[a].height, true);
-
+
if (s->do_masking) {
/* masking, find original pixels tiles from undo buffer to composite over */
int tilex, tiley, tilew, tileh;
@@ -1232,7 +1232,7 @@ static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
/* set masking */
s->do_masking = paint_use_opacity_masking(s->brush);
-
+
return 1;
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 45ee1ebac11..32355d41ada 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -74,6 +74,7 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_report.h"
@@ -1055,7 +1056,7 @@ static bool check_seam(
/* set up the other face */
*other_face = tri_index;
-
+
/* we check if difference is 1 here, else we might have a case of edge 2-0 for a tri */
*orig_fidx = (i1_fidx < i2_fidx && (i2_fidx - i1_fidx == 1)) ? i1_fidx : i2_fidx;
@@ -2117,7 +2118,7 @@ static void project_bucket_clip_face(
int inside_face_flag = 0;
int flip;
bool collinear = false;
-
+
float bucket_bounds_ss[4][2];
/* detect pathological case where face the three vertices are almost collinear in screen space.
@@ -2128,12 +2129,12 @@ static void project_bucket_clip_face(
{
collinear = true;
}
-
+
/* get the UV space bounding box */
inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v1coSS);
inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v2coSS) << 1;
inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v3coSS) << 2;
-
+
if (inside_bucket_flag == ISECT_ALL3) {
/* is_flip_object is used here because we use the face winding */
flip = (((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != is_flip_object) !=
@@ -2150,20 +2151,20 @@ static void project_bucket_clip_face(
copy_v2_v2(bucket_bounds_uv[0], uv1co);
copy_v2_v2(bucket_bounds_uv[1], uv2co);
copy_v2_v2(bucket_bounds_uv[2], uv3co);
- }
-
+ }
+
*tot = 3;
return;
}
/* handle pathological case here, no need for further intersections below since tringle area is almost zero */
if (collinear) {
int flag;
-
+
(*tot) = 0;
if (cull)
return;
-
+
if (inside_bucket_flag & ISECT_1) { copy_v2_v2(bucket_bounds_uv[*tot], uv1co); (*tot)++; }
flag = inside_bucket_flag & (ISECT_1 | ISECT_2);
@@ -2171,9 +2172,9 @@ static void project_bucket_clip_face(
if (line_rect_clip(bucket_bounds, v1coSS, v2coSS, uv1co, uv2co, bucket_bounds_uv[*tot], is_ortho))
(*tot)++;
}
-
+
if (inside_bucket_flag & ISECT_2) { copy_v2_v2(bucket_bounds_uv[*tot], uv2co); (*tot)++; }
-
+
flag = inside_bucket_flag & (ISECT_2 | ISECT_3);
if (flag && flag != (ISECT_2 | ISECT_3)) {
if (line_rect_clip(bucket_bounds, v2coSS, v3coSS, uv2co, uv3co, bucket_bounds_uv[*tot], is_ortho))
@@ -2187,7 +2188,7 @@ static void project_bucket_clip_face(
if (line_rect_clip(bucket_bounds, v3coSS, v1coSS, uv3co, uv1co, bucket_bounds_uv[*tot], is_ortho))
(*tot)++;
}
-
+
if ((*tot) < 3) {
/* no intersections to speak of, but more probable is that all face is just outside the
* rectangle and culled due to float precision issues. Since above tests have failed,
@@ -2352,7 +2353,7 @@ static void project_bucket_clip_face(
(*tot)--;
}
}
-
+
/* its possible there is only a few left after remove doubles */
if ((*tot) < 3) {
// printf("removed too many doubles B\n");
@@ -2976,7 +2977,7 @@ static bool project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int buck
int fidx;
project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds);
-
+
/* Is one of the faces verts in the bucket bounds? */
fidx = 2;
@@ -3487,7 +3488,7 @@ static void proj_paint_layer_clone_init(
/* get active instead */
mloopuv_clone_base = CustomData_get_layer(&ps->dm->loopData, CD_MLOOPUV);
}
-
+
}
memset(layer_clone, 0, sizeof(*layer_clone));
@@ -3513,7 +3514,7 @@ static bool project_paint_clone_face_skip(
if (ps->do_material_slots) {
if (lc->slot_clone != lc->slot_last_clone) {
- if (!slot->uvname ||
+ if (!slot->uvname ||
!(lc->mloopuv_clone_base = CustomData_get_layer_named(
&ps->dm->loopData, CD_MLOOPUV,
lc->slot_clone->uvname)))
@@ -3707,7 +3708,7 @@ static void project_paint_prepare_all_faces(
ps->dm_mloopuv[lt->poly] = mloopuv_base;
continue;
}
-
+
tpage = slot->ima;
}
}
@@ -4399,7 +4400,7 @@ static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, con
if (ps->is_texbrush)
mul_v3_v3(rgba, texrgb);
-
+
mul_v3_fl(rgba, mask);
rgba[3] = mask;
@@ -4608,7 +4609,7 @@ static void *do_projectpaint_thread(void *ph_v)
projPixel->newColor.ch, ps->blend);
}
}
-
+
if (lock_alpha) {
if (is_floatbuf) {
/* slightly more involved case since floats are in premultiplied space we need
@@ -4686,7 +4687,7 @@ static void *do_projectpaint_thread(void *ph_v)
/* masking to keep brush contribution to a pixel limited. note we do not do
* a simple max(mask, mask_accum), as this is very sensitive to spacing and
* gives poor results for strokes crossing themselves.
- *
+ *
* Instead we use a formula that adds up but approaches brush_alpha slowly
* and never exceeds it, which gives nice smooth results. */
float mask_accum = *projPixel->mask_accum;
@@ -4919,14 +4920,14 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
touch_any = 1;
}
}
-
+
/* calculate pivot for rotation around seletion if needed */
if (U.uiflag & USER_ORBIT_SELECTION) {
float w[3];
int tri_index;
-
+
tri_index = project_paint_PickFace(ps, pos, w);
-
+
if (tri_index != -1) {
const MLoopTri *lt = &ps->dm_mlooptri[tri_index];
const int lt_vtri[3] = { PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt) };
@@ -4939,14 +4940,14 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
ps->dm_mvert[lt_vtri[1]].co,
ps->dm_mvert[lt_vtri[2]].co,
w);
-
+
ups->average_stroke_counter++;
mul_m4_v3(ps->obmat, world);
add_v3_v3(ups->average_stroke_accum, world);
ups->last_stroke_valid = true;
}
}
-
+
return touch_any;
}
@@ -5085,9 +5086,9 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
ps->do_material_slots = (settings->imapaint.mode == IMAGEPAINT_MODE_MATERIAL);
ps->stencil_ima = settings->imapaint.stencil;
- ps->canvas_ima = (!ps->do_material_slots) ?
+ ps->canvas_ima = (!ps->do_material_slots) ?
settings->imapaint.canvas : NULL;
- ps->clone_ima = (!ps->do_material_slots) ?
+ ps->clone_ima = (!ps->do_material_slots) ?
settings->imapaint.clone : NULL;
ps->do_mask_cavity = (settings->imapaint.paint.flags & PAINT_USE_CAVITY_MASK) ? true : false;
@@ -5319,7 +5320,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, NULL)) {
BKE_paint_data_warning(op->reports, uvs, mat, tex, true);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
project_state_init(C, ob, &ps, BRUSH_STROKE_NORMAL);
@@ -5519,7 +5520,7 @@ void PAINT_OT_image_from_view(wmOperatorType *ot)
void BKE_paint_data_warning(struct ReportList *reports, bool uvs, bool mat, bool tex, bool stencil)
{
- BKE_reportf(reports, RPT_WARNING, "Missing%s%s%s%s detected!",
+ BKE_reportf(reports, RPT_WARNING, "Missing%s%s%s%s detected!",
!uvs ? " UVs," : "",
!mat ? " Materials," : "",
!tex ? " Textures," : "",
@@ -5540,7 +5541,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
bool hasuvs = true;
imapaint->missing_data = 0;
-
+
BLI_assert(ob->type == OB_MESH);
if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
@@ -5554,16 +5555,16 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
int i;
hasmat = false;
hastex = false;
-
+
for (i = 1; i < ob->totcol + 1; i++) {
Material *ma = give_current_material(ob, i);
-
+
if (ma) {
hasmat = true;
if (!ma->texpaintslot) {
/* refresh here just in case */
BKE_texpaint_slot_refresh_cache(scene, ma);
-
+
/* if still no slots, we have to add */
if (ma->texpaintslot) {
hastex = true;
@@ -5583,7 +5584,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
hastex = false;
}
}
-
+
me = BKE_mesh_from_object(ob);
layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
@@ -5604,7 +5605,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
if (!hasmat) imapaint->missing_data |= IMAGEPAINT_MISSING_MATERIAL;
if (!hastex) imapaint->missing_data |= IMAGEPAINT_MISSING_TEX;
if (!hasstencil) imapaint->missing_data |= IMAGEPAINT_MISSING_STENCIL;
-
+
if (uvs) {
*uvs = hasuvs;
}
@@ -5617,7 +5618,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
if (stencil) {
*stencil = hasstencil;
}
-
+
return hasuvs && hasmat && hastex && hasstencil;
}
@@ -5654,7 +5655,7 @@ static Image *proj_paint_image_create(wmOperator *op, Main *bmain)
}
ima = BKE_image_add_generated(bmain, width, height, imagename, alpha ? 32 : 24, use_float,
gen_type, color, false);
-
+
return ima;
}
@@ -5681,32 +5682,32 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
ED_node_shader_default(C, &ma->id);
ntree = ma->nodetree;
}
-
+
ma->use_nodes = true;
-
+
/* try to add an image node */
imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE);
-
+
ima = proj_paint_image_create(op, bmain);
imanode->id = &ima->id;
-
+
nodeSetActive(ntree, imanode);
-
+
ntreeUpdateTree(CTX_data_main(C), ntree);
-
+
if (ima) {
BKE_texpaint_slot_refresh_cache(scene, ma);
BKE_image_signal(ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE);
WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
DEG_id_tag_update(&ma->id, 0);
ED_area_tag_redraw(CTX_wm_area(C));
-
+
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
-
+
return true;
}
}
-
+
return false;
}
@@ -5734,7 +5735,7 @@ static int texture_paint_add_texture_paint_slot_invoke(bContext *C, wmOperator *
/* no material found, just assign to first slot */
assign_material(bmain, ob, ma, ob->actcol, BKE_MAT_ASSIGN_USERPREF);
}
-
+
type = RNA_enum_from_value(layer_type_items, type);
/* get the name of the texture layer type */
@@ -5819,7 +5820,7 @@ static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op))
scene->toolsettings->uv_flag |= UV_SYNC_SELECTION;
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
-
+
DEG_id_tag_update(ob->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, scene);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index f56ef32ba72..3a8ab12b96d 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -88,10 +88,10 @@ static void BRUSH_OT_add(wmOperatorType *ot)
ot->name = "Add Brush";
ot->description = "Add brush by mode type";
ot->idname = "BRUSH_OT_add";
-
+
/* api callbacks */
ot->exec = brush_add_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -145,10 +145,10 @@ static void BRUSH_OT_scale_size(wmOperatorType *ot)
ot->name = "Scale Sculpt/Paint Brush Size";
ot->description = "Change brush size by a scalar";
ot->idname = "BRUSH_OT_scale_size";
-
+
/* api callbacks */
ot->exec = brush_scale_size_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -286,10 +286,10 @@ static void BRUSH_OT_reset(wmOperatorType *ot)
ot->name = "Reset Brush";
ot->description = "Return brush to defaults based on current tool";
ot->idname = "BRUSH_OT_reset";
-
+
/* api callbacks */
ot->exec = brush_reset_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -354,7 +354,7 @@ static Brush *brush_tool_toggle(Main *bmain, Brush *brush_orig, const int tool,
/* store the previously-selected brush */
if (br)
br->toggle_brush = brush_orig;
-
+
return br;
}
else if (brush_orig->toggle_brush) {
@@ -930,7 +930,7 @@ static int stencil_reset_transform_exec(bContext *C, wmOperator *op)
if (!br)
return OPERATOR_CANCELLED;
-
+
if (do_mask) {
br->mask_stencil_pos[0] = 256;
br->mask_stencil_pos[1] = 256;
@@ -1201,7 +1201,7 @@ static void ed_keymap_paint_brush_radial_control(wmKeyMap *keymap, const char *p
static void paint_partial_visibility_keys(wmKeyMap *keymap)
{
wmKeyMapItem *kmi;
-
+
/* Partial visibility */
kmi = WM_keymap_add_item(keymap, "PAINT_OT_hide_show", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "action", PARTIALVIS_SHOW);
@@ -1247,7 +1247,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
wmKeyMap *keymap;
wmKeyMapItem *kmi;
int i;
-
+
keymap = WM_keymap_find(keyconf, "Paint Curve", 0, 0);
keymap->poll = paint_curve_poll;
@@ -1286,7 +1286,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "SCULPT_OT_dynamic_topology_toggle", DKEY, KM_PRESS, KM_CTRL, 0);
/* Dynamic-topology detail size
- *
+ *
* This should be improved further, perhaps by showing a triangle
* grid rather than brush alpha */
kmi = WM_keymap_add_item(keymap, "SCULPT_OT_set_detail_size", DKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 3ded6326c67..b63f9461401 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -126,7 +126,7 @@ typedef struct PaintStroke {
float zoom_2d;
int pen_flip;
-
+
/* line constraint */
bool constrain_line;
float constrained_pos[2];
@@ -735,10 +735,10 @@ PaintStroke *paint_stroke_new(bContext *C,
/* initialize here */
ups->overlap_factor = 1.0;
ups->stroke_active = true;
-
+
zero_v3(ups->average_stroke_accum);
ups->average_stroke_counter = 0;
-
+
/* initialize here to avoid initialization conflict with threaded strokes */
curvemapping_initialize(br->curve);
if (p->flags & PAINT_USE_CAVITY_MASK)
@@ -928,11 +928,11 @@ static void paint_stroke_sample_average(const PaintStroke *stroke,
PaintSample *average)
{
int i;
-
+
memset(average, 0, sizeof(*average));
BLI_assert(stroke->num_samples > 0);
-
+
for (i = 0; i < stroke->num_samples; i++) {
add_v2_v2(average->mouse, stroke->samples[i].mouse);
average->pressure += stroke->samples[i].pressure;
@@ -1096,17 +1096,17 @@ static void paint_stroke_line_constrain(PaintStroke *stroke, float mouse[2])
if (stroke->constrain_line) {
float line[2];
float angle, len, res;
-
+
sub_v2_v2v2(line, mouse, stroke->last_mouse_position);
angle = atan2f(line[1], line[0]);
len = len_v2(line);
-
+
/* divide angle by PI/4 */
angle = 4.0f * angle / (float)M_PI;
-
+
/* now take residue */
res = angle - floorf(angle);
-
+
/* residue decides how close we are at a certain angle */
if (res <= 0.5f) {
angle = floorf(angle) * (float)M_PI_4;
@@ -1114,7 +1114,7 @@ static void paint_stroke_line_constrain(PaintStroke *stroke, float mouse[2])
else {
angle = (floorf(angle) + 1.0f) * (float)M_PI_4;
}
-
+
mouse[0] = stroke->constrained_pos[0] = len * cosf(angle) + stroke->last_mouse_position[0];
mouse[1] = stroke->constrained_pos[1] = len * sinf(angle) + stroke->last_mouse_position[1];
}
@@ -1209,12 +1209,12 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
else if (br->flag & BRUSH_LINE) {
if (event->alt)
stroke->constrain_line = true;
- else
+ else
stroke->constrain_line = false;
copy_v2_fl2(mouse, event->mval[0], event->mval[1]);
paint_stroke_line_constrain(stroke, mouse);
-
+
if (stroke->stroke_started && (first_modal || (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)))) {
if ((br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) || (br->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) {
copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 594fbbd04d4..80c4d4099a2 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -221,10 +221,10 @@ void paint_stroke_operator_properties(wmOperatorType *ot)
prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL,
+ RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL,
"Stroke Mode",
"Action taken when a paint stroke is made");
-
+
}
/* 3D Paint */
@@ -436,7 +436,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
CLAMP(x, 0, ar->winx);
CLAMP(y, 0, ar->winy);
-
+
if (use_palette) {
if (!palette) {
palette = BKE_palette_add(CTX_data_main(C), "Palette");
@@ -473,12 +473,12 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
if (imapaint_pick_face(&vc, mval, &faceindex, totpoly)) {
Image *image;
-
- if (use_material)
+
+ if (use_material)
image = imapaint_face_image(ob_eval, me_eval, faceindex);
else
image = imapaint->canvas;
-
+
if (image) {
ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf && ibuf->rect) {
@@ -486,16 +486,16 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
float u, v;
imapaint_pick_uv(me_eval, scene, ob_eval, faceindex, mval, uv);
sample_success = true;
-
+
u = fmodf(uv[0], 1.0f);
v = fmodf(uv[1], 1.0f);
-
+
if (u < 0.0f) u += 1.0f;
if (v < 0.0f) v += 1.0f;
-
+
u = u * ibuf->x;
v = v * ibuf->y;
-
+
if (ibuf->rect_float) {
float rgba_f[4];
bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v);
@@ -521,7 +521,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
}
}
}
-
+
BKE_image_release_ibuf(image, ibuf, NULL);
}
}
@@ -542,7 +542,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
glReadBuffer(GL_BACK);
}
cp = (unsigned char *)&col;
-
+
if (use_palette) {
rgb_uchar_to_float(color->rgb, cp);
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 3e4a2e24920..02dae51c594 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -59,6 +59,7 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_paint.h"
#include "BKE_report.h"
@@ -974,7 +975,7 @@ static void vertex_paint_init_session(Depsgraph *depsgraph, Scene *scene, Object
if (ob->sculpt == NULL) {
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
- BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, 0, false);
+ BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false);
}
}
@@ -1067,6 +1068,11 @@ static void ed_vwpaintmode_enter_generic(
ob->mode |= mode_flag;
Mesh *me = BKE_mesh_from_object(ob);
+ /* Same as sculpt mode, make sure we don't have cached derived mesh which
+ * points to freed arrays.
+ */
+ BKE_object_free_derived_caches(ob);
+
if (mode_flag == OB_MODE_VERTEX_PAINT) {
const ePaintMode paint_mode = ePaintVertex;
ED_mesh_color_ensure(me, NULL);
@@ -1108,6 +1114,9 @@ static void ed_vwpaintmode_enter_generic(
}
vertex_paint_init_session(depsgraph, scene, ob);
+
+ /* Flush object mode. */
+ DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
}
void ED_object_vpaintmode_enter_ex(
@@ -1189,6 +1198,10 @@ static void ed_vwpaintmode_exit_generic(
ED_mesh_mirror_topo_table(NULL, NULL, 'e');
}
+ /* Never leave derived meshes behind. */
+ BKE_object_free_derived_caches(ob);
+
+ /* Flush object mode. */
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
}
@@ -2604,7 +2617,7 @@ static float tex_color_alpha_ubyte(
}
static void do_vpaint_brush_draw_task_cb_ex(
- void *__restrict userdata,
+ void *__restrict userdata,
const int n,
const ParallelRangeTLS *__restrict UNUSED(tls))
{
@@ -3139,6 +3152,10 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
* avoid this if we can! */
DEG_id_tag_update(ob->data, 0);
}
+ else {
+ /* Flush changes through DEG. */
+ DEG_id_tag_update(ob->data, DEG_TAG_COPY_ON_WRITE);
+ }
}
static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
index d7668a48139..8516d92214d 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
@@ -152,6 +152,7 @@ static bool vertex_paint_from_weight(Object *ob)
}
/* TODO: respect selection. */
+ /* TODO: Do we want to take weights from evaluated mesh instead? 2.7x was not doing it anyway... */
mp = me->mpoly;
vgroup_active = ob->actdef - 1;
for (int i = 0; i < me->totpoly; i++, mp++) {
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
index c5c9aa48760..cacfdc2dbba 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -41,6 +41,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_context.h"
+#include "BKE_mesh_runtime.h"
#include "DEG_depsgraph.h"
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
index e560a4cddff..7c2977a0788 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -52,6 +52,7 @@
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_object_deform.h"
#include "BKE_paint.h"
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index c0674289a5a..3475aadd171 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -631,7 +631,7 @@ bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float loca
if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) {
float p = 4.0f;
-
+
test->dist = ((powf(local_co[0], p) +
powf(local_co[1], p) +
powf(local_co[2], p)) / powf(side, p));
@@ -730,7 +730,7 @@ static float calc_overlap(StrokeCache *cache, const char symm, const char axis,
{
float mirror[3];
float distsq;
-
+
/* flip_v3_v3(mirror, cache->traced_location, symm); */
flip_v3_v3(mirror, cache->true_location, symm);
@@ -1119,7 +1119,7 @@ static float brush_strength(
case SCULPT_TOOL_DRAW:
case SCULPT_TOOL_LAYER:
return alpha * flip * pressure * overlap * feather;
-
+
case SCULPT_TOOL_MASK:
overlap = (1 + overlap) / 2;
switch ((BrushMaskTool)brush->mask_tool) {
@@ -1152,7 +1152,7 @@ static float brush_strength(
}
else {
/* reduce strength for DEEPEN, PEAKS, and CONTRAST */
- return 0.5f * alpha * flip * pressure * overlap * feather;
+ return 0.5f * alpha * flip * pressure * overlap * feather;
}
case SCULPT_TOOL_SMOOTH:
@@ -1209,7 +1209,7 @@ float tex_strength(SculptSession *ss, const Brush *br,
avg = 1;
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
- /* Get strength by feeding the vertex
+ /* Get strength by feeding the vertex
* location directly into a texture */
avg = BKE_brush_sample_tex_3D(scene, br, point, rgba, 0, ss->tex_pool);
}
@@ -1219,7 +1219,7 @@ float tex_strength(SculptSession *ss, const Brush *br,
/* if the active area is being applied for symmetry, flip it
* across the symmetry axis and rotate it back to the original
- * position in order to project it. This insures that the
+ * position in order to project it. This insures that the
* brush texture will be oriented correctly. */
flip_v3_v3(symm_point, point, cache->mirror_symmetry_pass);
@@ -1279,16 +1279,16 @@ bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v)
BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
else
BKE_pbvh_node_get_BB(node, bb_min, bb_max);
-
+
for (i = 0; i < 3; ++i) {
if (bb_min[i] > center[i])
nearest[i] = bb_min[i];
else if (bb_max[i] < center[i])
nearest[i] = bb_max[i];
else
- nearest[i] = center[i];
+ nearest[i] = center[i];
}
-
+
sub_v3_v3v3(t, center, nearest);
return len_squared_v3(t) < data->radius_squared;
@@ -1399,7 +1399,7 @@ static void update_sculpt_normal(Sculpt *sd, Object *ob,
{
const Brush *brush = BKE_paint_brush(&sd->paint);
StrokeCache *cache = ob->sculpt->cache;
-
+
if (cache->mirror_symmetry_pass == 0 &&
cache->radial_symmetry_pass == 0 &&
(cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL)))
@@ -2041,7 +2041,7 @@ static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
-
+
switch ((BrushMaskTool)brush->mask_tool) {
case BRUSH_MASK_DRAW:
do_mask_brush_draw(sd, ob, nodes, totnode);
@@ -2192,7 +2192,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius);
mul_v3_v3(offset, ss->cache->scale);
mul_v3_fl(offset, bstrength);
-
+
/* we divide out the squared alpha and multiply by the squared crease to give us the pinch strength */
crease_correction = brush->crease_pinch_factor * brush->crease_pinch_factor;
brush_alpha = BKE_brush_alpha_get(scene, brush);
@@ -4040,7 +4040,7 @@ static void do_symmetrical_brush_actions(
cache->bstrength = brush_strength(sd, cache, feather, ups);
cache->symmetry = symm;
- /* 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 */
+ /* symm is a bit combination of XYZ - 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
for (i = 0; i <= symm; ++i) {
if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
cache->mirror_symmetry_pass = i;
@@ -4175,14 +4175,14 @@ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
(md->mode & eModifierMode_Realtime))
{
MirrorModifierData *mmd = (MirrorModifierData *)md;
-
+
if (mmd->flag & MOD_MIR_CLIPPING) {
/* check each axis for mirroring */
for (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])
@@ -4271,7 +4271,7 @@ static void sculpt_update_cache_invariants(
Paint *p = &sd->paint;
Brush *br;
int size = BKE_brush_size_get(scene, brush);
-
+
BLI_strncpy(cache->saved_active_brush_name, brush->id.name + 2,
sizeof(cache->saved_active_brush_name));
@@ -4367,7 +4367,7 @@ static void sculpt_update_cache_invariants(
#define PIXEL_INPUT_THRESHHOLD 5
if (brush->sculpt_tool == SCULPT_TOOL_ROTATE)
cache->dial = BLI_dial_initialize(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD);
-
+
#undef PIXEL_INPUT_THRESHHOLD
}
@@ -4949,7 +4949,7 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
const Brush *brush = BKE_paint_brush(&sd->paint);
-
+
sculpt_stroke_modifiers_check(C, ob, brush);
sculpt_update_cache_variants(C, sd, ob, itemptr);
sculpt_restore_mesh(sd, ob);
@@ -5048,7 +5048,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
sculpt_undo_push_end();
BKE_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
-
+
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH)
BKE_pbvh_bmesh_after_stroke(ss->pbvh);
@@ -5092,7 +5092,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
paint_stroke_data_free(op);
return OPERATOR_PASS_THROUGH;
}
-
+
if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
paint_stroke_data_free(op);
return OPERATOR_FINISHED;
@@ -5102,7 +5102,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
OPERATOR_RETVAL_CHECK(retval);
BLI_assert(retval == OPERATOR_RUNNING_MODAL);
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -5149,7 +5149,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
ot->name = "Sculpt";
ot->idname = "SCULPT_OT_brush_stroke";
ot->description = "Sculpt a stroke into the geometry";
-
+
/* api callbacks */
ot->invoke = sculpt_brush_stroke_invoke;
ot->modal = paint_stroke_modal;
@@ -5166,7 +5166,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "ignore_background_click", 0,
"Ignore Background Click",
- "Clicks on the background do not start the stroke");
+ "Clicks on the background do not start the stroke");
}
/**** Reset the copy of the mesh that is being sculpted on (currently just for the layer brush) ****/
@@ -5190,11 +5190,11 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
ot->name = "Set Persistent Base";
ot->idname = "SCULPT_OT_set_persistent_base";
ot->description = "Reset the copy of the mesh that is being sculpted on";
-
+
/* api callbacks */
ot->exec = sculpt_set_persistent_base_exec;
ot->poll = sculpt_mode_poll;
-
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -5210,14 +5210,12 @@ static void sculpt_dynamic_topology_triangulate(BMesh *bm)
void sculpt_pbvh_clear(Object *ob)
{
SculptSession *ss = ob->sculpt;
- DerivedMesh *dm = ob->derivedFinal;
/* Clear out any existing DM and PBVH */
- if (ss->pbvh)
+ if (ss->pbvh) {
BKE_pbvh_free(ss->pbvh);
+ }
ss->pbvh = NULL;
- if (dm)
- dm->getPBVH(NULL, dm);
BKE_object_free_derived_caches(ob);
}
@@ -5298,7 +5296,7 @@ void sculpt_dynamic_topology_enable_ex(
/* Enable dynamic topology */
me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
-
+
/* Enable logging for undo/redo */
ss->bm_log = BM_log_create(ss->bm);
@@ -5522,12 +5520,12 @@ static void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot)
ot->name = "Dynamic Topology Toggle";
ot->idname = "SCULPT_OT_dynamic_topology_toggle";
ot->description = "Dynamic topology alters the mesh topology while sculpting";
-
+
/* api callbacks */
ot->invoke = sculpt_dynamic_topology_toggle_invoke;
ot->exec = sculpt_dynamic_topology_toggle_exec;
ot->poll = sculpt_mode_poll;
-
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -5560,11 +5558,11 @@ static void SCULPT_OT_optimize(wmOperatorType *ot)
ot->name = "Optimize";
ot->idname = "SCULPT_OT_optimize";
ot->description = "Recalculate the sculpt BVH to improve performance";
-
+
/* api callbacks */
ot->exec = sculpt_optimize_exec;
ot->poll = sculpt_and_dynamic_topology_poll;
-
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -5614,7 +5612,7 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot)
ot->name = "Symmetrize";
ot->idname = "SCULPT_OT_symmetrize";
ot->description = "Symmetrize the topology modifications";
-
+
/* api callbacks */
ot->exec = sculpt_symmetrize_exec;
ot->poll = sculpt_and_dynamic_topology_poll;
@@ -5629,7 +5627,7 @@ static void sculpt_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob)
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
ob->sculpt->mode_type = OB_MODE_SCULPT;
- BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, 0, false);
+ BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false);
}
static int ed_object_sculptmode_flush_recalc_flag(Scene *scene, Object *ob, MultiresModifierData *mmd)
@@ -5643,7 +5641,7 @@ static int ed_object_sculptmode_flush_recalc_flag(Scene *scene, Object *ob, Mult
}
void ED_object_sculptmode_enter_ex(
- Depsgraph *depsgraph,
+ Main *bmain, Depsgraph *depsgraph,
Scene *scene, Object *ob,
ReportList *reports)
{
@@ -5665,6 +5663,11 @@ void ED_object_sculptmode_enter_ex(
BKE_sculptsession_free(ob);
}
+ /* Make sure derived final from original object does not reference possibly
+ * freed memory.
+ */
+ BKE_object_free_derived_mesh_caches(ob);
+
sculpt_init_session(depsgraph, scene, ob);
/* Mask layer is required */
@@ -5686,7 +5689,7 @@ void ED_object_sculptmode_enter_ex(
Paint *paint = BKE_paint_get_active_from_paintmode(scene, ePaintSculpt);
BKE_paint_init(scene, ePaintSculpt, PAINT_CURSOR_SCULPT);
- paint_cursor_start_explicit(paint, G.main->wm.first, sculpt_poll_view3d);
+ paint_cursor_start_explicit(paint, bmain->wm.first, sculpt_poll_view3d);
/* Check dynamic-topology flag; re-enter dynamic-topology mode when changing modes,
* As long as no data was added that is not supported. */
@@ -5735,14 +5738,18 @@ void ED_object_sculptmode_enter_ex(
}
// ED_workspace_object_mode_sync_from_object(G.main->wm.first, workspace, ob);
+
+ /* Flush object mode. */
+ DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
}
void ED_object_sculptmode_enter(struct bContext *C, ReportList *reports)
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ED_object_sculptmode_enter_ex(depsgraph, scene, ob, reports);
+ ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, reports);
}
void ED_object_sculptmode_exit_ex(
@@ -5788,6 +5795,10 @@ void ED_object_sculptmode_exit_ex(
paint_cursor_delete_textures();
+ /* Never leave derived meshes behind. */
+ BKE_object_free_derived_mesh_caches(ob);
+
+ /* Flush object mode. */
DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
}
@@ -5802,6 +5813,7 @@ void ED_object_sculptmode_exit(bContext *C)
static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
{
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+ Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
@@ -5818,7 +5830,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
ED_object_sculptmode_exit_ex(depsgraph, scene, ob);
}
else {
- ED_object_sculptmode_enter_ex(depsgraph, scene, ob, op->reports);
+ ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, op->reports);
}
WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
@@ -5836,11 +5848,11 @@ static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot)
ot->name = "Sculpt Mode";
ot->idname = "SCULPT_OT_sculptmode_toggle";
ot->description = "Toggle sculpt mode in 3D view";
-
+
/* api callbacks */
ot->exec = sculpt_mode_toggle_exec;
ot->poll = ED_operator_object_active_editable_mesh;
-
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index bca33ad8014..ff6b5a6f374 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -28,7 +28,7 @@
/** \file blender/editors/sculpt_paint/sculpt_intern.h
* \ingroup edsculpt
*/
-
+
#ifndef __SCULPT_INTERN_H__
#define __SCULPT_INTERN_H__
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index b819fe8e97d..2872ad4fb9c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -58,6 +58,7 @@
#include "BKE_paint.h"
#include "BKE_key.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_subsurf.h"
#include "BKE_undo_system.h"
@@ -144,7 +145,7 @@ static bool sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoN
SculptSession *ss = ob->sculpt;
MVert *mvert;
int *index;
-
+
if (unode->maxvert) {
/* regular mesh restore */
@@ -157,7 +158,7 @@ static bool sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoN
if (kb) {
ob->shapenr = BLI_findindex(&key->block, kb) + 1;
- BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, 0, false);
+ BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, false);
WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
}
else {
@@ -197,7 +198,7 @@ static bool sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoN
/* pbvh uses it's own mvert array, so coords should be */
/* propagated to pbvh here */
- BKE_pbvh_apply_vertCos(ss->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(ss->pbvh, vertCos, unode->totvert);
MEM_freeN(vertCos);
}
@@ -261,7 +262,7 @@ static bool sculpt_undo_restore_hidden(
if (unode->maxvert) {
MVert *mvert = ss->mvert;
-
+
for (i = 0; i < unode->totvert; i++) {
MVert *v = &mvert[unode->index[i]];
if ((BLI_BITMAP_TEST(unode->vert_hidden, i) != 0) != ((v->flag & ME_HIDE) != 0)) {
@@ -273,12 +274,12 @@ static bool sculpt_undo_restore_hidden(
}
else if (unode->maxgrid && dm->getGridData) {
BLI_bitmap **grid_hidden = dm->getGridHidden(dm);
-
+
for (i = 0; i < unode->totgrid; i++) {
SWAP(BLI_bitmap *,
unode->grid_hidden[i],
grid_hidden[unode->grids[i]]);
-
+
}
}
@@ -292,7 +293,7 @@ static bool sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNod
MVert *mvert;
float *vmask;
int *index, i, j;
-
+
if (unode->maxvert) {
/* regular mesh restore */
@@ -492,7 +493,9 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb)
}
}
- BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, 0, need_mask);
+ DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
+
+ BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, need_mask);
/* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */
dm = mesh_get_derived_final(depsgraph, scene, ob, 0);
@@ -671,10 +674,10 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh,
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid,
NULL, NULL, NULL);
-
+
unode->grid_hidden = MEM_mapallocN(sizeof(*unode->grid_hidden) * totgrid,
"unode->grid_hidden");
-
+
for (i = 0; i < totgrid; i++) {
if (grid_hidden[grid_indices[i]])
unode->grid_hidden[i] = MEM_dupallocN(grid_hidden[grid_indices[i]]);
@@ -691,7 +694,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(
SculptUndoNode *unode;
SculptSession *ss = ob->sculpt;
int totvert, allvert, totgrid, maxgrid, gridsize, *grids;
-
+
unode = MEM_callocN(sizeof(SculptUndoNode), "SculptUndoNode");
BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
unode->type = type;
@@ -706,7 +709,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(
}
else
maxgrid = 0;
-
+
/* we will use this while sculpting, is mapalloc slow to access then? */
/* general TODO, fix count_alloc */
@@ -722,7 +725,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(
sculpt_undo_alloc_and_store_hidden(ss->pbvh, unode);
else
unode->vert_hidden = BLI_BITMAP_NEW(allvert, "SculptUndoNode.vert_hidden");
-
+
break;
case SCULPT_UNDO_MASK:
unode->mask = MEM_mapallocN(sizeof(float) * allvert, "SculptUndoNode.mask");
@@ -736,7 +739,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(
BLI_assert(!"Dynamic topology should've already been handled");
break;
}
-
+
BLI_addtail(&usculpt->nodes, unode);
if (maxgrid) {
@@ -788,7 +791,7 @@ static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
const int *vert_indices;
int allvert;
int i;
-
+
BKE_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
for (i = 0; i < allvert; i++) {
@@ -927,7 +930,7 @@ SculptUndoNode *sculpt_undo_push_node(
}
unode = sculpt_undo_alloc_node(ob, node, type);
-
+
BLI_thread_unlock(LOCK_CUSTOM1);
/* copy threaded, hopefully this is the performance critical part */
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 6928610f280..46d704e8f74 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -138,7 +138,7 @@ typedef struct UvSculptData {
/* uvsmooth Paint for fast reference */
Paint *uvsculpt;
-
+
/* tool to use. duplicating here to change if modifier keys are pressed */
char tool;
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 07d12de3662..b7a80a92998 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -375,7 +375,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
specs.rate = scene->r.ffcodecdata.audio_mixrate;
BLI_strncpy(filename, path, sizeof(filename));
- BLI_path_abs(filename, bmain->name);
+ BLI_path_abs(filename, BKE_main_blendfile_path(bmain));
if (split)
result = AUD_mixdown_per_channel(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA + 1) * specs.rate / FPS,
diff --git a/source/blender/editors/space_action/action_buttons.c b/source/blender/editors/space_action/action_buttons.c
index fbe72697827..a5cc66add87 100644
--- a/source/blender/editors/space_action/action_buttons.c
+++ b/source/blender/editors/space_action/action_buttons.c
@@ -75,9 +75,9 @@ void action_buttons_register(ARegionType *UNUSED(art))
{
#if 0
PanelType *pt;
-
+
// TODO: AnimData / Actions List
-
+
pt = MEM_callocN(sizeof(PanelType), "spacetype action panel properties");
strcpy(pt->idname, "ACTION_PT_properties");
strcpy(pt->label, N_("Active F-Curve"));
@@ -85,7 +85,7 @@ void action_buttons_register(ARegionType *UNUSED(art))
pt->draw = action_anim_panel_properties;
pt->poll = action_anim_panel_poll;
BLI_addtail(&art->paneltypes, pt);
-
+
pt = MEM_callocN(sizeof(PanelType), "spacetype action panel properties");
strcpy(pt->idname, "ACTION_PT_key_properties");
strcpy(pt->label, N_("Active Keyframe"));
@@ -93,7 +93,7 @@ void action_buttons_register(ARegionType *UNUSED(art))
pt->draw = action_anim_panel_key_properties;
pt->poll = action_anim_panel_poll;
BLI_addtail(&art->paneltypes, pt);
-
+
pt = MEM_callocN(sizeof(PanelType), "spacetype action panel modifiers");
strcpy(pt->idname, "ACTION_PT_modifiers");
strcpy(pt->label, N_("Modifiers"));
@@ -108,7 +108,7 @@ static int action_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = action_has_buttons_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -120,7 +120,7 @@ void ACTION_OT_properties(wmOperatorType *ot)
ot->name = "Properties";
ot->idname = "ACTION_OT_properties";
ot->description = "Toggle the properties region visibility";
-
+
ot->exec = action_properties_toggle_exec;
ot->poll = ED_operator_action_active;
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index 2bfe756f76e..74c9f2f8cfb 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -87,7 +87,7 @@ AnimData *ED_actedit_animdata_from_context(bContext *C)
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
Object *ob = CTX_data_active_object(C);
AnimData *adt = NULL;
-
+
/* Get AnimData block to use */
if (saction->mode == SACTCONT_ACTION) {
/* Currently, "Action Editor" means object-level only... */
@@ -101,7 +101,7 @@ AnimData *ED_actedit_animdata_from_context(bContext *C)
adt = key->adt;
}
}
-
+
return adt;
}
@@ -112,7 +112,7 @@ static bAction *action_create_new(bContext *C, bAction *oldact)
{
ScrArea *sa = CTX_wm_area(C);
bAction *action;
-
+
/* create action - the way to do this depends on whether we've got an
* existing one there already, in which case we make a copy of it
* (which is useful for "versioning" actions within the same file)
@@ -125,24 +125,24 @@ static bAction *action_create_new(bContext *C, bAction *oldact)
/* just make a new (empty) action */
action = BKE_action_add(CTX_data_main(C), "Action");
}
-
- /* when creating new ID blocks, there is already 1 user (as for all new datablocks),
+
+ /* when creating new ID blocks, there is already 1 user (as for all new datablocks),
* but the RNA pointer code will assign all the proper users instead, so we compensate
* for that here
*/
BLI_assert(action->id.us == 1);
id_us_min(&action->id);
-
+
/* set ID-Root type */
if (sa->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
+
if (saction->mode == SACTCONT_SHAPEKEY)
action->idroot = ID_KE;
else
action->idroot = ID_OB;
}
-
+
return action;
}
@@ -151,17 +151,17 @@ static void actedit_change_action(bContext *C, bAction *act)
{
bScreen *screen = CTX_wm_screen(C);
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
-
+
PointerRNA ptr, idptr;
PropertyRNA *prop;
-
+
/* create RNA pointers and get the property */
RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, saction, &ptr);
prop = RNA_struct_find_property(&ptr, "action");
-
+
/* NOTE: act may be NULL here, so better to just use a cast here */
RNA_id_pointer_create((ID *)act, &idptr);
-
+
/* set the new pointer, and force a refresh */
RNA_property_pointer_set(&ptr, prop, idptr);
RNA_property_update(C, &ptr, prop);
@@ -178,13 +178,13 @@ static void actedit_change_action(bContext *C, bAction *act)
static int action_new_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
-
+
/* Check tweakmode is off (as you don't want to be tampering with the action in that case) */
- /* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */
+ /* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */
if (ED_operator_action_active(C)) {
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
Object *ob = CTX_data_active_object(C);
-
+
/* For now, actions are only for the active object, and on object and shapekey levels... */
if (saction->mode == SACTCONT_ACTION) {
/* XXX: This assumes that actions are assigned to the active object in this mode */
@@ -206,7 +206,7 @@ static int action_new_poll(bContext *C)
return true;
}
}
-
+
/* something failed... */
return false;
}
@@ -215,18 +215,18 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
{
PointerRNA ptr, idptr;
PropertyRNA *prop;
-
+
/* hook into UI */
UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
-
+
if (prop) {
bAction *action = NULL, *oldact = NULL;
AnimData *adt = NULL;
PointerRNA oldptr;
-
+
oldptr = RNA_property_pointer_get(&ptr, prop);
oldact = (bAction *)oldptr.id.data;
-
+
/* stash the old action to prevent it from being lost */
if (ptr.type == &RNA_AnimData) {
adt = ptr.data;
@@ -234,7 +234,7 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
else if (ptr.type == &RNA_SpaceDopeSheetEditor) {
adt = ED_actedit_animdata_from_context(C);
}
-
+
/* Perform stashing operation - But only if there is an action */
if (adt && oldact) {
/* stash the action */
@@ -255,10 +255,10 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
//printf("WARNING: Failed to stash %s. It may already exist in the NLA stack though\n", oldact->id.name);
}
}
-
+
/* create action */
action = action_create_new(C, oldact);
-
+
/* set this new action
* NOTE: we can't use actedit_change_action, as this function is also called from the NLA
*/
@@ -266,24 +266,24 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
RNA_property_pointer_set(&ptr, prop, idptr);
RNA_property_update(C, &ptr, prop);
}
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_new(wmOperatorType *ot)
{
/* identifiers */
ot->name = "New Action";
ot->idname = "ACTION_OT_new";
ot->description = "Create new action";
-
+
/* api callbacks */
ot->exec = action_new_exec;
ot->poll = action_new_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -300,7 +300,7 @@ static int action_pushdown_poll(bContext *C)
if (ED_operator_action_active(C)) {
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
AnimData *adt = ED_actedit_animdata_from_context(C);
-
+
/* Check for AnimData, Actions, and that tweakmode is off */
if (adt && saction->action) {
/* NOTE: We check this for the AnimData block in question and not the global flag,
@@ -310,7 +310,7 @@ static int action_pushdown_poll(bContext *C)
return true;
}
}
-
+
/* something failed... */
return false;
}
@@ -319,7 +319,7 @@ static int action_pushdown_exec(bContext *C, wmOperator *op)
{
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
AnimData *adt = ED_actedit_animdata_from_context(C);
-
+
/* Do the deed... */
if (adt) {
/* Perform the pushdown operation
@@ -334,13 +334,13 @@ static int action_pushdown_exec(bContext *C, wmOperator *op)
/* action can be safely added */
BKE_nla_action_pushdown(adt);
}
-
+
/* Stop displaying this action in this editor
* NOTE: The editor itself doesn't set a user...
*/
saction->action = NULL;
}
-
+
/* Send notifiers that stuff has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
return OPERATOR_FINISHED;
@@ -352,11 +352,11 @@ void ACTION_OT_push_down(wmOperatorType *ot)
ot->name = "Push Down Action";
ot->idname = "ACTION_OT_push_down";
ot->description = "Push action down on to the NLA stack as a new strip";
-
+
/* callbacks */
ot->exec = action_pushdown_exec;
ot->poll = action_pushdown_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -367,7 +367,7 @@ static int action_stash_exec(bContext *C, wmOperator *op)
{
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
AnimData *adt = ED_actedit_animdata_from_context(C);
-
+
/* Perform stashing operation */
if (adt) {
/* don't do anything if this action is empty... */
@@ -390,12 +390,12 @@ static int action_stash_exec(bContext *C, wmOperator *op)
/* action has already been added - simply warn about this, and clear */
BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
}
-
+
/* clear action refs from editor, and then also the backing data (not necessary) */
actedit_change_action(C, NULL);
}
}
-
+
/* Send notifiers that stuff has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
return OPERATOR_FINISHED;
@@ -407,16 +407,16 @@ void ACTION_OT_stash(wmOperatorType *ot)
ot->name = "Stash Action";
ot->idname = "ACTION_OT_stash";
ot->description = "Store this action in the NLA stack as a non-contributing strip for later use";
-
+
/* callbacks */
ot->exec = action_stash_exec;
ot->poll = action_pushdown_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
- ot->prop = RNA_def_boolean(ot->srna, "create_new", true, "Create New Action",
+ ot->prop = RNA_def_boolean(ot->srna, "create_new", true, "Create New Action",
"Create a new action once the existing one has been safely stored");
}
@@ -430,7 +430,7 @@ static int action_stash_create_poll(bContext *C)
{
if (ED_operator_action_active(C)) {
AnimData *adt = ED_actedit_animdata_from_context(C);
-
+
/* Check tweakmode is off (as you don't want to be tampering with the action in that case) */
/* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */
if (adt) {
@@ -439,19 +439,19 @@ static int action_stash_create_poll(bContext *C)
}
else {
/* There may not be any action/animdata yet, so, just fallback to the global setting
- * (which may not be totally valid yet if the action editor was used and things are
+ * (which may not be totally valid yet if the action editor was used and things are
* now in an inconsistent state)
*/
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
Scene *scene = CTX_data_scene(C);
-
+
if (!(scene->flag & SCE_NLA_EDIT_ON)) {
/* For now, actions are only for the active object, and on object and shapekey levels... */
return ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY);
}
}
}
-
+
/* something failed... */
return false;
}
@@ -460,7 +460,7 @@ static int action_stash_create_exec(bContext *C, wmOperator *op)
{
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
AnimData *adt = ED_actedit_animdata_from_context(C);
-
+
/* Check for no action... */
if (saction->action == NULL) {
/* just create a new action */
@@ -478,10 +478,10 @@ static int action_stash_create_exec(bContext *C, wmOperator *op)
/* stash the action */
if (BKE_nla_action_stash(adt)) {
bAction *new_action = NULL;
-
+
/* create new action not based on the old one (since the "new" operator already does that) */
new_action = action_create_new(C, NULL);
-
+
/* The stash operation will remove the user already,
* so the flushing step later shouldn't double up
* the usercount fixes. Hence, we must unset this ref
@@ -497,7 +497,7 @@ static int action_stash_create_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* Send notifiers that stuff has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
return OPERATOR_FINISHED;
@@ -509,11 +509,11 @@ void ACTION_OT_stash_and_create(wmOperatorType *ot)
ot->name = "Stash Action";
ot->idname = "ACTION_OT_stash_and_create";
ot->description = "Store this action in the NLA stack as a non-contributing strip for later use, and create a new action";
-
+
/* callbacks */
ot->exec = action_stash_create_exec;
ot->poll = action_stash_create_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -533,7 +533,7 @@ void ACTION_OT_stash_and_create(wmOperatorType *ot)
void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports, bool force_delete)
{
ScrArea *sa = CTX_wm_area(C);
-
+
/* If the old action only has a single user (that it's about to lose),
* warn user about it
*
@@ -545,7 +545,7 @@ void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act,
"Action '%s' will not be saved, create Fake User or Stash in NLA Stack to retain",
act->id.name + 2);
}
-
+
/* Clear Fake User and remove action stashing strip (if present) */
if (force_delete) {
/* Remove stashed strip binding this action to this datablock */
@@ -556,18 +556,18 @@ void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act,
if (adt) {
NlaTrack *nlt, *nlt_next;
NlaStrip *strip, *nstrip;
-
+
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt_next) {
nlt_next = nlt->next;
-
+
if (strstr(nlt->name, DATA_("[Action Stash]"))) {
for (strip = nlt->strips.first; strip; strip = nstrip) {
nstrip = strip->next;
-
+
if (strip->act == act) {
/* Remove this strip, and the track too if it doesn't have anything else */
BKE_nlastrip_free(&nlt->strips, strip);
-
+
if (nlt->strips.first == NULL) {
BLI_assert(nstrip == NULL);
BKE_nlatrack_free(&adt->nla_tracks, nlt);
@@ -577,18 +577,18 @@ void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act,
}
}
}
-
+
/* Clear Fake User */
id_fake_user_clear(&act->id);
}
-
- /* If in Tweak Mode, don't unlink. Instead, this
+
+ /* If in Tweak Mode, don't unlink. Instead, this
* becomes a shortcut to exit Tweak Mode instead
*/
if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
/* Exit Tweak Mode */
BKE_nla_tweakmode_exit(adt);
-
+
/* Flush this to the Action Editor (if that's where this change was initiated) */
if (sa->spacetype == SPACE_ACTION) {
actedit_change_action(C, NULL);
@@ -604,11 +604,11 @@ void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act,
/* clear AnimData -> action */
PointerRNA ptr;
PropertyRNA *prop;
-
+
/* create AnimData RNA pointers */
RNA_pointer_create(id, &RNA_AnimData, adt, &ptr);
prop = RNA_struct_find_property(&ptr, "action");
-
+
/* clear... */
RNA_property_pointer_set(&ptr, prop, PointerRNA_NULL);
RNA_property_update(C, &ptr, prop);
@@ -623,12 +623,12 @@ static int action_unlink_poll(bContext *C)
if (ED_operator_action_active(C)) {
SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
AnimData *adt = ED_actedit_animdata_from_context(C);
-
+
/* Only when there's an active action, in the right modes... */
if (saction->action && adt)
return true;
}
-
+
/* something failed... */
return false;
}
@@ -637,11 +637,11 @@ static int action_unlink_exec(bContext *C, wmOperator *op)
{
AnimData *adt = ED_actedit_animdata_from_context(C);
bool force_delete = RNA_boolean_get(op->ptr, "force_delete");
-
+
if (adt && adt->action) {
ED_animedit_unlink_action(C, NULL, adt, adt->action, op->reports, force_delete);
}
-
+
return OPERATOR_FINISHED;
}
@@ -655,17 +655,17 @@ static int action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *evt)
void ACTION_OT_unlink(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Unlink Action";
ot->idname = "ACTION_OT_unlink";
ot->description = "Unlink this action from the active action slot (and/or exit Tweak Mode)";
-
+
/* callbacks */
ot->invoke = action_unlink_invoke;
ot->exec = action_unlink_exec;
ot->poll = action_unlink_poll;
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "force_delete", false, "Force Delete", "Clear Fake User and remove "
"copy stashed in this data-block's NLA stack");
@@ -679,7 +679,7 @@ void ACTION_OT_unlink(wmOperatorType *ot)
static NlaStrip *action_layer_get_nlastrip(ListBase *strips, float ctime)
{
NlaStrip *strip;
-
+
for (strip = strips->first; strip; strip = strip->next) {
/* Can we use this? */
if (IN_RANGE_INCL(ctime, strip->start, strip->end)) {
@@ -695,7 +695,7 @@ static NlaStrip *action_layer_get_nlastrip(ListBase *strips, float ctime)
return strip;
}
}
-
+
/* nothing suitable found... */
return NULL;
}
@@ -709,18 +709,18 @@ static void action_layer_switch_strip(AnimData *adt,
* NOTE: We need to manually clear this stuff ourselves, as tweakmode exit doesn't do it
*/
BKE_nla_tweakmode_exit(adt);
-
+
if (old_strip) {
old_strip->flag &= ~(NLASTRIP_FLAG_ACTIVE | NLASTRIP_FLAG_SELECT);
}
if (old_track) {
old_track->flag &= ~(NLATRACK_ACTIVE | NLATRACK_SELECTED);
}
-
+
/* Make this one the active one instead */
strip->flag |= (NLASTRIP_FLAG_ACTIVE | NLASTRIP_FLAG_SELECT);
nlt->flag |= NLATRACK_ACTIVE;
-
+
/* Copy over "solo" flag - This is useful for stashed actions... */
if (old_track) {
if (old_track->flag & NLATRACK_SOLO) {
@@ -733,15 +733,15 @@ static void action_layer_switch_strip(AnimData *adt,
if (adt->flag & ADT_NLA_EVAL_OFF) {
/* disable NLA muting */
adt->flag &= ~ADT_NLA_EVAL_OFF;
-
+
/* mark this track as being solo */
adt->flag |= ADT_NLA_SOLO_TRACK;
nlt->flag |= NLATRACK_SOLO;
-
+
// TODO: Needs restpose flushing (when we get reference track)
}
}
-
+
/* Enter tweakmode again - hopefully we're now "it" */
BKE_nla_tweakmode_enter(adt);
BLI_assert(adt->actstrip == strip);
@@ -762,7 +762,7 @@ static int action_layer_next_poll(bContext *C)
*/
if (adt->nla_tracks.last) {
NlaTrack *nlt = (NlaTrack *)adt->nla_tracks.last;
-
+
if (nlt->flag & NLATRACK_DISABLED) {
/* A disabled track will either be the track itself,
* or one of the ones above it.
@@ -780,7 +780,7 @@ static int action_layer_next_poll(bContext *C)
}
}
}
-
+
/* something failed... */
return false;
}
@@ -789,26 +789,26 @@ static int action_layer_next_exec(bContext *C, wmOperator *op)
{
AnimData *adt = ED_actedit_animdata_from_context(C);
NlaTrack *act_track;
-
+
Scene *scene = CTX_data_scene(C);
float ctime = BKE_scene_frame_get(scene);
-
+
/* Get active track */
act_track = BKE_nlatrack_find_tweaked(adt);
-
+
if (act_track == NULL) {
BKE_report(op->reports, RPT_ERROR, "Could not find current NLA Track");
return OPERATOR_CANCELLED;
}
-
+
/* Find next action, and hook it up */
if (act_track->next) {
NlaTrack *nlt;
-
+
/* Find next action to use */
for (nlt = act_track->next; nlt; nlt = nlt->next) {
NlaStrip *strip = action_layer_get_nlastrip(&nlt->strips, ctime);
-
+
if (strip) {
action_layer_switch_strip(adt, act_track, adt->actstrip, nlt, strip);
break;
@@ -820,7 +820,7 @@ static int action_layer_next_exec(bContext *C, wmOperator *op)
* NOTE: This will mean exiting tweakmode...
*/
BKE_nla_tweakmode_exit(adt);
-
+
/* Deal with solo flags...
* Assume: Solo Track == NLA Muting
*/
@@ -828,14 +828,14 @@ static int action_layer_next_exec(bContext *C, wmOperator *op)
/* turn off solo flags on tracks */
act_track->flag &= ~NLATRACK_SOLO;
adt->flag &= ~ADT_NLA_SOLO_TRACK;
-
+
/* turn on NLA muting (to keep same effect) */
adt->flag |= ADT_NLA_EVAL_OFF;
-
+
// TODO: Needs restpose flushing (when we get reference track)
}
}
-
+
/* Update the action that this editor now uses
* NOTE: The calls above have already handled the usercount/animdata side of things
*/
@@ -849,11 +849,11 @@ void ACTION_OT_layer_next(wmOperatorType *ot)
ot->name = "Next Layer";
ot->idname = "ACTION_OT_layer_next";
ot->description = "Switch to editing action in animation layer above the current action in the NLA Stack";
-
+
/* callbacks */
ot->exec = action_layer_next_exec;
ot->poll = action_layer_next_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -870,7 +870,7 @@ static int action_layer_prev_poll(bContext *C)
/* Tweak Mode: We need to check if there are any tracks below the active one that we can move to */
if (adt->nla_tracks.first) {
NlaTrack *nlt = (NlaTrack *)adt->nla_tracks.first;
-
+
/* Since the first disabled track is the track being tweaked/edited,
* we can simplify things by only checking the first track:
* - If it is disabled, this is the track being tweaked,
@@ -890,7 +890,7 @@ static int action_layer_prev_poll(bContext *C)
}
}
}
-
+
/* something failed... */
return false;
}
@@ -900,19 +900,19 @@ static int action_layer_prev_exec(bContext *C, wmOperator *op)
AnimData *adt = ED_actedit_animdata_from_context(C);
NlaTrack *act_track;
NlaTrack *nlt;
-
+
Scene *scene = CTX_data_scene(C);
float ctime = BKE_scene_frame_get(scene);
-
+
/* Sanity Check */
if (adt == NULL) {
BKE_report(op->reports, RPT_ERROR, "Internal Error: Could not find Animation Data/NLA Stack to use");
return OPERATOR_CANCELLED;
}
-
+
/* Get active track */
act_track = BKE_nlatrack_find_tweaked(adt);
-
+
/* If there is no active track, that means we are using the active action... */
if (act_track) {
/* Active Track - Start from the one below it */
@@ -922,17 +922,17 @@ static int action_layer_prev_exec(bContext *C, wmOperator *op)
/* Active Action - Use the top-most track */
nlt = adt->nla_tracks.last;
}
-
+
/* Find previous action and hook it up */
for (; nlt; nlt = nlt->prev) {
NlaStrip *strip = action_layer_get_nlastrip(&nlt->strips, ctime);
-
+
if (strip) {
action_layer_switch_strip(adt, act_track, adt->actstrip, nlt, strip);
break;
}
}
-
+
/* Update the action that this editor now uses
* NOTE: The calls above have already handled the usercount/animdata side of things
*/
@@ -946,11 +946,11 @@ void ACTION_OT_layer_prev(wmOperatorType *ot)
ot->name = "Previous Layer";
ot->idname = "ACTION_OT_layer_prev";
ot->description = "Switch to editing action in animation layer below the current action in the NLA Stack";
-
+
/* callbacks */
ot->exec = action_layer_prev_exec;
ot->poll = action_layer_prev_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 3e9b742480a..7c8be943a87 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -53,7 +53,7 @@
#include "BKE_pointcache.h"
-/* Everything from source (BIF, BDR, BSE) ------------------------------ */
+/* Everything from source (BIF, BDR, BSE) ------------------------------ */
#include "BIF_gl.h"
@@ -73,41 +73,41 @@
/* Channel List */
/* left hand part */
-void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
+void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
View2D *v2d = &ar->v2d;
float y = 0.0f;
size_t items;
int height;
-
+
/* build list of channels to draw */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
if (height > BLI_rcti_size_y(&v2d->mask)) {
- /* don't use totrect set, as the width stays the same
- * (NOTE: this is ok here, the configuration is pretty straightforward)
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
*/
v2d->tot.ymin = (float)(-height);
}
/* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */
UI_view2d_sync(NULL, ac->sa, v2d, V2D_LOCK_COPY);
-
+
/* loop through channels, and set up drawing depending on their type */
{ /* first pass: just the standard GL-drawing for backdrop + text */
size_t channel_index = 0;
-
+
y = (float)ACHANNEL_FIRST(ac);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
@@ -115,7 +115,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
/* draw all channels using standard channel-drawing API */
ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index);
}
-
+
/* adjust y-position for next one */
y -= ACHANNEL_STEP(ac);
channel_index++;
@@ -124,13 +124,13 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
{ /* second pass: widgets */
uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
size_t channel_index = 0;
-
+
y = (float)ACHANNEL_FIRST(ac);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
@@ -138,16 +138,16 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
/* draw all channels using standard channel-drawing API */
ANIM_channel_draw_widgets(C, ac, ale, block, yminc, ymaxc, channel_index);
}
-
+
/* adjust y-position for next one */
y -= ACHANNEL_STEP(ac);
channel_index++;
}
-
+
UI_block_end(C, block);
UI_block_draw(C, block);
}
-
+
/* free tempolary channels */
ANIM_animdata_freelist(&anim_data);
}
@@ -163,50 +163,50 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
-
+
View2D *v2d = &ar->v2d;
bDopeSheet *ads = &saction->ads;
AnimData *adt = NULL;
-
+
float act_start, act_end, y;
-
+
unsigned char col1[3], col2[3];
unsigned char col1a[3], col2a[3];
unsigned char col1b[3], col2b[3];
-
+
const bool show_group_colors = !(saction->flag & SACTION_NODRAWGCOLORS);
-
-
+
+
/* get theme colors */
UI_GetThemeColor3ubv(TH_BACK, col2);
UI_GetThemeColor3ubv(TH_HILITE, col1);
-
+
UI_GetThemeColor3ubv(TH_GROUP, col2a);
UI_GetThemeColor3ubv(TH_GROUP_ACTIVE, col1a);
-
+
UI_GetThemeColor3ubv(TH_DOPESHEET_CHANNELOB, col1b);
UI_GetThemeColor3ubv(TH_DOPESHEET_CHANNELSUBOB, col2b);
-
+
/* set view-mapping rect (only used for x-axis), for NLA-scaling mapping with less calculation */
/* if in NLA there's a strip active, map the view */
if (ac->datatype == ANIMCONT_ACTION) {
/* adt = ANIM_nla_mapping_get(ac, NULL); */ /* UNUSED */
-
+
/* start and end of action itself */
calc_action_range(ac->data, &act_start, &act_end, 0);
}
-
+
/* build list of channels to draw */
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
int height = ((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac)));
- /* don't use totrect set, as the width stays the same
- * (NOTE: this is ok here, the configuration is pretty straightforward)
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
*/
v2d->tot.ymin = (float)(-height);
-
+
/* first backdrop strips */
y = (float)(-ACHANNEL_HEIGHT(ac));
@@ -216,18 +216,18 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
glEnable(GL_BLEND);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
{
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
int sel = 0;
-
+
/* determine if any need to draw channel */
if (ale->datatype != ALE_NONE) {
/* determine if channel is selected */
@@ -287,10 +287,10 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
}
}
-
+
/* draw region twice: firstly backdrop, then the current range */
immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
-
+
if (ac->datatype == ANIMCONT_ACTION)
immRectf(pos, act_start, (float)y - ACHANNEL_HEIGHT_HALF(ac), act_end, (float)y + ACHANNEL_HEIGHT_HALF(ac));
}
@@ -298,7 +298,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
/* frames less than one get less saturated background */
immUniformColor3ubvAlpha(sel ? col1 : col2, 0x22);
immRectf(pos, 0.0f, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF(ac));
-
+
/* frames one and higher get a saturated background */
immUniformColor3ubvAlpha(sel ? col1 : col2, 0x44);
immRectf(pos, v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF(ac), v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF(ac));
@@ -315,7 +315,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
}
}
}
-
+
/* Increment the step */
y -= ACHANNEL_STEP(ac);
}
@@ -335,7 +335,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
/* Draw keyframes
* 1) Only channels that are visible in the Action Editor get drawn/evaluated.
* This is to try to optimize this for heavier data sets
- * 2) Keyframes which are out of view horizontally are disregarded
+ * 2) Keyframes which are out of view horizontally are disregarded
*/
y = (float)(-ACHANNEL_HEIGHT(ac));
@@ -397,7 +397,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
ListBase pidlist;
const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize);
float yoffs = 0.f;
-
+
if (!(saction->cache_display & TIME_CACHE_DISPLAY) || (!ob))
return;
@@ -438,7 +438,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
gpuPushMatrix();
gpuTranslate2f(0.0, (float)V2D_SCROLL_HEIGHT + yoffs);
gpuScale2f(1.0, cache_draw_height);
-
+
switch (pid->type) {
case PTCACHE_TYPE_SOFTBODY:
col[0] = 1.0; col[1] = 0.4; col[2] = 0.02;
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 7f0882c505e..a9f9488d049 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -57,8 +57,9 @@
#include "BKE_fcurve.h"
#include "BKE_gpencil.h"
#include "BKE_global.h"
-#include "BKE_library.h"
#include "BKE_key.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_nla.h"
#include "BKE_context.h"
#include "BKE_report.h"
@@ -95,56 +96,56 @@
static int act_markers_make_local_poll(bContext *C)
{
SpaceAction *sact = CTX_wm_space_action(C);
-
+
/* 1) */
if (sact == NULL)
return 0;
-
+
/* 2) */
if (ELEM(sact->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) == 0)
return 0;
if (sact->action == NULL)
return 0;
-
+
/* 3) */
if (sact->flag & SACTION_POSEMARKERS_SHOW)
return 0;
-
+
/* 4) */
return ED_markers_get_first_selected(ED_context_get_markers(C)) != NULL;
}
static int act_markers_make_local_exec(bContext *C, wmOperator *UNUSED(op))
-{
+{
ListBase *markers = ED_context_get_markers(C);
-
+
SpaceAction *sact = CTX_wm_space_action(C);
bAction *act = (sact) ? sact->action : NULL;
-
+
TimeMarker *marker, *markern = NULL;
-
+
/* sanity checks */
if (ELEM(NULL, markers, act))
return OPERATOR_CANCELLED;
-
+
/* migrate markers */
for (marker = markers->first; marker; marker = markern) {
markern = marker->next;
-
+
/* move if marker is selected */
if (marker->flag & SELECT) {
BLI_remlink(markers, marker);
BLI_addtail(&act->markers, marker);
}
}
-
+
/* now enable the "show posemarkers only" setting, so that we can see that something did happen */
sact->flag |= SACTION_POSEMARKERS_SHOW;
-
+
/* notifiers - both sets, as this change affects both */
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -154,11 +155,11 @@ void ACTION_OT_markers_make_local(wmOperatorType *ot)
ot->name = "Make Markers Local";
ot->idname = "ACTION_OT_markers_make_local";
ot->description = "Move selected scene markers to the active Action as local 'pose' markers";
-
+
/* callbacks */
ot->exec = act_markers_make_local_exec;
ot->poll = act_markers_make_local_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -175,17 +176,17 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const
bAnimListElem *ale;
int filter;
bool found = false;
-
+
/* get data to filter, from Action or Dopesheet */
/* XXX: what is sel doing here?!
* Commented it, was breaking things (eg. the "auto preview range" tool). */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL *//*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* set large values to try to override */
*min = 999999999.0f;
*max = -999999999.0f;
-
+
/* check if any channels to set range with */
if (anim_data.first) {
/* go through channels, finding max extents */
@@ -268,7 +269,7 @@ static int actkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
bAnimContext ac;
Scene *scene;
float min, max;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
@@ -276,7 +277,7 @@ static int actkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
else
scene = ac.scene;
-
+
/* set the range directly */
get_keyframe_extents(&ac, &min, &max, false);
scene->r.flag |= SCER_PRV_RANGE;
@@ -286,25 +287,25 @@ static int actkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
if (scene->r.psfra == scene->r.pefra) {
scene->r.pefra = scene->r.psfra + 1;
}
-
+
/* set notifier that things have changed */
// XXX err... there's nothing for frame ranges yet, but this should do fine too
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_previewrange_set(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Auto-Set Preview Range";
ot->idname = "ACTION_OT_previewrange_set";
ot->description = "Set Preview Range based on extents of selected Keyframes";
-
+
/* api callbacks */
ot->exec = actkeys_previewrange_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -323,31 +324,31 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min,
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
short found = 0; /* NOTE: not bool, since we want prioritise individual channels over expanders */
float y;
-
+
/* get all items - we need to do it this way */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through all channels, finding the first one that's selected */
y = (float)ACHANNEL_FIRST(ac);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
+
/* must be selected... */
- if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
+ if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT))
{
/* update best estimate */
*min = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
*max = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
+
/* is this high enough priority yet? */
found = acf->channel_role;
-
+
/* only stop our search when we've found an actual channel
* - datablock expanders get less priority so that we don't abort prematurely
*/
@@ -355,14 +356,14 @@ static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min,
break;
}
}
-
+
/* adjust y-position for next one */
y -= ACHANNEL_STEP(ac);
}
-
+
/* free all temp data */
ANIM_animdata_freelist(&anim_data);
-
+
return (found != 0);
}
@@ -372,12 +373,12 @@ static int actkeys_viewall(bContext *C, const bool only_sel)
View2D *v2d;
float extra, min, max;
bool found;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
v2d = &ac.ar->v2d;
-
+
/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
found = get_keyframe_extents(&ac, &min, &max, only_sel);
@@ -387,7 +388,7 @@ static int actkeys_viewall(bContext *C, const bool only_sel)
if (fabsf(max - min) < 1.0f) {
/* Exception - center the single keyfrme */
float xwidth = BLI_rctf_size_x(&v2d->cur);
-
+
v2d->cur.xmin = min - xwidth / 2.0f;
v2d->cur.xmax = max + xwidth / 2.0f;
}
@@ -395,12 +396,12 @@ static int actkeys_viewall(bContext *C, const bool only_sel)
/* Normal case - stretch the two keyframes out to fill the space, with extra spacing */
v2d->cur.xmin = min;
v2d->cur.xmax = max;
-
+
extra = 0.125f * BLI_rctf_size_x(&v2d->cur);
v2d->cur.xmin -= extra;
v2d->cur.xmax += extra;
}
-
+
/* set vertical range */
if (only_sel == false) {
/* view all -> the summary channel is usually the shows everything, and resides right at the top... */
@@ -411,30 +412,30 @@ static int actkeys_viewall(bContext *C, const bool only_sel)
/* locate first selected channel (or the active one), and frame those */
float ymin = v2d->cur.ymin;
float ymax = v2d->cur.ymax;
-
+
if (actkeys_channels_get_selected_extents(&ac, &ymin, &ymax)) {
/* recenter the view so that this range is in the middle */
float ymid = (ymax - ymin) / 2.0f + ymin;
float x_center;
-
+
UI_view2d_center_get(v2d, &x_center, NULL);
UI_view2d_center_set(v2d, x_center, ymid);
}
}
-
+
/* do View2D syncing */
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
-
+
/* just redraw this view */
ED_area_tag_redraw(CTX_wm_area(C));
-
+
return OPERATOR_FINISHED;
}
/* ......... */
static int actkeys_viewall_exec(bContext *C, wmOperator *UNUSED(op))
-{
+{
/* whole range */
return actkeys_viewall(C, false);
}
@@ -453,11 +454,11 @@ void ACTION_OT_view_all(wmOperatorType *ot)
ot->name = "View All";
ot->idname = "ACTION_OT_view_all";
ot->description = "Reset viewable area to show full keyframe range";
-
+
/* api callbacks */
ot->exec = actkeys_viewall_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -468,11 +469,11 @@ void ACTION_OT_view_selected(wmOperatorType *ot)
ot->name = "View Selected";
ot->idname = "ACTION_OT_view_selected";
ot->description = "Reset viewable area to show selected keyframes range";
-
+
/* api callbacks */
ot->exec = actkeys_viewsel_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -483,7 +484,7 @@ static int actkeys_view_frame_exec(bContext *C, wmOperator *op)
{
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
ANIM_center_frame(C, smooth_viewtx);
-
+
return OPERATOR_FINISHED;
}
@@ -493,11 +494,11 @@ void ACTION_OT_view_frame(wmOperatorType *ot)
ot->name = "View Frame";
ot->idname = "ACTION_OT_view_frame";
ot->description = "Reset viewable area to show range around current frame";
-
+
/* api callbacks */
ot->exec = actkeys_view_frame_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -509,20 +510,20 @@ void ACTION_OT_view_frame(wmOperatorType *ot)
/* NOTE: the backend code for this is shared with the graph editor */
static short copy_action_keys(bAnimContext *ac)
-{
+{
ListBase anim_data = {NULL, NULL};
int filter, ok = 0;
-
+
/* clear buffer first */
ANIM_fcurves_copybuf_free();
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* copy keyframes */
ok = copy_animedit_keys(ac, &anim_data);
-
+
/* clean up */
ANIM_animdata_freelist(&anim_data);
@@ -532,21 +533,21 @@ static short copy_action_keys(bAnimContext *ac)
static short paste_action_keys(bAnimContext *ac,
const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
-{
+{
ListBase anim_data = {NULL, NULL};
int filter, ok = 0;
-
- /* filter data
- * - First time we try to filter more strictly, allowing only selected channels
+
+ /* filter data
+ * - First time we try to filter more strictly, allowing only selected channels
* to allow copying animation between channels
* - Second time, we loosen things up if nothing was found the first time, allowing
* users to just paste keyframes back into the original curve again [#31670]
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
-
+
if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* paste keyframes */
ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
@@ -561,7 +562,7 @@ static short paste_action_keys(bAnimContext *ac,
static int actkeys_copy_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
@@ -584,17 +585,17 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
}
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Copy Keyframes";
ot->idname = "ACTION_OT_copy";
ot->description = "Copy selected keyframes to the copy/paste buffer";
-
+
/* api callbacks */
ot->exec = actkeys_copy_exec;
ot->poll = ED_operator_action_active;
@@ -610,14 +611,14 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
const bool flipped = RNA_boolean_get(op->ptr, "flipped");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* ac.reports by default will be the global reports list, which won't show warnings */
ac.reports = op->reports;
-
+
/* paste keyframes */
if (ac.datatype == ANIMCONT_GPENCIL) {
if (ED_gpencil_anim_copybuf_paste(&ac, offset_mode) == false) {
@@ -639,10 +640,10 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_paste(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -650,15 +651,15 @@ void ACTION_OT_paste(wmOperatorType *ot)
ot->name = "Paste Keyframes";
ot->idname = "ACTION_OT_paste";
ot->description = "Paste keyframes from copy/paste buffer for the selected channels, starting on the current frame";
-
+
/* api callbacks */
// ot->invoke = WM_operator_props_popup; // better wait for action redo panel
ot->exec = actkeys_paste_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_enum(ot->srna, "offset", rna_enum_keyframe_paste_offset_items, KEYFRAME_PASTE_OFFSET_CFRA_START, "Offset", "Paste time offset of keys");
RNA_def_enum(ot->srna, "merge", rna_enum_keyframe_paste_merge_items, KEYFRAME_PASTE_MERGE_MIX, "Type", "Method of merging pasted keys and existing");
@@ -677,40 +678,40 @@ static const EnumPropertyItem prop_actkeys_insertkey_types[] = {
};
/* this function is responsible for inserting new keyframes */
-static void insert_action_keys(bAnimContext *ac, short mode)
+static void insert_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
struct Depsgraph *depsgraph = ac->depsgraph;
ReportList *reports = ac->reports;
Scene *scene = ac->scene;
ToolSettings *ts = scene->toolsettings;
short flag = 0;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
if (mode == 2) filter |= ANIMFILTER_SEL;
else if (mode == 3) filter |= ANIMFILTER_ACTGROUPED;
-
+
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* init keyframing flag */
flag = ANIM_get_keyframing_flags(scene, 1);
-
+
/* insert keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
float cfra;
-
+
/* adjust current frame for NLA-scaling */
if (adt)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
- else
+ else
cfra = (float)CFRA;
-
+
/* read value from property the F-Curve represents, or from the curve only?
* - ale->id != NULL: Typically, this means that we have enough info to try resolving the path
* - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
@@ -718,16 +719,17 @@ static void insert_action_keys(bAnimContext *ac, short mode)
* (TODO: add the full-blown PointerRNA relative parsing case here...)
*/
if (ale->id && !ale->owner) {
- insert_keyframe(depsgraph, reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, flag);
+ insert_keyframe(ac->bmain, depsgraph, reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, flag);
}
else {
const float curval = evaluate_fcurve(fcu, cfra);
insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
}
-
+
ale->update |= ANIM_UPDATE_DEFAULT;
}
-
+
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -738,31 +740,31 @@ static void insert_gpencil_keys(bAnimContext *ac, short mode)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
Scene *scene = ac->scene;
ToolSettings *ts = scene->toolsettings;
eGP_GetFrame_Mode add_frame_mode;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
if (mode == 2) filter |= ANIMFILTER_SEL;
-
+
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
-
+
+
/* add a copy or a blank frame? */
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST)
add_frame_mode = GP_GETFRAME_ADD_COPY; /* XXX: actframe may not be what we want? */
else
add_frame_mode = GP_GETFRAME_ADD_NEW;
-
-
+
+
/* insert gp frames */
for (ale = anim_data.first; ale; ale = ale->next) {
bGPDlayer *gpl = (bGPDlayer *)ale->data;
BKE_gpencil_layer_getframe(gpl, CFRA, add_frame_mode);
}
-
+
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -773,19 +775,19 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
if (ac.datatype == ANIMCONT_MASK) {
BKE_report(op->reports, RPT_ERROR, "Insert Keyframes is not yet implemented for this mode");
return OPERATOR_CANCELLED;
}
-
+
/* what channels to affect? */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* insert keyframes */
if (ac.datatype == ANIMCONT_GPENCIL) {
insert_gpencil_keys(&ac, mode);
@@ -796,7 +798,7 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -806,15 +808,15 @@ void ACTION_OT_keyframe_insert(wmOperatorType *ot)
ot->name = "Insert Keyframes";
ot->idname = "ACTION_OT_keyframe_insert";
ot->description = "Insert keyframes for the specified channels";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = actkeys_insertkey_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_insertkey_types, 0, "Type", "");
}
@@ -826,14 +828,14 @@ static void duplicate_action_keys(bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
else
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and delete selected keys */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE))
@@ -857,31 +859,31 @@ static void duplicate_action_keys(bAnimContext *ac)
static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* duplicate keyframes */
duplicate_action_keys(&ac);
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_duplicate(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Duplicate Keyframes";
ot->idname = "ACTION_OT_duplicate";
ot->description = "Make a copy of all selected keyframes";
-
+
/* api callbacks */
ot->exec = actkeys_duplicate_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -915,26 +917,26 @@ static bool delete_action_keys(bAnimContext *ac)
else {
FCurve *fcu = (FCurve *)ale->key_data;
AnimData *adt = ale->adt;
-
+
/* delete selected keyframes only */
changed = delete_fcurve_keys(fcu);
-
+
/* Only delete curve too if it won't be doing anything anymore */
if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0)) {
ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
ale->key_data = NULL;
}
}
-
+
if (changed) {
ale->update |= ANIM_UPDATE_DEFAULT;
changed_final = true;
}
}
-
+
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
-
+
return changed_final;
}
@@ -943,33 +945,33 @@ static bool delete_action_keys(bAnimContext *ac)
static int actkeys_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* delete keyframes */
if (!delete_action_keys(&ac))
return OPERATOR_CANCELLED;
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_delete(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Delete Keyframes";
ot->idname = "ACTION_OT_delete";
ot->description = "Remove all selected keyframes";
-
+
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = actkeys_delete_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -977,15 +979,15 @@ void ACTION_OT_delete(wmOperatorType *ot)
/* ******************** Clean Keyframes Operator ************************* */
static void clean_action_keys(bAnimContext *ac, float thresh, bool clean_chan)
-{
+{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and clean curves */
for (ale = anim_data.first; ale; ale = ale->next) {
clean_fcurve(ac, ale, thresh, clean_chan);
@@ -1004,44 +1006,44 @@ static int actkeys_clean_exec(bContext *C, wmOperator *op)
bAnimContext ac;
float thresh;
bool clean_chan;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
}
-
+
/* get cleaning threshold */
thresh = RNA_float_get(op->ptr, "threshold");
clean_chan = RNA_boolean_get(op->ptr, "channels");
-
+
/* clean keyframes */
clean_action_keys(&ac, thresh, clean_chan);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_clean(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clean Keyframes";
ot->idname = "ACTION_OT_clean";
ot->description = "Simplify F-Curves by removing closely spaced keyframes";
-
+
/* api callbacks */
- //ot->invoke = // XXX we need that number popup for this!
+ //ot->invoke = // XXX we need that number popup for this!
ot->exec = actkeys_clean_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_float(ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
RNA_def_boolean(ot->srna, "channels", false, "Channels", "");
@@ -1051,15 +1053,15 @@ void ACTION_OT_clean(wmOperatorType *ot)
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
static void sample_action_keys(bAnimContext *ac)
-{
+{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and add keys between selected keyframes on every frame */
for (ale = anim_data.first; ale; ale = ale->next) {
sample_fcurve((FCurve *)ale->key_data);
@@ -1076,36 +1078,36 @@ static void sample_action_keys(bAnimContext *ac)
static int actkeys_sample_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
}
-
+
/* sample keyframes */
sample_action_keys(&ac);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_sample(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Sample Keyframes";
ot->idname = "ACTION_OT_sample";
ot->description = "Add keyframes on every frame between the selected keyframes";
-
+
/* api callbacks */
ot->exec = actkeys_sample_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1123,33 +1125,33 @@ void ACTION_OT_sample(wmOperatorType *ot)
static const EnumPropertyItem prop_actkeys_expo_types[] = {
{FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"},
{FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"},
-
+
{MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"},
{CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"},
{0, NULL, 0, NULL, NULL}
};
/* this function is responsible for setting extrapolation mode for keyframes */
-static void setexpo_action_keys(bAnimContext *ac, short mode)
+static void setexpo_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through setting mode per F-Curve */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
-
+
if (mode >= 0) {
/* just set mode setting */
fcu->extend = mode;
}
else {
- /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
+ /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
* without having to go through FModifier UI in Graph Editor to do so
*/
if (mode == MAKE_CYCLIC_EXPO) {
@@ -1162,10 +1164,10 @@ static void setexpo_action_keys(bAnimContext *ac, short mode)
else if (mode == CLEAR_CYCLIC_EXPO) {
/* remove all the modifiers fitting this description */
FModifier *fcm, *fcn = NULL;
-
+
for (fcm = fcu->modifiers.first; fcm; fcm = fcn) {
fcn = fcm->next;
-
+
if (fcm->type == FMODIFIER_TYPE_CYCLES)
remove_fmodifier(&fcu->modifiers, fcm);
}
@@ -1185,43 +1187,43 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
}
-
+
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* set handle type */
setexpo_action_keys(&ac, mode);
-
+
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_extrapolation_type(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Keyframe Extrapolation";
ot->idname = "ACTION_OT_extrapolation_type";
ot->description = "Set extrapolation mode for selected F-Curves";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = actkeys_expo_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_expo_types, 0, "Type", "");
}
@@ -1229,17 +1231,17 @@ void ACTION_OT_extrapolation_type(wmOperatorType *ot)
/* ******************** Set Interpolation-Type Operator *********************** */
/* this function is responsible for setting interpolation mode for keyframes */
-static void setipo_action_keys(bAnimContext *ac, short mode)
+static void setipo_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
KeyframeEditFunc set_cb = ANIM_editkeyframes_ipo(mode);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through setting BezTriple interpolation
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
*/
@@ -1259,43 +1261,43 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
}
-
+
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* set handle type */
setipo_action_keys(&ac, mode);
-
+
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_interpolation_type(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Keyframe Interpolation";
ot->idname = "ACTION_OT_interpolation_type";
ot->description = "Set interpolation mode for the F-Curve segments starting from the selected keyframes";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = actkeys_ipo_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", "");
}
@@ -1303,25 +1305,25 @@ void ACTION_OT_interpolation_type(wmOperatorType *ot)
/* ******************** Set Handle-Type Operator *********************** */
/* this function is responsible for setting handle-type of selected keyframes */
-static void sethandles_action_keys(bAnimContext *ac, short mode)
+static void sethandles_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc edit_cb = ANIM_editkeyframes_handles(mode);
KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through setting flags for handles
+
+ /* loop through setting flags for handles
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
*/
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
-
+
/* any selected keyframes for editing? */
if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL)) {
/* change type of selected handles */
@@ -1341,43 +1343,43 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
}
-
+
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* set handle type */
sethandles_action_keys(&ac, mode);
-
+
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_handle_type(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Keyframe Handle Type";
ot->idname = "ACTION_OT_handle_type";
ot->description = "Set type of handle for selected keyframes";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = actkeys_handletype_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", "");
}
@@ -1385,17 +1387,17 @@ void ACTION_OT_handle_type(wmOperatorType *ot)
/* ******************** Set Keyframe-Type Operator *********************** */
/* this function is responsible for setting keyframe type for keyframes */
-static void setkeytype_action_keys(bAnimContext *ac, short mode)
+static void setkeytype_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
KeyframeEditFunc set_cb = ANIM_editkeyframes_keytype(mode);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through setting BezTriple interpolation
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
*/
@@ -1415,11 +1417,11 @@ static void setkeytype_gpencil_keys(bAnimContext *ac, short mode)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through each layer */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
@@ -1438,19 +1440,19 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
if (ac.datatype == ANIMCONT_MASK) {
BKE_report(op->reports, RPT_ERROR, "Not implemented for Masks");
return OPERATOR_PASS_THROUGH;
}
-
+
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* set handle type */
if (ac.datatype == ANIMCONT_GPENCIL) {
setkeytype_gpencil_keys(&ac, mode);
@@ -1458,28 +1460,28 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op)
else {
setkeytype_action_keys(&ac, mode);
}
-
+
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_keyframe_type(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Keyframe Type";
ot->idname = "ACTION_OT_keyframe_type";
ot->description = "Set type of keyframe for the selected keyframes";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = actkeys_keytype_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_keyframe_type_items, 0, "Type", "");
}
@@ -1506,39 +1508,39 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
bAnimListElem *ale;
int filter;
KeyframeEditData ked = {{NULL}};
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* init edit data */
/* loop over action data, averaging values */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
}
-
+
ANIM_animdata_freelist(&anim_data);
-
+
/* set the new current frame value, based on the average time */
if (ked.i1) {
Scene *scene = ac.scene;
CFRA = round_fl_to_int(ked.f1 / ked.i1);
SUBFRA = 0.f;
}
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
-
+
return OPERATOR_FINISHED;
}
@@ -1548,11 +1550,11 @@ void ACTION_OT_frame_jump(wmOperatorType *ot)
ot->name = "Jump to Keyframes";
ot->idname = "ACTION_OT_frame_jump";
ot->description = "Set the current frame to the average frame value of selected keyframes";
-
+
/* api callbacks */
ot->exec = actkeys_framejump_exec;
ot->poll = actkeys_framejump_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1573,22 +1575,22 @@ static const EnumPropertyItem prop_actkeys_snap_types[] = {
};
/* this function is responsible for snapping keyframes to frame-times */
-static void snap_action_keys(bAnimContext *ac, short mode)
+static void snap_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc edit_cb;
-
+
/* filter data */
if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
else
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* get beztriple editing callbacks */
edit_cb = ANIM_editkeyframes_snap(mode);
@@ -1597,11 +1599,11 @@ static void snap_action_keys(bAnimContext *ac, short mode)
ked.list.first = (ac->markers) ? ac->markers->first : NULL;
ked.list.last = (ac->markers) ? ac->markers->last : NULL;
}
-
+
/* snap keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gplayer_snap_frames(ale->data, ac->scene, mode);
}
@@ -1609,7 +1611,7 @@ static void snap_action_keys(bAnimContext *ac, short mode)
ED_masklayer_snap_frames(ale->data, ac->scene, mode);
}
else if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
}
@@ -1630,38 +1632,38 @@ static int actkeys_snap_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get snapping mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* snap keyframes */
snap_action_keys(&ac, mode);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_snap(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Keys";
ot->idname = "ACTION_OT_snap";
ot->description = "Snap selected keyframes to the times specified";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = actkeys_snap_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_snap_types, 0, "Type", "");
}
@@ -1680,42 +1682,42 @@ static const EnumPropertyItem prop_actkeys_mirror_types[] = {
};
/* this function is responsible for mirroring keyframes */
-static void mirror_action_keys(bAnimContext *ac, short mode)
+static void mirror_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc edit_cb;
-
+
/* get beztriple editing callbacks */
edit_cb = ANIM_editkeyframes_mirror(mode);
ked.scene = ac->scene;
-
+
/* for 'first selected marker' mode, need to find first selected marker first! */
/* XXX should this be made into a helper func in the API? */
if (mode == ACTKEYS_MIRROR_MARKER) {
TimeMarker *marker = ED_markers_get_first_selected(ac->markers);
-
+
if (marker)
ked.f1 = (float)marker->frame;
else
return;
}
-
+
/* filter data */
if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
else
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* mirror keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gplayer_mirror_frames(ale->data, ac->scene, mode);
}
@@ -1723,14 +1725,14 @@ static void mirror_action_keys(bAnimContext *ac, short mode)
/* TODO */
}
else if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
}
else {
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
}
-
+
ale->update |= ANIM_UPDATE_DEFAULT;
}
@@ -1744,38 +1746,38 @@ static int actkeys_mirror_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get mirroring mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* mirror keyframes */
mirror_action_keys(&ac, mode);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_mirror(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Mirror Keys";
ot->idname = "ACTION_OT_mirror";
ot->description = "Flip selected keyframes over the selected mirror line";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = actkeys_mirror_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", "");
}
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index 99987f21448..25d3560b175 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -54,7 +54,7 @@ void ACTION_OT_properties(struct wmOperatorType *ot);
/* ***************************************** */
/* action_draw.c */
-void draw_channel_names(struct bContext *C, struct bAnimContext *ac, struct ARegion *ar);
+void draw_channel_names(struct bContext *C, struct bAnimContext *ac, struct ARegion *ar);
void draw_channel_strips(struct bAnimContext *ac, struct SpaceAction *saction, struct ARegion *ar);
void timeline_draw_cache(struct SpaceAction *saction, struct Object *ob, struct Scene *scene);
@@ -127,7 +127,7 @@ void ACTION_OT_layer_prev(struct wmOperatorType *ot);
void ACTION_OT_markers_make_local(struct wmOperatorType *ot);
-/* defines for snap keyframes
+/* defines for snap keyframes
* NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h)
*/
enum eActKeys_Snap_Mode {
@@ -137,7 +137,7 @@ enum eActKeys_Snap_Mode {
ACTKEYS_SNAP_NEAREST_MARKER,
};
-/* defines for mirror keyframes
+/* defines for mirror keyframes
* NOTE: keep in sync with eEditKeyframes_Mirror (in ED_keyframes_edit.h)
*/
enum eActKeys_Mirror_Mode {
@@ -146,7 +146,7 @@ enum eActKeys_Mirror_Mode {
ACTKEYS_MIRROR_XAXIS,
ACTKEYS_MIRROR_MARKER,
};
-
+
/* ***************************************** */
/* action_ops.c */
void action_operatortypes(void);
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 40ddcf4886a..bf7f75db95c 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -53,7 +53,7 @@ void action_operatortypes(void)
{
/* view */
WM_operatortype_append(ACTION_OT_properties);
-
+
/* keyframes */
/* selection */
WM_operatortype_append(ACTION_OT_clickselect);
@@ -66,7 +66,7 @@ void action_operatortypes(void)
WM_operatortype_append(ACTION_OT_select_more);
WM_operatortype_append(ACTION_OT_select_less);
WM_operatortype_append(ACTION_OT_select_leftright);
-
+
/* editing */
WM_operatortype_append(ACTION_OT_snap);
WM_operatortype_append(ACTION_OT_mirror);
@@ -82,17 +82,17 @@ void action_operatortypes(void)
WM_operatortype_append(ACTION_OT_keyframe_insert);
WM_operatortype_append(ACTION_OT_copy);
WM_operatortype_append(ACTION_OT_paste);
-
+
WM_operatortype_append(ACTION_OT_new);
WM_operatortype_append(ACTION_OT_unlink);
-
+
WM_operatortype_append(ACTION_OT_push_down);
WM_operatortype_append(ACTION_OT_stash);
WM_operatortype_append(ACTION_OT_stash_and_create);
-
+
WM_operatortype_append(ACTION_OT_layer_next);
WM_operatortype_append(ACTION_OT_layer_prev);
-
+
WM_operatortype_append(ACTION_OT_previewrange_set);
WM_operatortype_append(ACTION_OT_view_all);
WM_operatortype_append(ACTION_OT_view_selected);
@@ -105,7 +105,7 @@ void ED_operatormacros_action(void)
{
wmOperatorType *ot;
wmOperatorTypeMacro *otmacro;
-
+
ot = WM_operatortype_append_macro("ACTION_OT_duplicate_move", "Duplicate",
"Make a copy of all selected keyframes and move them",
OPTYPE_UNDO | OPTYPE_REGISTER);
@@ -120,7 +120,7 @@ void ED_operatormacros_action(void)
static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
{
wmKeyMapItem *kmi;
-
+
/* action_select.c - selection tools */
/* click-select: keyframe (replace) */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
@@ -152,7 +152,7 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
RNA_boolean_set(kmi->ptr, "extend", true);
RNA_boolean_set(kmi->ptr, "column", false);
RNA_boolean_set(kmi->ptr, "channel", true);
-
+
/* click-select: left/right */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
@@ -160,71 +160,74 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", true);
RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_TEST);
-
+
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_LEFT);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_RIGHT);
-
+
/* deselect all */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "invert", false);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "invert", true);
-
+
/* borderselect */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_border", BKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "axis_range", false);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "axis_range", true);
-
+
/* region select */
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "ACTION_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
-
+
WM_keymap_add_item(keymap, "ACTION_OT_select_circle", CKEY, KM_PRESS, 0, 0);
-
+
/* column select */
RNA_enum_set(WM_keymap_add_item(keymap, "ACTION_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_KEYS);
RNA_enum_set(WM_keymap_add_item(keymap, "ACTION_OT_select_column", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_CFRA);
RNA_enum_set(WM_keymap_add_item(keymap, "ACTION_OT_select_column", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_COLUMN);
RNA_enum_set(WM_keymap_add_item(keymap, "ACTION_OT_select_column", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_BETWEEN);
-
+
/* select more/less */
WM_keymap_add_item(keymap, "ACTION_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ACTION_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
-
+
/* select linked */
WM_keymap_add_item(keymap, "ACTION_OT_select_linked", LKEY, KM_PRESS, 0, 0);
-
-
+
+
/* action_edit.c */
/* jump to selected keyframes */
WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* menu + single-step transform */
WM_keymap_add_item(keymap, "ACTION_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ACTION_OT_mirror", MKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* menu + set setting */
WM_keymap_add_item(keymap, "ACTION_OT_handle_type", VKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ACTION_OT_interpolation_type", TKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "ACTION_OT_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "ACTION_OT_keyframe_type", RKEY, KM_PRESS, 0, 0);
-
+ WM_keymap_add_item(keymap, "ACTION_OT_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "ACTION_OT_keyframe_type", RKEY, KM_PRESS, 0, 0);
+
+ /* specials */
+ WM_keymap_add_menu(keymap, "DOPESHEET_MT_specials", WKEY, KM_PRESS, 0, 0);
+
/* destructive */
WM_keymap_add_item(keymap, "ACTION_OT_sample", OKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_menu(keymap, "DOPESHEET_MT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "DOPESHEET_MT_delete", DELKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "ACTION_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ACTION_OT_keyframe_insert", IKEY, KM_PRESS, 0, 0);
-
+
/* copy/paste */
WM_keymap_add_item(keymap, "ACTION_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ACTION_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
@@ -246,19 +249,19 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_item(keymap, "ACTION_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ACTION_OT_view_frame", PAD0, KM_PRESS, 0, 0);
-
+
/* animation module */
/* channels list
* NOTE: these operators were originally for the channels list, but are added here too for convenience...
*/
WM_keymap_add_item(keymap, "ANIM_OT_channels_editable_toggle", TABKEY, KM_PRESS, 0, 0);
-
+
/* find (i.e. a shortcut for setting the name filter) */
WM_keymap_add_item(keymap, "ANIM_OT_channels_find", FKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* transform system */
transform_keymap_for_space(keyconf, keymap, SPACE_ACTION);
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_action");
@@ -271,22 +274,21 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
void action_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
-
+
/* keymap for all regions */
keymap = WM_keymap_find(keyconf, "Dopesheet Generic", SPACE_ACTION, 0);
-
+
/* region management... */
WM_keymap_add_item(keymap, "ACTION_OT_properties", NKEY, KM_PRESS, 0, 0);
-
-
+
+
/* channels */
- /* Channels are not directly handled by the Action Editor module, but are inherited from the Animation module.
+ /* Channels are not directly handled by the Action Editor module, but are inherited from the Animation module.
* All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these
* are all used for the Graph-Editor too.
*/
-
+
/* keyframes */
keymap = WM_keymap_find(keyconf, "Dopesheet", SPACE_ACTION, 0);
action_keymap_keyframes(keyconf, keymap);
}
-
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 4cc38741d3e..83bda4d63a5 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -89,22 +89,22 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc test_cb, sel_cb;
-
+
/* determine type-based settings */
if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
else
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
-
+
/* filter data */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* init BezTriple looping data */
test_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
-
+
/* See if we should be selecting or deselecting */
if (test) {
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -128,10 +128,10 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
}
}
}
-
+
/* convert sel to selectmode, and use that to get editor */
sel_cb = ANIM_editkeyframes_select(sel);
-
+
/* Now set the flags */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER)
@@ -139,9 +139,9 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
else if (ale->type == ANIMTYPE_MASKLAYER)
ED_masklayer_frame_select_set(ale->data, sel);
else
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -151,37 +151,37 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
static int actkeys_deselectall_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* 'standard' behavior - check if selected, then apply relevant selection */
if (RNA_boolean_get(op->ptr, "invert"))
deselect_action_keys(&ac, 0, SELECT_INVERT);
else
deselect_action_keys(&ac, 1, SELECT_ADD);
-
+
/* set notifier that keyframe selection have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select All";
ot->idname = "ACTION_OT_select_all_toggle";
ot->description = "Toggle selection of all keyframes";
-
+
/* api callbacks */
ot->exec = actkeys_deselectall_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_boolean(ot->srna, "invert", 0, "Invert", "");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
@@ -208,39 +208,39 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditData ked;
KeyframeEditFunc ok_cb, select_cb;
View2D *v2d = &ac->ar->v2d;
rctf rectf;
float ymin = 0, ymax = (float)(-ACHANNEL_HEIGHT_HALF(ac));
-
+
/* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin + 2, &rectf.xmin, &rectf.ymin);
UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax - 2, &rectf.xmax, &rectf.ymax);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* get beztriple editing/validation funcs */
select_cb = ANIM_editkeyframes_select(selectmode);
-
+
if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS))
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
else
ok_cb = NULL;
-
+
/* init editing data */
memset(&ked, 0, sizeof(KeyframeEditData));
-
+
/* loop over data, doing border select */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* get new vertical minimum extent of channel */
ymin = ymax - ACHANNEL_STEP(ac);
-
+
/* set horizontal range (if applicable) */
if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
/* if channel is mapped in NLA, apply correction */
@@ -255,7 +255,7 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s
ked.f2 = rectf.xmax;
}
}
-
+
/* perform vertical suitability check (if applicable) */
if ((mode == ACTKEYS_BORDERSEL_FRAMERANGE) ||
!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
@@ -293,11 +293,11 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s
break;
}
}
-
+
/* set minimum extent to be the maximum of the next channel */
ymax = ymin;
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -311,7 +311,7 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op)
short mode = 0, selectmode = 0;
const bool select = !RNA_boolean_get(op->ptr, "deselect");
const bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
@@ -320,7 +320,7 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op)
if (!extend) {
deselect_action_keys(&ac, 1, SELECT_SUBTRACT);
}
-
+
/* get settings from operator */
WM_operator_properties_border_to_rcti(op, &rect);
@@ -330,10 +330,10 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op)
else {
selectmode = SELECT_SUBTRACT;
}
-
+
/* selection 'mode' depends on whether borderselect region only matters on one axis */
if (RNA_boolean_get(op->ptr, "axis_range")) {
- /* mode depends on which axis of the range is larger to determine which axis to use
+ /* mode depends on which axis of the range is larger to determine which axis to use
* - checking this in region-space is fine, as it's fundamentally still going to be a different rect size
* - the frame-range select option is favored over the channel one (x over y), as frame-range one is often
* used for tweaking timing when "blocking", while channels is not that useful...
@@ -343,17 +343,17 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op)
else
mode = ACTKEYS_BORDERSEL_CHANNELS;
}
- else
+ else
mode = ACTKEYS_BORDERSEL_ALLKEYS;
-
+
/* apply borderselect action */
borderselect_action(&ac, rect, mode, selectmode);
-
+
/* set notifier that keyframe selection have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
-}
+}
void ACTION_OT_select_border(wmOperatorType *ot)
{
@@ -361,21 +361,21 @@ void ACTION_OT_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->idname = "ACTION_OT_select_border";
ot->description = "Select all keyframes within the specified region";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = actkeys_borderselect_exec;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
-
+
ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
}
@@ -390,24 +390,24 @@ static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view,
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditData ked;
KeyframeEditFunc ok_cb, select_cb;
View2D *v2d = &ac->ar->v2d;
rctf rectf, scaled_rectf;
float ymin = 0, ymax = (float)(-ACHANNEL_HEIGHT_HALF(ac));
-
+
/* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* get beztriple editing/validation funcs */
select_cb = ANIM_editkeyframes_select(selectmode);
ok_cb = ANIM_editkeyframes_ok(mode);
-
+
/* init editing data */
memset(&ked, 0, sizeof(KeyframeEditData));
if (mode == BEZT_OK_CHANNEL_LASSO) {
@@ -423,17 +423,17 @@ static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view,
else {
ked.data = &scaled_rectf;
}
-
+
/* loop over data, doing region select */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* get new vertical minimum extent of channel */
ymin = ymax - ACHANNEL_STEP(ac);
-
+
/* compute midpoint of channel (used for testing if the key is in the region or not) */
ked.channel_y = ymin + ACHANNEL_HEIGHT_HALF(ac);
-
+
/* if channel is mapped in NLA, apply correction
* - Apply to the bounds being checked, not all the keyframe points,
* to avoid having scaling everything
@@ -450,16 +450,16 @@ static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view,
ked.f1 = rectf.xmin;
ked.f2 = rectf.xmax;
}
-
+
/* Update values for scaled_rectf - which is used to compute the mapping in the callbacks
- * NOTE: Since summary tracks need late-binding remapping, the callbacks may overwrite these
+ * NOTE: Since summary tracks need late-binding remapping, the callbacks may overwrite these
* with the properly remapped ked.f1/f2 values, when needed
*/
scaled_rectf.xmin = ked.f1;
scaled_rectf.xmax = ked.f2;
scaled_rectf.ymin = ymin;
scaled_rectf.ymax = ymax;
-
+
/* perform vertical suitability check (if applicable) */
if ((mode == ACTKEYS_BORDERSEL_FRAMERANGE) ||
!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
@@ -501,59 +501,59 @@ static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view,
break;
}
}
-
+
/* set minimum extent to be the maximum of the next channel */
ymax = ymin;
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
}
-
+
/* ----------------------------------- */
-
+
static int actkeys_lassoselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
KeyframeEdit_LassoData data_lasso;
rcti rect;
rctf rect_fl;
-
+
short selectmode;
bool extend;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
data_lasso.rectf_view = &rect_fl;
data_lasso.mcords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcords_tot);
if (data_lasso.mcords == NULL)
return OPERATOR_CANCELLED;
-
+
/* clear all selection if not extending selection */
extend = RNA_boolean_get(op->ptr, "extend");
if (!extend)
deselect_action_keys(&ac, 1, SELECT_SUBTRACT);
-
+
if (!RNA_boolean_get(op->ptr, "deselect"))
selectmode = SELECT_ADD;
else
selectmode = SELECT_SUBTRACT;
-
+
/* get settings from operator */
BLI_lasso_boundbox(&rect, data_lasso.mcords, data_lasso.mcords_tot);
BLI_rctf_rcti_copy(&rect_fl, &rect);
-
+
/* apply borderselect action */
region_select_action_keys(&ac, &rect_fl, BEZT_OK_CHANNEL_LASSO, selectmode, &data_lasso);
-
+
MEM_freeN((void *)data_lasso.mcords);
-
+
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -563,17 +563,17 @@ void ACTION_OT_select_lasso(wmOperatorType *ot)
ot->name = "Lasso Select";
ot->description = "Select keyframe points using lasso selection";
ot->idname = "ACTION_OT_select_lasso";
-
+
/* api callbacks */
ot->invoke = WM_gesture_lasso_invoke;
ot->modal = WM_gesture_lasso_modal;
ot->exec = actkeys_lassoselect_exec;
ot->poll = ED_operator_action_active;
ot->cancel = WM_gesture_lasso_cancel;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_gesture_lasso_select(ot);
}
@@ -585,10 +585,10 @@ static int action_circle_select_exec(bContext *C, wmOperator *op)
bAnimContext ac;
const bool select = !RNA_boolean_get(op->ptr, "deselect");
const short selectmode = select ? SELECT_ADD : SELECT_SUBTRACT;
-
+
KeyframeEdit_CircleData data = {0};
rctf rect_fl;
-
+
float x = RNA_int_get(op->ptr, "x");
float y = RNA_int_get(op->ptr, "y");
float radius = RNA_int_get(op->ptr, "radius");
@@ -596,23 +596,23 @@ static int action_circle_select_exec(bContext *C, wmOperator *op)
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
data.mval[0] = x;
data.mval[1] = y;
data.radius_squared = radius * radius;
data.rectf_view = &rect_fl;
-
+
rect_fl.xmin = x - radius;
rect_fl.xmax = x + radius;
rect_fl.ymin = y - radius;
rect_fl.ymax = y + radius;
-
+
/* apply region select action */
region_select_action_keys(&ac, &rect_fl, BEZT_OK_CHANNEL_CIRCLE, selectmode, &data);
-
+
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -621,13 +621,13 @@ void ACTION_OT_select_circle(wmOperatorType *ot)
ot->name = "Circle Select";
ot->description = "Select keyframe points using circle selection";
ot->idname = "ACTION_OT_select_circle";
-
+
ot->invoke = WM_gesture_circle_invoke;
ot->modal = WM_gesture_circle_modal;
ot->exec = action_circle_select_exec;
ot->poll = ED_operator_action_active;
ot->cancel = WM_gesture_circle_cancel;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
@@ -652,7 +652,7 @@ static const EnumPropertyItem prop_column_select_types[] = {
{0, NULL, 0, NULL, NULL}
};
-/* ------------------- */
+/* ------------------- */
/* Selects all visible keyframes between the specified markers */
/* TODO, this is almost an _exact_ duplicate of a function of the same name in graph_select.c
@@ -662,31 +662,31 @@ static void markers_selectkeys_between(bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc ok_cb, select_cb;
KeyframeEditData ked = {{NULL}};
float min, max;
-
+
/* get extreme markers */
ED_markers_get_minmax(ac->markers, 1, &min, &max);
min -= 0.5f;
max += 0.5f;
-
+
/* get editing funcs + data */
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
select_cb = ANIM_editkeyframes_select(SELECT_ADD);
ked.f1 = min;
ked.f2 = max;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* select keys in-between */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
@@ -702,7 +702,7 @@ static void markers_selectkeys_between(bAnimContext *ac)
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -714,52 +714,52 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
Scene *scene = ac->scene;
CfraElem *ce;
KeyframeEditFunc select_cb, ok_cb;
KeyframeEditData ked = {{NULL}};
-
+
/* build list of columns */
switch (mode) {
case ACTKEYS_COLUMNSEL_KEYS: /* list of selected keys */
if (ac->datatype == ANIMCONT_GPENCIL) {
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next)
ED_gplayer_make_cfra_list(ale->data, &ked.list, 1);
}
else {
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next)
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
}
ANIM_animdata_freelist(&anim_data);
break;
-
+
case ACTKEYS_COLUMNSEL_CFRA: /* current frame */
/* make a single CfraElem for storing this */
ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
BLI_addtail(&ked.list, ce);
-
+
ce->cfra = (float)CFRA;
break;
-
+
case ACTKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
break;
-
+
default: /* invalid option */
return;
}
-
+
/* set up BezTriple edit callbacks */
select_cb = ANIM_editkeyframes_select(SELECT_ADD);
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
-
+
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
@@ -768,10 +768,10 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
else
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* loop over cfraelems (stored in the KeyframeEditData->list)
* - we need to do this here, as we can apply fewer NLA-mapping conversions
*/
@@ -781,7 +781,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
ked.f1 = BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
else
ked.f1 = ce->cfra;
-
+
/* select elements with frame number matching cfraelem */
if (ale->type == ANIMTYPE_GPLAYER)
ED_gpencil_select_frame(ale->data, ce->cfra, SELECT_ADD);
@@ -791,7 +791,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
}
-
+
/* free elements */
BLI_freelistN(&ked.list);
ANIM_animdata_freelist(&anim_data);
@@ -803,39 +803,39 @@ static int actkeys_columnselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* action to take depends on the mode */
mode = RNA_enum_get(op->ptr, "mode");
-
+
if (mode == ACTKEYS_COLUMNSEL_MARKERS_BETWEEN)
markers_selectkeys_between(&ac);
else
columnselect_action_keys(&ac, mode);
-
+
/* set notifier that keyframe selection have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void ACTION_OT_select_column(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select All";
ot->idname = "ACTION_OT_select_column";
ot->description = "Select all keyframes on the specified frame(s)";
-
+
/* api callbacks */
ot->exec = actkeys_columnselect_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
}
@@ -845,38 +845,38 @@ void ACTION_OT_select_column(wmOperatorType *ot)
static int actkeys_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
KeyframeEditFunc sel_cb = ANIM_editkeyframes_select(SELECT_ADD);
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* loop through all of the keys and select additional keyframes based on these */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
-
+
/* check if anything selected? */
if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ok_cb, NULL)) {
/* select every keyframe in this curve then */
ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL);
}
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -886,11 +886,11 @@ void ACTION_OT_select_linked(wmOperatorType *ot)
ot->name = "Select Linked";
ot->idname = "ACTION_OT_select_linked";
ot->description = "Select keyframes occurring in the same F-Curves as selected ones";
-
+
/* api callbacks */
ot->exec = actkeys_select_linked_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -903,37 +903,37 @@ static void select_moreless_action_keys(bAnimContext *ac, short mode)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc build_cb;
-
-
+
+
/* init selmap building data */
build_cb = ANIM_editkeyframes_buildselmap(mode);
-
+
/* loop through all of the keys and select additional keyframes based on these */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
-
+
/* only continue if F-Curve has keyframes */
if (fcu->bezt == NULL)
continue;
-
+
/* build up map of whether F-Curve's keyframes should be selected or not */
ked.data = MEM_callocN(fcu->totvert, "selmap actEdit more");
ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, build_cb, NULL);
-
+
/* based on this map, adjust the selection status of the keyframes */
ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_selmap_flush, NULL);
-
+
/* free the selmap used here */
MEM_freeN(ked.data);
ked.data = NULL;
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -943,17 +943,17 @@ static void select_moreless_action_keys(bAnimContext *ac, short mode)
static int actkeys_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* perform select changes */
select_moreless_action_keys(&ac, SELMAP_MORE);
-
+
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -963,11 +963,11 @@ void ACTION_OT_select_more(wmOperatorType *ot)
ot->name = "Select More";
ot->idname = "ACTION_OT_select_more";
ot->description = "Select keyframes beside already selected ones";
-
+
/* api callbacks */
ot->exec = actkeys_select_more_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -977,17 +977,17 @@ void ACTION_OT_select_more(wmOperatorType *ot)
static int actkeys_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* perform select changes */
select_moreless_action_keys(&ac, SELMAP_LESS);
-
+
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -997,11 +997,11 @@ void ACTION_OT_select_less(wmOperatorType *ot)
ot->name = "Select Less";
ot->idname = "ACTION_OT_select_less";
ot->description = "Deselect keyframes on ends of selection islands";
-
+
/* api callbacks */
ot->exec = actkeys_select_less_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1024,25 +1024,25 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc ok_cb, select_cb;
KeyframeEditData ked = {{NULL}};
Scene *scene = ac->scene;
-
+
/* if select mode is replace, deselect all keyframes (and channels) first */
if (select_mode == SELECT_REPLACE) {
select_mode = SELECT_ADD;
-
+
/* - deselect all other keyframes, so that just the newly selected remain
* - channels aren't deselected, since we don't re-select any as a consequence
*/
deselect_action_keys(ac, 0, SELECT_SUBTRACT);
}
-
+
/* set callbacks and editing data */
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
select_cb = ANIM_editkeyframes_select(select_mode);
-
+
if (leftright == ACTKEYS_LRSEL_LEFT) {
ked.f1 = MINAFRAMEF;
ked.f2 = (float)(CFRA + 0.1f);
@@ -1051,18 +1051,18 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
ked.f1 = (float)(CFRA - 0.1f);
ked.f2 = MAXFRAMEF;
}
-
+
/* filter data */
if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
else
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* select keys */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
@@ -1075,15 +1075,15 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
else
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
-
+
/* Sync marker support */
if (select_mode == SELECT_ADD) {
SpaceAction *saction = (SpaceAction *)ac->sl;
-
+
if ((saction) && (saction->flag & SACTION_MARKERS_MOVE)) {
ListBase *markers = ED_animcontext_get_markers(ac);
TimeMarker *marker;
-
+
for (marker = markers->first; marker; marker = marker->next) {
if (((leftright == ACTKEYS_LRSEL_LEFT) && (marker->frame < CFRA)) ||
((leftright == ACTKEYS_LRSEL_RIGHT) && (marker->frame >= CFRA)))
@@ -1108,28 +1108,28 @@ static int actkeys_select_leftright_exec(bContext *C, wmOperator *op)
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
short selectmode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* select mode is either replace (deselect all, then add) or add/extend */
if (RNA_boolean_get(op->ptr, "extend"))
selectmode = SELECT_INVERT;
else
selectmode = SELECT_REPLACE;
-
+
/* if "test" mode is set, we don't have any info to set this with */
if (leftright == ACTKEYS_LRSEL_TEST)
return OPERATOR_CANCELLED;
-
+
/* do the selecting now */
actkeys_select_leftright(&ac, leftright, selectmode);
-
+
/* set notifier that keyframe selection (and channels too) have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1137,11 +1137,11 @@ static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wm
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* handle mode-based testing */
if (leftright == ACTKEYS_LRSEL_TEST) {
Scene *scene = ac.scene;
@@ -1156,7 +1156,7 @@ static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wm
else
RNA_enum_set(op->ptr, "mode", ACTKEYS_LRSEL_RIGHT);
}
-
+
/* perform selection */
return actkeys_select_leftright_exec(C, op);
}
@@ -1164,24 +1164,24 @@ static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wm
void ACTION_OT_select_leftright(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Select Left/Right";
ot->idname = "ACTION_OT_select_leftright";
ot->description = "Select keyframes to the left or the right of the current frame";
-
+
/* api callbacks */
ot->invoke = actkeys_select_leftright_invoke;
ot->exec = actkeys_select_leftright_exec;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_actkeys_leftright_select_types, ACTKEYS_LRSEL_TEST, "Mode", "");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
-
+
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -1198,19 +1198,19 @@ void ACTION_OT_select_leftright(wmOperatorType *ot)
*/
/* ------------------- */
-
+
/* option 1) select keyframe directly under mouse */
static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short select_mode, float selx)
{
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc select_cb, ok_cb;
-
+
/* get functions for selecting keyframes */
select_cb = ANIM_editkeyframes_select(select_mode);
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
ked.f1 = selx;
ked.iterflags |= KED_F1_NLA_UNMAP;
-
+
/* select the nominated keyframe on the given frame */
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frame(ale->data, selx, select_mode);
@@ -1224,10 +1224,10 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s
{
ListBase anim_data = {NULL, NULL};
int filter;
-
+
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frame(ale->data, selx, select_mode);
@@ -1236,7 +1236,7 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s
ED_mask_select_frame(ale->data, selx, select_mode);
}
}
-
+
ANIM_animdata_freelist(&anim_data);
}
else {
@@ -1254,14 +1254,14 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc select_cb, ok_cb;
KeyframeEditData ked = {{NULL}};
-
+
/* set up BezTriple edit callbacks */
select_cb = ANIM_editkeyframes_select(select_mode);
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
-
+
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
@@ -1270,16 +1270,16 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se
else
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* set frame for validation callback to refer to */
if (adt)
ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
else
ked.f1 = selx;
-
+
/* select elements with frame number matching cfra */
if (ale->type == ANIMTYPE_GPLAYER)
ED_gpencil_select_frame(ale->key_data, selx, select_mode);
@@ -1288,7 +1288,7 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se
else
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
-
+
/* free elements */
BLI_freelistN(&ked.list);
ANIM_animdata_freelist(&anim_data);
@@ -1298,10 +1298,10 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se
static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, short select_mode)
{
KeyframeEditFunc select_cb;
-
+
/* get functions for selecting keyframes */
select_cb = ANIM_editkeyframes_select(select_mode);
-
+
/* select all keyframes in this channel */
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frames(ale->data, select_mode);
@@ -1315,10 +1315,10 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s
{
ListBase anim_data = {NULL, NULL};
int filter;
-
+
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
ED_gpencil_select_frames(ale->data, select_mode);
@@ -1327,7 +1327,7 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s
ED_mask_select_frames(ale->data, select_mode);
}
}
-
+
ANIM_animdata_freelist(&anim_data);
}
else {
@@ -1335,7 +1335,7 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s
}
}
}
-
+
/* ------------------- */
static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_mode, bool column, bool same_channel)
@@ -1344,7 +1344,7 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
DLRBT_Tree anim_keys;
bAnimListElem *ale;
int filter;
-
+
View2D *v2d = &ac->ar->v2d;
bDopeSheet *ads = NULL;
int channel_index;
@@ -1354,28 +1354,28 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
float key_hsize;
float x, y;
rctf rectf;
-
+
/* get dopesheet info */
if (ac->datatype == ANIMCONT_DOPESHEET)
ads = ac->data;
-
+
/* use View2D to determine the index of the channel (i.e a row in the list) where keyframe was */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
UI_view2d_listview_view_to_cell(v2d, 0, ACHANNEL_STEP(ac), 0, (float)ACHANNEL_HEIGHT_HALF(ac), x, y, NULL, &channel_index);
-
+
/* x-range to check is +/- 7px for standard keyframe under standard dpi/y-scale (in screen/region-space),
* on either side of mouse click (size of keyframe icon)
*/
key_hsize = ACHANNEL_HEIGHT(ac) * 0.8f; /* standard channel height (to allow for some slop) */
key_hsize = roundf(key_hsize / 2.0f); /* half-size (for either side), but rounded up to nearest int (for easier targetting) */
-
+
UI_view2d_region_to_view(v2d, mval[0] - (int)key_hsize, mval[1], &rectf.xmin, &rectf.ymin);
UI_view2d_region_to_view(v2d, mval[0] + (int)key_hsize, mval[1], &rectf.xmax, &rectf.ymax);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* try to get channel */
ale = BLI_findlink(&anim_data, channel_index);
if (ale == NULL) {
@@ -1388,10 +1388,10 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
/* found match - must return here... */
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
ActKeyColumn *ak, *akn = NULL;
-
+
/* make list of keyframes */
BLI_dlrbTree_init(&anim_keys);
-
+
if (ale->key_data) {
switch (ale->datatype) {
case ALE_SCE:
@@ -1443,7 +1443,7 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
/* start from keyframe at root of BST, traversing until we find one within the range that was clicked on */
for (ak = anim_keys.root; ak; ak = akn) {
if (IN_RANGE(ak->cfra, rectf.xmin, rectf.xmax)) {
- /* set the frame to use, and apply inverse-correction for NLA-mapping
+ /* set the frame to use, and apply inverse-correction for NLA-mapping
* so that the frame will get selected by the selection functions without
* requiring to map each frame once again...
*/
@@ -1457,41 +1457,41 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
else
akn = ak->left;
}
-
+
/* remove active channel from list of channels for separate treatment (since it's needed later on) */
BLI_remlink(&anim_data, ale);
-
+
/* cleanup temporary lists */
BLI_dlrbTree_free(&anim_keys);
-
+
/* free list of channels, since it's not used anymore */
ANIM_animdata_freelist(&anim_data);
}
-
+
/* for replacing selection, firstly need to clear existing selection */
if (select_mode == SELECT_REPLACE) {
/* reset selection mode for next steps */
select_mode = SELECT_ADD;
-
+
/* deselect all keyframes */
deselect_action_keys(ac, 0, SELECT_SUBTRACT);
-
+
/* highlight channel clicked on */
if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET)) {
/* deselect all other channels first */
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
-
+
/* Highlight Action-Group or F-Curve? */
if (ale && ale->data) {
if (ale->type == ANIMTYPE_GROUP) {
bActionGroup *agrp = ale->data;
-
+
agrp->flag |= AGRP_SELECTED;
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
}
else if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
FCurve *fcu = ale->data;
-
+
fcu->flag |= FCURVE_SELECTED;
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
}
@@ -1500,11 +1500,11 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
else if (ac->datatype == ANIMCONT_GPENCIL) {
/* deselect all other channels first */
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
-
+
/* Highlight GPencil Layer */
if ((ale && ale->data) && (ale->type == ANIMTYPE_GPLAYER)) {
bGPDlayer *gpl = ale->data;
-
+
gpl->flag |= GP_LAYER_SELECT;
//gpencil_layer_setactive(gpd, gpl);
}
@@ -1522,28 +1522,28 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
}
}
}
-
+
/* only select keyframes if we clicked on a valid channel and hit something */
if (ale) {
if (found) {
/* apply selection to keyframes */
if (column) {
- /* select all keyframes in the same frame as the one we hit on the active channel
+ /* select all keyframes in the same frame as the one we hit on the active channel
* [T41077]: "frame" not "selx" here (i.e. no NLA corrections yet) as the code here
- * does that itself again as it needs to work on multiple datablocks
+ * does that itself again as it needs to work on multiple datablocks
*/
actkeys_mselect_column(ac, select_mode, frame);
}
else if (same_channel) {
/* select all keyframes in the active channel */
- actkeys_mselect_channel_only(ac, ale, select_mode);
+ actkeys_mselect_channel_only(ac, ale, select_mode);
}
else {
/* select the nominated keyframe on the given frame */
actkeys_mselect_single(ac, ale, select_mode, selx);
}
}
-
+
/* free this channel */
MEM_freeN(ale);
}
@@ -1556,11 +1556,11 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent
/* ARegion *ar; */ /* UNUSED */
short selectmode;
bool column, channel;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get useful pointers from animation context data */
/* ar = ac.ar; */ /* UNUSED */
@@ -1569,48 +1569,48 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent
selectmode = SELECT_INVERT;
else
selectmode = SELECT_REPLACE;
-
+
/* column selection */
column = RNA_boolean_get(op->ptr, "column");
channel = RNA_boolean_get(op->ptr, "channel");
-
+
/* select keyframe(s) based upon mouse position*/
mouse_action_keys(&ac, event->mval, selectmode, column, channel);
-
+
/* set notifier that keyframe selection (and channels too) have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
+
/* for tweak grab to work */
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
-
+
void ACTION_OT_clickselect(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Mouse Select Keys";
ot->idname = "ACTION_OT_clickselect";
ot->description = "Select keyframes by clicking on them";
-
+
/* callbacks */
ot->invoke = actkeys_clickselect_invoke;
ot->poll = ED_operator_action_active;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select",
+ prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select",
"Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select",
+
+ prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select",
"Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "channel", 0, "Only Channel",
+
+ prop = RNA_def_boolean(ot->srna, "channel", 0, "Only Channel",
"Select all the keyframes in the channel under the mouse"); // CTRLKEY + ALTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 8f8241cabcf..e130ea9369c 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -69,24 +69,24 @@
ARegion *action_has_buttons_region(ScrArea *sa)
{
ARegion *ar, *arnew;
-
+
ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
if (ar) return ar;
-
+
/* add subdiv level; after main */
ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
-
+
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "buttons for action");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_UI;
arnew->alignment = RGN_ALIGN_RIGHT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
-
+
return arnew;
}
@@ -96,62 +96,62 @@ static SpaceLink *action_new(const ScrArea *sa, const Scene *scene)
{
SpaceAction *saction;
ARegion *ar;
-
+
saction = MEM_callocN(sizeof(SpaceAction), "initaction");
saction->spacetype = SPACE_ACTION;
-
+
saction->autosnap = SACTSNAP_FRAME;
saction->mode = SACTCONT_DOPESHEET;
-
+
saction->ads.filterflag |= ADS_FILTER_SUMMARY;
-
+
/* enable all cache display */
saction->cache_display |= TIME_CACHE_DISPLAY;
saction->cache_display |= (TIME_CACHE_SOFTBODY | TIME_CACHE_PARTICLES);
saction->cache_display |= (TIME_CACHE_CLOTH | TIME_CACHE_SMOKE | TIME_CACHE_DYNAMICPAINT);
saction->cache_display |= TIME_CACHE_RIGIDBODY;
-
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for action");
-
+
BLI_addtail(&saction->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_BOTTOM;
-
+
/* channel list region */
ar = MEM_callocN(sizeof(ARegion), "channel region for action");
BLI_addtail(&saction->regionbase, ar);
ar->regiontype = RGN_TYPE_CHANNELS;
ar->alignment = RGN_ALIGN_LEFT;
-
+
/* only need to set scroll settings, as this will use 'listview' v2d configuration */
ar->v2d.scroll = V2D_SCROLL_BOTTOM;
ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
-
+
/* ui buttons */
ar = MEM_callocN(sizeof(ARegion), "buttons region for action");
-
+
BLI_addtail(&saction->regionbase, ar);
ar->regiontype = RGN_TYPE_UI;
ar->alignment = RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
-
+
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for action");
-
+
BLI_addtail(&saction->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
ar->v2d.tot.xmin = (float)(SFRA - 10);
ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
ar->v2d.tot.xmax = (float)(EFRA + 10);
ar->v2d.tot.ymax = 0.0f;
-
+
ar->v2d.cur = ar->v2d.tot;
-
+
ar->v2d.min[0] = 0.0f;
ar->v2d.min[1] = 0.0f;
-
+
ar->v2d.max[0] = MAXFRAMEF;
ar->v2d.max[1] = FLT_MAX;
@@ -163,13 +163,13 @@ static SpaceLink *action_new(const ScrArea *sa, const Scene *scene)
ar->v2d.keepofs = V2D_KEEPOFS_Y;
ar->v2d.align = V2D_ALIGN_NO_POS_Y;
ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
-
+
return (SpaceLink *)saction;
}
/* not spacelink itself */
static void action_free(SpaceLink *UNUSED(sl))
-{
+{
// SpaceAction *saction = (SpaceAction *) sl;
}
@@ -178,16 +178,16 @@ static void action_free(SpaceLink *UNUSED(sl))
static void action_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
{
SpaceAction *saction = sa->spacedata.first;
-
+
saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
}
static SpaceLink *action_duplicate(SpaceLink *sl)
{
SpaceAction *sactionn = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
-
+
return (SpaceLink *)sactionn;
}
@@ -197,9 +197,9 @@ static SpaceLink *action_duplicate(SpaceLink *sl)
static void action_main_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
-
+
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "Dopesheet", SPACE_ACTION, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -220,44 +220,44 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
short marker_flag = 0;
short cfra_flag = 0;
short unit = 0;
-
+
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_view2d_view_ortho(v2d);
-
+
/* time grid */
unit = (saction->flag & SACTION_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
UI_view2d_grid_free(grid);
-
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
-
+
/* start and end frame */
ANIM_draw_framerange(scene, v2d);
-
+
/* data */
if (ANIM_animdata_get_context(C, &ac)) {
draw_channel_strips(&ac, saction, ar);
}
-
+
/* current frame */
if (saction->flag & SACTION_DRAWTIME) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
ANIM_draw_cfra(C, v2d, cfra_flag);
-
+
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
-
+
marker_flag = ((ac.markers && (ac.markers != &ac.scene->markers)) ? DRAW_MARKERS_LOCAL : 0) | DRAW_MARKERS_MARGIN;
ED_markers_draw(C, marker_flag);
-
+
/* caches */
if (saction->mode == SACTCONT_TIMELINE) {
timeline_draw_cache(saction, obact, scene);
}
-
+
/* preview range */
UI_view2d_view_ortho(v2d);
ANIM_draw_previewrange(C, v2d, 0);
@@ -265,15 +265,15 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
/* callback */
UI_view2d_view_ortho(v2d);
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
+
/* draw current frame number-indicator on top of scrollers */
if ((saction->flag & SACTION_NODRAWCFRANUM) == 0) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
@@ -285,16 +285,18 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
static void action_channel_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
/* ensure the 2d view sync works - main region has bottom scroller */
ar->v2d.scroll = V2D_SCROLL_BOTTOM;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-
+
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "Animation Channels", 0, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
-
+
+ WM_keymap_add_menu(keymap, "DOPESHEET_MT_specials_channels", WKEY, KM_PRESS, 0, 0);
+
keymap = WM_keymap_find(wm->defaultconf, "Dopesheet Generic", SPACE_ACTION, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -304,21 +306,21 @@ static void action_channel_region_draw(const bContext *C, ARegion *ar)
/* draw entirely, view changes should be handled here */
bAnimContext ac;
View2D *v2d = &ar->v2d;
-
+
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_view2d_view_ortho(v2d);
-
+
/* data */
if (ANIM_animdata_get_context(C, &ac)) {
draw_channel_names((bContext *)C, &ac, ar);
}
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* no scrollers here */
}
@@ -393,7 +395,7 @@ static void saction_channel_region_message_subscribe(
.user_data = ar,
.notify = ED_region_do_msg_notify_tag_redraw,
};
-
+
/* All dopesheet filter settings, etc. affect the drawing of this editor,
* also same applies for all animation-related datatypes that may appear here,
* so just whitelist the entire structs for updates
@@ -402,13 +404,13 @@ static void saction_channel_region_message_subscribe(
wmMsgParams_RNA msg_key_params = {{{0}}};
StructRNA *type_array[] = {
&RNA_DopeSheet, /* dopesheet filters */
-
+
&RNA_ActionGroup, /* channel groups */
-
+
&RNA_FCurve, /* F-Curve */
&RNA_Keyframe,
&RNA_FCurveSample,
-
+
&RNA_GreasePencil, /* Grease Pencil */
&RNA_GPencilLayer,
&RNA_GPencilFrame,
@@ -518,7 +520,7 @@ static void saction_main_region_message_subscribe(
WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
}
}
-
+
/* Now run the general "channels region" one - since channels and main should be in sync */
saction_channel_region_message_subscribe(C, workspace, scene, screen, sa, ar, mbus);
}
@@ -529,7 +531,7 @@ static void action_listener(
WorkSpace *UNUSED(workspace))
{
SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
+
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
@@ -550,7 +552,7 @@ static void action_listener(
saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
ED_area_tag_refresh(sa);
}
- /* autocolor only really needs to change when channels are added/removed, or previously hidden stuff appears
+ /* autocolor only really needs to change when channels are added/removed, or previously hidden stuff appears
* (assume for now that if just adding these works, that will be fine)
*/
else if (((wmn->data == ND_KEYFRAME) && ELEM(wmn->action, NA_ADDED, NA_REMOVED)) ||
@@ -558,7 +560,7 @@ static void action_listener(
{
ED_area_tag_refresh(sa);
}
- /* for simple edits to the curve data though (or just plain selections), a simple redraw should work
+ /* for simple edits to the curve data though (or just plain selections), a simple redraw should work
* (see T39851 for an example of how this can go wrong)
*/
else {
@@ -598,7 +600,7 @@ static void action_listener(
saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
ED_area_tag_refresh(sa);
break;
-
+
default: /* just redrawing the view will do */
ED_area_tag_redraw(sa);
break;
@@ -721,12 +723,12 @@ static void action_header_region_listener(
case NC_ANIMATION:
switch (wmn->data) {
case ND_ANIMCHAN: /* set of visible animchannels changed */
- /* NOTE: for now, this should usually just mean that the filters changed
+ /* NOTE: for now, this should usually just mean that the filters changed
* It may be better if we had a dedicated flag for that though
*/
ED_region_tag_redraw(ar);
break;
-
+
case ND_KEYFRAME: /* new keyframed added -> active action may have changed */
//saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
ED_region_tag_redraw(ar);
@@ -741,9 +743,9 @@ static void action_header_region_listener(
static void action_buttons_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
ED_region_panels_init(wm, ar);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Dopesheet Generic", SPACE_ACTION, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -790,19 +792,19 @@ static void action_region_listener(
static void action_refresh(const bContext *C, ScrArea *sa)
{
SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
- /* update the state of the animchannels in response to changes from the data they represent
+
+ /* update the state of the animchannels in response to changes from the data they represent
* NOTE: the temp flag is used to indicate when this needs to be done, and will be cleared once handled
*/
if (saction->flag & SACTION_TEMP_NEEDCHANSYNC) {
ARegion *ar;
-
+
/* Perform syncing of channel state incl. selection
* Active action setting also occurs here (as part of anim channel filtering in anim_filter.c)
*/
ANIM_sync_animchannels_to_data(C);
saction->flag &= ~SACTION_TEMP_NEEDCHANSYNC;
-
+
/* Tag everything for redraw
* - Regions (such as header) need to be manually tagged for redraw too
* or else they don't update [#28962]
@@ -811,7 +813,7 @@ static void action_refresh(const bContext *C, ScrArea *sa)
for (ar = sa->regionbase.first; ar; ar = ar->next)
ED_region_tag_redraw(ar);
}
-
+
/* region updates? */
// XXX re-sizing y-extents of tot should go here?
}
@@ -838,10 +840,10 @@ void ED_spacetype_action(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype action");
ARegionType *art;
-
+
st->spaceid = SPACE_ACTION;
strncpy(st->name, "Action", BKE_ST_MAXNAME);
-
+
st->new = action_new;
st->free = action_free;
st->init = action_init;
@@ -862,32 +864,32 @@ void ED_spacetype_action(void)
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
-
+
art->init = action_header_region_init;
art->draw = action_header_region_draw;
art->listener = action_header_region_listener;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: channels */
art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
art->regionid = RGN_TYPE_CHANNELS;
art->prefsizex = 200;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
-
+
art->init = action_channel_region_init;
art->draw = action_channel_region_draw;
art->listener = action_channel_region_listener;
art->message_subscribe = saction_channel_region_message_subscribe;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: UI buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
art->regionid = RGN_TYPE_UI;
@@ -896,11 +898,10 @@ void ED_spacetype_action(void)
art->listener = action_region_listener;
art->init = action_buttons_area_init;
art->draw = action_buttons_area_draw;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
action_buttons_register(art);
-
+
BKE_spacetype_register(st);
}
-
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 4fddcb2bfef..33ec7f771ba 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -79,7 +79,7 @@ void ED_spacetypes_init(void)
/* UI_UNIT_X is now a variable, is used in some spacetype inits? */
U.widget_unit = 20;
-
+
/* create space types */
ED_spacetype_outliner();
ED_spacetype_view3d();
@@ -123,7 +123,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_render();
ED_operatortypes_mask();
ED_operatortypes_io();
-
+
ED_operatortypes_view2d();
ED_operatortypes_ui();
@@ -223,32 +223,32 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf)
typedef struct RegionDrawCB {
struct RegionDrawCB *next, *prev;
-
+
void (*draw)(const struct bContext *, struct ARegion *, void *);
void *customdata;
-
+
int type;
-
+
} RegionDrawCB;
-void *ED_region_draw_cb_activate(ARegionType *art,
+void *ED_region_draw_cb_activate(ARegionType *art,
void (*draw)(const struct bContext *, struct ARegion *, void *),
void *customdata, int type)
{
RegionDrawCB *rdc = MEM_callocN(sizeof(RegionDrawCB), "RegionDrawCB");
-
+
BLI_addtail(&art->drawcalls, rdc);
rdc->draw = draw;
rdc->customdata = customdata;
rdc->type = type;
-
+
return rdc;
}
void ED_region_draw_cb_exit(ARegionType *art, void *handle)
{
RegionDrawCB *rdc;
-
+
for (rdc = art->drawcalls.first; rdc; rdc = rdc->next) {
if (rdc == (RegionDrawCB *)handle) {
BLI_remlink(&art->drawcalls, rdc);
@@ -266,7 +266,7 @@ void *ED_region_draw_cb_customdata(void *handle)
void ED_region_draw_cb_draw(const bContext *C, ARegion *ar, int type)
{
RegionDrawCB *rdc;
-
+
for (rdc = ar->type->drawcalls.first; rdc; rdc = rdc->next) {
if (rdc->type == type) {
rdc->draw(C, ar, rdc->customdata);
@@ -295,17 +295,17 @@ static void xxx_free(SpaceLink *UNUSED(sl))
/* spacetype; init callback for usage, should be redoable */
static void xxx_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
{
-
+
/* link area to SpaceXXX struct */
-
+
/* define how many regions, the order and types */
-
+
/* add types to regions */
}
static SpaceLink *xxx_duplicate(SpaceLink *UNUSED(sl))
{
-
+
return NULL;
}
@@ -323,16 +323,16 @@ static void xxx_keymap(wmKeyConfig *UNUSED(keyconf))
void ED_spacetype_xxx(void)
{
static SpaceType st;
-
+
st.spaceid = SPACE_VIEW3D;
-
+
st.new = xxx_new;
st.free = xxx_free;
st.init = xxx_init;
st.duplicate = xxx_duplicate;
st.operatortypes = xxx_operatortypes;
st.keymap = xxx_keymap;
-
+
BKE_spacetype_register(&st);
}
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index cfaa7bf91bd..dd943e7988d 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -144,7 +144,7 @@ static int buttons_context_path_world(ButsContextPath *path)
else if (buttons_context_path_scene(path)) {
scene = path->ptr[path->len - 1].data;
world = scene->world;
-
+
if (world) {
RNA_id_pointer_create(&scene->world->id, &path->ptr[path->len]);
path->len++;
@@ -421,7 +421,7 @@ static int buttons_context_path_texture(const bContext *C, ButsContextPath *path
if (!ct->user)
return 0;
-
+
id = ct->user->id;
if (id) {
@@ -489,7 +489,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
}
/* No pinned root, use scene as initial root. */
else {
- if (mainb == BCONTEXT_WORKSPACE) {
+ if (ELEM(mainb, BCONTEXT_WORKSPACE, BCONTEXT_TOOL)) {
RNA_id_pointer_create(&workspace->id, &path->ptr[0]);
path->len++;
}
@@ -525,6 +525,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
case BCONTEXT_WORLD:
found = buttons_context_path_world(path);
break;
+ case BCONTEXT_TOOL:
case BCONTEXT_WORKSPACE:
found = buttons_context_path_workspace(path);
break;
@@ -572,7 +573,7 @@ static int buttons_shading_context(const bContext *C, int mainb)
return 1;
if (mainb == BCONTEXT_DATA && ob && ELEM(ob->type, OB_LAMP, OB_CAMERA))
return 1;
-
+
return 0;
}
@@ -586,7 +587,7 @@ static int buttons_shading_new_context(const bContext *C, int flag)
return BCONTEXT_DATA;
else if (flag & (1 << BCONTEXT_WORLD))
return BCONTEXT_WORLD;
-
+
return BCONTEXT_RENDER;
}
@@ -858,7 +859,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
else if (CTX_data_equals(member, "particle_settings")) {
/* only available when pinned */
PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSettings);
-
+
if (ptr && ptr->data) {
CTX_data_pointer_set(result, ptr->id.data, &RNA_ParticleSettings, ptr->data);
return 1;
@@ -866,7 +867,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
else {
/* get settings from active particle system instead */
ptr = get_pointer_type(path, &RNA_ParticleSystem);
-
+
if (ptr && ptr->data) {
ParticleSettings *part = ((ParticleSystem *)ptr->data)->part;
CTX_data_pointer_set(result, ptr->id.data, &RNA_ParticleSettings, part);
@@ -906,7 +907,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
}
-
+
else if (CTX_data_equals(member, "smoke")) {
PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
@@ -963,7 +964,7 @@ static void pin_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
}
else
sbuts->pinid = NULL;
-
+
ED_area_tag_redraw(CTX_wm_area(C));
}
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 8198650fd8a..47f97b8087f 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -86,7 +86,7 @@ void BUTTONS_OT_toolbox(wmOperatorType *ot)
ot->name = "Toolbox";
ot->description = "Display button panel toolbox";
ot->idname = "BUTTONS_OT_toolbox";
-
+
/* api callbacks */
ot->invoke = toolbox_invoke;
ot->poll = ED_operator_buttons_active;
@@ -102,14 +102,15 @@ typedef struct FileBrowseOp {
static int file_browse_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
FileBrowseOp *fbo = op->customdata;
ID *id;
char *str, path[FILE_MAX];
const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath";
-
+
if (RNA_struct_property_is_set(op->ptr, path_prop) == 0 || fbo == NULL)
return OPERATOR_CANCELLED;
-
+
str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0);
/* add slash for directories, important for some properties */
@@ -118,14 +119,14 @@ static int file_browse_exec(bContext *C, wmOperator *op)
id = fbo->ptr.id.data;
BLI_strncpy(path, str, FILE_MAX);
- BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name);
-
+ BLI_path_abs(path, id ? ID_BLEND_PATH(bmain, id) : BKE_main_blendfile_path(bmain));
+
if (BLI_is_dir(path)) {
/* do this first so '//' isnt converted to '//\' on windows */
BLI_add_slash(path);
if (is_relative) {
BLI_strncpy(path, str, FILE_MAX);
- BLI_path_rel(path, G.main->name);
+ BLI_path_rel(path, BKE_main_blendfile_path(bmain));
str = MEM_reallocN(str, strlen(path) + 2);
BLI_strncpy(str, path, FILE_MAX);
}
@@ -255,7 +256,7 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot)
ot->name = "Accept";
ot->description = "Open a file browser, Hold Shift to open the file, Alt to browse containing directory";
ot->idname = "BUTTONS_OT_file_browse";
-
+
/* api callbacks */
ot->invoke = file_browse_invoke;
ot->exec = file_browse_exec;
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 8beb163cf98..5feb74edef7 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -78,7 +78,7 @@
/************************* Texture User **************************/
-static void buttons_texture_user_property_add(ListBase *users, ID *id,
+static void buttons_texture_user_property_add(ListBase *users, ID *id,
PointerRNA ptr, PropertyRNA *prop,
const char *category, int icon, const char *name)
{
@@ -95,7 +95,7 @@ static void buttons_texture_user_property_add(ListBase *users, ID *id,
BLI_addtail(users, user);
}
-static void buttons_texture_user_node_add(ListBase *users, ID *id,
+static void buttons_texture_user_node_add(ListBase *users, ID *id,
bNodeTree *ntree, bNode *node,
const char *category, int icon, const char *name)
{
@@ -122,10 +122,10 @@ static void buttons_texture_users_find_nodetree(ListBase *users, ID *id,
if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
PointerRNA ptr;
/* PropertyRNA *prop; */ /* UNUSED */
-
+
RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
/* prop = RNA_struct_find_property(&ptr, "texture"); */ /* UNUSED */
-
+
buttons_texture_user_node_add(users, id, ntree, node,
category, RNA_struct_ui_icon(ptr.type), node->name);
}
@@ -449,7 +449,7 @@ static void template_texture_show(bContext *C, void *data_p, void *prop_p)
for (user = ct->users.first; user; user = user->next)
if (user->ptr.data == data_p && user->prop == prop_p)
break;
-
+
if (user) {
/* select texture */
template_texture_select(C, user, NULL);
@@ -479,12 +479,12 @@ void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, Prope
for (user = ct->users.first; user; user = user->next)
if (user->ptr.data == ptr->data && user->prop == prop)
break;
-
+
/* draw button */
if (user) {
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but;
-
+
but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Show texture in texture tab"));
UI_but_func_set(but, template_texture_show, user->ptr.data, user->prop);
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 5b027883a4b..be687d365f3 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -52,6 +52,8 @@
#include "UI_resources.h"
+#include "GPU_glew.h"
+
#include "buttons_intern.h" /* own include */
/* ******************** default callbacks for buttons space ***************** */
@@ -60,7 +62,7 @@ static SpaceLink *buttons_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s
{
ARegion *ar;
SpaceButs *sbuts;
-
+
sbuts = MEM_callocN(sizeof(SpaceButs), "initbuts");
sbuts->spacetype = SPACE_BUTS;
sbuts->align = BUT_VERTICAL;
@@ -69,11 +71,11 @@ static SpaceLink *buttons_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for buts");
-
+
BLI_addtail(&sbuts->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
#if 0
/* context region */
ar = MEM_callocN(sizeof(ARegion), "context region for buts");
@@ -84,7 +86,7 @@ static SpaceLink *buttons_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for buts");
-
+
BLI_addtail(&sbuts->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
@@ -93,12 +95,12 @@ static SpaceLink *buttons_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s
/* not spacelink itself */
static void buttons_free(SpaceLink *sl)
-{
+{
SpaceButs *sbuts = (SpaceButs *) sl;
if (sbuts->path)
MEM_freeN(sbuts->path);
-
+
if (sbuts->texuser) {
ButsContextTexture *ct = sbuts->texuser;
BLI_freelistN(&ct->users);
@@ -123,11 +125,11 @@ static void buttons_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
static SpaceLink *buttons_duplicate(SpaceLink *sl)
{
SpaceButs *sbutsn = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
sbutsn->path = NULL;
sbutsn->texuser = NULL;
-
+
return (SpaceLink *)sbutsn;
}
@@ -144,7 +146,6 @@ static void buttons_main_region_init(wmWindowManager *wm, ARegion *ar)
static void buttons_main_region_draw_properties(const bContext *C, SpaceButs *sbuts, ARegion *ar)
{
- BLI_assert(sbuts->space_subtype == SB_SUBTYPE_DATA);
const bool vertical = (sbuts->align == BUT_VERTICAL);
buttons_context_compute(C, sbuts);
@@ -197,6 +198,9 @@ static void buttons_main_region_draw_properties(const bContext *C, SpaceButs *sb
case BCONTEXT_BONE_CONSTRAINT:
contexts[0] = "bone_constraint";
break;
+ case BCONTEXT_TOOL:
+ contexts[0] = "tool";
+ break;
}
if (contexts[0]) {
@@ -206,13 +210,12 @@ static void buttons_main_region_draw_properties(const bContext *C, SpaceButs *sb
static void buttons_main_region_draw_tool(const bContext *C, SpaceButs *sbuts, ARegion *ar)
{
- BLI_assert(sbuts->space_subtype == SB_SUBTYPE_TOOL);
const bool vertical = (sbuts->align == BUT_VERTICAL);
+ const char *contexts[3] = {NULL};
const WorkSpace *workspace = CTX_wm_workspace(C);
if (workspace->tools_space_type == SPACE_VIEW3D) {
const int mode = CTX_data_mode_enum(C);
- const char *contexts[3] = {NULL};
switch (mode) {
case CTX_MODE_EDIT_MESH:
ARRAY_SET_ITEMS(contexts, ".mesh_edit");
@@ -264,6 +267,11 @@ static void buttons_main_region_draw_tool(const bContext *C, SpaceButs *sbuts, A
else if (workspace->tools_space_type == SPACE_IMAGE) {
/* TODO */
}
+
+ if (contexts[0] == NULL) {
+ UI_ThemeClearColor(TH_BACK);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
}
static void buttons_main_region_draw(const bContext *C, ARegion *ar)
@@ -271,12 +279,12 @@ static void buttons_main_region_draw(const bContext *C, ARegion *ar)
/* draw entirely, view changes should be handled here */
SpaceButs *sbuts = CTX_wm_space_buts(C);
- if (sbuts->space_subtype == SB_SUBTYPE_DATA) {
- buttons_main_region_draw_properties(C, sbuts, ar);
- }
- else if (sbuts->space_subtype == SB_SUBTYPE_TOOL) {
+ if (sbuts->mainb == BCONTEXT_TOOL) {
buttons_main_region_draw_tool(C, sbuts, ar);
}
+ else {
+ buttons_main_region_draw_properties(C, sbuts, ar);
+ }
sbuts->re_align = 0;
sbuts->mainbo = sbuts->mainb;
@@ -306,7 +314,7 @@ static void buttons_operatortypes(void)
static void buttons_keymap(struct wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Property Editor", SPACE_BUTS, 0);
-
+
WM_keymap_add_item(keymap, "BUTTONS_OT_toolbox", RIGHTMOUSE, KM_PRESS, 0, 0);
}
@@ -320,10 +328,8 @@ static void buttons_header_region_draw(const bContext *C, ARegion *ar)
{
SpaceButs *sbuts = CTX_wm_space_buts(C);
- if (sbuts->space_subtype == SB_SUBTYPE_DATA) {
- /* Needed for RNA to get the good values! */
- buttons_context_compute(C, sbuts);
- }
+ /* Needed for RNA to get the good values! */
+ buttons_context_compute(C, sbuts);
ED_region_header(C, ar);
}
@@ -355,7 +361,7 @@ static void buttons_header_region_message_subscribe(
static void buttons_area_redraw(ScrArea *sa, short buttons)
{
SpaceButs *sbuts = sa->spacedata.first;
-
+
/* if the area's current button set is equal to the one to redraw */
if (sbuts->mainb == buttons)
ED_area_tag_redraw(sa);
@@ -590,33 +596,15 @@ static void buttons_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id,
}
}
-static int buttons_space_subtype_get(ScrArea *sa)
-{
- SpaceButs *sbuts = sa->spacedata.first;
- return sbuts->space_subtype;
-}
-
-static void buttons_space_subtype_set(ScrArea *sa, int value)
-{
- SpaceButs *sbuts = sa->spacedata.first;
- sbuts->space_subtype = value;
-}
-
-static void buttons_space_subtype_item_extend(
- bContext *UNUSED(C), EnumPropertyItem **item, int *totitem)
-{
- RNA_enum_items_add(item, totitem, rna_enum_space_button_mode_items);
-}
-
/* only called once, from space/spacetypes.c */
void ED_spacetype_buttons(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype buttons");
ARegionType *art;
-
+
st->spaceid = SPACE_BUTS;
strncpy(st->name, "Buttons", BKE_ST_MAXNAME);
-
+
st->new = buttons_new;
st->free = buttons_free;
st->init = buttons_init;
@@ -626,9 +614,6 @@ void ED_spacetype_buttons(void)
st->listener = buttons_area_listener;
st->context = buttons_context;
st->id_remap = buttons_id_remap;
- st->space_subtype_item_extend = buttons_space_subtype_item_extend;
- st->space_subtype_get = buttons_space_subtype_get;
- st->space_subtype_set = buttons_space_subtype_set;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
@@ -640,13 +625,13 @@ void ED_spacetype_buttons(void)
BLI_addhead(&st->regiontypes, art);
buttons_context_register(art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
-
+
art->init = buttons_header_region_init;
art->draw = buttons_header_region_draw;
art->message_subscribe = buttons_header_region_message_subscribe;
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index 7ff7ea73628..bc2aa3ae67f 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -91,7 +91,7 @@ static void clip_draw_dopesheet_background(ARegion *ar, MovieClip *clip, unsigne
MovieTracking *tracking = &clip->tracking;
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
MovieTrackingDopesheetCoverageSegment *coverage_segment;
-
+
for (coverage_segment = dopesheet->coverage_segments.first;
coverage_segment;
coverage_segment = coverage_segment->next)
@@ -291,7 +291,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
MovieClip *clip = ED_space_clip_get_clip(sc);
uiStyle *style = UI_style_get();
int fontid = style->widget.uifont_id;
-
+
if (!clip)
return;
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 942bc2661c3..67aa7e19de7 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -297,7 +297,7 @@ bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r
ret = true;
}
}
-
+
IMB_freeImBuf(ibuf);
return ret;
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 0d9371a7784..498a4d6fbbd 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -318,7 +318,7 @@ static int reload_exec(bContext *C, wmOperator *UNUSED(op))
if (!clip)
return OPERATOR_CANCELLED;
- BKE_movieclip_reload(clip);
+ BKE_movieclip_reload(CTX_data_main(C), clip);
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
@@ -1315,7 +1315,7 @@ static void proxy_endjob(void *pjv)
if (pj->clip->source == MCLIP_SRC_MOVIE) {
/* Timecode might have changed, so do a full reload to deal with this. */
- BKE_movieclip_reload(pj->clip);
+ BKE_movieclip_reload(pj->main, pj->clip);
}
else {
/* For image sequences we'll preserve original cache. */
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 42832d24bb3..f022bb7e6f8 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -1273,7 +1273,7 @@ static void graph_region_draw(const bContext *C, ARegion *ar)
scrollers = UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
+
/* currnt frame indicator */
if (sc->flag & SC_SHOW_SECONDS) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
UI_view2d_view_orthoSpecial(ar, v2d, 1);
@@ -1320,7 +1320,7 @@ static void dopesheet_region_draw(const bContext *C, ARegion *ar)
scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
+
/* currnt frame number indicator */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ANIM_draw_cfra_number(C, v2d, cfra_flag);
diff --git a/source/blender/editors/space_clip/tracking_ops_intern.h b/source/blender/editors/space_clip/tracking_ops_intern.h
index 6ac9287c914..b53799b88d8 100644
--- a/source/blender/editors/space_clip/tracking_ops_intern.h
+++ b/source/blender/editors/space_clip/tracking_ops_intern.h
@@ -50,4 +50,4 @@ void clip_tracking_hide_cursor(struct bContext *C);
void ed_tracking_delect_all_tracks(struct ListBase *tracks_base);
void ed_tracking_delect_all_plane_tracks(struct ListBase *plane_tracks_base);
-#endif /* __TRACKING_OPS_INTERN_H__ */ \ No newline at end of file
+#endif /* __TRACKING_OPS_INTERN_H__ */
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index c8a06545e0f..66b203ff612 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -74,7 +74,7 @@ void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_du
/* fake the edit line being in the scroll buffer */
ConsoleLine *cl = sc->history.last;
int prompt_len = strlen(sc->prompt);
-
+
cl_dummy->type = CONSOLE_LINE_INPUT;
cl_dummy->len = prompt_len + cl->len;
cl_dummy->len_alloc = cl_dummy->len + 1;
@@ -83,7 +83,7 @@ void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_du
memcpy(cl_dummy->line + prompt_len, cl->line, cl->len + 1);
BLI_addtail(&sc->scrollback, cl_dummy);
}
-void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy)
+void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy)
{
MEM_freeN(cl_dummy->line);
BLI_remlink(&sc->scrollback, cl_dummy);
@@ -98,10 +98,10 @@ static int console_textview_begin(TextViewContext *tvc)
tvc->lheight = sc->lheight * UI_DPI_FAC;
tvc->sel_start = sc->sel_start;
tvc->sel_end = sc->sel_end;
-
+
/* iterator */
tvc->iter = sc->scrollback.last;
-
+
return (tvc->iter != NULL);
}
@@ -109,7 +109,7 @@ static void console_textview_end(TextViewContext *tvc)
{
SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
(void)sc;
-
+
}
static int console_textview_step(TextViewContext *tvc)
@@ -199,7 +199,7 @@ static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar,
{
ConsoleLine cl_dummy = {NULL};
int ret = 0;
-
+
View2D *v2d = &ar->v2d;
TextViewContext tvc = {0};
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index b740ff4b397..4867d42030c 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -92,9 +92,9 @@ void console_scrollback_free(SpaceConsole *sc, ConsoleLine *cl)
static void console_scrollback_limit(SpaceConsole *sc)
{
int tot;
-
+
if (U.scrollback < 32) U.scrollback = 256; // XXX - save in user defaults
-
+
for (tot = BLI_listbase_count(&sc->scrollback); tot > U.scrollback; tot--)
console_scrollback_free(sc, sc->scrollback.first);
}
@@ -122,16 +122,16 @@ static bool console_line_cursor_set(ConsoleLine *cl, int cursor)
if (cursor < 0) cursor_new = 0;
else if (cursor > cl->len) cursor_new = cl->len;
else cursor_new = cursor;
-
+
if (cursor_new == cl->cursor) {
return false;
}
-
+
cl->cursor = cursor_new;
return true;
}
-#if 0 // XXX unused
+#if 0 // XXX unused
static void console_lb_debug__internal(ListBase *lb)
{
ConsoleLine *cl;
@@ -147,7 +147,7 @@ static void console_history_debug(const bContext *C)
{
SpaceConsole *sc = CTX_wm_space_console(C);
-
+
console_lb_debug__internal(&sc->history);
}
#endif
@@ -155,7 +155,7 @@ static void console_history_debug(const bContext *C)
static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from)
{
ConsoleLine *ci = MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add");
-
+
if (from) {
BLI_assert(strlen(from->line) == from->len);
ci->line = BLI_strdupn(from->line, from->len);
@@ -168,7 +168,7 @@ static ConsoleLine *console_lb_add__internal(ListBase *lb, ConsoleLine *from)
ci->len_alloc = 64;
ci->len = 0;
}
-
+
BLI_addtail(lb, ci);
return ci;
}
@@ -182,7 +182,7 @@ static ConsoleLine *console_history_add(SpaceConsole *sc, ConsoleLine *from)
static ConsoleLine *console_scrollback_add(const bContext *C, ConsoleLine *from)
{
SpaceConsole *sc = CTX_wm_space_console(C);
-
+
return console_lb_add__internal(&sc->scrollback, from);
}
#endif
@@ -192,9 +192,9 @@ static ConsoleLine *console_lb_add_str__internal(ListBase *lb, char *str, bool o
ConsoleLine *ci = MEM_callocN(sizeof(ConsoleLine), "ConsoleLine Add");
if (own) ci->line = str;
else ci->line = BLI_strdup(str);
-
+
ci->len = ci->len_alloc = strlen(str);
-
+
BLI_addtail(lb, ci);
return ci;
}
@@ -215,7 +215,7 @@ ConsoleLine *console_history_verify(const bContext *C)
ConsoleLine *ci = sc->history.last;
if (ci == NULL)
ci = console_history_add(sc, NULL);
-
+
return ci;
}
@@ -233,7 +233,7 @@ static void console_line_verify_length(ConsoleLine *ci, int len)
char *new_line = MEM_callocN(new_len, "console line");
memcpy(new_line, ci->line, ci->len);
MEM_freeN(ci->line);
-
+
ci->line = new_line;
ci->len_alloc = new_len;
}
@@ -242,7 +242,7 @@ static void console_line_verify_length(ConsoleLine *ci, int len)
static int console_line_insert(ConsoleLine *ci, char *str)
{
int len = strlen(str);
-
+
if (len > 0 && str[len - 1] == '\n') { /* stop new lines being pasted at the end of lines */
str[len - 1] = '\0';
len--;
@@ -250,15 +250,15 @@ static int console_line_insert(ConsoleLine *ci, char *str)
if (len == 0)
return 0;
-
+
console_line_verify_length(ci, len + ci->len);
-
+
memmove(ci->line + ci->cursor + len, ci->line + ci->cursor, (ci->len - ci->cursor) + 1);
memcpy(ci->line + ci->cursor, str, len);
-
+
ci->len += len;
ci->cursor += len;
-
+
return len;
}
@@ -312,11 +312,11 @@ static const EnumPropertyItem console_move_type_items[] = {
static int console_move_exec(bContext *C, wmOperator *op)
{
ConsoleLine *ci = console_history_verify(C);
-
+
int type = RNA_enum_get(op->ptr, "type");
bool done = false;
int pos;
-
+
switch (type) {
case LINE_BEGIN:
pos = ci->cursor;
@@ -364,7 +364,7 @@ static int console_move_exec(bContext *C, wmOperator *op)
done = console_line_cursor_set(ci, pos);
break;
}
-
+
if (done) {
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -383,7 +383,7 @@ void CONSOLE_OT_move(wmOperatorType *ot)
ot->name = "Move Cursor";
ot->description = "Move cursor position";
ot->idname = "CONSOLE_OT_move";
-
+
/* api callbacks */
ot->exec = console_move_exec;
ot->poll = ED_operator_console_active;
@@ -410,9 +410,9 @@ static int console_insert_exec(bContext *C, wmOperator *op)
}
len = console_line_insert(ci, str);
-
+
MEM_freeN(str);
-
+
if (len == 0) {
return OPERATOR_CANCELLED;
}
@@ -442,7 +442,7 @@ static int console_insert_invoke(bContext *C, wmOperator *op, const wmEvent *eve
else {
char str[BLI_UTF8_MAX + 1];
size_t len;
-
+
if (event->utf8_buf[0]) {
len = BLI_str_utf8_size_safe(event->utf8_buf);
memcpy(str, event->utf8_buf, len);
@@ -466,7 +466,7 @@ void CONSOLE_OT_insert(wmOperatorType *ot)
ot->name = "Insert";
ot->description = "Insert text at cursor position";
ot->idname = "CONSOLE_OT_insert";
-
+
/* api callbacks */
ot->exec = console_insert_exec;
ot->invoke = console_insert_invoke;
@@ -588,11 +588,11 @@ static int console_delete_exec(bContext *C, wmOperator *op)
const short type = RNA_enum_get(op->ptr, "type");
bool done = false;
-
+
if (ci->len == 0) {
return OPERATOR_CANCELLED;
}
-
+
switch (type) {
case DEL_NEXT_CHAR:
case DEL_NEXT_WORD:
@@ -640,7 +640,7 @@ static int console_delete_exec(bContext *C, wmOperator *op)
ED_area_tag_redraw(CTX_wm_area(C));
console_scroll_bottom(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -651,7 +651,7 @@ void CONSOLE_OT_delete(wmOperatorType *ot)
ot->name = "Delete";
ot->description = "Delete text by cursor position";
ot->idname = "CONSOLE_OT_delete";
-
+
/* api callbacks */
ot->exec = console_delete_exec;
ot->poll = ED_operator_console_active;
@@ -700,17 +700,17 @@ static int console_clear_exec(bContext *C, wmOperator *op)
{
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *ar = CTX_wm_region(C);
-
+
const bool scrollback = RNA_boolean_get(op->ptr, "scrollback");
const bool history = RNA_boolean_get(op->ptr, "history");
-
+
/*ConsoleLine *ci = */ console_history_verify(C);
-
+
if (scrollback) { /* last item in mistory */
while (sc->scrollback.first)
console_scrollback_free(sc, sc->scrollback.first);
}
-
+
if (history) {
while (sc->history.first)
console_history_free(sc, sc->history.first);
@@ -729,11 +729,11 @@ void CONSOLE_OT_clear(wmOperatorType *ot)
ot->name = "Clear";
ot->description = "Clear text by type";
ot->idname = "CONSOLE_OT_clear";
-
+
/* api callbacks */
ot->exec = console_clear_exec;
ot->poll = ED_operator_console_active;
-
+
/* properties */
RNA_def_boolean(ot->srna, "scrollback", 1, "Scrollback", "Clear the scrollback history");
RNA_def_boolean(ot->srna, "history", 0, "History", "Clear the command history");
@@ -778,7 +778,7 @@ static int console_history_cycle_exec(bContext *C, wmOperator *op)
console_history_add(sc, (ConsoleLine *)sc->history.last);
}
-
+
ci = sc->history.last;
console_select_offset(sc, ci->len - prev_len);
@@ -797,11 +797,11 @@ void CONSOLE_OT_history_cycle(wmOperatorType *ot)
ot->name = "History Cycle";
ot->description = "Cycle through history";
ot->idname = "CONSOLE_OT_history_cycle";
-
+
/* api callbacks */
ot->exec = console_history_cycle_exec;
ot->poll = ED_operator_console_active;
-
+
/* properties */
RNA_def_boolean(ot->srna, "reverse", 0, "Reverse", "Reverse cycle history");
}
@@ -852,11 +852,11 @@ void CONSOLE_OT_history_append(wmOperatorType *ot)
ot->name = "History Append";
ot->description = "Append history at cursor position";
ot->idname = "CONSOLE_OT_history_append";
-
+
/* api callbacks */
ot->exec = console_history_append_exec;
ot->poll = ED_operator_console_active;
-
+
/* properties */
RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
RNA_def_int(ot->srna, "current_character", 0, 0, INT_MAX, "Cursor", "The index of the cursor", 0, 10000);
@@ -870,15 +870,15 @@ static int console_scrollback_append_exec(bContext *C, wmOperator *op)
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *ar = CTX_wm_region(C);
ConsoleLine *ci;
-
+
char *str = RNA_string_get_alloc(op->ptr, "text", NULL, 0); /* own this text in the new line, don't free */
int type = RNA_enum_get(op->ptr, "type");
console_history_verify(C);
-
+
ci = console_scrollback_add_str(sc, str, 1); /* own the string */
ci->type = type;
-
+
console_scrollback_limit(sc);
/* 'ar' can be null depending on the operator that runs
@@ -888,7 +888,7 @@ static int console_scrollback_append_exec(bContext *C, wmOperator *op)
}
ED_area_tag_redraw(CTX_wm_area(C));
-
+
return OPERATOR_FINISHED;
}
@@ -907,11 +907,11 @@ void CONSOLE_OT_scrollback_append(wmOperatorType *ot)
ot->name = "Scrollback Append";
ot->description = "Append scrollback text by type";
ot->idname = "CONSOLE_OT_scrollback_append";
-
+
/* api callbacks */
ot->exec = console_scrollback_append_exec;
ot->poll = ED_operator_console_active;
-
+
/* properties */
RNA_def_string(ot->srna, "text", NULL, 0, "Text", "Text to insert at the cursor position");
RNA_def_enum(ot->srna, "type", console_line_type_items, CONSOLE_LINE_OUTPUT, "Type", "Console output type");
@@ -924,7 +924,7 @@ static int console_copy_exec(bContext *C, wmOperator *UNUSED(op))
DynStr *buf_dyn;
char *buf_str;
-
+
ConsoleLine *cl;
int sel[2];
int offset = 0;
@@ -1088,7 +1088,7 @@ static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEven
sel_prev[0] = sc->sel_start;
sel_prev[1] = sc->sel_end;
-
+
console_cursor_set_to_pos(sc, ar, scu, mval, true);
/* only redraw if the selection changed */
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 549fe503b31..c65c9a175a0 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -56,26 +56,26 @@ static SpaceLink *console_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s
{
ARegion *ar;
SpaceConsole *sconsole;
-
+
sconsole = MEM_callocN(sizeof(SpaceConsole), "initconsole");
sconsole->spacetype = SPACE_CONSOLE;
-
+
sconsole->lheight = 14;
-
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for console");
-
+
BLI_addtail(&sconsole->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
-
+
+
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for text");
-
+
BLI_addtail(&sconsole->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
/* keep in sync with info */
ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
ar->v2d.align |= V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y; /* align bottom left */
@@ -94,10 +94,10 @@ static SpaceLink *console_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s
static void console_free(SpaceLink *sl)
{
SpaceConsole *sc = (SpaceConsole *) sl;
-
+
while (sc->scrollback.first)
console_scrollback_free(sc, sc->scrollback.first);
-
+
while (sc->history.first)
console_history_free(sc, sc->history.first);
}
@@ -112,13 +112,13 @@ static void console_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)
static SpaceLink *console_duplicate(SpaceLink *sl)
{
SpaceConsole *sconsolen = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
-
+
/* TODO - duplicate?, then we also need to duplicate the py namespace */
BLI_listbase_clear(&sconsolen->scrollback);
BLI_listbase_clear(&sconsolen->history);
-
+
return (SpaceLink *)sconsolen;
}
@@ -147,10 +147,10 @@ static void console_main_region_init(wmWindowManager *wm, ARegion *ar)
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "Console", SPACE_CONSOLE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
-
+
/* add drop boxes */
lb = WM_dropboxmap_find("Console", SPACE_CONSOLE, RGN_TYPE_WINDOW);
-
+
WM_event_add_dropbox_handler(&ar->handlers, lb);
}
@@ -208,7 +208,7 @@ static void path_drop_copy(wmDrag *drag, wmDropBox *drop)
static void console_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Console", SPACE_CONSOLE, RGN_TYPE_WINDOW);
-
+
WM_dropbox_add(lb, "CONSOLE_OT_insert", id_drop_poll, id_drop_copy);
WM_dropbox_add(lb, "CONSOLE_OT_insert", path_drop_poll, path_drop_copy);
}
@@ -236,10 +236,10 @@ static void console_main_region_draw(const bContext *C, ARegion *ar)
console_history_verify(C); /* make sure we have some command line */
console_textview_main(sc, ar);
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_GRID_CLAMP);
UI_view2d_scrollers_draw(C, v2d, scrollers);
@@ -255,9 +255,9 @@ static void console_operatortypes(void)
WM_operatortype_append(CONSOLE_OT_indent);
WM_operatortype_append(CONSOLE_OT_unindent);
-
+
/* for use by python only */
- WM_operatortype_append(CONSOLE_OT_history_append);
+ WM_operatortype_append(CONSOLE_OT_history_append);
WM_operatortype_append(CONSOLE_OT_scrollback_append);
WM_operatortype_append(CONSOLE_OT_clear);
@@ -273,7 +273,7 @@ static void console_keymap(struct wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Console", SPACE_CONSOLE, 0);
wmKeyMapItem *kmi;
-
+
#ifdef __APPLE__
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_END);
@@ -281,14 +281,14 @@ static void console_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD);
-
+
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", false);
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", true);
@@ -296,17 +296,17 @@ static void console_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", false);
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", true);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR);
-
+
RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", true);
RNA_boolean_set(WM_keymap_add_item(keymap, "CONSOLE_OT_history_cycle", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "reverse", false);
-
+
#if 0
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD);
@@ -315,7 +315,7 @@ static void console_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_PAGE);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_move", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_PAGE);
#endif
-
+
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR);
RNA_enum_set(WM_keymap_add_item(keymap, "CONSOLE_OT_delete", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", DEL_PREV_CHAR); /* same as above [#26623] */
@@ -331,7 +331,7 @@ static void console_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "interactive", true);
kmi = WM_keymap_add_item(keymap, "CONSOLE_OT_execute", PADENTER, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "interactive", true);
-
+
//WM_keymap_add_item(keymap, "CONSOLE_OT_autocomplete", TABKEY, KM_PRESS, 0, 0); /* python operator - space_text.py */
WM_keymap_add_item(keymap, "CONSOLE_OT_autocomplete", SPACEKEY, KM_PRESS, KM_CTRL, 0); /* python operator - space_text.py */
#endif
@@ -343,7 +343,7 @@ static void console_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CONSOLE_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "CONSOLE_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
#endif
-
+
WM_keymap_add_item(keymap, "CONSOLE_OT_select_set", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CONSOLE_OT_select_word", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
@@ -401,10 +401,10 @@ void ED_spacetype_console(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype console");
ARegionType *art;
-
+
st->spaceid = SPACE_CONSOLE;
strncpy(st->name, "Console", BKE_ST_MAXNAME);
-
+
st->new = console_new;
st->free = console_free;
st->init = console_init;
@@ -412,7 +412,7 @@ void ED_spacetype_console(void)
st->operatortypes = console_operatortypes;
st->keymap = console_keymap;
st->dropboxes = console_dropboxes;
-
+
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype console region");
art->regionid = RGN_TYPE_WINDOW;
@@ -422,20 +422,20 @@ void ED_spacetype_console(void)
art->draw = console_main_region_draw;
art->cursor = console_cursor;
art->listener = console_main_region_listener;
-
-
+
+
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype console region");
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
-
+
art->init = console_header_region_init;
art->draw = console_header_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 75763b53d7f..360009d3ea4 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -86,7 +86,7 @@ static char *file_draw_tooltip_func(bContext *UNUSED(C), void *argN, const char
return BLI_strdup(dyn_tooltip);
}
-/* Note: This function uses pixelspace (0, 0, winx, winy), not view2d.
+/* Note: This function uses pixelspace (0, 0, winx, winy), not view2d.
* The controls are laid out as follows:
*
* -------------------------------------------
@@ -121,14 +121,14 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
int available_w = max_x - min_x;
int line1_w = available_w;
int line2_w = available_w;
-
+
uiBut *but;
uiBlock *block;
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_params(sfile);
ARegion *artmp;
const bool is_browse_only = (sfile->op == NULL);
-
+
/* Initialize UI block. */
BLI_snprintf(uiblockstr, sizeof(uiblockstr), "win %p", (void *)ar);
block = UI_block_begin(C, ar, uiblockstr, UI_EMBOSS);
@@ -212,11 +212,11 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
UI_but_flag_enable(but, UI_BUT_REDALERT);
}
}
-
+
/* clear func */
UI_block_func_set(block, NULL, NULL, NULL);
}
-
+
/* Filename number increment / decrement buttons. */
if (fnumbuttons && (params->flag & FILE_DIRSEL_ONLY) == 0) {
UI_block_align_begin(block);
@@ -233,7 +233,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
RNA_int_set(UI_but_operator_ptr_get(but), "increment", 1);
UI_block_align_end(block);
}
-
+
/* Execute / cancel buttons. */
if (loadbutton) {
const struct FileDirEntry *file = sfile->files ? filelist_file(sfile->files, params->active_file) : NULL;
@@ -254,7 +254,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, IFACE_("Cancel"),
max_x - loadbutton, line2_y, loadbutton, btn_h, "");
}
-
+
UI_block_end(C, block);
UI_block_draw(C, block);
}
@@ -274,10 +274,10 @@ static void file_draw_icon(uiBlock *block, const char *path, int sx, int sy, int
uiBut *but;
int x, y;
// float alpha = 1.0f;
-
+
x = sx;
y = sy - height;
-
+
/*if (icon == ICON_FILE_BLANK) alpha = 0.375f;*/
but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, NULL);
@@ -323,7 +323,7 @@ void file_calc_previews(const bContext *C, ARegion *ar)
{
SpaceFile *sfile = CTX_wm_space_file(C);
View2D *v2d = &ar->v2d;
-
+
ED_fileselect_init_layout(sfile, ar);
UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
}
@@ -424,6 +424,7 @@ static void file_draw_preview(
static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
{
+ Main *bmain = CTX_data_main(C);
char newname[FILE_MAX + 12];
char orgname[FILE_MAX + 12];
char filename[FILE_MAX + 12];
@@ -432,10 +433,11 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- BLI_make_file_string(G.main->name, orgname, sfile->params->dir, oldname);
+ const char *blendfile_path = BKE_main_blendfile_path(bmain);
+ BLI_make_file_string(blendfile_path, orgname, sfile->params->dir, oldname);
BLI_strncpy(filename, sfile->params->renameedit, sizeof(filename));
BLI_filename_make_safe(filename);
- BLI_make_file_string(G.main->name, newname, sfile->params->dir, filename);
+ BLI_make_file_string(blendfile_path, newname, sfile->params->dir, filename);
if (!STREQ(orgname, newname)) {
if (!BLI_exists(newname)) {
@@ -556,11 +558,11 @@ void file_draw_list(const bContext *C, ARegion *ar)
const float thumb_icon_aspect = sqrtf(64.0f / (float)(params->thumbnail_size));
numfiles = filelist_files_ensure(files);
-
+
if (params->display != FILE_IMGDISPLAY) {
draw_background(layout, v2d);
-
+
draw_dividers(layout, v2d);
}
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 977d9fe7f3a..742715039cf 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -109,9 +109,9 @@ void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but);
int file_highlight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my);
void file_sfile_filepath_set(struct SpaceFile *sfile, const char *filepath);
-void file_sfile_to_operator_ex(struct wmOperator *op, struct SpaceFile *sfile, char *filepath);
-void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile);
-void file_operator_to_sfile(struct SpaceFile *sfile, struct wmOperator *op);
+void file_sfile_to_operator_ex(bContext *C, struct wmOperator *op, struct SpaceFile *sfile, char *filepath);
+void file_sfile_to_operator(bContext *C, struct wmOperator *op, struct SpaceFile *sfile);
+void file_operator_to_sfile(bContext *C, struct SpaceFile *sfile, struct wmOperator *op);
/* filesel.c */
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index e5abab12c23..0cd31ce7ca5 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -75,7 +75,7 @@
static FileSelection find_file_mouse_rect(SpaceFile *sfile, ARegion *ar, const rcti *rect_region)
{
FileSelection sel;
-
+
View2D *v2d = &ar->v2d;
rcti rect_view;
rctf rect_view_fl;
@@ -92,7 +92,7 @@ static FileSelection find_file_mouse_rect(SpaceFile *sfile, ARegion *ar, const r
(int)(v2d->tot.ymax - rect_view_fl.ymax));
sel = ED_fileselect_layout_offset_rect(sfile->layout, &rect_view);
-
+
return sel;
}
@@ -101,14 +101,14 @@ static void file_deselect_all(SpaceFile *sfile, unsigned int flag)
FileSelection sel;
sel.first = 0;
sel.last = filelist_files_ensure(sfile->files) - 1;
-
+
filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
}
typedef enum FileSelect {
FILE_SELECT_NOTHING = 0,
- FILE_SELECT_DIR = 1,
- FILE_SELECT_FILE = 2
+ FILE_SELECT_DIR = 1,
+ FILE_SELECT_FILE = 2
} FileSelect;
static void clamp_to_filelist(int numfiles, FileSelection *sel)
@@ -122,7 +122,7 @@ static void clamp_to_filelist(int numfiles, FileSelection *sel)
sel->first = -1;
sel->last = -1;
}
-
+
/* fix if last file invalid */
if ( (sel->first > 0) && (sel->last < 0) )
sel->last = numfiles - 1;
@@ -176,6 +176,7 @@ static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill
static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
{
+ Main *bmain = CTX_data_main(C);
FileSelect retval = FILE_SELECT_NOTHING;
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_params(sfile);
@@ -213,7 +214,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
}
}
else {
- BLI_cleanup_dir(G.main->name, params->dir);
+ BLI_cleanup_dir(BKE_main_blendfile_path(bmain), params->dir);
strcat(params->dir, file->relpath);
BLI_add_slash(params->dir);
}
@@ -298,10 +299,10 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
FileSelect retval = FILE_SELECT_NOTHING;
FileSelection sel = file_selection_get(C, rect, fill); /* get the selection */
const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL;
-
+
/* flag the files as selected in the filelist */
filelist_entries_select_index_range_set(sfile->files, &sel, select, FILE_SEL_SELECTED, check_type);
-
+
/* Don't act on multiple selected files */
if (sel.first != sel.last) select = 0;
@@ -333,7 +334,7 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
/* update operator for name change event */
file_draw_check(C);
-
+
return retval;
}
@@ -460,7 +461,7 @@ void FILE_OT_select_border(wmOperatorType *ot)
ot->name = "Activate/Select File";
ot->description = "Activate/select the file(s) contained in the border";
ot->idname = "FILE_OT_select_border";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = file_border_select_exec;
@@ -529,7 +530,7 @@ void FILE_OT_select(wmOperatorType *ot)
ot->name = "Activate/Select File";
ot->description = "Activate/select file";
ot->idname = "FILE_OT_select";
-
+
/* api callbacks */
ot->invoke = file_select_invoke;
ot->poll = ED_operator_file_active;
@@ -777,7 +778,7 @@ static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op))
const int numfiles = filelist_files_ensure(sfile->files);
const bool has_selection = file_is_any_selected(sfile->files);
- sel.first = 0;
+ sel.first = 0;
sel.last = numfiles - 1;
/* select all only if previously no file was selected */
@@ -813,7 +814,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot)
ot->name = "(De)select All Files";
ot->description = "Select or deselect all files";
ot->idname = "FILE_OT_select_all_toggle";
-
+
/* api callbacks */
ot->exec = file_select_all_exec;
ot->poll = ED_operator_file_active;
@@ -826,6 +827,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot)
/* Note we could get rid of this one, but it's used by some addon so... Does not hurt keeping it around for now. */
static int bookmark_select_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
PropertyRNA *prop;
@@ -835,12 +837,12 @@ static int bookmark_select_exec(bContext *C, wmOperator *op)
RNA_property_string_get(op->ptr, prop, entry);
BLI_strncpy(params->dir, entry, sizeof(params->dir));
- BLI_cleanup_dir(G.main->name, params->dir);
+ BLI_cleanup_dir(BKE_main_blendfile_path(bmain), params->dir);
ED_file_change_dir(C);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -852,7 +854,7 @@ void FILE_OT_select_bookmark(wmOperatorType *ot)
ot->name = "Select Directory";
ot->description = "Select a bookmarked directory";
ot->idname = "FILE_OT_select_bookmark";
-
+
/* api callbacks */
ot->exec = bookmark_select_exec;
ot->poll = ED_operator_file_active;
@@ -871,7 +873,7 @@ static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op))
if (params->dir[0] != '\0') {
char name[FILE_MAX];
-
+
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, NULL, FS_INSERT_SAVE);
BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
@@ -888,7 +890,7 @@ void FILE_OT_bookmark_add(wmOperatorType *ot)
ot->name = "Add Bookmark";
ot->description = "Add a bookmark for the selected/active directory";
ot->idname = "FILE_OT_bookmark_add";
-
+
/* api callbacks */
ot->exec = bookmark_add_exec;
ot->poll = ED_operator_file_active;
@@ -913,7 +915,7 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op)
}
if ((index > -1) && (index < nentries)) {
char name[FILE_MAX];
-
+
fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
@@ -933,7 +935,7 @@ void FILE_OT_bookmark_delete(wmOperatorType *ot)
ot->name = "Delete Bookmark";
ot->description = "Delete selected bookmark";
ot->idname = "FILE_OT_bookmark_delete";
-
+
/* api callbacks */
ot->exec = bookmark_delete_exec;
ot->poll = ED_operator_file_active;
@@ -1080,7 +1082,7 @@ static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op))
ScrArea *sa = CTX_wm_area(C);
char name[FILE_MAX];
struct FSMenu *fsmenu = ED_fsmenu_get();
-
+
while (ED_fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) {
fsmenu_remove_entry(fsmenu, FS_CATEGORY_RECENT, 0);
}
@@ -1097,7 +1099,7 @@ void FILE_OT_reset_recent(wmOperatorType *ot)
ot->name = "Reset Recent";
ot->description = "Reset Recent files";
ot->idname = "FILE_OT_reset_recent";
-
+
/* api callbacks */
ot->exec = reset_recent_exec;
ot->poll = ED_operator_file_active;
@@ -1148,7 +1150,7 @@ static int file_highlight_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
return OPERATOR_CANCELLED;
ED_area_tag_redraw(CTX_wm_area(C));
-
+
return OPERATOR_FINISHED;
}
@@ -1158,7 +1160,7 @@ void FILE_OT_highlight(struct wmOperatorType *ot)
ot->name = "Highlight File";
ot->description = "Highlight selected file(s)";
ot->idname = "FILE_OT_highlight";
-
+
/* api callbacks */
ot->invoke = file_highlight_invoke;
ot->poll = ED_operator_file_active;
@@ -1169,11 +1171,11 @@ int file_cancel_exec(bContext *C, wmOperator *UNUSED(unused))
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
wmOperator *op = sfile->op;
-
+
sfile->op = NULL;
WM_event_fileselect_event(wm, op, EVT_FILESELECT_CANCEL);
-
+
return OPERATOR_FINISHED;
}
@@ -1193,22 +1195,23 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
ot->name = "Cancel File Load";
ot->description = "Cancel loading of selected file";
ot->idname = "FILE_OT_cancel";
-
+
/* api callbacks */
ot->exec = file_cancel_exec;
ot->poll = file_operator_poll;
}
-void file_sfile_to_operator_ex(wmOperator *op, SpaceFile *sfile, char *filepath)
+void file_sfile_to_operator_ex(bContext *C, wmOperator *op, SpaceFile *sfile, char *filepath)
{
+ Main *bmain = CTX_data_main(C);
PropertyRNA *prop;
BLI_join_dirfile(filepath, FILE_MAX, sfile->params->dir, sfile->params->file); /* XXX, not real length */
if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
if (RNA_property_boolean_get(op->ptr, prop)) {
- BLI_path_rel(filepath, G.main->name);
+ BLI_path_rel(filepath, BKE_main_blendfile_path(bmain));
}
}
@@ -1221,7 +1224,7 @@ void file_sfile_to_operator_ex(wmOperator *op, SpaceFile *sfile, char *filepath)
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
RNA_property_string_set(op->ptr, prop, filepath);
}
-
+
/* some ops have multiple files to select */
/* this is called on operators check() so clear collections first since
* they may be already set. */
@@ -1259,7 +1262,7 @@ void file_sfile_to_operator_ex(wmOperator *op, SpaceFile *sfile, char *filepath)
num_dirs++;
}
}
-
+
/* make sure the directory specified in the button is added even if no directory selected */
if (0 == num_dirs) {
RNA_property_collection_add(op->ptr, prop, &itemptr);
@@ -1270,15 +1273,16 @@ void file_sfile_to_operator_ex(wmOperator *op, SpaceFile *sfile, char *filepath)
}
}
-void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile)
+void file_sfile_to_operator(bContext *C, wmOperator *op, SpaceFile *sfile)
{
char filepath[FILE_MAX];
- file_sfile_to_operator_ex(op, sfile, filepath);
+ file_sfile_to_operator_ex(C, op, sfile, filepath);
}
-void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op)
+void file_operator_to_sfile(bContext *C, SpaceFile *sfile, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
PropertyRNA *prop;
/* If neither of the above are set, split the filepath back */
@@ -1295,10 +1299,10 @@ void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op)
RNA_property_string_get(op->ptr, prop, sfile->params->dir);
}
}
-
+
/* we could check for relative_path property which is used when converting
* in the other direction but doesnt hurt to do this every time */
- BLI_path_abs(sfile->params->dir, G.main->name);
+ BLI_path_abs(sfile->params->dir, BKE_main_blendfile_path(bmain));
/* XXX, files and dirs updates missing, not really so important though */
}
@@ -1330,12 +1334,12 @@ void file_draw_check(bContext *C)
wmOperator *op = sfile->op;
if (op) { /* fail on reload */
if (op->type->check) {
- file_sfile_to_operator(op, sfile);
-
+ file_sfile_to_operator(C, op, sfile);
+
/* redraw */
if (op->type->check(C, op)) {
- file_operator_to_sfile(sfile, op);
-
+ file_operator_to_sfile(C, sfile, op);
+
/* redraw, else the changed settings wont get updated */
ED_area_tag_redraw(CTX_wm_area(C));
}
@@ -1369,6 +1373,7 @@ bool file_draw_check_exists(SpaceFile *sfile)
int file_exec(bContext *C, wmOperator *exec_op)
{
+ Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
const struct FileDirEntry *file = filelist_file(sfile->files, sfile->params->active_file);
@@ -1384,7 +1389,7 @@ int file_exec(bContext *C, wmOperator *exec_op)
BLI_parent_dir(sfile->params->dir);
}
else {
- BLI_cleanup_path(G.main->name, sfile->params->dir);
+ BLI_cleanup_path(BKE_main_blendfile_path(bmain), sfile->params->dir);
BLI_path_append(sfile->params->dir, sizeof(sfile->params->dir) - 1, file->relpath);
BLI_add_slash(sfile->params->dir);
}
@@ -1394,13 +1399,13 @@ int file_exec(bContext *C, wmOperator *exec_op)
/* opening file - sends events now, so things get handled on windowqueue level */
else if (sfile->op) {
wmOperator *op = sfile->op;
-
- /* when used as a macro, for doubleclick,
+
+ /* when used as a macro, for doubleclick,
* to prevent closing when doubleclicking on .. item */
if (RNA_boolean_get(exec_op->ptr, "need_active")) {
const int numfiles = filelist_files_ensure(sfile->files);
int i, active = 0;
-
+
for (i = 0; i < numfiles; i++) {
if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
active = 1;
@@ -1410,17 +1415,17 @@ int file_exec(bContext *C, wmOperator *exec_op)
if (active == 0)
return OPERATOR_CANCELLED;
}
-
+
sfile->op = NULL;
- file_sfile_to_operator_ex(op, sfile, filepath);
+ file_sfile_to_operator_ex(C, op, sfile, filepath);
if (BLI_exists(sfile->params->dir)) {
fsmenu_insert_entry(ED_fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, NULL,
FS_INSERT_SAVE | FS_INSERT_FIRST);
}
- BLI_make_file_string(G.main->name, filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
+ BLI_make_file_string(BKE_main_blendfile_path(bmain), filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(ED_fsmenu_get(), filepath);
WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC);
@@ -1438,10 +1443,10 @@ void FILE_OT_execute(struct wmOperatorType *ot)
ot->name = "Execute File Window";
ot->description = "Execute selected file";
ot->idname = "FILE_OT_execute";
-
+
/* api callbacks */
ot->exec = file_exec;
- ot->poll = file_operator_poll;
+ ot->poll = file_operator_poll;
/* properties */
prop = RNA_def_boolean(ot->srna, "need_active", 0, "Need Active",
@@ -1452,11 +1457,12 @@ void FILE_OT_execute(struct wmOperatorType *ot)
int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
{
+ Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
-
+
if (sfile->params) {
if (BLI_parent_dir(sfile->params->dir)) {
- BLI_cleanup_dir(G.main->name, sfile->params->dir);
+ BLI_cleanup_dir(BKE_main_blendfile_path(bmain), sfile->params->dir);
ED_file_change_dir(C);
if (sfile->params->recursion_level > 1) {
/* Disable 'dirtree' recursion when going up in tree. */
@@ -1466,7 +1472,7 @@ int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -1478,7 +1484,7 @@ void FILE_OT_parent(struct wmOperatorType *ot)
ot->name = "Parent File";
ot->description = "Move to parent directory";
ot->idname = "FILE_OT_parent";
-
+
/* api callbacks */
ot->exec = file_parent_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
@@ -1509,7 +1515,7 @@ void FILE_OT_previous(struct wmOperatorType *ot)
ot->name = "Previous Folder";
ot->description = "Move to previous folder";
ot->idname = "FILE_OT_previous";
-
+
/* api callbacks */
ot->exec = file_previous_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
@@ -1540,7 +1546,7 @@ void FILE_OT_next(struct wmOperatorType *ot)
ot->name = "Next Folder";
ot->description = "Move to next folder";
ot->idname = "FILE_OT_next";
-
+
/* api callbacks */
ot->exec = file_next_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
@@ -1581,7 +1587,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
/* escape if not our timer */
if (sfile->smoothscroll_timer == NULL || sfile->smoothscroll_timer != event->customdata)
return OPERATOR_PASS_THROUGH;
-
+
numfiles = filelist_files_ensure(sfile->files);
/* check if we are editing a name */
@@ -1621,9 +1627,9 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->columns;
}
}
-
+
numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, ar);
-
+
/* check if we have reached our final scroll position */
if ( (sfile->scroll_offset >= offset) && (sfile->scroll_offset < offset + numfiles_layout) ) {
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
@@ -1631,10 +1637,10 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
return OPERATOR_FINISHED;
}
- /* temporarily set context to the main window region,
+ /* temporarily set context to the main window region,
* so the scroll operators work */
CTX_wm_region_set(C, ar);
-
+
/* scroll one step in the desired direction */
if (sfile->scroll_offset < offset) {
if (sfile->layout->flag & FILE_LAYOUT_HOR) {
@@ -1643,7 +1649,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
else {
WM_operator_name_call(C, "VIEW2D_OT_scroll_up", 0, NULL);
}
-
+
}
else {
if (sfile->layout->flag & FILE_LAYOUT_HOR) {
@@ -1653,27 +1659,27 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
WM_operator_name_call(C, "VIEW2D_OT_scroll_down", 0, NULL);
}
}
-
+
ED_region_tag_redraw(ar);
-
+
/* and restore context */
CTX_wm_region_set(C, oldar);
-
+
return OPERATOR_FINISHED;
}
void FILE_OT_smoothscroll(wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Smooth Scroll";
ot->idname = "FILE_OT_smoothscroll";
ot->description = "Smooth scroll to make editable file visible";
-
+
/* api callbacks */
ot->invoke = file_smoothscroll_invoke;
-
+
ot->poll = ED_operator_file_active;
}
@@ -1694,7 +1700,7 @@ static int filepath_drop_exec(bContext *C, wmOperator *op)
file_sfile_filepath_set(sfile, filepath);
if (sfile->op) {
- file_sfile_to_operator(sfile->op, sfile);
+ file_sfile_to_operator(C, sfile->op, sfile);
file_draw_check(C);
}
@@ -1749,12 +1755,12 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
ScrArea *sa = CTX_wm_area(C);
-
+
if (!sfile->params) {
BKE_report(op->reports, RPT_WARNING, "No parent directory given");
return OPERATOR_CANCELLED;
}
-
+
path[0] = '\0';
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
@@ -1824,7 +1830,7 @@ void FILE_OT_directory_new(struct wmOperatorType *ot)
ot->name = "Create New Directory";
ot->description = "Create a new directory";
ot->idname = "FILE_OT_directory_new";
-
+
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = file_directory_new_exec;
@@ -1840,12 +1846,13 @@ void FILE_OT_directory_new(struct wmOperatorType *ot)
/* TODO This should go to BLI_path_utils. */
static void file_expand_directory(bContext *C)
{
+ Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
-
+
if (sfile->params) {
if (BLI_path_is_rel(sfile->params->dir)) {
/* Use of 'default' folder here is just to avoid an error message on '//' prefix. */
- BLI_path_abs(sfile->params->dir, G.relbase_valid ? G.main->name : BKE_appdir_folder_default());
+ BLI_path_abs(sfile->params->dir, G.relbase_valid ? BKE_main_blendfile_path(bmain) : BKE_appdir_folder_default());
}
else if (sfile->params->dir[0] == '~') {
char tmpstr[sizeof(sfile->params->dir) - 1];
@@ -1898,8 +1905,9 @@ static bool can_create_dir(const char *dir)
void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UNUSED(arg_but))
{
+ Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
-
+
if (sfile->params) {
file_expand_directory(C);
@@ -1928,7 +1936,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
}
}
- BLI_cleanup_dir(G.main->name, sfile->params->dir);
+ BLI_cleanup_dir(BKE_main_blendfile_path(bmain), sfile->params->dir);
if (filelist_is_dir(sfile->files, sfile->params->dir)) {
/* if directory exists, enter it immediately */
@@ -1975,6 +1983,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg_but)
{
+ Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
uiBut *but = arg_but;
char matched_file[FILE_MAX];
@@ -1995,7 +2004,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
if (matches) {
/* replace the pattern (or filename that the user typed in, with the first selected file of the match */
BLI_strncpy(sfile->params->file, matched_file, sizeof(sfile->params->file));
-
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
@@ -2004,7 +2013,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
/* if directory, open it and empty filename field */
if (filelist_is_dir(sfile->files, filepath)) {
- BLI_cleanup_dir(G.main->name, filepath);
+ BLI_cleanup_dir(BKE_main_blendfile_path(bmain), filepath);
BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir));
sfile->params->file[0] = '\0';
ED_file_change_dir(C);
@@ -2024,7 +2033,7 @@ void FILE_OT_refresh(struct wmOperatorType *ot)
ot->name = "Refresh Filelist";
ot->description = "Refresh the file list";
ot->idname = "FILE_OT_refresh";
-
+
/* api callbacks */
ot->exec = file_refresh_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
@@ -2035,13 +2044,13 @@ static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused))
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
ScrArea *sa = CTX_wm_area(C);
-
+
if (sfile->params) {
sfile->params->flag ^= FILE_HIDE_DOT;
ED_fileselect_clear(wm, sa, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -2052,7 +2061,7 @@ void FILE_OT_hidedot(struct wmOperatorType *ot)
ot->name = "Toggle Hide Dot Files";
ot->description = "Toggle hide hidden dot files";
ot->idname = "FILE_OT_hidedot";
-
+
/* api callbacks */
ot->exec = file_hidedot_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
@@ -2067,11 +2076,11 @@ ARegion *file_tools_region(ScrArea *sa)
/* add subdiv level; after header */
ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
-
+
/* is error! */
if (ar == NULL)
return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "tools for file");
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_TOOLS;
@@ -2089,7 +2098,7 @@ static int file_bookmark_toggle_exec(bContext *C, wmOperator *UNUSED(unused))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = file_tools_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -2102,7 +2111,7 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot)
ot->name = "Toggle Bookmarks";
ot->description = "Toggle bookmarks display";
ot->idname = "FILE_OT_bookmark_toggle";
-
+
/* api callbacks */
ot->exec = file_bookmark_toggle_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
@@ -2144,7 +2153,7 @@ static int file_filenum_exec(bContext *C, wmOperator *op)
{
SpaceFile *sfile = CTX_wm_space_file(C);
ScrArea *sa = CTX_wm_area(C);
-
+
int inc = RNA_int_get(op->ptr, "increment");
if (sfile->params && (inc != 0)) {
filenum_newname(sfile->params->file, sizeof(sfile->params->file), inc);
@@ -2152,7 +2161,7 @@ static int file_filenum_exec(bContext *C, wmOperator *op)
file_draw_check(C);
// WM_event_add_notifier(C, NC_WINDOW, NULL);
}
-
+
return OPERATOR_FINISHED;
}
@@ -2163,7 +2172,7 @@ void FILE_OT_filenum(struct wmOperatorType *ot)
ot->name = "Increment Number in Filename";
ot->description = "Increment number in filename";
ot->idname = "FILE_OT_filenum";
-
+
/* api callbacks */
ot->exec = file_filenum_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
@@ -2176,7 +2185,7 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
-
+
if (sfile->params) {
int idx = sfile->params->highlight_file;
int numfiles = filelist_files_ensure(sfile->files);
@@ -2188,7 +2197,7 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op))
}
ED_area_tag_redraw(sa);
}
-
+
return OPERATOR_FINISHED;
}
@@ -2232,10 +2241,10 @@ void FILE_OT_rename(struct wmOperatorType *ot)
ot->name = "Rename File or Directory";
ot->description = "Rename file or file directory";
ot->idname = "FILE_OT_rename";
-
+
/* api callbacks */
ot->exec = file_rename_exec;
- ot->poll = file_rename_poll;
+ ot->poll = file_rename_poll;
}
@@ -2262,13 +2271,14 @@ static int file_delete_poll(bContext *C)
}
else
poll = 0;
-
+
return poll;
}
int file_delete_exec(bContext *C, wmOperator *op)
{
char str[FILE_MAX];
+ Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
ScrArea *sa = CTX_wm_area(C);
@@ -2281,7 +2291,7 @@ int file_delete_exec(bContext *C, wmOperator *op)
for (i = 0; i < numfiles; i++) {
if (filelist_entry_select_index_get(sfile->files, i, CHECK_FILES)) {
file = filelist_file(sfile->files, i);
- BLI_make_file_string(G.main->name, str, sfile->params->dir, file->relpath);
+ BLI_make_file_string(BKE_main_blendfile_path(bmain), str, sfile->params->dir, file->relpath);
if (BLI_delete(str, false, false) != 0 ||
BLI_exists(str))
{
@@ -2289,7 +2299,7 @@ int file_delete_exec(bContext *C, wmOperator *op)
}
}
}
-
+
if (report_error) {
BKE_reportf(op->reports, RPT_ERROR,
"Could not delete file: %s",
@@ -2298,7 +2308,7 @@ int file_delete_exec(bContext *C, wmOperator *op)
ED_fileselect_clear(wm, sa, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2309,7 +2319,7 @@ void FILE_OT_delete(struct wmOperatorType *ot)
ot->name = "Delete Selected Files";
ot->description = "Delete selected files";
ot->idname = "FILE_OT_delete";
-
+
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = file_delete_exec;
@@ -2321,6 +2331,6 @@ void ED_operatormacros_file(void)
{
// wmOperatorType *ot;
// wmOperatorTypeMacro *otmacro;
-
+
/* future macros */
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 343d09bd81c..8123bed541c 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -43,7 +43,7 @@
#else
# include <io.h>
# include <direct.h>
-#endif
+#endif
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -188,13 +188,13 @@ void folderlist_free(ListBase *folderlist)
ListBase *folderlist_duplicate(ListBase *folderlist)
{
-
+
if (folderlist) {
ListBase *folderlistn = MEM_callocN(sizeof(*folderlistn), __func__);
FolderList *folder;
-
+
BLI_duplicatelist(folderlistn, folderlist);
-
+
for (folder = folderlistn->first; folder; folder = folder->next) {
folder->foldername = MEM_dupallocN(folder->foldername);
}
@@ -404,7 +404,7 @@ static int compare_direntry_generic(const FileListInternEntry *entry1, const Fil
if (FILENAME_IS_CURRENT(entry2->relpath)) return 1;
if (FILENAME_IS_PARENT(entry1->relpath)) return -1;
if (FILENAME_IS_PARENT(entry2->relpath)) return 1;
-
+
return 0;
}
@@ -436,7 +436,7 @@ static int compare_date(void *UNUSED(user_data), const void *a1, const void *a2)
if ((ret = compare_direntry_generic(entry1, entry2))) {
return ret;
}
-
+
time1 = (int64_t)entry1->st.st_mtime;
time2 = (int64_t)entry2->st.st_mtime;
if (time1 < time2) return 1;
@@ -459,7 +459,7 @@ static int compare_size(void *UNUSED(user_data), const void *a1, const void *a2)
if ((ret = compare_direntry_generic(entry1, entry2))) {
return ret;
}
-
+
size1 = entry1->st.st_size;
size2 = entry2->st.st_size;
if (size1 < size2) return 1;
@@ -1347,7 +1347,7 @@ void filelist_free(struct FileList *filelist)
printf("Attempting to delete empty filelist.\n");
return;
}
-
+
filelist_clear_ex(filelist, false, false); /* No need to clear cache & selection_state, we free them anyway. */
filelist_cache_free(&filelist->filelist_cache);
@@ -1419,7 +1419,7 @@ void filelist_setdir(struct FileList *filelist, char *r_dir)
{
BLI_assert(strlen(r_dir) < FILE_MAX_LIBEXTRA);
- BLI_cleanup_dir(G.main->name, r_dir);
+ BLI_cleanup_dir(BKE_main_blendfile_path_from_global(), r_dir);
const bool is_valid_path = filelist->checkdirf(filelist, r_dir, true);
BLI_assert(is_valid_path);
UNUSED_VARS_NDEBUG(is_valid_path);
@@ -1555,7 +1555,7 @@ FileDirEntry *filelist_file(struct FileList *filelist, int index)
int filelist_file_findpath(struct FileList *filelist, const char *filename)
{
int fidx = -1;
-
+
if (filelist->filelist.nbr_entries_filtered < 0) {
return fidx;
}
@@ -1950,17 +1950,17 @@ static bool file_is_blend_backup(const char *str)
}
else {
const char *loc;
-
+
if (a > b + 1)
b++;
-
+
/* allow .blend1 .blend2 .blend32 */
loc = BLI_strcasestr(str + a - b, ".blend");
-
+
if (loc)
retval = 1;
}
-
+
return (retval);
}
@@ -2024,7 +2024,7 @@ static int file_extension_type(const char *dir, const char *relpath)
int ED_file_extension_icon(const char *path)
{
const int type = ED_path_extension_type(path);
-
+
switch (type) {
case FILE_TYPE_BLENDER:
return ICON_FILE_BLEND;
@@ -2313,13 +2313,13 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const
#if 0
/* Kept for reference here, in case we want to add back that feature later. We do not need it currently. */
/* Code ***NOT*** updated for job stuff! */
-static void filelist_readjob_main_rec(struct FileList *filelist)
+static void filelist_readjob_main_rec(Main *bmain, FileList *filelist)
{
ID *id;
FileDirEntry *files, *firstlib = NULL;
ListBase *lb;
int a, fake, idcode, ok, totlib, totbl;
-
+
// filelist->type = FILE_MAIN; // XXX TODO: add modes to filebrowser
BLI_assert(filelist->filelist.entries == NULL);
@@ -2375,7 +2375,7 @@ static void filelist_readjob_main_rec(struct FileList *filelist)
/* make files */
idcode = groupname_to_code(filelist->filelist.root);
- lb = which_libbase(G.main, idcode);
+ lb = which_libbase(bmain, idcode);
if (lb == NULL) return;
filelist->filelist.nbr_entries = 0;
@@ -2394,7 +2394,7 @@ static void filelist_readjob_main_rec(struct FileList *filelist)
}
files = filelist->filelist.entries;
-
+
if (!(filelist->filter_data.flags & FLF_HIDE_PARENT)) {
files->entry->relpath = BLI_strdup(FILENAME_PARENT);
files->typeflag |= FILE_TYPE_DIR;
@@ -2700,13 +2700,14 @@ static void filelist_readjob_free(void *flrjv)
void filelist_readjob_start(FileList *filelist, const bContext *C)
{
+ Main *bmain = CTX_data_main(C);
wmJob *wm_job;
FileListReadJob *flrj;
/* prepare job data */
flrj = MEM_callocN(sizeof(*flrj), __func__);
flrj->filelist = filelist;
- BLI_strncpy(flrj->main_name, G.main->name, sizeof(flrj->main_name));
+ BLI_strncpy(flrj->main_name, BKE_main_blendfile_path(bmain), sizeof(flrj->main_name));
filelist->flags &= ~(FL_FORCE_RESET | FL_IS_READY);
filelist->flags |= FL_IS_PENDING;
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 6536dc77f77..418a9f8c16f 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -96,11 +96,13 @@ short ED_fileselect_set_params(SpaceFile *sfile)
FileSelectParams *params;
wmOperator *op = sfile->op;
+ const char *blendfile_path = BKE_main_blendfile_path_from_global();
+
/* create new parameters if necessary */
if (!sfile->params) {
sfile->params = MEM_callocN(sizeof(FileSelectParams), "fileselparams");
/* set path to most recently opened .blend */
- BLI_split_dirfile(G.main->name, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file));
+ BLI_split_dirfile(blendfile_path, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file));
sfile->params->filter_glob[0] = '\0';
/* set the default thumbnails size */
sfile->params->thumbnail_size = 128;
@@ -149,8 +151,8 @@ short ED_fileselect_set_params(SpaceFile *sfile)
}
if (params->dir[0]) {
- BLI_cleanup_dir(G.main->name, params->dir);
- BLI_path_abs(params->dir, G.main->name);
+ BLI_cleanup_dir(blendfile_path, params->dir);
+ BLI_path_abs(params->dir, blendfile_path);
}
if (is_directory == true && is_filename == false && is_filepath == false && is_files == false) {
@@ -224,7 +226,7 @@ short ED_fileselect_set_params(SpaceFile *sfile)
else {
params->flag &= ~FILE_HIDE_DOT;
}
-
+
if (params->type == FILE_LOADLIB) {
params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0;
@@ -283,8 +285,8 @@ short ED_fileselect_set_params(SpaceFile *sfile)
sfile->folders_prev = folderlist_new();
if (!sfile->params->dir[0]) {
- if (G.main->name[0]) {
- BLI_split_dir_part(G.main->name, sfile->params->dir, sizeof(sfile->params->dir));
+ if (blendfile_path[0] != '\0') {
+ BLI_split_dir_part(blendfile_path, sfile->params->dir, sizeof(sfile->params->dir));
}
else {
const char *doc_path = BKE_appdir_folder_default();
@@ -366,12 +368,12 @@ FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const rcti *r
if (layout == NULL)
return sel;
-
+
colmin = (rect->xmin) / (layout->tile_w + 2 * layout->tile_border_x);
rowmin = (rect->ymin) / (layout->tile_h + 2 * layout->tile_border_y);
colmax = (rect->xmax) / (layout->tile_w + 2 * layout->tile_border_x);
rowmax = (rect->ymax) / (layout->tile_h + 2 * layout->tile_border_y);
-
+
if (is_inside(colmin, rowmin, layout->columns, layout->rows) ||
is_inside(colmax, rowmax, layout->columns, layout->rows) )
{
@@ -380,12 +382,12 @@ FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const rcti *r
CLAMP(colmax, 0, layout->columns - 1);
CLAMP(rowmax, 0, layout->rows - 1);
}
-
+
if ((colmin > layout->columns - 1) || (rowmin > layout->rows - 1)) {
sel.first = -1;
}
else {
- if (layout->flag & FILE_LAYOUT_HOR)
+ if (layout->flag & FILE_LAYOUT_HOR)
sel.first = layout->rows * colmin + rowmin;
else
sel.first = colmin + layout->columns * rowmin;
@@ -394,7 +396,7 @@ FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const rcti *r
sel.last = -1;
}
else {
- if (layout->flag & FILE_LAYOUT_HOR)
+ if (layout->flag & FILE_LAYOUT_HOR)
sel.last = layout->rows * colmax + rowmax;
else
sel.last = colmax + layout->columns * rowmax;
@@ -410,14 +412,14 @@ int ED_fileselect_layout_offset(FileLayout *layout, int x, int y)
if (layout == NULL)
return -1;
-
+
offsetx = (x) / (layout->tile_w + 2 * layout->tile_border_x);
offsety = (y) / (layout->tile_h + 2 * layout->tile_border_y);
-
+
if (offsetx > layout->columns - 1) return -1;
if (offsety > layout->rows - 1) return -1;
-
- if (layout->flag & FILE_LAYOUT_HOR)
+
+ if (layout->flag & FILE_LAYOUT_HOR)
active_file = layout->rows * offsetx + offsety;
else
active_file = offsetx + layout->columns * offsety;
@@ -611,12 +613,12 @@ void ED_file_change_dir(bContext *C)
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file)
{
int match = 0;
-
+
int i;
FileDirEntry *file;
int n = filelist_files_ensure(sfile->files);
- /* select any file that matches the pattern, this includes exact match
+ /* select any file that matches the pattern, this includes exact match
* if the user selects a single file by entering the filename
*/
for (i = 0; i < n; i++) {
@@ -645,7 +647,7 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
DIR *dir;
struct dirent *de;
-
+
BLI_split_dir_part(str, dirname, sizeof(dirname));
dir = opendir(dirname);
@@ -660,7 +662,7 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
else {
char path[FILE_MAX];
BLI_stat_t status;
-
+
BLI_join_dirfile(path, sizeof(path), dirname, de->d_name);
if (BLI_stat(path, &status) == 0) {
@@ -726,7 +728,7 @@ void ED_fileselect_exit(wmWindowManager *wm, ScrArea *sa, SpaceFile *sfile)
folderlist_free(sfile->folders_prev);
folderlist_free(sfile->folders_next);
-
+
if (sfile->files) {
ED_fileselect_clear(wm, sa, sfile);
filelist_free(sfile->files);
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index ea251f2018c..5ecb95bf61b 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -350,7 +350,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx
idx--;
if (fsm_iter) {
- /* you should only be able to remove entries that were
+ /* you should only be able to remove entries that were
* not added by default, like windows drives.
* also separators (where path == NULL) shouldn't be removed */
if (fsm_iter->save && fsm_iter->path) {
@@ -510,18 +510,18 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
/* Get mounted volumes better method OSX 10.6 and higher, see: */
/*https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html*/
/* we get all volumes sorted including network and do not relay on user-defined finder visibility, less confusing */
-
+
CFURLRef cfURL = NULL;
CFURLEnumeratorResult result = kCFURLEnumeratorSuccess;
CFURLEnumeratorRef volEnum = CFURLEnumeratorCreateForMountedVolumes(NULL, kCFURLEnumeratorSkipInvisibles, NULL);
-
+
while (result != kCFURLEnumeratorEnd) {
char defPath[FILE_MAX];
result = CFURLEnumeratorGetNextURL(volEnum, &cfURL, NULL);
if (result != kCFURLEnumeratorSuccess)
continue;
-
+
CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX);
/* Add end slash for consistency with other platforms */
@@ -529,29 +529,29 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, defPath, NULL, FS_INSERT_SORTED);
}
-
+
CFRelease(volEnum);
-
+
/* Finally get user favorite places */
if (read_bookmarks) {
UInt32 seed;
LSSharedFileListRef list = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteItems, NULL);
CFArrayRef pathesArray = LSSharedFileListCopySnapshot(list, &seed);
CFIndex pathesCount = CFArrayGetCount(pathesArray);
-
+
for (CFIndex i = 0; i < pathesCount; i++) {
LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(pathesArray, i);
-
+
CFURLRef cfURL = NULL;
- OSErr err = LSSharedFileListItemResolve(itemRef,
+ OSErr err = LSSharedFileListItemResolve(itemRef,
kLSSharedFileListNoUserInteraction |
kLSSharedFileListDoNotMountVolumes,
&cfURL, NULL);
if (err != noErr || !cfURL)
continue;
-
+
CFStringRef pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
-
+
if (pathString == NULL || !CFStringGetCString(pathString, line, sizeof(line), kCFStringEncodingUTF8))
continue;
@@ -563,11 +563,11 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_LAST);
}
-
+
CFRelease(pathString);
CFRelease(cfURL);
}
-
+
CFRelease(pathesArray);
CFRelease(list);
}
diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h
index 83ce4776a66..85804538e19 100644
--- a/source/blender/editors/space_file/fsmenu.h
+++ b/source/blender/editors/space_file/fsmenu.h
@@ -60,7 +60,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, enum FSMenuCategory category,
/** saves the 'bookmarks' to the specified file */
void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename);
-
+
/** reads the 'bookmarks' from the specified file */
void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename);
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index c647ec78270..62e7c7923e8 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -115,9 +115,9 @@ static SpaceLink *file_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
/* not spacelink itself */
static void file_free(SpaceLink *sl)
-{
+{
SpaceFile *sfile = (SpaceFile *) sl;
-
+
BLI_assert(sfile->previews_timer == NULL);
if (sfile->files) {
@@ -185,7 +185,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
{
SpaceFile *sfileo = (SpaceFile *)sl;
SpaceFile *sfilen = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
sfilen->op = NULL; /* file window doesn't own operators */
@@ -203,7 +203,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
if (sfileo->folders_next)
sfilen->folders_next = folderlist_duplicate(sfileo->folders_next);
-
+
if (sfileo->layout) {
sfilen->layout = MEM_dupallocN(sfileo->layout);
}
@@ -326,9 +326,9 @@ static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sce
static void file_main_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-
+
/* own keymaps */
keymap = WM_keymap_find(wm->defaultconf, "File Browser", SPACE_FILE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -410,9 +410,9 @@ static void file_main_region_draw(const bContext *C, ARegion *ar)
UI_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
-
+
/* Allow dynamically sliders to be set, saves notifiers etc. */
-
+
if (params->display == FILE_IMGDISPLAY) {
v2d->scroll = V2D_SCROLL_RIGHT;
v2d->keepofs &= ~V2D_LOCKOFS_Y;
@@ -422,7 +422,7 @@ static void file_main_region_draw(const bContext *C, ARegion *ar)
v2d->scroll = V2D_SCROLL_BOTTOM;
v2d->keepofs &= ~V2D_LOCKOFS_X;
v2d->keepofs |= V2D_LOCKOFS_Y;
-
+
/* XXX this happens on scaling down Screen (like from startup.blend) */
/* view2d has no type specific for filewindow case, which doesnt scroll vertically */
if (v2d->cur.ymax < 0) {
@@ -438,18 +438,18 @@ static void file_main_region_draw(const bContext *C, ARegion *ar)
/* set view */
UI_view2d_view_ortho(v2d);
-
+
/* on first read, find active file */
if (params->highlight_file == -1) {
wmEvent *event = CTX_wm_window(C)->eventstate;
file_highlight_set(sfile, ar, event->x, event->y);
}
-
+
file_draw_list(C, ar);
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
@@ -603,8 +603,8 @@ static void file_keymap(struct wmKeyConfig *keyconf)
RNA_int_set(kmi->ptr, "increment", -10);
kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADMINUS, KM_PRESS, KM_CTRL, 0);
RNA_int_set(kmi->ptr, "increment", -100);
-
-
+
+
/* keys for button region (top) */
keymap = WM_keymap_find(keyconf, "File Browser Buttons", SPACE_FILE, 0);
kmi = WM_keymap_add_item(keymap, "FILE_OT_filenum", PADPLUSKEY, KM_PRESS, 0, 0);
@@ -655,9 +655,9 @@ static void file_tools_region_listener(
static void file_header_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
ED_region_header_init(ar);
-
+
keymap = WM_keymap_find(wm->defaultconf, "File Browser", SPACE_FILE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -748,10 +748,10 @@ void ED_spacetype_file(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype file");
ARegionType *art;
-
+
st->spaceid = SPACE_FILE;
strncpy(st->name, "File", BKE_ST_MAXNAME);
-
+
st->new = file_new;
st->free = file_free;
st->init = file_init;
@@ -772,7 +772,7 @@ void ED_spacetype_file(void)
art->message_subscribe = file_main_region_message_subscribe;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
art->regionid = RGN_TYPE_HEADER;
@@ -782,7 +782,7 @@ void ED_spacetype_file(void)
art->draw = file_header_region_draw;
// art->listener = file_header_region_listener;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: ui */
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
art->regionid = RGN_TYPE_UI;
@@ -843,7 +843,7 @@ void ED_file_exit(void)
void ED_file_read_bookmarks(void)
{
const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
-
+
fsmenu_free();
fsmenu_read_system(ED_fsmenu_get(), true);
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index e96749b8e4d..706beb9784a 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -81,25 +81,25 @@ static int graph_panel_context(const bContext *C, bAnimListElem **ale, FCurve **
{
bAnimContext ac;
bAnimListElem *elem = NULL;
-
- /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
+
+ /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
* to work correctly is able to be correctly retrieved. There's no point showing empty panels?
*/
- if (ANIM_animdata_get_context(C, &ac) == 0)
+ if (ANIM_animdata_get_context(C, &ac) == 0)
return 0;
-
+
/* try to find 'active' F-Curve */
elem = get_active_fcurve_channel(&ac);
- if (elem == NULL)
+ if (elem == NULL)
return 0;
-
+
if (fcu)
*fcu = (FCurve *)elem->data;
if (ale)
*ale = elem;
else
MEM_freeN(elem);
-
+
return 1;
}
@@ -118,7 +118,7 @@ static void graph_panel_view(const bContext *C, Panel *pa)
Scene *scene = CTX_data_scene(C);
PointerRNA spaceptr, sceneptr;
uiLayout *col, *sub, *row;
-
+
/* get RNA pointers for use when creating the UI elements */
RNA_id_pointer_create(&scene->id, &sceneptr);
RNA_pointer_create(&sc->id, &RNA_SpaceGraphEditor, sipo, &spaceptr);
@@ -126,7 +126,7 @@ static void graph_panel_view(const bContext *C, Panel *pa)
/* 2D-Cursor */
col = uiLayoutColumn(pa->layout, false);
uiItemR(col, &spaceptr, "show_cursor", 0, NULL, ICON_NONE);
-
+
sub = uiLayoutColumn(col, true);
uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
uiItemO(sub, IFACE_("Cursor from Selection"), ICON_NONE, "GRAPH_OT_frame_jump");
@@ -139,7 +139,7 @@ static void graph_panel_view(const bContext *C, Panel *pa)
else
uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE);
uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA);
-
+
row = uiLayoutSplit(sub, 0.7f, true);
uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE);
uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE);
@@ -159,10 +159,10 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
if (!graph_panel_context(C, &ale, &fcu))
return;
-
+
/* F-Curve pointer */
RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
-
+
/* user-friendly 'name' for F-Curve */
col = uiLayoutColumn(layout, false);
if (ale->type == ANIMTYPE_FCURVE) {
@@ -172,7 +172,7 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
else {
/* NLA Control Curve, etc. */
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
+
/* get name */
if (acf && acf->name) {
acf->name(ale, name);
@@ -181,35 +181,35 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
strcpy(name, IFACE_("<invalid>"));
icon = ICON_ERROR;
}
-
+
/* icon */
if (ale->type == ANIMTYPE_NLACURVE)
icon = ICON_NLA;
}
uiItemL(col, name, icon);
-
+
/* RNA-Path Editing - only really should be enabled when things aren't working */
col = uiLayoutColumn(layout, true);
uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED) != 0);
uiItemR(col, &fcu_ptr, "data_path", 0, "", ICON_RNA);
uiItemR(col, &fcu_ptr, "array_index", 0, NULL, ICON_NONE);
-
+
/* color settings */
col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Display Color:"), ICON_NONE);
-
+
row = uiLayoutRow(col, true);
uiItemR(row, &fcu_ptr, "color_mode", 0, "", ICON_NONE);
-
+
sub = uiLayoutRow(row, true);
uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
-
+
/* smoothing setting */
col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Auto Handle Smoothing:"), ICON_NONE);
uiItemR(col, &fcu_ptr, "auto_smoothing", 0, "", ICON_NONE);
-
+
MEM_freeN(ale);
}
@@ -220,31 +220,31 @@ static short get_active_fcurve_keyframe_edit(FCurve *fcu, BezTriple **bezt, BezT
{
BezTriple *b;
int i;
-
+
/* zero the pointers */
*bezt = *prevbezt = NULL;
-
+
/* sanity checks */
if ((fcu->bezt == NULL) || (fcu->totvert == 0))
return 0;
-
- /* find first selected keyframe for now, and call it the active one
- * - this is a reasonable assumption, given that whenever anyone
+
+ /* find first selected keyframe for now, and call it the active one
+ * - this is a reasonable assumption, given that whenever anyone
* wants to edit numerically, there is likely to only be 1 vert selected
*/
for (i = 0, b = fcu->bezt; i < fcu->totvert; i++, b++) {
if (BEZT_ISSEL_ANY(b)) {
- /* found
+ /* found
* - 'previous' is either the one before, of the keyframe itself (which is still fine)
* XXX: we can just make this null instead if needed
*/
*prevbezt = (i > 0) ? b - 1 : b;
*bezt = b;
-
+
return 1;
}
}
-
+
/* not found */
return 0;
}
@@ -253,7 +253,7 @@ static short get_active_fcurve_keyframe_edit(FCurve *fcu, BezTriple **bezt, BezT
static void graphedit_activekey_update_cb(bContext *UNUSED(C), void *fcu_ptr, void *UNUSED(bezt_ptr))
{
FCurve *fcu = (FCurve *)fcu_ptr;
-
+
/* make sure F-Curve and its handles are still valid after this editing */
sort_time_fcurve(fcu);
calchandles_fcurve(fcu);
@@ -263,8 +263,8 @@ static void graphedit_activekey_update_cb(bContext *UNUSED(C), void *fcu_ptr, vo
static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
{
BezTriple *bezt = (BezTriple *)bezt_ptr;
-
- /* since editing the handles, make sure they're set to types which are receptive to editing
+
+ /* since editing the handles, make sure they're set to types which are receptive to editing
* see transform_conversions.c :: createTransGraphEditData(), last step in second loop
*/
if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
@@ -275,7 +275,7 @@ static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bez
else {
BKE_nurb_bezt_handle_test(bezt, true);
}
-
+
/* now call standard updates */
graphedit_activekey_update_cb(C, fcu_ptr, bezt_ptr);
}
@@ -305,20 +305,20 @@ static void graphedit_activekey_left_handle_coord_cb(bContext *C, void *fcu_ptr,
static void graphedit_activekey_right_handle_coord_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
{
BezTriple *bezt = (BezTriple *)bezt_ptr;
-
+
/* original state of handle selection - to be restored after performing the recalculation */
const char f1 = bezt->f1;
const char f3 = bezt->f3;
-
- /* temporarily make it so that only the right handle is selected, so that updates go correctly
+
+ /* temporarily make it so that only the right handle is selected, so that updates go correctly
* (i.e. it now acts as if we've just transforming the vert when it is selected by itself)
*/
bezt->f1 &= ~SELECT;
bezt->f3 |= SELECT;
-
+
/* perform normal updates NOW */
graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
-
+
/* restore selection state so that no-one notices this hack */
bezt->f1 = f1;
bezt->f3 = f3;
@@ -329,34 +329,34 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
bAnimListElem *ale;
FCurve *fcu;
BezTriple *bezt, *prevbezt;
-
+
uiLayout *layout = pa->layout;
uiLayout *col;
uiBlock *block;
if (!graph_panel_context(C, &ale, &fcu))
return;
-
+
block = uiLayoutGetBlock(layout);
/* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */
-
+
/* only show this info if there are keyframes to edit */
if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
PropertyRNA *fcu_prop = NULL;
uiBut *but;
int unit = B_UNIT_NONE;
-
+
/* RNA pointer to keyframe, to allow editing */
RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
-
+
/* get property that F-Curve affects, for some unit-conversion magic */
RNA_id_pointer_create(ale->id, &id_ptr);
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop)) {
/* determine the unit for this property */
unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
}
-
+
/* interpolation */
col = uiLayoutColumn(layout, false);
if (fcu->flag & FCURVE_DISCRETE_VALUES) {
@@ -367,7 +367,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
else {
uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
}
-
+
/* easing type */
if (bezt->ipo > BEZT_IPO_BEZ)
uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);
@@ -386,8 +386,8 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
default:
break;
}
-
- /* numerical coordinate editing
+
+ /* numerical coordinate editing
* - we use the button-versions of the calls so that we can attach special update handlers
* and unit conversion magic that cannot be achieved using a purely RNA-approach
*/
@@ -395,50 +395,50 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
/* keyframe itself */
{
uiItemL(col, IFACE_("Key:"), ICON_NONE);
-
+
but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
-
+
but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
UI_but_unit_type_set(but, unit);
}
-
+
/* previous handle - only if previous was Bezier interpolation */
if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);
-
+
but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
-
+
but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
UI_but_unit_type_set(but, unit);
-
+
/* XXX: with label? */
but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_left_type", 0, 0, 0, -1, -1, "Type of left handle");
UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
}
-
+
/* next handle - only if current is Bezier interpolation */
if (bezt->ipo == BEZT_IPO_BEZ) {
/* NOTE: special update callbacks are needed on the coords here due to T39911 */
uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
-
+
but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
-
+
but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
UI_but_unit_type_set(but, unit);
-
+
/* XXX: with label? */
but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right_type", 0, 0, 0, -1, -1, "Type of right handle");
@@ -459,7 +459,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
else
uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
}
-
+
MEM_freeN(ale);
}
@@ -471,26 +471,26 @@ static void do_graph_region_driver_buttons(bContext *C, void *fcu_v, int event)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
-
+
switch (event) {
case B_IPO_DEPCHANGE:
{
/* force F-Curve & Driver to get re-evaluated (same as the old Update Dependencies) */
FCurve *fcu = (FCurve *)fcu_v;
ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
-
+
/* clear invalid flags */
if (fcu) {
fcu->flag &= ~FCURVE_DISABLED;
driver->flag &= ~DRIVER_FLAG_INVALID;
}
-
+
/* rebuild depsgraph for the new deps */
DEG_relations_tag_update(bmain);
break;
}
}
-
+
/* default for now */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); // XXX could use better notifier
}
@@ -499,7 +499,7 @@ static void do_graph_region_driver_buttons(bContext *C, void *fcu_v, int event)
static void driver_add_var_cb(bContext *C, void *driver_v, void *UNUSED(arg))
{
ChannelDriver *driver = (ChannelDriver *)driver_v;
-
+
/* add a new variable */
driver_add_new_variable(driver);
ED_undo_push(C, "Add Driver Variable");
@@ -510,7 +510,7 @@ static void driver_delete_var_cb(bContext *C, void *driver_v, void *dvar_v)
{
ChannelDriver *driver = (ChannelDriver *)driver_v;
DriverVar *dvar = (DriverVar *)dvar_v;
-
+
/* remove the active variable */
driver_free_variable_ex(driver, dvar);
ED_undo_push(C, "Delete Driver Variable");
@@ -521,9 +521,9 @@ static void driver_dvar_invalid_name_query_cb(bContext *C, void *dvar_v, void *U
{
uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Invalid Variable Name"), ICON_NONE);
uiLayout *layout = UI_popup_menu_layout(pup);
-
+
DriverVar *dvar = (DriverVar *)dvar_v;
-
+
if (dvar->flag & DVAR_FLAG_INVALID_EMPTY) {
uiItemL(layout, "It cannot be left blank", ICON_ERROR);
}
@@ -531,7 +531,7 @@ static void driver_dvar_invalid_name_query_cb(bContext *C, void *dvar_v, void *U
uiItemL(layout, "It cannot start with a number", ICON_ERROR);
}
if (dvar->flag & DVAR_FLAG_INVALID_START_CHAR) {
- uiItemL(layout,
+ uiItemL(layout,
"It cannot start with a special character,"
" including '$', '@', '!', '~', '+', '-', '_', '.', or ' '",
ICON_NONE);
@@ -548,7 +548,7 @@ static void driver_dvar_invalid_name_query_cb(bContext *C, void *dvar_v, void *U
if (dvar->flag & DVAR_FLAG_INVALID_PY_KEYWORD) {
uiItemL(layout, "It cannot be a reserved keyword in Python", ICON_INFO);
}
-
+
UI_popup_menu_end(C, pup);
}
@@ -557,7 +557,7 @@ static void driver_update_flags_cb(bContext *UNUSED(C), void *fcu_v, void *UNUSE
{
FCurve *fcu = (FCurve *)fcu_v;
ChannelDriver *driver = fcu->driver;
-
+
/* clear invalid flags */
fcu->flag &= ~FCURVE_DISABLED;
driver->flag &= ~DRIVER_FLAG_INVALID;
@@ -580,22 +580,22 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa
DriverTarget *dtar = &dvar->targets[0];
PointerRNA dtar_ptr;
uiLayout *row, *col;
-
+
/* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
-
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+
/* Target ID */
row = uiLayoutRow(layout, false);
uiLayoutSetRedAlert(row, ((dtar->flag & DTAR_FLAG_INVALID) && !dtar->id));
uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:"));
-
+
/* Target Property */
if (dtar->id) {
PointerRNA root_ptr;
-
+
/* get pointer for resolving the property selected */
RNA_id_pointer_create(dtar->id, &root_ptr);
-
+
/* rna path */
col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID));
@@ -652,23 +652,23 @@ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *
Object *ob2 = (Object *)dtar2->id;
PointerRNA dtar_ptr, dtar2_ptr;
uiLayout *col;
-
+
/* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
- RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
/* Object 1 */
col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
-
+
if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
PointerRNA tar_ptr;
-
+
RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
}
-
+
uiLayoutSetRedAlert(col, false); /* we can clear it again now - it's only needed when creating the ID/Bone fields */
uiItemR(col, &dtar_ptr, "transform_space", 0, NULL, ICON_NONE);
@@ -676,14 +676,14 @@ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *
col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
-
+
if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
PointerRNA tar_ptr;
-
+
RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
}
-
+
uiLayoutSetRedAlert(col, false); /* we can clear it again now - it's only needed when creating the ID/Bone fields */
uiItemR(col, &dtar2_ptr, "transform_space", 0, NULL, ICON_NONE);
}
@@ -695,22 +695,22 @@ static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar
Object *ob = (Object *)dtar->id;
PointerRNA dtar_ptr;
uiLayout *col, *sub;
-
+
/* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
-
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+
/* properties */
col = uiLayoutColumn(layout, true);
uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object"), ICON_NONE);
-
+
if (dtar->id && GS(dtar->id->name) == ID_OB && ob->pose) {
PointerRNA tar_ptr;
-
+
RNA_pointer_create(dtar->id, &RNA_Pose, ob->pose, &tar_ptr);
uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
}
-
+
sub = uiLayoutColumn(layout, true);
uiItemR(sub, &dtar_ptr, "transform_type", 0, NULL, ICON_NONE);
uiItemR(sub, &dtar_ptr, "transform_space", 0, IFACE_("Space"), ICON_NONE);
@@ -726,21 +726,21 @@ static void graph_draw_driven_property_panel(uiLayout *layout, ID *id, FCurve *f
uiLayout *row;
char name[256];
int icon = 0;
-
+
/* F-Curve pointer */
RNA_pointer_create(id, &RNA_FCurve, fcu, &fcu_ptr);
-
+
/* get user-friendly 'name' for F-Curve */
icon = getname_anim_fcurve(name, id, fcu);
-
+
/* panel layout... */
row = uiLayoutRow(layout, true);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
-
+
/* -> user friendly 'name' for datablock that owns F-Curve */
/* XXX: Actually, we may need the datablock icons only... (e.g. right now will show bone for bone props) */
uiItemL(row, id->name + 2, icon);
-
+
/* -> user friendly 'name' for F-Curve/driver target */
uiItemL(row, "", VICO_SMALL_TRI_RIGHT_VEC);
uiItemL(row, name, ICON_RNA);
@@ -751,51 +751,51 @@ static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *f
{
ChannelDriver *driver = fcu->driver;
DriverVar *dvar;
-
+
PointerRNA driver_ptr;
uiLayout *col, *row;
uiBlock *block;
uiBut *but;
-
+
/* set event handler for panel */
block = uiLayoutGetBlock(layout);
UI_block_func_handle_set(block, do_graph_region_driver_buttons, NULL);
-
+
/* driver-level settings - type, expressions, and errors */
RNA_pointer_create(id, &RNA_Driver, driver, &driver_ptr);
-
+
col = uiLayoutColumn(layout, true);
block = uiLayoutGetBlock(col);
uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);
-
+
{
char valBuf[32];
-
+
/* value of driver */
row = uiLayoutRow(col, true);
uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
uiItemL(row, valBuf, ICON_NONE);
}
-
+
/* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
if (driver->type == DRIVER_TYPE_PYTHON) {
bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL);
bool bpy_ctx_expr_error = (strstr(driver->expression, "bpy.context.") != NULL);
-
+
/* expression */
/* TODO: "Show syntax hints" button */
col = uiLayoutColumn(layout, true);
block = uiLayoutGetBlock(col);
-
+
uiItemL(col, IFACE_("Expression:"), ICON_NONE);
uiItemR(col, &driver_ptr, "expression", 0, "", ICON_NONE);
uiItemR(col, &driver_ptr, "use_self", 0, NULL, ICON_NONE);
-
+
/* errors? */
col = uiLayoutColumn(layout, true);
block = uiLayoutGetBlock(col);
-
+
if ((G.f & G_SCRIPT_AUTOEXEC) == 0) {
/* TODO: Add button to enable? */
uiItemL(col, IFACE_("ERROR: Python auto-execution disabled"), ICON_CANCEL);
@@ -803,12 +803,12 @@ static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *f
else if (driver->flag & DRIVER_FLAG_INVALID) {
uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_CANCEL);
}
-
+
/* Explicit bpy-references are evil. Warn about these to prevent errors */
/* TODO: put these in a box? */
if (bpy_data_expr_error || bpy_ctx_expr_error) {
uiItemL(col, IFACE_("WARNING: Driver expression may not work correctly"), ICON_HELP);
-
+
if (bpy_data_expr_error) {
uiItemL(col, IFACE_("TIP: Use variables instead of bpy.data paths (see below)"), ICON_ERROR);
}
@@ -821,10 +821,10 @@ static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *f
/* errors? */
col = uiLayoutColumn(layout, true);
block = uiLayoutGetBlock(col);
-
+
if (driver->flag & DRIVER_FLAG_INVALID)
uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
-
+
/* Warnings about a lack of variables
* NOTE: The lack of variables is generally a bad thing, since it indicates
* that the driver doesn't work at all. This particular scenario arises
@@ -833,14 +833,14 @@ static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *f
*/
if (BLI_listbase_is_empty(&driver->variables)) {
uiItemL(col, IFACE_("ERROR: Driver is useless without any inputs"), ICON_ERROR);
-
+
if (!BLI_listbase_is_empty(&fcu->modifiers)) {
uiItemL(col, IFACE_("TIP: Use F-Curves for procedural animation instead"), ICON_INFO);
uiItemL(col, IFACE_("F-Modifiers can generate curves for those too"), ICON_INFO);
}
}
}
-
+
/* add/copy/paste driver variables */
{
/* add driver variable */
@@ -851,62 +851,62 @@ static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *f
NULL, 0.0, 0.0, 0, 0,
TIP_("Driver variables ensure that all dependencies will be accounted for, eusuring that drivers will update correctly"));
UI_but_func_set(but, driver_add_var_cb, driver, NULL);
-
+
/* copy/paste (as sub-row) */
row = uiLayoutRow(row, true);
block = uiLayoutGetBlock(row);
-
+
uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_driver_variables_copy");
uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_driver_variables_paste");
}
-
+
/* loop over targets, drawing them */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
PointerRNA dvar_ptr;
uiLayout *box;
uiLayout *subrow, *sub;
-
+
/* sub-layout column for this variable's settings */
col = uiLayoutColumn(layout, true);
-
+
/* 1) header panel */
box = uiLayoutBox(col);
RNA_pointer_create(id, &RNA_DriverVariable, dvar, &dvar_ptr);
-
+
row = uiLayoutRow(box, false);
block = uiLayoutGetBlock(row);
-
+
/* 1.1) variable type and name */
subrow = uiLayoutRow(row, true);
-
+
/* 1.1.1) variable type */
sub = uiLayoutRow(subrow, true); /* HACK: special group just for the enum, otherwise we */
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); /* we get ugly layout with text included too... */
-
+
uiItemR(sub, &dvar_ptr, "type", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
+
/* 1.1.2) variable name */
sub = uiLayoutRow(subrow, true); /* HACK: special group to counteract the effects of the previous */
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND); /* enum, which now pushes everything too far right */
-
+
uiItemR(sub, &dvar_ptr, "name", 0, "", ICON_NONE);
-
+
/* 1.2) invalid name? */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
+
if (dvar->flag & DVAR_FLAG_INVALID_NAME) {
but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ERROR, 290, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Invalid variable name, click here for details"));
UI_but_func_set(but, driver_dvar_invalid_name_query_cb, dvar, NULL); // XXX: reports?
}
-
+
/* 1.3) remove button */
but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable"));
UI_but_func_set(but, driver_delete_var_cb, driver, dvar);
UI_block_emboss_set(block, UI_EMBOSS);
-
-
+
+
/* 2) variable type settings */
box = uiLayoutBox(col);
/* controls to draw depends on the type of variable */
@@ -924,15 +924,15 @@ static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *f
graph_panel_driverVar__transChan(box, id, dvar);
break;
}
-
+
/* 3) value of variable */
{
char valBuf[32];
-
+
box = uiLayoutBox(col);
row = uiLayoutRow(box, true);
uiItemL(row, IFACE_("Value:"), ICON_NONE);
-
+
if ((dvar->type == DVAR_TYPE_ROT_DIFF) ||
(dvar->type == DVAR_TYPE_TRANSFORM_CHAN &&
dvar->targets[0].transChan >= DTAR_TRANSCHAN_ROTX &&
@@ -943,11 +943,11 @@ static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *f
else {
BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
}
-
+
uiItemL(row, valBuf, ICON_NONE);
}
}
-
+
/* XXX: This should become redundant. But sometimes the flushing fails, so keep this around for a while longer as a "last resort" */
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
@@ -969,9 +969,9 @@ static void graph_panel_driven_property(const bContext *C, Panel *pa)
if (!graph_panel_context(C, &ale, &fcu))
return;
-
+
graph_draw_driven_property_panel(pa->layout, ale->id, fcu);
-
+
MEM_freeN(ale);
}
@@ -980,13 +980,13 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
{
bAnimListElem *ale;
FCurve *fcu;
-
+
/* Get settings from context */
if (!graph_panel_context(C, &ale, &fcu))
return;
-
+
graph_draw_driver_settings_panel(pa->layout, ale->id, fcu);
-
+
/* cleanup */
MEM_freeN(ale);
}
@@ -1003,40 +1003,40 @@ static int graph_panel_drivers_popover_poll(const bContext *C, PanelType *UNUSED
static void graph_panel_drivers_popover(const bContext *C, Panel *pa)
{
uiLayout *layout = pa->layout;
-
+
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
int index = -1;
uiBut *but = NULL;
-
+
/* Get active property to show driver properties for */
but = UI_context_active_but_prop_get((bContext *)C, &ptr, &prop, &index);
if (but) {
FCurve *fcu;
bool driven, special;
-
+
fcu = rna_get_fcurve_context_ui((bContext *)C,
&ptr, prop, index,
NULL, NULL, &driven, &special);
-
+
/* Populate Panel - With a combination of the contents of the Driven and Driver panels */
if (fcu) {
ID *id = ptr.id.data;
-
+
/* Driven Property Settings */
uiItemL(layout, IFACE_("Driven Property:"), ICON_NONE);
graph_draw_driven_property_panel(pa->layout, id, fcu);
/* TODO: All vs Single */
-
+
uiItemS(layout);
uiItemS(layout);
-
+
/* Drivers Settings */
uiItemL(layout, IFACE_("Driver Settings:"), ICON_NONE);
graph_draw_driver_settings_panel(pa->layout, id, fcu);
}
}
-
+
/* Show drivers editor is always visible */
uiItemO(layout, IFACE_("Show in Drivers Editor"), ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
}
@@ -1055,7 +1055,7 @@ static void do_graph_region_modifier_buttons(bContext *C, void *UNUSED(arg), int
}
}
-static void graph_panel_modifiers(const bContext *C, Panel *pa)
+static void graph_panel_modifiers(const bContext *C, Panel *pa)
{
bAnimListElem *ale;
FCurve *fcu;
@@ -1063,37 +1063,37 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa)
uiLayout *col, *row;
uiBlock *block;
bool active;
-
+
if (!graph_panel_context(C, &ale, &fcu))
return;
-
+
block = uiLayoutGetBlock(pa->layout);
UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL);
-
+
/* 'add modifier' button at top of panel */
{
row = uiLayoutRow(pa->layout, false);
-
- /* this is an operator button which calls a 'add modifier' operator...
+
+ /* this is an operator button which calls a 'add modifier' operator...
* a menu might be nicer but would be tricky as we need some custom filtering
*/
uiItemMenuEnumO(row, (bContext *)C, "GRAPH_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE);
-
+
/* copy/paste (as sub-row) */
row = uiLayoutRow(row, true);
uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
}
-
+
active = !(fcu->flag & FCURVE_MOD_OFF);
/* draw each modifier */
for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
col = uiLayoutColumn(pa->layout, true);
uiLayoutSetActive(col, active);
-
+
ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm);
}
-
+
MEM_freeN(ale);
}
@@ -1111,7 +1111,7 @@ void graph_buttons_register(ARegionType *art)
pt->draw = graph_panel_properties;
pt->poll = graph_panel_poll;
BLI_addtail(&art->paneltypes, pt);
-
+
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
strcpy(pt->idname, "GRAPH_PT_key_properties");
strcpy(pt->label, N_("Active Keyframe"));
@@ -1138,7 +1138,7 @@ void graph_buttons_register(ARegionType *art)
pt->draw = graph_panel_drivers;
pt->poll = graph_panel_drivers_poll;
BLI_addtail(&art->paneltypes, pt);
-
+
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers pover");
strcpy(pt->idname, "GRAPH_PT_drivers_popover");
strcpy(pt->label, N_("Add/Edit Driver"));
@@ -1156,7 +1156,7 @@ void graph_buttons_register(ARegionType *art)
pt->draw = graph_panel_modifiers;
pt->poll = graph_panel_poll;
BLI_addtail(&art->paneltypes, pt);
-
+
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel view");
strcpy(pt->idname, "GRAPH_PT_view");
strcpy(pt->label, N_("View Properties"));
@@ -1170,7 +1170,7 @@ static int graph_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = graph_has_buttons_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -1182,7 +1182,7 @@ void GRAPH_OT_properties(wmOperatorType *ot)
ot->name = "Properties";
ot->idname = "GRAPH_OT_properties";
ot->description = "Toggle the properties region visibility";
-
+
ot->exec = graph_properties_toggle_exec;
ot->poll = ED_operator_graphedit_active;
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 94984dd590c..7c6af0b4c62 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -63,7 +63,7 @@
/* *************************** */
/* Utility Drawing Defines */
-/* determine the alpha value that should be used when
+/* determine the alpha value that should be used when
* drawing components for some F-Curve (fcu)
* - selected F-Curves should be more visible than partially visible ones
*/
@@ -175,14 +175,14 @@ static void draw_fcurve_selected_keyframe_vertices(FCurve *fcu, View2D *v2d, boo
BezTriple *bezt = fcu->bezt;
for (int i = 0; i < fcu->totvert; i++, bezt++) {
- /* as an optimization step, only draw those in view
+ /* as an optimization step, only draw those in view
* - we apply a correction factor to ensure that points don't pop in/out due to slight twitches of view size
*/
if (IN_RANGE(bezt->vec[1][0], (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
if (edit) {
/* 'Keyframe' vertex only, as handle lines and handles have already been drawn
* - only draw those with correct selection state for the current drawing color
- * -
+ * -
*/
if ((bezt->f2 & SELECT) == sel)
immVertex2fv(pos, bezt->vec[1]);
@@ -273,7 +273,7 @@ static void draw_fcurve_vertices(ARegion *ar, FCurve *fcu, bool do_handles, bool
{
View2D *v2d = &ar->v2d;
- /* only draw points if curve is visible
+ /* only draw points if curve is visible
* - draw unselected points before selected points as separate passes
* to make sure in the case of overlapping points that the selected is always visible
* - draw handles before keyframes, so that keyframes will overlap handles (keyframes are more important for users)
@@ -330,7 +330,7 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
immBeginAtMost(GWN_PRIM_LINES, 4 * 2 * fcu->totvert);
- /* slightly hacky, but we want to draw unselected points before selected ones
+ /* slightly hacky, but we want to draw unselected points before selected ones
* so that selected points are clearly visible
*/
for (sel = 0; sel < 2; sel++) {
@@ -340,18 +340,18 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
unsigned char col[4];
for (b = 0; b < fcu->totvert; b++, prevbezt = bezt, bezt++) {
- /* if only selected keyframes can get their handles shown,
+ /* if only selected keyframes can get their handles shown,
* check that keyframe is selected
*/
if (sipo->flag & SIPO_SELVHANDLESONLY) {
if (BEZT_ISSEL_ANY(bezt) == 0)
continue;
}
-
+
/* draw handle with appropriate set of colors if selection is ok */
if ((bezt->f2 & SELECT) == sel) {
fp = bezt->vec[0];
-
+
/* only draw first handle if previous segment had handles */
if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
UI_GetThemeColor3ubv(basecol + bezt->h1, col);
@@ -361,7 +361,7 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
immAttrib4ubv(color, col);
immVertex2fv(pos, fp + 3);
}
-
+
/* only draw second handle if this segment is bezier */
if (bezt->ipo == BEZT_IPO_BEZ) {
UI_GetThemeColor3ubv(basecol + bezt->h2, col);
@@ -385,7 +385,7 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
immAttrib4ubv(color, col);
immVertex2fv(pos, fp + 3);
}
-
+
/* only draw second handle if this segment is bezier, and selection is ok */
if (((bezt->f3 & SELECT) == sel) &&
(bezt->ipo == BEZT_IPO_BEZ))
@@ -408,7 +408,7 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu)
/* Samples ---------------- */
-/* helper func - draw sample-range marker for an F-Curve as a cross
+/* helper func - draw sample-range marker for an F-Curve as a cross
* NOTE: the caller MUST HAVE GL_LINE_SMOOTH & GL_BLEND ENABLED, otherwise, the controls don't
* have a consistent appearance (due to off-pixel alignments)...
*/
@@ -437,15 +437,15 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
{
FPoint *first, *last;
float hsize, xscale, yscale;
-
+
/* get view settings */
hsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);
-
+
/* get verts */
first = fcu->fpt;
last = (first) ? (first + (fcu->totvert - 1)) : (NULL);
-
+
/* draw */
if (first && last) {
/* anti-aliased lines for more consistent appearance */
@@ -491,10 +491,10 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
/* disable any drivers temporarily */
driver = fcu->driver;
fcu->driver = NULL;
-
+
/* compute unit correction factor */
unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
-
+
/* Note about sampling frequency:
* Ideally, this is chosen such that we have 1-2 pixels = 1 segment
* which means that our curves can be as smooth as possible. However,
@@ -510,10 +510,10 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
/* grid->dx represents the number of 'frames' between gridlines, but we divide by U.v2d_min_gridsize to get pixels-steps */
/* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */
samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize);
-
+
if (sipo->flag & SIPO_BEAUTYDRAW_OFF) {
/* Low Precision = coarse lower-bound clamping
- *
+ *
* Although the "Beauty Draw" flag was originally for AA'd
* line drawing, the sampling rate here has a much greater
* impact on performance (e.g. for T40372)!
@@ -529,15 +529,15 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
if (samplefreq < 0.00001f)
samplefreq = 0.00001f;
}
-
-
+
+
/* the start/end times are simply the horizontal extents of the 'cur' rect */
stime = v2d->cur.xmin;
etime = v2d->cur.xmax + samplefreq; /* + samplefreq here so that last item gets included... */
-
-
- /* at each sampling interval, add a new vertex
- * - apply the unit correction factor to the calculated values so that
+
+
+ /* at each sampling interval, add a new vertex
+ * - apply the unit correction factor to the calculated values so that
* the displayed values appear correctly in the viewport
*/
@@ -584,11 +584,11 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
gpuTranslate2f(0.0f, offset);
immBegin(GWN_PRIM_LINE_STRIP, count);
-
+
/* extrapolate to left? - left-side of view comes before first keyframe? */
if (prevfpt->vec[0] > v2d->cur.xmin) {
v[0] = v2d->cur.xmin;
-
+
/* y-value depends on the interpolation */
if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (fcu->totvert == 1)) {
/* just extend across the first keyframe's value */
@@ -600,26 +600,26 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
if (fac) fac = 1.0f / fac;
v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
}
-
+
immVertex2fv(shdr_pos, v);
}
-
+
/* loop over samples, drawing segments */
/* draw curve between first and last keyframe (if there are enough to do so) */
while (b--) {
/* Linear interpolation: just add one point (which should add a new line segment) */
immVertex2fv(shdr_pos, prevfpt->vec);
-
+
/* get next pointers */
if (b > 0) {
prevfpt++;
}
}
-
+
/* extrapolate to right? (see code for left-extrapolation above too) */
if (prevfpt->vec[0] < v2d->cur.xmax) {
v[0] = v2d->cur.xmax;
-
+
/* y-value depends on the interpolation */
if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (fcu->totvert == 1)) {
/* based on last keyframe's value */
@@ -632,29 +632,29 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
if (fac) fac = 1.0f / fac;
v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
}
-
+
immVertex2fv(shdr_pos, v);
}
-
+
immEnd();
gpuPopMatrix();
}
-/* helper func - check if the F-Curve only contains easily drawable segments
+/* helper func - check if the F-Curve only contains easily drawable segments
* (i.e. no easing equation interpolations)
*/
static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
{
BezTriple *bezt;
int i;
-
+
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
if (ELEM(bezt->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN, BEZT_IPO_BEZ) == false) {
return false;
}
}
-
+
return true;
}
@@ -670,7 +670,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
int resol;
float unit_scale, offset;
short mapping_flag = ANIM_get_normalization_flags(ac);
-
+
/* apply unit mapping */
gpuPushMatrix();
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
@@ -681,12 +681,12 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
* bezier interpolation, and are drawn at full res.
* This is tricky to optimize, but maybe can be improved at some point... */
immBeginAtMost(GWN_PRIM_LINE_STRIP, (b * 32 + 3));
-
+
/* extrapolate to left? */
if (prevbezt->vec[1][0] > v2d->cur.xmin) {
/* left-side of view comes before first keyframe, so need to extend as not cyclic */
v1[0] = v2d->cur.xmin;
-
+
/* y-value depends on the interpolation */
if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (prevbezt->ipo == BEZT_IPO_CONST) || (fcu->totvert == 1)) {
/* just extend across the first keyframe's value */
@@ -704,17 +704,17 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
if (fac) fac = 1.0f / fac;
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[0][1] - prevbezt->vec[1][1]);
}
-
+
immVertex2fv(pos, v1);
}
-
+
/* if only one keyframe, add it now */
if (fcu->totvert == 1) {
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
immVertex2fv(pos, v1);
}
-
+
/* draw curve between first and last keyframe (if there are enough to do so) */
/* TODO: optimize this to not have to calc stuff out of view too? */
while (b--) {
@@ -723,7 +723,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
immVertex2fv(pos, v1);
-
+
v1[0] = bezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
immVertex2fv(pos, v1);
@@ -735,10 +735,10 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
immVertex2fv(pos, v1);
}
else if (prevbezt->ipo == BEZT_IPO_BEZ) {
- /* Bezier-Interpolation: draw curve as series of segments between keyframes
+ /* Bezier-Interpolation: draw curve as series of segments between keyframes
* - resol determines number of points to sample in between keyframes
*/
-
+
/* resol depends on distance between points (not just horizontal) OR is a fixed high res */
/* TODO: view scale should factor into this someday too... */
if (fcu->driver) {
@@ -747,7 +747,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
else {
resol = (int)(5.0f * len_v2v2(bezt->vec[1], prevbezt->vec[1]));
}
-
+
if (resol < 2) {
/* only draw one */
v1[0] = prevbezt->vec[1][0];
@@ -758,32 +758,32 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
/* clamp resolution to max of 32 */
/* NOTE: higher values will crash */
if (resol > 32) resol = 32;
-
+
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
v2[0] = prevbezt->vec[2][0];
v2[1] = prevbezt->vec[2][1];
-
+
v3[0] = bezt->vec[0][0];
v3[1] = bezt->vec[0][1];
v4[0] = bezt->vec[1][0];
v4[1] = bezt->vec[1][1];
-
+
correct_bezpart(v1, v2, v3, v4);
-
+
BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
BKE_curve_forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
-
+
for (fp = data; resol; resol--, fp += 3) {
immVertex2fv(pos, fp);
}
}
}
-
+
/* get next pointers */
prevbezt = bezt;
bezt++;
-
+
/* last point? */
if (b == 0) {
v1[0] = prevbezt->vec[1][0];
@@ -791,11 +791,11 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
immVertex2fv(pos, v1);
}
}
-
+
/* extrapolate to right? (see code for left-extrapolation above too) */
if (prevbezt->vec[1][0] < v2d->cur.xmax) {
v1[0] = v2d->cur.xmax;
-
+
/* y-value depends on the interpolation */
if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (prevbezt->ipo == BEZT_IPO_CONST) || (fcu->totvert == 1)) {
/* based on last keyframe's value */
@@ -814,10 +814,10 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
if (fac) fac = 1.0f / fac;
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[2][1] - prevbezt->vec[1][1]);
}
-
+
immVertex2fv(pos, v1);
}
-
+
immEnd();
gpuPopMatrix();
@@ -825,7 +825,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
/* Debugging -------------------------------- */
-/* Draw indicators which show the value calculated from the driver,
+/* Draw indicators which show the value calculated from the driver,
* and how this is mapped to the value that comes out of it. This
* is handy for helping users better understand how to interpret
* the graphs, and also facilitates debugging.
@@ -837,7 +837,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
short mapping_flag = ANIM_get_normalization_flags(ac);
float offset;
float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
-
+
/* for now, only show when debugging driver... */
//if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0)
// return;
@@ -852,19 +852,19 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
immUniform1i("num_colors", 0); /* Simple dashes. */
/* No curve to modify/visualize the result?
- * => We still want to show the 1-1 default...
+ * => We still want to show the 1-1 default...
*/
if ((fcu->totvert == 0) && BLI_listbase_is_empty(&fcu->modifiers)) {
float t;
-
+
/* draw with thin dotted lines in style of what curve would have been */
immUniformColor3fv(fcu->color);
-
+
immUniform1f("dash_width", 40.0f);
immUniform1f("dash_factor", 0.5f);
glLineWidth(2.0f);
-
- /* draw 1-1 line, stretching just past the screen limits
+
+ /* draw 1-1 line, stretching just past the screen limits
* NOTE: we need to scale the y-values to be valid for the units
*/
immBegin(GWN_PRIM_LINES, 2);
@@ -877,17 +877,17 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
immEnd();
}
-
+
/* draw driver only if actually functional */
if ((driver->flag & DRIVER_FLAG_INVALID) == 0) {
/* grab "coordinates" for driver outputs */
float x = driver->curval;
float y = fcu->curval * unitfac;
-
+
/* only draw indicators if the point is in range*/
if (x >= v2d->cur.xmin) {
float co[2];
-
+
/* draw dotted lines leading towards this point from both axes ....... */
immUniformColor3f(0.9f, 0.9f, 0.9f);
immUniform1f("dash_width", 10.0f);
@@ -916,7 +916,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
immVertex2fv(shdr_pos, co);
immEnd();
-
+
immUnbindProgram();
/* GWN_PRIM_POINTS do not survive dashed line geometry shader... */
@@ -926,15 +926,15 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
/* -> outer frame */
immUniformColor3f(0.9f, 0.9f, 0.9f);
glPointSize(7.0);
-
+
immBegin(GWN_PRIM_POINTS, 1);
immVertex2f(shdr_pos, x, y);
immEnd();
-
+
/* inner frame */
immUniformColor3f(0.9f, 0.0f, 0.0f);
glPointSize(3.0);
-
+
immBegin(GWN_PRIM_POINTS, 1);
immVertex2f(shdr_pos, x, y);
immEnd();
@@ -946,16 +946,16 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
/* Public Curve-Drawing API ---------------- */
-/* Draw the 'ghost' F-Curves (i.e. snapshots of the curve)
+/* Draw the 'ghost' F-Curves (i.e. snapshots of the curve)
* NOTE: unit mapping has already been applied to the values, so do not try and apply again
*/
void graph_draw_ghost_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
{
FCurve *fcu;
-
+
/* draw with thick dotted lines */
glLineWidth(3.0f);
-
+
/* anti-aliased lines for less jagged appearance */
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
glEnable(GL_LINE_SMOOTH);
@@ -976,12 +976,12 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
/* the ghost curves are simply sampled F-Curves stored in sipo->ghostCurves */
for (fcu = sipo->ghostCurves.first; fcu; fcu = fcu->next) {
- /* set whatever color the curve has set
+ /* set whatever color the curve has set
* - this is set by the function which creates these
* - draw with a fixed opacity of 2
*/
immUniformColor3fvAlpha(fcu->color, 0.5f);
-
+
/* simply draw the stored samples */
draw_fcurve_curve_samples(ac, NULL, fcu, &ar->v2d, shdr_pos);
}
@@ -1002,21 +1002,21 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* build list of curves to draw */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE);
filter |= ((sel) ? (ANIMFILTER_SEL) : (ANIMFILTER_UNSEL));
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* for each curve:
- * draw curve, then handle-lines, and finally vertices in this order so that
+ * draw curve, then handle-lines, and finally vertices in this order so that
* the data will be layered correctly
*/
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
FModifier *fcm = find_active_fmodifier(&fcu->modifiers);
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* map keyframes for drawing if scaled F-Curve */
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
@@ -1028,7 +1028,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
* - controls from active modifier take precedence over keyframes
* (XXX! editing tools need to take this into account!)
*/
-
+
/* 1) draw curve line */
if (((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) ||
(((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)))
@@ -1041,7 +1041,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
else {
glLineWidth(1.0);
}
-
+
/* anti-aliased lines for less jagged appearance */
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
glEnable(GL_LINE_SMOOTH);
@@ -1081,8 +1081,8 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
/* draw F-Curve */
if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) {
- /* draw a curve affected by modifiers or only allowed to have integer values
- * by sampling it at various small-intervals over the visible region
+ /* draw a curve affected by modifiers or only allowed to have integer values
+ * by sampling it at various small-intervals over the visible region
*/
draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
}
@@ -1108,8 +1108,8 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
}
glDisable(GL_BLEND);
}
-
- /* 2) draw handles and vertices as appropriate based on active
+
+ /* 2) draw handles and vertices as appropriate based on active
* - if the option to only show controls if the F-Curve is selected is enabled, we must obey this
*/
if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) {
@@ -1127,46 +1127,46 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
short mapping_flag = ANIM_get_normalization_flags(ac);
float offset;
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
-
+
/* apply unit-scaling to all values via OpenGL */
gpuPushMatrix();
gpuScale2f(1.0f, unit_scale);
gpuTranslate2f(0.0f, offset);
-
+
/* set this once and for all - all handles and handle-verts should use the same thickness */
glLineWidth(1.0);
-
+
if (fcu->bezt) {
bool do_handles = draw_fcurve_handles_check(sipo, fcu);
-
+
if (do_handles) {
/* only draw handles/vertices on keyframes */
glEnable(GL_BLEND);
draw_fcurve_handles(sipo, fcu);
glDisable(GL_BLEND);
}
-
+
draw_fcurve_vertices(ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY));
}
else {
/* samples: only draw two indicators at either end as indicators */
draw_fcurve_samples(sipo, ar, fcu);
}
-
+
gpuPopMatrix();
}
}
-
+
/* 3) draw driver debugging stuff */
if ((ac->datatype == ANIMCONT_DRIVERS) && (fcu->flag & FCURVE_ACTIVE)) {
graph_draw_driver_debug(ac, ale->id, fcu);
}
-
+
/* undo mapping of keyframes for drawing if scaled F-Curve */
if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
}
-
+
/* free list of curves */
ANIM_animdata_freelist(&anim_data);
}
@@ -1175,40 +1175,40 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
/* Channel List */
/* left hand part */
-void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
+void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
View2D *v2d = &ar->v2d;
float y = 0.0f, height;
size_t items;
int i = 0;
-
+
/* build list of channels to draw */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* Update max-extent of channels here (taking into account scrollers):
* - this is done to allow the channel list to be scrollable, but must be done here
* to avoid regenerating the list again and/or also because channels list is drawn first
- * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
+ * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
height = (float)((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac) * 2));
UI_view2d_totRect_set(v2d, BLI_rcti_size_x(&ar->v2d.mask), height);
-
+
/* loop through channels, and set up drawing depending on their type */
{ /* first pass: just the standard GL-drawing for backdrop + text */
size_t channel_index = 0;
-
+
y = (float)ACHANNEL_FIRST(ac);
-
+
for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
@@ -1216,7 +1216,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
/* draw all channels using standard channel-drawing API */
ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index);
}
-
+
/* adjust y-position for next one */
y -= ACHANNEL_STEP(ac);
channel_index++;
@@ -1225,17 +1225,17 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
{ /* second pass: widgets */
uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
size_t channel_index = 0;
-
+
y = (float)ACHANNEL_FIRST(ac);
-
+
/* set blending again, as may not be set in previous step */
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
+
for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
@@ -1243,18 +1243,18 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
/* draw all channels using standard channel-drawing API */
ANIM_channel_draw_widgets(C, ac, ale, block, yminc, ymaxc, channel_index);
}
-
+
/* adjust y-position for next one */
y -= ACHANNEL_STEP(ac);
channel_index++;
}
-
+
UI_block_end(C, block);
UI_block_draw(C, block);
-
+
glDisable(GL_BLEND);
}
-
+
/* free tempolary channels */
ANIM_animdata_freelist(&anim_data);
}
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 562efcbb0ea..26a6e93ba57 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -54,10 +54,11 @@
#include "BLT_translation.h"
+#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_nla.h"
-#include "BKE_context.h"
#include "BKE_report.h"
#include "DEG_depsgraph_build.h"
@@ -83,36 +84,36 @@
/* Get the min/max keyframes*/
/* note: it should return total boundbox, filter for selection only can be argument... */
-void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax,
+void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax,
const bool do_sel_only, const bool include_handles)
{
Scene *scene = ac->scene;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get data to filter, from Dopesheet */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* set large values initial values that will be easy to override */
if (xmin) *xmin = 999999999.0f;
if (xmax) *xmax = -999999999.0f;
if (ymin) *ymin = 999999999.0f;
if (ymax) *ymax = -999999999.0f;
-
+
/* check if any channels to set range with */
if (anim_data.first) {
bool foundBounds = false;
-
+
/* go through channels, finding max extents */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
float txmin, txmax, tymin, tymax;
float unitFac, offset;
-
+
/* get range */
if (calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) {
short mapping_flag = ANIM_get_normalization_flags(ac);
@@ -122,24 +123,24 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
txmin = BKE_nla_tweakedit_remap(adt, txmin, NLATIME_CONVERT_MAP);
txmax = BKE_nla_tweakedit_remap(adt, txmax, NLATIME_CONVERT_MAP);
}
-
+
/* apply unit corrections */
unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
tymin += offset;
tymax += offset;
tymin *= unitFac;
tymax *= unitFac;
-
+
/* try to set cur using these values, if they're more extreme than previously set values */
if ((xmin) && (txmin < *xmin)) *xmin = txmin;
if ((xmax) && (txmax > *xmax)) *xmax = txmax;
if ((ymin) && (tymin < *ymin)) *ymin = tymin;
if ((ymax) && (tymax > *ymax)) *ymax = tymax;
-
+
foundBounds = true;
}
}
-
+
/* ensure that the extents are not too extreme that view implodes...*/
if (foundBounds) {
if ((xmin && xmax) && (fabsf(*xmax - *xmin) < 0.001f)) {
@@ -157,7 +158,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
if (ymin) *ymin = -5;
if (ymax) *ymax = 5;
}
-
+
/* free memory */
ANIM_animdata_freelist(&anim_data);
}
@@ -171,7 +172,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
if (xmin) *xmin = -5;
if (xmax) *xmax = 100;
}
-
+
if (ymin) *ymin = -5;
if (ymax) *ymax = 5;
}
@@ -184,7 +185,7 @@ static int graphkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
bAnimContext ac;
Scene *scene;
float min, max;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
@@ -192,31 +193,31 @@ static int graphkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
else
scene = ac.scene;
-
+
/* set the range directly */
get_graph_keyframe_extents(&ac, &min, &max, NULL, NULL, false, false);
scene->r.flag |= SCER_PRV_RANGE;
scene->r.psfra = round_fl_to_int(min);
scene->r.pefra = round_fl_to_int(max);
-
+
/* set notifier that things have changed */
// XXX err... there's nothing for frame ranges yet, but this should do fine too
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_previewrange_set(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Auto-Set Preview Range";
ot->idname = "GRAPH_OT_previewrange_set";
ot->description = "Automatically set Preview Range based on range of keyframes";
-
+
/* api callbacks */
ot->exec = graphkeys_previewrange_exec;
ot->poll = ED_operator_graphedit_active; // XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier...
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -228,11 +229,11 @@ static int graphkeys_viewall(bContext *C, const bool do_sel_only, const bool inc
{
bAnimContext ac;
rctf cur_new;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
get_graph_keyframe_extents(&ac,
&cur_new.xmin, &cur_new.xmax,
@@ -240,9 +241,9 @@ static int graphkeys_viewall(bContext *C, const bool do_sel_only, const bool inc
do_sel_only, include_handles);
BLI_rctf_scale(&cur_new, 1.1f);
-
+
UI_view2d_smooth_view(C, ac.ar, &cur_new, smooth_viewtx);
-
+
return OPERATOR_FINISHED;
}
@@ -252,16 +253,16 @@ static int graphkeys_viewall_exec(bContext *C, wmOperator *op)
{
const bool include_handles = RNA_boolean_get(op->ptr, "include_handles");
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
+
/* whole range */
return graphkeys_viewall(C, false, include_handles, smooth_viewtx);
}
-
+
static int graphkeys_view_selected_exec(bContext *C, wmOperator *op)
{
const bool include_handles = RNA_boolean_get(op->ptr, "include_handles");
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
+
/* only selected */
return graphkeys_viewall(C, true, include_handles, smooth_viewtx);
}
@@ -274,16 +275,16 @@ void GRAPH_OT_view_all(wmOperatorType *ot)
ot->name = "View All";
ot->idname = "GRAPH_OT_view_all";
ot->description = "Reset viewable area to show full keyframe range";
-
+
/* api callbacks */
ot->exec = graphkeys_viewall_exec;
ot->poll = ED_operator_graphedit_active; /* XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier... */
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
- ot->prop = RNA_def_boolean(ot->srna, "include_handles", true, "Include Handles",
+ ot->prop = RNA_def_boolean(ot->srna, "include_handles", true, "Include Handles",
"Include handles of keyframes when calculating extents");
}
@@ -300,9 +301,9 @@ void GRAPH_OT_view_selected(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
- ot->prop = RNA_def_boolean(ot->srna, "include_handles", true, "Include Handles",
+ ot->prop = RNA_def_boolean(ot->srna, "include_handles", true, "Include Handles",
"Include handles of keyframes when calculating extents");
}
@@ -321,11 +322,11 @@ void GRAPH_OT_view_frame(wmOperatorType *ot)
ot->name = "View Frame";
ot->idname = "GRAPH_OT_view_frame";
ot->description = "Reset viewable area to show range around current frame";
-
+
/* api callbacks */
ot->exec = graphkeys_view_frame_exec;
ot->poll = ED_operator_graphedit_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -337,25 +338,25 @@ void GRAPH_OT_view_frame(wmOperatorType *ot)
/* Bake each F-Curve into a set of samples, and store as a ghost curve */
static void create_ghost_curves(bAnimContext *ac, int start, int end)
-{
+{
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* free existing ghost curves */
free_fcurves(&sipo->ghostCurves);
-
+
/* sanity check */
if (start >= end) {
printf("Error: Frame range for Ghost F-Curve creation is inappropriate\n");
return;
}
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and add keys between selected keyframes on every frame */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
@@ -366,41 +367,41 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end)
float unitFac, offset;
int cfra;
short mapping_flag = ANIM_get_normalization_flags(ac);
-
+
/* disable driver so that it don't muck up the sampling process */
fcu->driver = NULL;
-
+
/* calculate unit-mapping factor */
unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
-
- /* create samples, but store them in a new curve
- * - we cannot use fcurve_store_samples() as that will only overwrite the original curve
+
+ /* create samples, but store them in a new curve
+ * - we cannot use fcurve_store_samples() as that will only overwrite the original curve
*/
gcu->fpt = fpt = MEM_callocN(sizeof(FPoint) * (end - start + 1), "Ghost FPoint Samples");
gcu->totvert = end - start + 1;
-
+
/* use the sampling callback at 1-frame intervals from start to end frames */
for (cfra = start; cfra <= end; cfra++, fpt++) {
float cfrae = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
-
+
fpt->vec[0] = cfrae;
fpt->vec[1] = (fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) + offset) * unitFac;
}
-
- /* set color of ghost curve
+
+ /* set color of ghost curve
* - make the color slightly darker
*/
gcu->color[0] = fcu->color[0] - 0.07f;
gcu->color[1] = fcu->color[1] - 0.07f;
gcu->color[2] = fcu->color[2] - 0.07f;
-
+
/* store new ghost curve */
BLI_addtail(&sipo->ghostCurves, gcu);
-
+
/* restore driver */
fcu->driver = driver;
}
-
+
/* admin and redraws */
ANIM_animdata_freelist(&anim_data);
}
@@ -412,39 +413,39 @@ static int graphkeys_create_ghostcurves_exec(bContext *C, wmOperator *UNUSED(op)
bAnimContext ac;
View2D *v2d;
int start, end;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* ghost curves are snapshots of the visible portions of the curves, so set range to be the visible range */
v2d = &ac.ar->v2d;
start = (int)v2d->cur.xmin;
end = (int)v2d->cur.xmax;
-
+
/* bake selected curves into a ghost curve */
create_ghost_curves(&ac, start, end);
-
+
/* update this editor only */
ED_area_tag_redraw(CTX_wm_area(C));
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_ghost_curves_create(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Create Ghost Curves";
ot->idname = "GRAPH_OT_ghost_curves_create";
ot->description = "Create snapshot (Ghosts) of selected F-Curves as background aid for active Graph Editor";
-
+
/* api callbacks */
ot->exec = graphkeys_create_ghostcurves_exec;
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
// todo: add props for start/end frames
}
@@ -455,36 +456,36 @@ static int graphkeys_clear_ghostcurves_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
SpaceIpo *sipo;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
sipo = (SpaceIpo *)ac.sl;
-
+
/* if no ghost curves, don't do anything */
if (BLI_listbase_is_empty(&sipo->ghostCurves))
return OPERATOR_CANCELLED;
-
+
/* free ghost curves */
free_fcurves(&sipo->ghostCurves);
-
+
/* update this editor only */
ED_area_tag_redraw(CTX_wm_area(C));
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_ghost_curves_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clear Ghost Curves";
ot->idname = "GRAPH_OT_ghost_curves_clear";
ot->description = "Clear F-Curve snapshots (Ghosts) for active Graph Editor";
-
+
/* api callbacks */
ot->exec = graphkeys_clear_ghostcurves_exec;
ot->poll = ED_operator_graphedit_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -517,27 +518,27 @@ static const EnumPropertyItem prop_graphkeys_insertkey_types[] = {
};
/* this function is responsible for snapping keyframes to frame-times */
-static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
+static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
size_t num_items;
-
+
ReportList *reports = ac->reports;
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
struct Depsgraph *depsgraph = ac->depsgraph;
Scene *scene = ac->scene;
ToolSettings *ts = scene->toolsettings;
short flag = 0;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
if (mode & GRAPHKEYS_INSERTKEY_SEL)
filter |= ANIMFILTER_SEL;
else if (mode & GRAPHKEYS_INSERTKEY_ACTIVE)
filter |= ANIMFILTER_ACTIVE;
-
+
num_items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
if (num_items == 0) {
if (mode & GRAPHKEYS_INSERTKEY_ACTIVE)
@@ -546,26 +547,26 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
BKE_report(reports, RPT_ERROR, "No selected F-Curves to add keyframes to");
else
BKE_report(reports, RPT_ERROR, "No channels to add keyframes to");
-
+
return;
}
-
+
/* init keyframing flag */
flag = ANIM_get_keyframing_flags(scene, 1);
-
+
/* insert keyframes */
if (mode & GRAPHKEYS_INSERTKEY_CURSOR) {
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
-
+
short mapping_flag = ANIM_get_normalization_flags(ac);
float offset;
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag, &offset);
-
+
float x, y;
-
-
+
+
/* perform time remapping for x-coordinate (if necessary) */
if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS))
x = sipo->cursorTime;
@@ -573,16 +574,16 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
x = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
else
x = (float)CFRA;
-
+
/* normalise units of cursor's value */
if (sipo)
y = (sipo->cursorVal / unit_scale) - offset;
else
y = 0.0f;
-
+
/* insert keyframe directly into the F-Curve */
insert_vert_fcurve(fcu, x, y, ts->keyframe_type, 0);
-
+
ale->update |= ANIM_UPDATE_DEFAULT;
}
}
@@ -591,15 +592,15 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
float cfra;
-
+
/* adjust current frame for NLA-mapping */
if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS))
cfra = sipo->cursorTime;
else if (adt)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
- else
+ else
cfra = (float)CFRA;
-
+
/* read value from property the F-Curve represents, or from the curve only?
* - ale->id != NULL: Typically, this means that we have enough info to try resolving the path
* - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
@@ -609,17 +610,18 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
* up adding the keyframes on a new F-Curve in the action data instead.
*/
if (ale->id && !ale->owner && !fcu->driver) {
- insert_keyframe(depsgraph, reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, flag);
+ insert_keyframe(ac->bmain, depsgraph, reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, flag);
}
else {
const float curval = evaluate_fcurve(fcu, cfra);
insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
}
-
+
ale->update |= ANIM_UPDATE_DEFAULT;
}
}
-
+
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -630,20 +632,20 @@ static int graphkeys_insertkey_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
eGraphKeys_InsertKey_Types mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* which channels to affect? */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* insert keyframes */
insert_graph_keys(&ac, mode);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -653,15 +655,15 @@ void GRAPH_OT_keyframe_insert(wmOperatorType *ot)
ot->name = "Insert Keyframes";
ot->idname = "GRAPH_OT_keyframe_insert";
ot->description = "Insert keyframes for the specified channels";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = graphkeys_insertkey_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_insertkey_types, 0, "Type", "");
}
@@ -675,11 +677,11 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
AnimData *adt;
FCurve *fcu;
float frame, val;
-
+
/* get animation context */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get active F-Curve 'anim-list-element' */
ale = get_active_fcurve_channel(&ac);
if (ELEM(NULL, ale, ale->data)) {
@@ -687,17 +689,17 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
fcu = ale->data;
-
+
/* when there are F-Modifiers on the curve, only allow adding
* keyframes if these will be visible after doing so...
*/
if (fcurve_is_keyframable(fcu)) {
ListBase anim_data;
ToolSettings *ts = ac.scene->toolsettings;
-
+
short mapping_flag = ANIM_get_normalization_flags(&ac);
float scale, offset;
-
+
/* preserve selection? */
if (RNA_boolean_get(op->ptr, "extend") == false) {
/* deselect all keyframes first, so that we can immediately start manipulating the newly added one(s)
@@ -705,28 +707,28 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
*/
deselect_graph_keys(&ac, false, SELECT_SUBTRACT, false);
}
-
+
/* get frame and value from props */
frame = RNA_float_get(op->ptr, "frame");
val = RNA_float_get(op->ptr, "value");
-
+
/* apply inverse NLA-mapping to frame to get correct time in un-scaled action */
adt = ANIM_nla_mapping_get(&ac, ale);
frame = BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP);
-
+
/* apply inverse unit-mapping to value to get correct value for F-Curves */
scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE, &offset);
-
+
val = val * scale - offset;
-
+
/* insert keyframe on the specified frame + value */
insert_vert_fcurve(fcu, frame, val, ts->keyframe_type, 0);
-
+
ale->update |= ANIM_UPDATE_DEPS;
-
+
BLI_listbase_clear(&anim_data);
BLI_addtail(&anim_data, ale);
-
+
ANIM_animdata_update(&ac, &anim_data);
}
else {
@@ -738,13 +740,13 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
else
BKE_report(op->reports, RPT_ERROR, "Remove F-Modifiers from F-Curve to add keyframes");
}
-
+
/* free temp data */
MEM_freeN(ale);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -756,23 +758,23 @@ static int graphkeys_click_insert_invoke(bContext *C, wmOperator *op, const wmEv
View2D *v2d;
int mval[2];
float x, y;
-
+
/* get animation context */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* store mouse coordinates in View2D space, into the operator's properties */
ar = ac.ar;
v2d = &ar->v2d;
-
+
mval[0] = (event->x - ar->winrct.xmin);
mval[1] = (event->y - ar->winrct.ymin);
-
+
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
-
+
RNA_float_set(op->ptr, "frame", x);
RNA_float_set(op->ptr, "value", y);
-
+
/* run exec now */
return graphkeys_click_insert_exec(C, op);
}
@@ -783,19 +785,19 @@ void GRAPH_OT_click_insert(wmOperatorType *ot)
ot->name = "Click-Insert Keyframes";
ot->idname = "GRAPH_OT_click_insert";
ot->description = "Insert new keyframe at the cursor position for the active F-Curve";
-
+
/* api callbacks */
ot->invoke = graphkeys_click_insert_invoke;
ot->exec = graphkeys_click_insert_exec;
ot->poll = graphop_active_fcurve_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_float(ot->srna, "frame", 1.0f, -FLT_MAX, FLT_MAX, "Frame Number", "Frame to insert keyframe on", 0, 100);
RNA_def_float(ot->srna, "value", 1.0f, -FLT_MAX, FLT_MAX, "Value", "Value for keyframe on", 0, 100);
-
+
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
}
@@ -803,20 +805,20 @@ void GRAPH_OT_click_insert(wmOperatorType *ot)
/* NOTE: the backend code for this is shared with the dopesheet editor */
static short copy_graph_keys(bAnimContext *ac)
-{
+{
ListBase anim_data = {NULL, NULL};
int filter, ok = 0;
-
+
/* clear buffer first */
ANIM_fcurves_copybuf_free();
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* copy keyframes */
ok = copy_animedit_keys(ac, &anim_data);
-
+
/* clean up */
ANIM_animdata_freelist(&anim_data);
@@ -825,21 +827,21 @@ static short copy_graph_keys(bAnimContext *ac)
static short paste_graph_keys(bAnimContext *ac,
const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
-{
+{
ListBase anim_data = {NULL, NULL};
int filter, ok = 0;
-
- /* filter data
- * - First time we try to filter more strictly, allowing only selected channels
+
+ /* filter data
+ * - First time we try to filter more strictly, allowing only selected channels
* to allow copying animation between channels
* - Second time, we loosen things up if nothing was found the first time, allowing
* users to just paste keyframes back into the original curve again [#31670]
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
-
+
if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* paste keyframes */
ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
@@ -854,32 +856,32 @@ static short paste_graph_keys(bAnimContext *ac,
static int graphkeys_copy_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* copy keyframes */
if (copy_graph_keys(&ac)) {
BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
return OPERATOR_CANCELLED;
}
-
+
/* just return - no operator needed here (no changes) */
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Copy Keyframes";
ot->idname = "GRAPH_OT_copy";
ot->description = "Copy selected keyframes to the copy/paste buffer";
-
+
/* api callbacks */
ot->exec = graphkeys_copy_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -893,11 +895,11 @@ static int graphkeys_paste_exec(bContext *C, wmOperator *op)
const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
const bool flipped = RNA_boolean_get(op->ptr, "flipped");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* ac.reports by default will be the global reports list, which won't show warnings */
ac.reports = op->reports;
@@ -905,30 +907,30 @@ static int graphkeys_paste_exec(bContext *C, wmOperator *op)
if (paste_graph_keys(&ac, offset_mode, merge_mode, flipped)) {
return OPERATOR_CANCELLED;
}
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_paste(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Paste Keyframes";
ot->idname = "GRAPH_OT_paste";
ot->description = "Paste keyframes from copy/paste buffer for the selected channels, starting on the current frame";
-
+
/* api callbacks */
// ot->invoke = WM_operator_props_popup; // better wait for graph redo panel
ot->exec = graphkeys_paste_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_enum(ot->srna, "offset", rna_enum_keyframe_paste_offset_items, KEYFRAME_PASTE_OFFSET_CFRA_START, "Offset", "Paste time offset of keys");
RNA_def_enum(ot->srna, "merge", rna_enum_keyframe_paste_merge_items, KEYFRAME_PASTE_MERGE_MIX, "Type", "Method of merging pasted keys and existing");
@@ -943,11 +945,11 @@ static void duplicate_graph_keys(bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and delete selected keys */
for (ale = anim_data.first; ale; ale = ale->next) {
duplicate_fcurve_keys((FCurve *)ale->key_data);
@@ -964,17 +966,17 @@ static void duplicate_graph_keys(bAnimContext *ac)
static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* duplicate keyframes */
duplicate_graph_keys(&ac);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -984,14 +986,14 @@ void GRAPH_OT_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Keyframes";
ot->idname = "GRAPH_OT_duplicate";
ot->description = "Make a copy of all selected keyframes";
-
+
/* api callbacks */
ot->exec = graphkeys_duplicate_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* to give to transform */
RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
}
@@ -1004,17 +1006,17 @@ static bool delete_graph_keys(bAnimContext *ac)
bAnimListElem *ale;
int filter;
bool changed_final = false;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and delete selected keys */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
AnimData *adt = ale->adt;
bool changed;
-
+
/* delete selected keyframes only */
changed = delete_fcurve_keys(fcu);
@@ -1022,7 +1024,7 @@ static bool delete_graph_keys(bAnimContext *ac)
ale->update |= ANIM_UPDATE_DEFAULT;
changed_final = true;
}
-
+
/* Only delete curve too if it won't be doing anything anymore */
if ((fcu->totvert == 0) &&
(list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0) &&
@@ -1044,33 +1046,33 @@ static bool delete_graph_keys(bAnimContext *ac)
static int graphkeys_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* delete keyframes */
if (!delete_graph_keys(&ac))
return OPERATOR_CANCELLED;
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_delete(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Delete Keyframes";
ot->idname = "GRAPH_OT_delete";
ot->description = "Remove all selected keyframes";
-
+
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = graphkeys_delete_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1078,15 +1080,15 @@ void GRAPH_OT_delete(wmOperatorType *ot)
/* ******************** Clean Keyframes Operator ************************* */
static void clean_graph_keys(bAnimContext *ac, float thresh, bool clean_chan)
-{
+{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and clean curves */
for (ale = anim_data.first; ale; ale = ale->next) {
clean_fcurve(ac, ale, thresh, clean_chan);
@@ -1105,38 +1107,38 @@ static int graphkeys_clean_exec(bContext *C, wmOperator *op)
bAnimContext ac;
float thresh;
bool clean_chan;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get cleaning threshold */
thresh = RNA_float_get(op->ptr, "threshold");
clean_chan = RNA_boolean_get(op->ptr, "channels");
/* clean keyframes */
clean_graph_keys(&ac, thresh, clean_chan);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_clean(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Clean Keyframes";
ot->idname = "GRAPH_OT_clean";
ot->description = "Simplify F-Curves by removing closely spaced keyframes";
-
+
/* api callbacks */
- //ot->invoke = // XXX we need that number popup for this!
+ //ot->invoke = // XXX we need that number popup for this!
ot->exec = graphkeys_clean_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_float(ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
RNA_def_boolean(ot->srna, "channels", false, "Channels", "");
@@ -1147,26 +1149,26 @@ void GRAPH_OT_clean(wmOperatorType *ot)
/* Bake each F-Curve into a set of samples */
static void bake_graph_curves(bAnimContext *ac, int start, int end)
-{
+{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and add keys between selected keyframes on every frame */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
ChannelDriver *driver = fcu->driver;
-
+
/* disable driver so that it don't muck up the sampling process */
fcu->driver = NULL;
-
+
/* create samples */
fcurve_store_samples(fcu, NULL, start, end, fcurve_samplingcb_evalcurve);
-
+
/* restore driver */
fcu->driver = driver;
@@ -1184,42 +1186,42 @@ static int graphkeys_bake_exec(bContext *C, wmOperator *UNUSED(op))
bAnimContext ac;
Scene *scene = NULL;
int start, end;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* for now, init start/end from preview-range extents */
- // TODO: add properties for this
+ // TODO: add properties for this
scene = ac.scene;
start = PSFRA;
end = PEFRA;
-
+
/* bake keyframes */
bake_graph_curves(&ac, start, end);
-
+
/* set notifier that keyframes have changed */
// NOTE: some distinction between order/number of keyframes and type should be made?
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_bake(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Bake Curve";
ot->idname = "GRAPH_OT_bake";
ot->description = "Bake selected F-Curves to a set of sampled points defining a similar curve";
-
+
/* api callbacks */
ot->invoke = WM_operator_confirm; // FIXME...
ot->exec = graphkeys_bake_exec;
- ot->poll = graphop_selected_fcurve_poll;
-
+ ot->poll = graphop_selected_fcurve_poll;
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
// todo: add props for start/end frames
}
@@ -1312,7 +1314,7 @@ static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
/* loop through all selected F-Curves, replacing its data with the sound samples */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
-
+
/* sample the sound */
fcurve_store_samples(fcu, &sbi, start, end, fcurve_samplingcb_sound);
@@ -1403,15 +1405,15 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot)
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
static void sample_graph_keys(bAnimContext *ac)
-{
+{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through filtered data and add keys between selected keyframes on every frame */
for (ale = anim_data.first; ale; ale = ale->next) {
sample_fcurve((FCurve *)ale->key_data);
@@ -1428,31 +1430,31 @@ static void sample_graph_keys(bAnimContext *ac)
static int graphkeys_sample_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* sample keyframes */
sample_graph_keys(&ac);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_sample(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Sample Keyframes";
ot->idname = "GRAPH_OT_sample";
ot->description = "Add keyframes on every frame between the selected keyframes";
-
+
/* api callbacks */
ot->exec = graphkeys_sample_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1471,27 +1473,27 @@ void GRAPH_OT_sample(wmOperatorType *ot)
static const EnumPropertyItem prop_graphkeys_expo_types[] = {
{FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"},
{FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"},
-
+
{MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"},
{CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"},
{0, NULL, 0, NULL, NULL}
};
/* this function is responsible for setting extrapolation mode for keyframes */
-static void setexpo_graph_keys(bAnimContext *ac, short mode)
+static void setexpo_graph_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through setting mode per F-Curve */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
-
+
if (mode >= 0) {
/* just set mode setting */
fcu->extend = mode;
@@ -1499,7 +1501,7 @@ static void setexpo_graph_keys(bAnimContext *ac, short mode)
ale->update |= ANIM_UPDATE_HANDLES;
}
else {
- /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
+ /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
* without having to go through FModifier UI in Graph Editor to do so
*/
if (mode == MAKE_CYCLIC_EXPO) {
@@ -1512,10 +1514,10 @@ static void setexpo_graph_keys(bAnimContext *ac, short mode)
else if (mode == CLEAR_CYCLIC_EXPO) {
/* remove all the modifiers fitting this description */
FModifier *fcm, *fcn = NULL;
-
+
for (fcm = fcu->modifiers.first; fcm; fcm = fcn) {
fcn = fcm->next;
-
+
if (fcm->type == FMODIFIER_TYPE_CYCLES)
remove_fmodifier(&fcu->modifiers, fcm);
}
@@ -1535,38 +1537,38 @@ static int graphkeys_expo_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* set handle type */
setexpo_graph_keys(&ac, mode);
-
+
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_extrapolation_type(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Keyframe Extrapolation";
ot->idname = "GRAPH_OT_extrapolation_type";
ot->description = "Set extrapolation mode for selected F-Curves";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = graphkeys_expo_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_expo_types, 0, "Type", "");
}
@@ -1574,17 +1576,17 @@ void GRAPH_OT_extrapolation_type(wmOperatorType *ot)
/* ******************** Set Interpolation-Type Operator *********************** */
/* this function is responsible for setting interpolation mode for keyframes */
-static void setipo_graph_keys(bAnimContext *ac, short mode)
+static void setipo_graph_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
KeyframeEditFunc set_cb = ANIM_editkeyframes_ipo(mode);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through setting BezTriple interpolation
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
*/
@@ -1604,38 +1606,38 @@ static int graphkeys_ipo_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* set handle type */
setipo_graph_keys(&ac, mode);
-
+
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_interpolation_type(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Keyframe Interpolation";
ot->idname = "GRAPH_OT_interpolation_type";
ot->description = "Set interpolation mode for the F-Curve segments starting from the selected keyframes";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = graphkeys_ipo_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", "");
}
@@ -1648,11 +1650,11 @@ static void seteasing_graph_keys(bAnimContext *ac, short mode)
bAnimListElem *ale;
int filter;
KeyframeEditFunc set_cb = ANIM_editkeyframes_easing(mode);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through setting BezTriple easing
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
*/
@@ -1670,20 +1672,20 @@ static int graphkeys_easing_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* set handle type */
seteasing_graph_keys(&ac, mode);
-
+
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1693,15 +1695,15 @@ void GRAPH_OT_easing_type(wmOperatorType *ot)
ot->name = "Set Keyframe Easing Type";
ot->idname = "GRAPH_OT_easing_type";
ot->description = "Set easing type for the F-Curve segments starting from the selected keyframes";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = graphkeys_easing_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_interpolation_easing_items, 0, "Type", "");
}
@@ -1709,25 +1711,25 @@ void GRAPH_OT_easing_type(wmOperatorType *ot)
/* ******************** Set Handle-Type Operator *********************** */
/* this function is responsible for setting handle-type of selected keyframes */
-static void sethandles_graph_keys(bAnimContext *ac, short mode)
+static void sethandles_graph_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc edit_cb = ANIM_editkeyframes_handles(mode);
KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through setting flags for handles
+
+ /* loop through setting flags for handles
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
*/
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
-
+
/* any selected keyframes for editing? */
if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL)) {
/* change type of selected handles */
@@ -1746,38 +1748,38 @@ static int graphkeys_handletype_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* set handle type */
sethandles_graph_keys(&ac, mode);
-
+
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_handle_type(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Set Keyframe Handle Type";
ot->idname = "GRAPH_OT_handle_type";
ot->description = "Set type of handle for selected keyframes";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = graphkeys_handletype_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", "");
}
@@ -1795,43 +1797,43 @@ void GRAPH_OT_handle_type(wmOperatorType *ot)
/* set of three euler-rotation F-Curves */
typedef struct tEulerFilter {
struct tEulerFilter *next, *prev;
-
+
ID *id; /* ID-block which owns the channels */
FCurve *(fcurves[3]); /* 3 Pointers to F-Curves */
const char *rna_path; /* Pointer to one of the RNA Path's used by one of the F-Curves */
} tEulerFilter;
-
+
static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
ListBase eulers = {NULL, NULL};
tEulerFilter *euf = NULL;
int groups = 0, failed = 0;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* The process is done in two passes:
* 1) Sets of three related rotation curves are identified from the selected channels,
* and are stored as a single 'operation unit' for the next step
* 2) Each set of three F-Curves is processed for each keyframe, with the values being
* processed as necessary
*/
-
+
/* step 1: extract only the rotation f-curves */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
-
- /* check if this is an appropriate F-Curve
+
+ /* check if this is an appropriate F-Curve
* - only rotation curves
* - for pchan curves, make sure we're only using the euler curves
*/
@@ -1843,9 +1845,9 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
(ale->id) ? ale->id->name : TIP_("<No ID>"), fcu->rna_path, fcu->array_index);
continue;
}
-
+
/* optimization: assume that xyz curves will always be stored consecutively,
- * so if the paths or the ID's don't match up, then a curve needs to be added
+ * so if the paths or the ID's don't match up, then a curve needs to be added
* to a new group
*/
if ((euf) && (euf->id == ale->id) && (STREQ(euf->rna_path, fcu->rna_path))) {
@@ -1857,7 +1859,7 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
euf = MEM_callocN(sizeof(tEulerFilter), "tEulerFilter");
BLI_addtail(&eulers, euf);
groups++;
-
+
euf->id = ale->id;
euf->rna_path = fcu->rna_path; /* this should be safe, since we're only using it for a short time */
euf->fcurves[fcu->array_index] = fcu;
@@ -1871,13 +1873,13 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No Euler Rotation F-Curves to fix up");
return OPERATOR_CANCELLED;
}
-
- /* step 2: go through each set of curves, processing the values at each keyframe
+
+ /* step 2: go through each set of curves, processing the values at each keyframe
* - it is assumed that there must be a full set of keyframes at each keyframe position
*/
for (euf = eulers.first; euf; euf = euf->next) {
int f;
-
+
/* sanity check: ensure that there are enough F-Curves to work on in this group */
/* TODO: also enforce assumption that there be a full set of keyframes at each position by ensuring that totvert counts are same? */
if (ELEM(NULL, euf->fcurves[0], euf->fcurves[1], euf->fcurves[2])) {
@@ -1888,7 +1890,7 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
(euf->fcurves[1] == NULL) ? "Y" : "",
(euf->fcurves[2] == NULL) ? "Z" : "",
euf->id->name, euf->rna_path);
-
+
/* keep track of number of failed sets, and carry on to next group */
failed++;
continue;
@@ -1900,21 +1902,21 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
FCurve *fcu = euf->fcurves[f];
BezTriple *bezt, *prev;
unsigned int i;
-
+
/* skip if not enough vets to do a decent analysis of... */
if (fcu->totvert <= 2)
continue;
-
+
/* prev follows bezt, bezt = "current" point to be fixed */
/* our method depends on determining a "difference" from the previous vert */
for (i = 1, prev = fcu->bezt, bezt = fcu->bezt + 1; i < fcu->totvert; i++, prev = bezt++) {
const float sign = (prev->vec[1][1] > bezt->vec[1][1]) ? 1.0f : -1.0f;
-
+
/* > 180 degree flip? */
if ((sign * (prev->vec[1][1] - bezt->vec[1][1])) >= (float)M_PI) {
/* 360 degrees to add/subtract frame value until difference is acceptably small that there's no more flip */
const float fac = sign * 2.0f * (float)M_PI;
-
+
while ((sign * (prev->vec[1][1] - bezt->vec[1][1])) >= (float)M_PI) {
bezt->vec[0][1] += fac;
bezt->vec[1][1] += fac;
@@ -1925,13 +1927,13 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
}
}
BLI_freelistN(&eulers);
-
+
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
/* updates + finishing warnings */
if (failed == groups) {
- BKE_report(op->reports, RPT_ERROR,
+ BKE_report(op->reports, RPT_ERROR,
"No Euler Rotations could be corrected, ensure each rotation has keys for all components, "
"and that F-Curves for these are in consecutive XYZ order and selected");
return OPERATOR_CANCELLED;
@@ -1943,15 +1945,15 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
"ensure each rotation has keys for all components, and that F-Curves for these are in "
"consecutive XYZ order and selected");
}
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
/* done at last */
return OPERATOR_FINISHED;
}
}
-
+
void GRAPH_OT_euler_filter(wmOperatorType *ot)
{
/* identifiers */
@@ -1960,11 +1962,11 @@ void GRAPH_OT_euler_filter(wmOperatorType *ot)
ot->description = "Fix large jumps and flips in the selected "
"Euler Rotation F-Curves arising from rotation "
"values being clipped when baking physics";
-
+
/* api callbacks */
ot->exec = graphkeys_euler_filter_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1988,18 +1990,18 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
bAnimListElem *ale;
int filter;
KeyframeEditData ked;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* init edit data */
memset(&ked, 0, sizeof(KeyframeEditData));
-
+
/* loop over action data, averaging values */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
short mapping_flag = ANIM_get_normalization_flags(&ac);
@@ -2010,9 +2012,9 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
memset(&current_ked, 0, sizeof(current_ked));
if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keyframes_loop(&current_ked, ale->key_data, NULL, bezt_calc_average, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else
ANIM_fcurve_keyframes_loop(&current_ked, ale->key_data, NULL, bezt_calc_average, NULL);
@@ -2022,14 +2024,14 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
ked.f2 += (current_ked.f2 + offset) * unit_scale;
ked.i2 += current_ked.i2;
}
-
+
ANIM_animdata_freelist(&anim_data);
-
+
/* set the new current frame and cursor values, based on the average time and value */
if (ked.i1) {
SpaceIpo *sipo = (SpaceIpo *)ac.sl;
Scene *scene = ac.scene;
-
+
/* take the average values, rounding to the nearest int as necessary for int results */
if (sipo->mode == SIPO_MODE_DRIVERS) {
/* Drivers Mode - Affects cursor (float) */
@@ -2043,10 +2045,10 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
sipo->cursorVal = ked.f2 / (float)ked.i1;
}
}
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
-
+
return OPERATOR_FINISHED;
}
@@ -2056,11 +2058,11 @@ void GRAPH_OT_frame_jump(wmOperatorType *ot)
ot->name = "Jump to Keyframes";
ot->idname = "GRAPH_OT_frame_jump";
ot->description = "Place the cursor on the midpoint of selected keyframes";
-
+
/* api callbacks */
ot->exec = graphkeys_framejump_exec;
ot->poll = graphkeys_framejump_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2085,23 +2087,23 @@ static const EnumPropertyItem prop_graphkeys_snap_types[] = {
};
/* this function is responsible for snapping keyframes to frame-times */
-static void snap_graph_keys(bAnimContext *ac, short mode)
+static void snap_graph_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
KeyframeEditData ked;
KeyframeEditFunc edit_cb;
float cursor_value = 0.0f;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* init custom data for iterating over keyframes */
- memset(&ked, 0, sizeof(KeyframeEditData));
+ memset(&ked, 0, sizeof(KeyframeEditData));
ked.scene = ac->scene;
if (mode == GRAPHKEYS_SNAP_NEAREST_MARKER) {
ked.list.first = (ac->markers) ? ac->markers->first : NULL;
@@ -2119,32 +2121,32 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
mode = SNAP_KEYS_TIME;
}
}
-
+
/* get beztriple editing callbacks */
edit_cb = ANIM_editkeyframes_snap(mode);
-
+
/* snap keyframes */
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) */
if (mode == GRAPHKEYS_SNAP_VALUE) {
short mapping_flag = ANIM_get_normalization_flags(ac);
float offset;
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag, &offset);
-
+
ked.f1 = (cursor_value / unit_scale) - offset;
}
-
+
/* perform snapping */
if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
}
- else
+ else
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
-
+
ale->update |= ANIM_UPDATE_DEFAULT;
}
@@ -2158,38 +2160,38 @@ static int graphkeys_snap_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get snapping mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* snap keyframes */
snap_graph_keys(&ac, mode);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_snap(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Keys";
ot->idname = "GRAPH_OT_snap";
ot->description = "Snap selected keyframes to the chosen times/values";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = graphkeys_snap_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_snap_types, 0, "Type", "");
}
@@ -2212,28 +2214,28 @@ static const EnumPropertyItem prop_graphkeys_mirror_types[] = {
};
/* this function is responsible for mirroring keyframes */
-static void mirror_graph_keys(bAnimContext *ac, short mode)
+static void mirror_graph_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
KeyframeEditData ked;
KeyframeEditFunc edit_cb;
float cursor_value = 0.0f;
/* init custom data for looping over keyframes */
- memset(&ked, 0, sizeof(KeyframeEditData));
+ memset(&ked, 0, sizeof(KeyframeEditData));
ked.scene = ac->scene;
-
+
/* store mode-specific custom data... */
if (mode == GRAPHKEYS_MIRROR_MARKER) {
TimeMarker *marker = NULL;
-
+
/* find first selected marker */
marker = ED_markers_get_first_selected(ac->markers);
-
+
/* store marker's time (if available) */
if (marker)
ked.f1 = (float)marker->frame;
@@ -2252,36 +2254,36 @@ static void mirror_graph_keys(bAnimContext *ac, short mode)
mode = MIRROR_KEYS_TIME;
}
}
-
+
/* get beztriple editing callbacks */
edit_cb = ANIM_editkeyframes_mirror(mode);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* mirror keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* apply unit corrections */
if (mode == GRAPHKEYS_MIRROR_VALUE) {
short mapping_flag = ANIM_get_normalization_flags(ac);
float offset;
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset);
-
+
ked.f1 = (cursor_value + offset) * unit_scale;
}
-
+
/* perform actual mirroring */
if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
}
- else
+ else
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
-
+
ale->update |= ANIM_UPDATE_DEFAULT;
}
@@ -2295,38 +2297,38 @@ static int graphkeys_mirror_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get mirroring mode */
mode = RNA_enum_get(op->ptr, "type");
-
+
/* mirror keyframes */
mirror_graph_keys(&ac, mode);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_mirror(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Mirror Keys";
ot->idname = "GRAPH_OT_mirror";
ot->description = "Flip selected keyframes over the selected mirror line";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = graphkeys_mirror_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_mirror_types, 0, "Type", "");
}
@@ -2339,15 +2341,15 @@ static int graphkeys_smooth_exec(bContext *C, wmOperator *UNUSED(op))
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* smooth keyframes */
for (ale = anim_data.first; ale; ale = ale->next) {
/* For now, we can only smooth by flattening handles AND smoothing curve values.
@@ -2361,24 +2363,24 @@ static int graphkeys_smooth_exec(bContext *C, wmOperator *UNUSED(op))
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_smooth(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Smooth Keys";
ot->idname = "GRAPH_OT_smooth";
ot->description = "Apply weighted moving means to make selected F-Curves less bumpy";
-
+
/* api callbacks */
ot->exec = graphkeys_smooth_exec;
ot->poll = graphop_editable_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2393,29 +2395,29 @@ static const EnumPropertyItem *graph_fmodifier_itemf(bContext *C, PointerRNA *UN
EnumPropertyItem *item = NULL;
int totitem = 0;
int i = 0;
-
+
if (C == NULL) {
return rna_enum_fmodifier_type_items;
}
-
+
/* start from 1 to skip the 'Invalid' modifier type */
for (i = 1; i < FMODIFIER_NUM_TYPES; i++) {
const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i);
int index;
-
+
/* check if modifier is valid for this context */
if (fmi == NULL)
continue;
-
+
index = RNA_enum_from_value(rna_enum_fmodifier_type_items, fmi->type);
if (index != -1) { /* Not all types are implemented yet... */
RNA_enum_item_add(&item, &totitem, &rna_enum_fmodifier_type_items[index]);
}
}
-
+
RNA_enum_item_end(&item, &totitem);
*r_free = true;
-
+
return item;
}
@@ -2426,14 +2428,14 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
bAnimListElem *ale;
int filter;
short type;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get type of modifier to add */
type = RNA_enum_get(op->ptr, "type");
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
if (RNA_boolean_get(op->ptr, "only_active"))
@@ -2441,12 +2443,12 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
else
filter |= (ANIMFILTER_SEL | ANIMFILTER_CURVE_VISIBLE);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* add f-modifier to each curve */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
FModifier *fcm;
-
+
/* add F-Modifier of specified type to active F-Curve, and make it the active one */
fcm = add_fmodifier(&fcu->modifiers, type, fcu);
if (fcm) {
@@ -2456,41 +2458,41 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Modifier could not be added (see console for details)");
break;
}
-
+
ale->update |= ANIM_UPDATE_DEPS;
}
-
+
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_fmodifier_add(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Add F-Curve Modifier";
ot->idname = "GRAPH_OT_fmodifier_add";
ot->description = "Add F-Modifier to the active/selected F-Curves";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = graph_fmodifier_add_exec;
- ot->poll = graphop_selected_fcurve_poll;
-
+ ot->poll = graphop_selected_fcurve_poll;
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
prop = RNA_def_enum(ot->srna, "type", rna_enum_fmodifier_type_items, 0, "Type", "");
RNA_def_enum_funcs(prop, graph_fmodifier_itemf);
ot->prop = prop;
-
+
RNA_def_boolean(ot->srna, "only_active", 1, "Only Active", "Only add F-Modifier to active F-Curve");
}
@@ -2501,28 +2503,28 @@ static int graph_fmodifier_copy_exec(bContext *C, wmOperator *op)
bAnimContext ac;
bAnimListElem *ale;
bool ok = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* clear buffer first */
ANIM_fmodifiers_copybuf_free();
-
+
/* get the active F-Curve */
ale = get_active_fcurve_channel(&ac);
-
+
/* if this exists, call the copy F-Modifiers API function */
if (ale && ale->data) {
FCurve *fcu = (FCurve *)ale->data;
-
+
/* TODO: when 'active' vs 'all' boolean is added, change last param! */
ok = ANIM_fmodifiers_copy_to_buf(&fcu->modifiers, 0);
-
+
/* free temp data now */
MEM_freeN(ale);
}
-
+
/* successful or not? */
if (ok == 0) {
BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
@@ -2531,21 +2533,21 @@ static int graph_fmodifier_copy_exec(bContext *C, wmOperator *op)
else
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_fmodifier_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Copy F-Modifiers";
ot->idname = "GRAPH_OT_fmodifier_copy";
ot->description = "Copy the F-Modifier(s) of the active F-Curve";
-
+
/* api callbacks */
ot->exec = graph_fmodifier_copy_exec;
- ot->poll = graphop_active_fcurve_poll;
-
+ ot->poll = graphop_active_fcurve_poll;
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
//ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All F-Modifiers", "Copy all the F-Modifiers, instead of just the active one");
}
@@ -2555,18 +2557,18 @@ void GRAPH_OT_fmodifier_copy(wmOperatorType *ot)
static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
const bool replace = RNA_boolean_get(op->ptr, "replace");
bool ok = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* filter data */
if (RNA_boolean_get(op->ptr, "only_active")) {
/* This should be the default (for buttons) - Just paste to the active FCurve */
@@ -2576,32 +2578,32 @@ static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op)
/* This is only if the operator gets called from a hotkey or search - Paste to all visible curves */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
}
-
+
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* paste modifiers */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
int tot;
-
+
tot = ANIM_fmodifiers_paste_from_buf(&fcu->modifiers, replace, fcu);
-
+
if (tot) {
ale->update |= ANIM_UPDATE_DEPS;
ok = true;
}
}
-
+
if (ok) {
ANIM_animdata_update(&ac, &anim_data);
}
ANIM_animdata_freelist(&anim_data);
-
+
/* successful or not? */
if (ok) {
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
else {
@@ -2609,24 +2611,24 @@ static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
}
-
+
void GRAPH_OT_fmodifier_paste(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Paste F-Modifiers";
ot->idname = "GRAPH_OT_fmodifier_paste";
ot->description = "Add copied F-Modifiers to the selected F-Curves";
-
+
/* api callbacks */
ot->exec = graph_fmodifier_paste_exec;
ot->poll = graphop_active_fcurve_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "only_active", true, "Only Active", "Only paste F-Modifiers on active F-Curve");
- RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
+ RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
"Replace existing F-Modifiers, instead of just appending to the end of the existing list");
}
@@ -2640,45 +2642,45 @@ static int graph_driver_vars_copy_exec(bContext *C, wmOperator *op)
bAnimContext ac;
bAnimListElem *ale;
bool ok = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* clear buffer first */
ANIM_driver_vars_copybuf_free();
-
+
/* get the active F-Curve */
ale = get_active_fcurve_channel(&ac);
-
+
/* if this exists, call the copy driver vars API function */
if (ale && ale->data) {
FCurve *fcu = (FCurve *)ale->data;
-
+
ok = ANIM_driver_vars_copy(op->reports, fcu);
-
+
/* free temp data now */
MEM_freeN(ale);
}
-
+
/* successful or not? */
if (ok)
return OPERATOR_FINISHED;
else
return OPERATOR_CANCELLED;
}
-
+
void GRAPH_OT_driver_variables_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Copy Driver Variables";
ot->idname = "GRAPH_OT_driver_variables_copy";
ot->description = "Copy the driver variables of the active F-Curve";
-
+
/* api callbacks */
ot->exec = graph_driver_vars_copy_exec;
- ot->poll = graphop_active_fcurve_poll;
-
+ ot->poll = graphop_active_fcurve_poll;
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2688,62 +2690,62 @@ void GRAPH_OT_driver_variables_copy(wmOperatorType *ot)
static int graph_driver_vars_paste_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
const bool replace = RNA_boolean_get(op->ptr, "replace");
bool ok = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* paste variables */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
ok |= ANIM_driver_vars_paste(op->reports, fcu, replace);
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
-
+
/* successful or not? */
if (ok) {
/* rebuild depsgraph, now that there are extra deps here */
DEG_relations_tag_update(CTX_data_main(C));
-
+
/* set notifier that keyframes have changed */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, CTX_data_scene(C));
-
+
return OPERATOR_FINISHED;
}
else {
return OPERATOR_CANCELLED;
}
}
-
+
void GRAPH_OT_driver_variables_paste(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Paste Driver Variables";
ot->idname = "GRAPH_OT_driver_variables_paste";
ot->description = "Add copied driver variables to the active driver";
-
+
/* api callbacks */
ot->exec = graph_driver_vars_paste_exec;
ot->poll = graphop_active_fcurve_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
- RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
+ RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
"Replace existing driver variables, instead of just appending to the end of the existing list");
}
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index d0241f09f04..da352d4ea06 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -87,7 +87,7 @@ enum eGraphKeys_ColumnSelect_Mode {
/* ***************************************** */
/* graph_edit.c */
-void get_graph_keyframe_extents(struct bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax,
+void get_graph_keyframe_extents(struct bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax,
const bool do_selected, const bool include_handles);
void GRAPH_OT_previewrange_set(struct wmOperatorType *ot);
@@ -119,7 +119,7 @@ void GRAPH_OT_frame_jump(struct wmOperatorType *ot);
void GRAPH_OT_snap(struct wmOperatorType *ot);
void GRAPH_OT_mirror(struct wmOperatorType *ot);
-/* defines for snap keyframes
+/* defines for snap keyframes
* NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h)
*/
enum eGraphKeys_Snap_Mode {
@@ -131,7 +131,7 @@ enum eGraphKeys_Snap_Mode {
GRAPHKEYS_SNAP_VALUE,
};
-/* defines for mirror keyframes
+/* defines for mirror keyframes
* NOTE: keep in sync with eEditKeyframes_Mirror (in ED_keyframes_edit.h)
*/
enum eGraphKeys_Mirror_Mode {
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 48d4e9ff8eb..bae5798ca21 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -83,19 +83,19 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
SpaceIpo *sipo = CTX_wm_space_graph(C);
float frame = RNA_float_get(op->ptr, "frame"); /* this isn't technically "frame", but it'll do... */
-
+
/* adjust the frame or the cursor x-value */
if (sipo->mode == SIPO_MODE_DRIVERS) {
/* adjust cursor x-value */
sipo->cursorTime = frame;
}
else {
- /* adjust the frame
+ /* adjust the frame
* NOTE: sync this part of the code with ANIM_OT_change_frame
*/
/* 1) frame is rounded to the nearest int, since frames are ints */
CFRA = round_fl_to_int(frame);
-
+
if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
/* Clip to preview range
* NOTE: Preview range won't go into negative values,
@@ -107,14 +107,14 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op)
/* Prevent negative frames */
FRAMENUMBER_MIN_CLAMP(CFRA);
}
-
+
SUBFRA = 0.0f;
BKE_sound_seek_scene(bmain, scene);
}
-
+
/* set the cursor value */
sipo->cursorVal = RNA_float_get(op->ptr, "value");
-
+
/* send notifiers - notifiers for frame should force an update for both vars ok... */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
@@ -135,14 +135,14 @@ static void graphview_cursor_setprops(bContext *C, wmOperator *op, const wmEvent
{
ARegion *ar = CTX_wm_region(C);
float viewx, viewy;
-
+
/* abort if not active region (should not really be possible) */
if (ar == NULL)
return;
-
+
/* convert from region coordinates to View2D 'tot' space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
-
+
/* store the values in the operator properties */
/* NOTE: we don't clamp frame here, as it might be used for the drivers cursor */
RNA_float_set(op->ptr, "frame", viewx);
@@ -153,18 +153,18 @@ static void graphview_cursor_setprops(bContext *C, wmOperator *op, const wmEvent
static int graphview_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bScreen *screen = CTX_wm_screen(C);
-
+
/* Change to frame that mouse is over before adding modal handler,
* as user could click on a single frame (jump to frame) as well as
* click-dragging over a range (modal scrubbing). Apply this change.
*/
graphview_cursor_setprops(C, op, event);
graphview_cursor_apply(C, op);
-
+
/* Signal that a scrubbing operating is starting */
if (screen)
screen->scrubbing = true;
-
+
/* add temp handler */
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
@@ -175,32 +175,32 @@ static int graphview_cursor_modal(bContext *C, wmOperator *op, const wmEvent *ev
{
bScreen *screen = CTX_wm_screen(C);
Scene *scene = CTX_data_scene(C);
-
+
/* execute the events */
switch (event->type) {
case ESCKEY:
if (screen)
screen->scrubbing = false;
-
+
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
return OPERATOR_FINISHED;
-
+
case MOUSEMOVE:
/* set the new values */
graphview_cursor_setprops(C, op, event);
graphview_cursor_apply(C, op);
break;
-
- case LEFTMOUSE:
+
+ case LEFTMOUSE:
case RIGHTMOUSE:
case MIDDLEMOUSE:
- /* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init
+ /* we check for either mouse-button to end, as checking for ACTIONMOUSE (which is used to init
* the modal op) doesn't work for some reason
*/
if (event->val == KM_RELEASE) {
if (screen)
screen->scrubbing = false;
-
+
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
return OPERATOR_FINISHED;
}
@@ -216,13 +216,13 @@ static void GRAPH_OT_cursor_set(wmOperatorType *ot)
ot->name = "Set Cursor";
ot->idname = "GRAPH_OT_cursor_set";
ot->description = "Interactively set the current frame and value cursor";
-
+
/* api callbacks */
ot->exec = graphview_cursor_exec;
ot->invoke = graphview_cursor_invoke;
ot->modal = graphview_cursor_modal;
ot->poll = graphview_cursor_poll;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO;
@@ -241,39 +241,39 @@ static int graphview_curves_hide_exec(bContext *C, wmOperator *op)
bAnimListElem *ale;
int filter;
const bool unselected = RNA_boolean_get(op->ptr, "unselected");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
- /* get list of all channels that selection may need to be flushed to
+
+ /* get list of all channels that selection may need to be flushed to
* - hierarchy must not affect what we have access to here...
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
-
+
/* filter data
- * - of the remaining visible curves, we want to hide the ones that are
- * selected/unselected (depending on "unselected" prop)
+ * - of the remaining visible curves, we want to hide the ones that are
+ * selected/unselected (depending on "unselected" prop)
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
if (unselected)
filter |= ANIMFILTER_UNSEL;
else
filter |= ANIMFILTER_SEL;
-
+
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
/* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */
/* TODO: find out why this is the case, and fix that */
if (ale->type == ANIMTYPE_OBJECT)
continue;
-
+
/* change the hide setting, and unselect it... */
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_CLEAR);
-
+
/* now, also flush selection status up/down as appropriate */
ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
}
@@ -281,7 +281,7 @@ static int graphview_curves_hide_exec(bContext *C, wmOperator *op)
/* cleanup */
ANIM_animdata_freelist(&anim_data);
BLI_freelistN(&all_data);
-
+
/* unhide selected */
if (unselected) {
/* turn off requirement for visible */
@@ -295,21 +295,21 @@ static int graphview_curves_hide_exec(bContext *C, wmOperator *op)
/* TODO: find out why this is the case, and fix that */
if (ale->type == ANIMTYPE_OBJECT)
continue;
-
+
/* change the hide setting, and unselect it... */
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD);
-
+
/* now, also flush selection status up/down as appropriate */
ANIM_flush_setting_anim_channels(&ac, &anim_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
}
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
-
-
+
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -319,14 +319,14 @@ static void GRAPH_OT_hide(wmOperatorType *ot)
ot->name = "Hide Curves";
ot->idname = "GRAPH_OT_hide";
ot->description = "Hide selected curves from Graph Editor view";
-
+
/* api callbacks */
ot->exec = graphview_curves_hide_exec;
ot->poll = ED_operator_graphedit_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected curves");
}
@@ -341,50 +341,50 @@ static int graphview_curves_reveal_exec(bContext *C, wmOperator *op)
bAnimListElem *ale;
int filter;
const bool select = RNA_boolean_get(op->ptr, "select");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
- /* get list of all channels that selection may need to be flushed to
+
+ /* get list of all channels that selection may need to be flushed to
* - hierarchy must not affect what we have access to here...
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
-
+
/* filter data
* - just go through all visible channels, ensuring that everything is set to be curve-visible
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
/* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */
/* TODO: find out why this is the case, and fix that */
if (ale->type == ANIMTYPE_OBJECT)
continue;
-
+
/* select if it is not visible */
if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE) == 0) {
ANIM_channel_setting_set(
&ac, ale, ACHANNEL_SETTING_SELECT,
select ? ACHANNEL_SETFLAG_ADD : ACHANNEL_SETFLAG_CLEAR);
}
-
+
/* change the visibility setting */
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
-
+
/* now, also flush selection status up/down as appropriate */
ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, true);
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
BLI_freelistN(&all_data);
-
+
/* send notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -394,11 +394,11 @@ static void GRAPH_OT_reveal(wmOperatorType *ot)
ot->name = "Reveal Curves";
ot->idname = "GRAPH_OT_reveal";
ot->description = "Make previously hidden curves visible again in Graph Editor view";
-
+
/* api callbacks */
ot->exec = graphview_curves_reveal_exec;
ot->poll = ED_operator_graphedit_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -411,19 +411,19 @@ void graphedit_operatortypes(void)
{
/* view */
WM_operatortype_append(GRAPH_OT_cursor_set);
-
+
WM_operatortype_append(GRAPH_OT_previewrange_set);
WM_operatortype_append(GRAPH_OT_view_all);
WM_operatortype_append(GRAPH_OT_view_selected);
WM_operatortype_append(GRAPH_OT_properties);
WM_operatortype_append(GRAPH_OT_view_frame);
-
+
WM_operatortype_append(GRAPH_OT_ghost_curves_create);
WM_operatortype_append(GRAPH_OT_ghost_curves_clear);
-
+
WM_operatortype_append(GRAPH_OT_hide);
WM_operatortype_append(GRAPH_OT_reveal);
-
+
/* keyframes */
/* selection */
WM_operatortype_append(GRAPH_OT_clickselect);
@@ -436,7 +436,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_select_more);
WM_operatortype_append(GRAPH_OT_select_less);
WM_operatortype_append(GRAPH_OT_select_leftright);
-
+
/* editing */
WM_operatortype_append(GRAPH_OT_snap);
WM_operatortype_append(GRAPH_OT_mirror);
@@ -453,18 +453,18 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_euler_filter);
WM_operatortype_append(GRAPH_OT_delete);
WM_operatortype_append(GRAPH_OT_duplicate);
-
+
WM_operatortype_append(GRAPH_OT_copy);
WM_operatortype_append(GRAPH_OT_paste);
-
+
WM_operatortype_append(GRAPH_OT_keyframe_insert);
WM_operatortype_append(GRAPH_OT_click_insert);
-
+
/* F-Curve Modifiers */
WM_operatortype_append(GRAPH_OT_fmodifier_add);
WM_operatortype_append(GRAPH_OT_fmodifier_copy);
WM_operatortype_append(GRAPH_OT_fmodifier_paste);
-
+
/* Drivers */
WM_operatortype_append(GRAPH_OT_driver_variables_copy);
WM_operatortype_append(GRAPH_OT_driver_variables_paste);
@@ -475,7 +475,7 @@ void ED_operatormacros_graph(void)
{
wmOperatorType *ot;
wmOperatorTypeMacro *otmacro;
-
+
ot = WM_operatortype_append_macro("GRAPH_OT_duplicate_move", "Duplicate",
"Make a copy of all selected keyframes and move them",
OPTYPE_UNDO | OPTYPE_REGISTER);
@@ -491,7 +491,7 @@ void ED_operatormacros_graph(void)
static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
{
wmKeyMapItem *kmi;
-
+
/* view */
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.show_handles");
@@ -500,8 +500,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
* This keymap is supposed to override ANIM_OT_change_frame, which does the same except it doesn't do y-values
*/
WM_keymap_add_item(keymap, "GRAPH_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
-
-
+
+
/* graph_select.c - selection tools */
/* click-select: keyframe (replace) */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
@@ -533,7 +533,7 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
RNA_boolean_set(kmi->ptr, "extend", true);
RNA_boolean_set(kmi->ptr, "curves", true);
RNA_boolean_set(kmi->ptr, "column", false);
-
+
/* click-select left/right */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
@@ -541,20 +541,20 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", true);
RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_TEST);
-
+
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_LEFT);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", GRAPHKEYS_LRSEL_RIGHT);
-
+
/* deselect all */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "invert", false);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "invert", true);
-
+
/* borderselect */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "axis_range", false);
@@ -562,68 +562,70 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "axis_range", true);
RNA_boolean_set(kmi->ptr, "include_handles", false);
-
+
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "axis_range", false);
RNA_boolean_set(kmi->ptr, "include_handles", true);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "axis_range", true);
RNA_boolean_set(kmi->ptr, "include_handles", true);
-
+
/* region select */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
-
+
WM_keymap_add_item(keymap, "GRAPH_OT_select_circle", CKEY, KM_PRESS, 0, 0);
-
+
/* column select */
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_KEYS);
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_CFRA);
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN);
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN);
-
+
/* select more/less */
WM_keymap_add_item(keymap, "GRAPH_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
-
+
/* select linked */
WM_keymap_add_item(keymap, "GRAPH_OT_select_linked", LKEY, KM_PRESS, 0, 0);
-
-
+
+
/* graph_edit.c */
/* jump to selected keyframes */
WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* menu + single-step transform */
WM_keymap_add_item(keymap, "GRAPH_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_mirror", MKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "GRAPH_OT_handle_type", VKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_interpolation_type", TKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_easing_type", EKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* destructive */
WM_keymap_add_item(keymap, "GRAPH_OT_smooth", OKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_sample", OKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "GRAPH_OT_bake", CKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_menu(keymap, "GRAPH_MT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "GRAPH_MT_delete", DELKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_menu(keymap, "GRAPH_MT_specials", WKEY, KM_PRESS, 0, 0);
+
WM_keymap_add_item(keymap, "GRAPH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* insertkey */
WM_keymap_add_item(keymap, "GRAPH_OT_keyframe_insert", IKEY, KM_PRESS, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_click_insert", ACTIONMOUSE, KM_CLICK, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_click_insert", ACTIONMOUSE, KM_CLICK, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", true);
-
+
/* copy/paste */
WM_keymap_add_item(keymap, "GRAPH_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
@@ -648,16 +650,16 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* F-Modifiers */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "only_active", false);
-
+
/* animation module */
/* channels list
* NOTE: these operators were originally for the channels list, but are added here too for convenience...
*/
WM_keymap_add_item(keymap, "ANIM_OT_channels_editable_toggle", TABKEY, KM_PRESS, 0, 0);
-
+
/* transform system */
transform_keymap_for_space(keyconf, keymap, SPACE_IPO);
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_fcurve");
@@ -665,15 +667,15 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
RNA_string_set(kmi->ptr, "value", "BOUNDING_BOX_CENTER");
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
RNA_string_set(kmi->ptr, "value", "CURSOR");
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
RNA_string_set(kmi->ptr, "value", "INDIVIDUAL_ORIGINS");
-
+
/* special markers hotkeys for anim editors: see note in definition of this function */
ED_marker_keymap_animedit_conflictfree(keymap);
}
@@ -684,35 +686,34 @@ void graphedit_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
/* keymap for all regions */
keymap = WM_keymap_find(keyconf, "Graph Editor Generic", SPACE_IPO, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_properties", NKEY, KM_PRESS, 0, 0);
-
+
/* extrapolation works on channels, not keys */
WM_keymap_add_item(keymap, "GRAPH_OT_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* find (i.e. a shortcut for setting the name filter) */
WM_keymap_add_item(keymap, "ANIM_OT_channels_find", FKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* hide/reveal selected curves */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_hide", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
-
+
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
-
+
WM_keymap_add_item(keymap, "GRAPH_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
-
-
+
+
/* channels */
- /* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module.
+ /* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module.
* All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these
* are all used for the Graph Editor too.
*/
-
+
/* keyframes */
keymap = WM_keymap_find(keyconf, "Graph Editor", SPACE_IPO, 0);
graphedit_keymap_keyframes(keyconf, keymap);
}
-
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 98cd847b427..ed9bed19d20 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -88,20 +88,20 @@ void deselect_graph_keys(bAnimContext *ac, bool test, short sel, bool do_channel
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
KeyframeEditData ked = {{NULL}};
KeyframeEditFunc test_cb, sel_cb;
-
+
/* determine type-based settings */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
-
+
/* filter data */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* init BezTriple looping data */
test_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
-
+
/* See if we should be selecting or deselecting */
if (test) {
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -111,17 +111,17 @@ void deselect_graph_keys(bAnimContext *ac, bool test, short sel, bool do_channel
}
}
}
-
+
/* convert sel to selectmode, and use that to get editor */
sel_cb = ANIM_editkeyframes_select(sel);
-
+
/* Now set the flags */
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
-
+
/* Keyframes First */
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
-
+
/* affect channel selection status? */
if (do_channels) {
/* only change selection of channel when the visibility of keyframes doesn't depend on this */
@@ -129,17 +129,17 @@ void deselect_graph_keys(bAnimContext *ac, bool test, short sel, bool do_channel
/* deactivate the F-Curve, and deselect if deselecting keyframes.
* otherwise select the F-Curve too since we've selected all the keyframes
*/
- if (sel == SELECT_SUBTRACT)
+ if (sel == SELECT_SUBTRACT)
fcu->flag &= ~FCURVE_SELECTED;
else
fcu->flag |= FCURVE_SELECTED;
}
-
+
/* always deactivate all F-Curves if we perform batch ops for selection */
fcu->flag &= ~FCURVE_ACTIVE;
}
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -150,56 +150,56 @@ static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
bAnimListElem *ale_active = NULL;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
- /* find active F-Curve, and preserve this for later
+
+ /* find active F-Curve, and preserve this for later
* or else it becomes annoying with the current active
* curve keeps fading out even while you're editing it
*/
ale_active = get_active_fcurve_channel(&ac);
-
+
/* 'standard' behavior - check if selected, then apply relevant selection */
if (RNA_boolean_get(op->ptr, "invert"))
deselect_graph_keys(&ac, 0, SELECT_INVERT, true);
else
deselect_graph_keys(&ac, 1, SELECT_ADD, true);
-
+
/* restore active F-Curve... */
if (ale_active) {
FCurve *fcu = (FCurve *)ale_active->data;
-
- /* all others should not be disabled, so we should be able to just set this directly...
+
+ /* all others should not be disabled, so we should be able to just set this directly...
* - selection needs to be set too, or else this won't work...
*/
fcu->flag |= (FCURVE_SELECTED | FCURVE_ACTIVE);
-
+
MEM_freeN(ale_active);
ale_active = NULL;
}
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select All";
ot->idname = "GRAPH_OT_select_all_toggle";
ot->description = "Toggle selection of all keyframes";
-
+
/* api callbacks */
ot->exec = graphkeys_deselectall_exec;
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_boolean(ot->srna, "invert", 0, "Invert", "");
}
@@ -226,24 +226,24 @@ static void borderselect_graphkeys(
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter, mapping_flag;
-
+
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
KeyframeEditData ked;
KeyframeEditFunc ok_cb, select_cb;
View2D *v2d = &ac->ar->v2d;
rctf rectf, scaled_rectf;
-
+
/* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* get beztriple editing/validation funcs */
select_cb = ANIM_editkeyframes_select(selectmode);
ok_cb = ANIM_editkeyframes_ok(mode);
-
+
/* init editing data */
memset(&ked, 0, sizeof(KeyframeEditData));
if (mode == BEZT_OK_REGION_LASSO) {
@@ -259,7 +259,7 @@ static void borderselect_graphkeys(
else {
ked.data = &scaled_rectf;
}
-
+
/* treat handles separately? */
if (incl_handles) {
ked.iterflags |= KEYFRAME_ITER_INCL_HANDLES;
@@ -267,29 +267,29 @@ static void borderselect_graphkeys(
}
else
mapping_flag = ANIM_UNITCONV_ONLYKEYS;
-
+
mapping_flag |= ANIM_get_normalization_flags(ac);
-
+
/* loop over data, doing border select */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
float offset;
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
-
+
/* apply NLA mapping to all the keyframes, since it's easier than trying to
* guess when a callback might use something different
*/
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, incl_handles == 0);
-
+
scaled_rectf.xmin = rectf.xmin;
scaled_rectf.xmax = rectf.xmax;
scaled_rectf.ymin = rectf.ymin / unit_scale - offset;
scaled_rectf.ymax = rectf.ymax / unit_scale - offset;
-
- /* set horizontal range (if applicable)
- * NOTE: these values are only used for x-range and y-range but not region
+
+ /* set horizontal range (if applicable)
+ * NOTE: these values are only used for x-range and y-range but not region
* (which uses ked.data, i.e. rectf)
*/
if (mode != BEZT_OK_VALUERANGE) {
@@ -300,12 +300,12 @@ static void borderselect_graphkeys(
ked.f1 = rectf.ymin;
ked.f2 = rectf.ymax;
}
-
+
/* firstly, check if any keyframes will be hit by this */
if (ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, ok_cb, NULL)) {
/* select keyframes that are in the appropriate places */
ANIM_fcurve_keyframes_loop(&ked, fcu, ok_cb, select_cb, NULL);
-
+
/* only change selection of channel when the visibility of keyframes doesn't depend on this */
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
/* select the curve too now that curve will be touched */
@@ -313,12 +313,12 @@ static void borderselect_graphkeys(
fcu->flag |= FCURVE_SELECTED;
}
}
-
+
/* un-apply NLA mapping from all the keyframes */
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles == 0);
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -334,7 +334,7 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
bool incl_handles;
const bool select = !RNA_boolean_get(op->ptr, "deselect");
const bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
@@ -344,7 +344,7 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
if (!extend)
deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true);
- /* get select mode
+ /* get select mode
* - 'include_handles' from the operator specifies whether to include handles in the selection
*/
if (select) {
@@ -353,15 +353,15 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
else {
selectmode = SELECT_SUBTRACT;
}
-
+
incl_handles = RNA_boolean_get(op->ptr, "include_handles");
-
+
/* get settings from operator */
WM_operator_properties_border_to_rcti(op, &rect);
-
+
/* selection 'mode' depends on whether borderselect region only matters on one axis */
if (RNA_boolean_get(op->ptr, "axis_range")) {
- /* mode depends on which axis of the range is larger to determine which axis to use
+ /* mode depends on which axis of the range is larger to determine which axis to use
* - checking this in region-space is fine, as it's fundamentally still going to be a different rect size
* - the frame-range select option is favored over the channel one (x over y), as frame-range one is often
* used for tweaking timing when "blocking", while channels is not that useful...
@@ -371,19 +371,19 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
else
mode = BEZT_OK_VALUERANGE;
}
- else
+ else
mode = BEZT_OK_REGION;
BLI_rctf_rcti_copy(&rect_fl, &rect);
/* apply borderselect action */
borderselect_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL);
-
+
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
-}
+}
void GRAPH_OT_select_border(wmOperatorType *ot)
{
@@ -391,21 +391,21 @@ void GRAPH_OT_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->idname = "GRAPH_OT_select_border";
ot->description = "Select all keyframes within the specified region";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = graphkeys_borderselect_exec;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
-
+
ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
RNA_def_boolean(ot->srna, "include_handles", 0, "Include Handles", "Are handles tested individually against the selection criteria");
}
@@ -416,34 +416,34 @@ void GRAPH_OT_select_border(wmOperatorType *ot)
static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
KeyframeEdit_LassoData data_lasso = {0};
rcti rect;
rctf rect_fl;
-
+
short selectmode;
bool incl_handles;
bool extend;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
data_lasso.rectf_view = &rect_fl;
data_lasso.mcords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcords_tot);
if (data_lasso.mcords == NULL)
return OPERATOR_CANCELLED;
-
+
/* clear all selection if not extending selection */
extend = RNA_boolean_get(op->ptr, "extend");
if (!extend)
deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true);
-
+
if (!RNA_boolean_get(op->ptr, "deselect"))
selectmode = SELECT_ADD;
else
selectmode = SELECT_SUBTRACT;
-
+
{
SpaceIpo *sipo = (SpaceIpo *)ac.sl;
if (selectmode == SELECT_ADD) {
@@ -454,19 +454,19 @@ static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0;
}
}
-
+
/* get settings from operator */
BLI_lasso_boundbox(&rect, data_lasso.mcords, data_lasso.mcords_tot);
BLI_rctf_rcti_copy(&rect_fl, &rect);
-
+
/* apply borderselect action */
borderselect_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso);
-
+
MEM_freeN((void *)data_lasso.mcords);
-
+
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -476,17 +476,17 @@ void GRAPH_OT_select_lasso(wmOperatorType *ot)
ot->name = "Lasso Select";
ot->description = "Select keyframe points using lasso selection";
ot->idname = "GRAPH_OT_select_lasso";
-
+
/* api callbacks */
ot->invoke = WM_gesture_lasso_invoke;
ot->modal = WM_gesture_lasso_modal;
ot->exec = graphkeys_lassoselect_exec;
ot->poll = graphop_visible_keyframes_poll;
ot->cancel = WM_gesture_lasso_cancel;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_gesture_lasso_select(ot);
}
@@ -499,10 +499,10 @@ static int graph_circle_select_exec(bContext *C, wmOperator *op)
const bool select = !RNA_boolean_get(op->ptr, "deselect");
const short selectmode = select ? SELECT_ADD : SELECT_SUBTRACT;
bool incl_handles = false;
-
+
KeyframeEdit_CircleData data = {0};
rctf rect_fl;
-
+
float x = RNA_int_get(op->ptr, "x");
float y = RNA_int_get(op->ptr, "y");
float radius = RNA_int_get(op->ptr, "radius");
@@ -510,17 +510,17 @@ static int graph_circle_select_exec(bContext *C, wmOperator *op)
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
data.mval[0] = x;
data.mval[1] = y;
data.radius_squared = radius * radius;
data.rectf_view = &rect_fl;
-
+
rect_fl.xmin = x - radius;
rect_fl.xmax = x + radius;
rect_fl.ymin = y - radius;
rect_fl.ymax = y + radius;
-
+
{
SpaceIpo *sipo = (SpaceIpo *)ac.sl;
if (selectmode == SELECT_ADD) {
@@ -531,13 +531,13 @@ static int graph_circle_select_exec(bContext *C, wmOperator *op)
incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0;
}
}
-
+
/* apply borderselect action */
borderselect_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
-
+
/* send notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -546,13 +546,13 @@ void GRAPH_OT_select_circle(wmOperatorType *ot)
ot->name = "Circle Select";
ot->description = "Select keyframe points using circle selection";
ot->idname = "GRAPH_OT_select_circle";
-
+
ot->invoke = WM_gesture_circle_invoke;
ot->modal = WM_gesture_circle_modal;
ot->exec = graph_circle_select_exec;
ot->poll = graphop_visible_keyframes_poll;
ot->cancel = WM_gesture_circle_cancel;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
@@ -577,7 +577,7 @@ static const EnumPropertyItem prop_column_select_types[] = {
{0, NULL, 0, NULL, NULL}
};
-/* ------------------- */
+/* ------------------- */
/* Selects all visible keyframes between the specified markers */
/* TODO, this is almost an _exact_ duplicate of a function of the same name in action_select.c
@@ -587,27 +587,27 @@ static void markers_selectkeys_between(bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc ok_cb, select_cb;
KeyframeEditData ked = {{NULL}};
float min, max;
-
+
/* get extreme markers */
ED_markers_get_minmax(ac->markers, 1, &min, &max);
min -= 0.5f;
max += 0.5f;
-
+
/* get editing funcs + data */
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
select_cb = ANIM_editkeyframes_select(SELECT_ADD);
ked.f1 = min;
ked.f2 = max;
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* select keys in-between */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
@@ -621,7 +621,7 @@ static void markers_selectkeys_between(bAnimContext *ac)
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -633,56 +633,56 @@ static void columnselect_graph_keys(bAnimContext *ac, short mode)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
Scene *scene = ac->scene;
CfraElem *ce;
KeyframeEditFunc select_cb, ok_cb;
KeyframeEditData ked;
-
+
/* initialize keyframe editing data */
memset(&ked, 0, sizeof(KeyframeEditData));
-
+
/* build list of columns */
switch (mode) {
case GRAPHKEYS_COLUMNSEL_KEYS: /* list of selected keys */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next)
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
-
+
ANIM_animdata_freelist(&anim_data);
break;
-
+
case GRAPHKEYS_COLUMNSEL_CFRA: /* current frame */
/* make a single CfraElem for storing this */
ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
BLI_addtail(&ked.list, ce);
-
+
ce->cfra = (float)CFRA;
break;
-
+
case GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
break;
-
+
default: /* invalid option */
return;
}
-
+
/* set up BezTriple edit callbacks */
select_cb = ANIM_editkeyframes_select(SELECT_ADD);
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
-
+
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* loop over cfraelems (stored in the KeyframeEditData->list)
* - we need to do this here, as we can apply fewer NLA-mapping conversions
*/
@@ -694,7 +694,7 @@ static void columnselect_graph_keys(bAnimContext *ac, short mode)
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
}
-
+
/* free elements */
BLI_freelistN(&ked.list);
ANIM_animdata_freelist(&anim_data);
@@ -706,39 +706,39 @@ static int graphkeys_columnselect_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* action to take depends on the mode */
mode = RNA_enum_get(op->ptr, "mode");
-
+
if (mode == GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN)
markers_selectkeys_between(&ac);
else
columnselect_graph_keys(&ac, mode);
-
+
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void GRAPH_OT_select_column(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select All";
ot->idname = "GRAPH_OT_select_column";
ot->description = "Select all keyframes on the specified frame(s)";
-
+
/* api callbacks */
ot->exec = graphkeys_columnselect_exec;
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
}
@@ -748,38 +748,38 @@ void GRAPH_OT_select_column(wmOperatorType *ot)
static int graphkeys_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
KeyframeEditFunc sel_cb = ANIM_editkeyframes_select(SELECT_ADD);
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* loop through all of the keys and select additional keyframes based on these */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
-
+
/* check if anything selected? */
if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ok_cb, NULL)) {
/* select every keyframe in this curve then */
ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL);
}
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -789,11 +789,11 @@ void GRAPH_OT_select_linked(wmOperatorType *ot)
ot->name = "Select Linked";
ot->idname = "GRAPH_OT_select_linked";
ot->description = "Select keyframes occurring in the same F-Curves as selected ones";
-
+
/* api callbacks */
ot->exec = graphkeys_select_linked_exec;
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -806,38 +806,38 @@ static void select_moreless_graph_keys(bAnimContext *ac, short mode)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditData ked;
KeyframeEditFunc build_cb;
-
-
+
+
/* init selmap building data */
build_cb = ANIM_editkeyframes_buildselmap(mode);
- memset(&ked, 0, sizeof(KeyframeEditData));
-
+ memset(&ked, 0, sizeof(KeyframeEditData));
+
/* loop through all of the keys and select additional keyframes based on these */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
-
+
/* only continue if F-Curve has keyframes */
if (fcu->bezt == NULL)
continue;
-
+
/* build up map of whether F-Curve's keyframes should be selected or not */
ked.data = MEM_callocN(fcu->totvert, "selmap graphEdit");
ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, build_cb, NULL);
-
+
/* based on this map, adjust the selection status of the keyframes */
ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_selmap_flush, NULL);
-
+
/* free the selmap used here */
MEM_freeN(ked.data);
ked.data = NULL;
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -847,17 +847,17 @@ static void select_moreless_graph_keys(bAnimContext *ac, short mode)
static int graphkeys_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* perform select changes */
select_moreless_graph_keys(&ac, SELMAP_MORE);
-
+
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -867,11 +867,11 @@ void GRAPH_OT_select_more(wmOperatorType *ot)
ot->name = "Select More";
ot->idname = "GRAPH_OT_select_more";
ot->description = "Select keyframes beside already selected ones";
-
+
/* api callbacks */
ot->exec = graphkeys_select_more_exec;
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -881,17 +881,17 @@ void GRAPH_OT_select_more(wmOperatorType *ot)
static int graphkeys_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* perform select changes */
select_moreless_graph_keys(&ac, SELMAP_LESS);
-
+
/* set notifier that keyframe selection has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -901,11 +901,11 @@ void GRAPH_OT_select_less(wmOperatorType *ot)
ot->name = "Select Less";
ot->idname = "GRAPH_OT_select_less";
ot->description = "Deselect keyframes on ends of selection islands";
-
+
/* api callbacks */
ot->exec = graphkeys_select_less_exec;
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -928,25 +928,25 @@ static void graphkeys_select_leftright(bAnimContext *ac, short leftright, short
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc ok_cb, select_cb;
KeyframeEditData ked = {{NULL}};
Scene *scene = ac->scene;
-
+
/* if select mode is replace, deselect all keyframes (and channels) first */
if (select_mode == SELECT_REPLACE) {
select_mode = SELECT_ADD;
-
+
/* - deselect all other keyframes, so that just the newly selected remain
* - channels aren't deselected, since we don't re-select any as a consequence
*/
deselect_graph_keys(ac, 0, SELECT_SUBTRACT, false);
}
-
+
/* set callbacks and editing data */
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
select_cb = ANIM_editkeyframes_select(select_mode);
-
+
if (leftright == GRAPHKEYS_LRSEL_LEFT) {
ked.f1 = MINAFRAMEF;
ked.f2 = (float)(CFRA + 0.1f);
@@ -955,15 +955,15 @@ static void graphkeys_select_leftright(bAnimContext *ac, short leftright, short
ked.f1 = (float)(CFRA - 0.1f);
ked.f2 = MAXFRAMEF;
}
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* select keys */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
if (adt) {
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
@@ -984,28 +984,28 @@ static int graphkeys_select_leftright_exec(bContext *C, wmOperator *op)
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
short selectmode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* select mode is either replace (deselect all, then add) or add/extend */
if (RNA_boolean_get(op->ptr, "extend"))
selectmode = SELECT_INVERT;
else
selectmode = SELECT_REPLACE;
-
+
/* if "test" mode is set, we don't have any info to set this with */
if (leftright == GRAPHKEYS_LRSEL_TEST)
return OPERATOR_CANCELLED;
-
+
/* do the selecting now */
graphkeys_select_leftright(&ac, leftright, selectmode);
-
+
/* set notifier that keyframe selection (and channels too) have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1013,11 +1013,11 @@ static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, const
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* handle mode-based testing */
if (leftright == GRAPHKEYS_LRSEL_TEST) {
Scene *scene = ac.scene;
@@ -1032,7 +1032,7 @@ static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, const
else
RNA_enum_set(op->ptr, "mode", GRAPHKEYS_LRSEL_RIGHT);
}
-
+
/* perform selection */
return graphkeys_select_leftright_exec(C, op);
}
@@ -1040,24 +1040,24 @@ static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, const
void GRAPH_OT_select_leftright(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Select Left/Right";
ot->idname = "GRAPH_OT_select_leftright";
ot->description = "Select keyframes to the left or the right of the current frame";
-
+
/* api callbacks */
ot->invoke = graphkeys_select_leftright_invoke;
ot->exec = graphkeys_select_leftright_exec;
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_graphkeys_leftright_select_types, GRAPHKEYS_LRSEL_TEST, "Mode", "");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
-
+
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -1075,18 +1075,18 @@ void GRAPH_OT_select_leftright(wmOperatorType *ot)
/* temp info for caching handle vertices close */
typedef struct tNearestVertInfo {
struct tNearestVertInfo *next, *prev;
-
+
FCurve *fcu; /* F-Curve that keyframe comes from */
-
+
BezTriple *bezt; /* keyframe to consider */
FPoint *fpt; /* sample point to consider */
-
+
short hpoint; /* the handle index that we hit (eHandleIndex) */
short sel; /* whether the handle is selected or not */
int dist; /* distance from mouse to vert */
-
+
eAnim_ChannelType ctype; /* type of animation channel this FCurve comes from */
-
+
float frame; /* frame that point was on when it matched (global time) */
} tNearestVertInfo;
@@ -1095,7 +1095,7 @@ typedef enum eGraphVertIndex {
NEAREST_HANDLE_LEFT = -1,
NEAREST_HANDLE_KEY,
NEAREST_HANDLE_RIGHT
-} eGraphVertIndex;
+} eGraphVertIndex;
/* Tolerance for absolute radius (in pixels) of the vert from the cursor to use */
// TODO: perhaps this should depend a bit on the size that the user set the vertices to be?
@@ -1121,9 +1121,9 @@ static void nearest_fcurve_vert_store(
/* Keyframes or Samples? */
if (bezt) {
int screen_co[2], dist;
-
- /* convert from data-space to screen coordinates
- * NOTE: hpoint+1 gives us 0,1,2 respectively for each handle,
+
+ /* convert from data-space to screen coordinates
+ * NOTE: hpoint+1 gives us 0,1,2 respectively for each handle,
* needed to access the relevant vertex coordinates in the 3x3
* 'vec' matrix
*/
@@ -1135,7 +1135,7 @@ static void nearest_fcurve_vert_store(
{
tNearestVertInfo *nvi = (tNearestVertInfo *)matches->last;
bool replace = false;
-
+
/* if there is already a point for the F-Curve, check if this point is closer than that was */
if ((nvi) && (nvi->fcu == fcu)) {
/* replace if we are closer, or if equal and that one wasn't selected but we are... */
@@ -1145,19 +1145,19 @@ static void nearest_fcurve_vert_store(
/* add new if not replacing... */
if (replace == 0)
nvi = MEM_callocN(sizeof(tNearestVertInfo), "Nearest Graph Vert Info - Bezt");
-
+
/* store values */
nvi->fcu = fcu;
nvi->ctype = ctype;
-
+
nvi->bezt = bezt;
nvi->hpoint = hpoint;
nvi->dist = dist;
-
+
nvi->frame = bezt->vec[1][0]; /* currently in global time... */
-
+
nvi->sel = BEZT_ISSEL_ANY(bezt); // XXX... should this use the individual verts instead?
-
+
/* add to list of matches if appropriate... */
if (replace == 0)
BLI_addtail(matches, nvi);
@@ -1174,12 +1174,12 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
View2D *v2d = &ac->ar->v2d;
short mapping_flag = 0;
-
- /* get curves to search through
+
+ /* get curves to search through
* - if the option to only show keyframes that belong to selected F-Curves is enabled,
* include the 'only selected' flag...
*/
@@ -1188,32 +1188,32 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
filter |= ANIMFILTER_SEL;
mapping_flag |= ANIM_get_normalization_flags(ac);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
float offset;
float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
-
+
/* apply NLA mapping to all the keyframes */
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
-
+
if (fcu->bezt) {
BezTriple *bezt1 = fcu->bezt, *prevbezt = NULL;
int i;
-
+
for (i = 0; i < fcu->totvert; i++, prevbezt = bezt1, bezt1++) {
/* keyframe */
nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale, offset);
-
+
/* handles - only do them if they're visible */
if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) {
/* first handle only visible if previous segment had handles */
if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale, offset);
}
-
+
/* second handle only visible if this segment is bezier */
if (bezt1->ipo == BEZT_IPO_BEZ) {
nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale, offset);
@@ -1223,14 +1223,14 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
}
else if (fcu->fpt) {
// TODO; do this for samples too
-
+
}
-
+
/* un-apply NLA mapping from all the keyframes */
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
}
-
+
/* free channels */
ANIM_animdata_freelist(&anim_data);
}
@@ -1240,22 +1240,22 @@ static tNearestVertInfo *get_best_nearest_fcurve_vert(ListBase *matches)
{
tNearestVertInfo *nvi = NULL;
short found = 0;
-
+
/* abort if list is empty */
if (BLI_listbase_is_empty(matches))
return NULL;
-
+
/* if list only has 1 item, remove it from the list and return */
if (BLI_listbase_is_single(matches)) {
/* need to remove from the list, otherwise it gets freed and then we can't return it */
return BLI_pophead(matches);
}
-
+
/* try to find the first selected F-Curve vert, then take the one after it */
for (nvi = matches->first; nvi; nvi = nvi->next) {
/* which mode of search are we in: find first selected, or find vert? */
if (found) {
- /* just take this vert now that we've found the selected one
+ /* just take this vert now that we've found the selected one
* - we'll need to remove this from the list so that it can be returned to the original caller
*/
BLI_remlink(matches, nvi);
@@ -1267,29 +1267,29 @@ static tNearestVertInfo *get_best_nearest_fcurve_vert(ListBase *matches)
found = 1;
}
}
-
+
/* if we're still here, this means that we failed to find anything appropriate in the first pass,
* so just take the first item now...
*/
return BLI_pophead(matches);
}
-/* Find the nearest vertices (either a handle or the keyframe) that are nearest to the mouse cursor (in area coordinates)
+/* Find the nearest vertices (either a handle or the keyframe) that are nearest to the mouse cursor (in area coordinates)
* NOTE: the match info found must still be freed
*/
static tNearestVertInfo *find_nearest_fcurve_vert(bAnimContext *ac, const int mval[2])
{
ListBase matches = {NULL, NULL};
tNearestVertInfo *nvi;
-
+
/* step 1: get the nearest verts */
get_nearest_fcurve_verts_list(ac, mval, &matches);
-
+
/* step 2: find the best vert */
nvi = get_best_nearest_fcurve_vert(&matches);
-
+
BLI_freelistN(&matches);
-
+
/* return the best vert found */
return nvi;
}
@@ -1302,30 +1302,30 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
SpaceIpo *sipo = (SpaceIpo *)ac->sl;
tNearestVertInfo *nvi;
BezTriple *bezt = NULL;
-
+
/* find the beztriple that we're selecting, and the handle that was clicked on */
nvi = find_nearest_fcurve_vert(ac, mval);
-
+
/* check if anything to select */
if (nvi == NULL)
return;
-
+
/* deselect all other curves? */
if (select_mode == SELECT_REPLACE) {
/* reset selection mode */
select_mode = SELECT_ADD;
-
+
/* deselect all other keyframes (+ F-Curves too) */
deselect_graph_keys(ac, 0, SELECT_SUBTRACT, true);
-
- /* deselect other channels too, but only only do this if
- * selection of channel when the visibility of keyframes
- * doesn't depend on this
+
+ /* deselect other channels too, but only only do this if
+ * selection of channel when the visibility of keyframes
+ * doesn't depend on this
*/
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0)
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
}
-
+
/* if points can be selected on this F-Curve */
// TODO: what about those with no keyframes?
if ((curves_only == 0) && ((nvi->fcu->flag & FCURVE_PROTECTED) == 0)) {
@@ -1343,7 +1343,7 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
BEZT_SEL_ALL(bezt);
}
}
-
+
/* handles - toggle selection of relevant handle */
else if (nvi->hpoint == NEAREST_HANDLE_LEFT) {
/* toggle selection */
@@ -1360,9 +1360,9 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
BEZT_SEL_ALL(bezt);
}
/* otherwise, select the handle that applied */
- else if (nvi->hpoint == NEAREST_HANDLE_LEFT)
+ else if (nvi->hpoint == NEAREST_HANDLE_LEFT)
bezt->f1 |= SELECT;
- else
+ else
bezt->f3 |= SELECT;
}
}
@@ -1373,22 +1373,22 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
else {
KeyframeEditFunc select_cb;
KeyframeEditData ked;
-
+
/* initialize keyframe editing data */
memset(&ked, 0, sizeof(KeyframeEditData));
-
+
/* set up BezTriple edit callbacks */
select_cb = ANIM_editkeyframes_select(select_mode);
-
+
/* select all keyframes */
ANIM_fcurve_keyframes_loop(&ked, nvi->fcu, NULL, select_cb, NULL);
}
-
+
/* only change selection of channel when the visibility of keyframes doesn't depend on this */
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
/* select or deselect curve? */
if (bezt) {
- /* take selection status from item that got hit, to prevent flip/flop on channel
+ /* take selection status from item that got hit, to prevent flip/flop on channel
* selection status when shift-selecting (i.e. "SELECT_INVERT") points
*/
if (BEZT_ISSEL_ANY(bezt))
@@ -1425,66 +1425,66 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditFunc select_cb, ok_cb;
KeyframeEditData ked;
tNearestVertInfo *nvi;
float selx = (float)ac->scene->r.cfra;
-
+
/* find the beztriple that we're selecting, and the handle that was clicked on */
nvi = find_nearest_fcurve_vert(ac, mval);
-
+
/* check if anything to select */
if (nvi == NULL)
return;
-
+
/* get frame number on which elements should be selected */
// TODO: should we restrict to integer frames only?
selx = nvi->frame;
-
+
/* if select mode is replace, deselect all keyframes first */
if (select_mode == SELECT_REPLACE) {
/* reset selection mode to add to selection */
select_mode = SELECT_ADD;
-
+
/* - deselect all other keyframes, so that just the newly selected remain
* - channels aren't deselected, since we don't re-select any as a consequence
*/
deselect_graph_keys(ac, 0, SELECT_SUBTRACT, false);
}
-
+
/* initialize keyframe editing data */
memset(&ked, 0, sizeof(KeyframeEditData));
-
+
/* set up BezTriple edit callbacks */
select_cb = ANIM_editkeyframes_select(select_mode);
ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
-
+
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
+
/* set frame for validation callback to refer to */
if (adt)
ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
else
ked.f1 = selx;
-
+
/* select elements with frame number matching cfra */
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
-
+
/* free elements */
MEM_freeN(nvi);
BLI_freelistN(&ked.list);
ANIM_animdata_freelist(&anim_data);
}
-
+
/* ------------------- */
/* handle clicking */
@@ -1502,7 +1502,7 @@ static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEve
selectmode = SELECT_INVERT;
else
selectmode = SELECT_REPLACE;
-
+
/* figure out action to take */
if (RNA_boolean_get(op->ptr, "column")) {
/* select all keyframes in the same frame as the one that was under the mouse */
@@ -1516,41 +1516,41 @@ static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEve
/* select keyframe under mouse */
mouse_graph_keys(&ac, event->mval, selectmode, 0);
}
-
+
/* set notifier that keyframe selection (and also channel selection in some cases) has changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
+
/* for tweak grab to work */
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
-
+
void GRAPH_OT_clickselect(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Mouse Select Keys";
ot->idname = "GRAPH_OT_clickselect";
ot->description = "Select keyframes by clicking on them";
-
+
/* callbacks */
ot->invoke = graphkeys_clickselect_invoke;
ot->poll = graphop_visible_keyframes_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select",
"Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select",
+
+ prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select",
"Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "curves", 0, "Only Curves",
+
+ prop = RNA_def_boolean(ot->srna, "curves", 0, "Only Curves",
"Select all the keyframes in the curve"); // CTRLKEY + ALTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index fc20a62c3d6..f55a5511e2d 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -57,7 +57,7 @@
/* ************************************************************** */
/* Active F-Curve */
-/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
+/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
* We return the 'wrapper' since it contains valuable context info (about hierarchy), which will need to be freed
* when the caller is done with it.
*
@@ -68,20 +68,20 @@ bAnimListElem *get_active_fcurve_channel(bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE);
size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* We take the first F-Curve only, since some other ones may have had 'active' flag set
* if they were from linked data.
*/
if (items) {
bAnimListElem *ale = (bAnimListElem *)anim_data.first;
-
+
/* remove first item from list, then free the rest of the list and return the stored one */
BLI_remlink(&anim_data, ale);
ANIM_animdata_freelist(&anim_data);
-
+
return ale;
}
-
+
/* no active F-Curve */
return NULL;
}
@@ -99,30 +99,30 @@ int graphop_visible_keyframes_poll(bContext *C)
size_t items;
int filter;
short found = 0;
-
+
/* firstly, check if in Graph Editor */
// TODO: also check for region?
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
return 0;
-
+
/* try to init Anim-Context stuff ourselves and check */
if (ANIM_animdata_get_context(C, &ac) == 0)
return 0;
-
+
/* loop over the visible (selection doesn't matter) F-Curves, and see if they're suitable
* stopping on the first successful match
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE);
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- if (items == 0)
+ if (items == 0)
return 0;
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
-
+
/* visible curves for selection must fulfill the following criteria:
* - it has bezier keyframes
- * - F-Curve modifiers do not interfere with the result too much
+ * - F-Curve modifiers do not interfere with the result too much
* (i.e. the modifier-control drawing check returns false)
*/
if (fcu->bezt == NULL)
@@ -132,7 +132,7 @@ int graphop_visible_keyframes_poll(bContext *C)
break;
}
}
-
+
/* cleanup and return findings */
ANIM_animdata_freelist(&anim_data);
return found;
@@ -148,27 +148,27 @@ int graphop_editable_keyframes_poll(bContext *C)
size_t items;
int filter;
short found = 0;
-
+
/* firstly, check if in Graph Editor */
// TODO: also check for region?
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
return 0;
-
+
/* try to init Anim-Context stuff ourselves and check */
if (ANIM_animdata_get_context(C, &ac) == 0)
return 0;
-
+
/* loop over the editable F-Curves, and see if they're suitable
* stopping on the first successful match
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- if (items == 0)
+ if (items == 0)
return 0;
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->data;
-
+
/* editable curves must fulfill the following criteria:
* - it has bezier keyframes
* - it must not be protected from editing (this is already checked for with the edit flag
@@ -182,7 +182,7 @@ int graphop_editable_keyframes_poll(bContext *C)
break;
}
}
-
+
/* cleanup and return findings */
ANIM_animdata_freelist(&anim_data);
return found;
@@ -195,21 +195,21 @@ int graphop_active_fcurve_poll(bContext *C)
bAnimListElem *ale;
ScrArea *sa = CTX_wm_area(C);
bool has_fcurve = 0;
-
+
/* firstly, check if in Graph Editor */
// TODO: also check for region?
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
return 0;
-
+
/* try to init Anim-Context stuff ourselves and check */
if (ANIM_animdata_get_context(C, &ac) == 0)
return 0;
-
+
/* try to get the Active F-Curve */
ale = get_active_fcurve_channel(&ac);
if (ale == NULL)
return 0;
-
+
/* do we have a suitable F-Curves?
* - For most cases, NLA Control Curves are sufficiently similar to NLA curves to serve this role too.
* Under the hood, they are F-Curves too. The only problems which will arise here are if these need to be
@@ -220,10 +220,10 @@ int graphop_active_fcurve_poll(bContext *C)
FCurve *fcu = (FCurve *)ale->data;
has_fcurve = (fcu->flag & FCURVE_VISIBLE) != 0;
}
-
+
/* free temp data... */
MEM_freeN(ale);
-
+
/* return success */
return has_fcurve;
}
@@ -236,24 +236,24 @@ int graphop_selected_fcurve_poll(bContext *C)
ScrArea *sa = CTX_wm_area(C);
size_t items;
int filter;
-
+
/* firstly, check if in Graph Editor */
// TODO: also check for region?
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
return 0;
-
+
/* try to init Anim-Context stuff ourselves and check */
if (ANIM_animdata_get_context(C, &ac) == 0)
return 0;
-
- /* get the editable + selected F-Curves, and as long as we got some, we can return
+
+ /* get the editable + selected F-Curves, and as long as we got some, we can return
* NOTE: curve-visible flag isn't included, otherwise selecting a curve via list to edit is too cumbersome
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT);
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- if (items == 0)
+ if (items == 0)
return 0;
-
+
/* cleanup and return findings */
ANIM_animdata_freelist(&anim_data);
return 1;
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 84220ce6faf..56236ea8f47 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -71,7 +71,7 @@
ARegion *graph_has_buttons_region(ScrArea *sa)
{
ARegion *ar, *arnew;
-
+
ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
if (ar) return ar;
@@ -80,15 +80,15 @@ ARegion *graph_has_buttons_region(ScrArea *sa)
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "buttons for graph");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_UI;
arnew->alignment = RGN_ALIGN_RIGHT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
-
+
return arnew;
}
@@ -99,82 +99,82 @@ static SpaceLink *graph_new(const ScrArea *UNUSED(sa), const Scene *scene)
{
ARegion *ar;
SpaceIpo *sipo;
-
+
/* Graph Editor - general stuff */
sipo = MEM_callocN(sizeof(SpaceIpo), "init graphedit");
sipo->spacetype = SPACE_IPO;
-
+
sipo->autosnap = SACTSNAP_FRAME;
-
+
/* allocate DopeSheet data for Graph Editor */
sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
sipo->ads->source = (ID *)scene;
-
+
/* settings for making it easier by default to just see what you're interested in tweaking */
sipo->ads->filterflag |= ADS_FILTER_ONLYSEL;
sipo->flag |= SIPO_SELVHANDLESONLY;
-
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for graphedit");
-
+
BLI_addtail(&sipo->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
/* channels */
ar = MEM_callocN(sizeof(ARegion), "channels region for graphedit");
-
+
BLI_addtail(&sipo->regionbase, ar);
ar->regiontype = RGN_TYPE_CHANNELS;
ar->alignment = RGN_ALIGN_LEFT;
-
+
ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
-
+
/* ui buttons */
ar = MEM_callocN(sizeof(ARegion), "buttons region for graphedit");
-
+
BLI_addtail(&sipo->regionbase, ar);
ar->regiontype = RGN_TYPE_UI;
ar->alignment = RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
-
+
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for graphedit");
-
+
BLI_addtail(&sipo->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
ar->v2d.tot.xmin = 0.0f;
ar->v2d.tot.ymin = (float)scene->r.sfra - 10.0f;
ar->v2d.tot.xmax = (float)scene->r.efra;
ar->v2d.tot.ymax = 10.0f;
-
+
ar->v2d.cur = ar->v2d.tot;
-
+
ar->v2d.min[0] = FLT_MIN;
ar->v2d.min[1] = FLT_MIN;
ar->v2d.max[0] = MAXFRAMEF;
ar->v2d.max[1] = FLT_MAX;
-
+
ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
-
+
ar->v2d.keeptot = 0;
-
+
return (SpaceLink *)sipo;
}
/* not spacelink itself */
static void graph_free(SpaceLink *sl)
-{
+{
SpaceIpo *si = (SpaceIpo *)sl;
-
+
if (si->ads) {
BLI_freelistN(&si->ads->chanbase);
MEM_freeN(si->ads);
}
-
+
if (si->ghostCurves.first)
free_fcurves(&si->ghostCurves);
}
@@ -184,13 +184,13 @@ static void graph_free(SpaceLink *sl)
static void graph_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
{
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
-
+
/* init dopesheet data if non-existent (i.e. for old files) */
if (sipo->ads == NULL) {
sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
sipo->ads->source = (ID *)(G.main->scene.first); // FIXME: this is a really nasty hack here for now...
}
-
+
/* force immediate init of any invalid F-Curve colors */
/* XXX: but, don't do SIPO_TEMP_NEEDCHANSYNC (i.e. channel select state sync)
* as this is run on each region resize; setting this here will cause selection
@@ -202,11 +202,11 @@ static void graph_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
static SpaceLink *graph_duplicate(SpaceLink *sl)
{
SpaceIpo *sipon = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
BLI_duplicatelist(&sipon->ghostCurves, &((SpaceIpo *)sl)->ghostCurves);
sipon->ads = MEM_dupallocN(sipon->ads);
-
+
return (SpaceLink *)sipon;
}
@@ -214,9 +214,9 @@ static SpaceLink *graph_duplicate(SpaceLink *sl)
static void graph_main_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
-
+
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "Graph Editor", SPACE_IPO, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -235,42 +235,42 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
View2DScrollers *scrollers;
float col[3];
short unitx = 0, unity = V2D_UNIT_VALUES, cfra_flag = 0;
-
+
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_view2d_view_ortho(v2d);
-
+
/* grid */
unitx = ((sipo->mode == SIPO_MODE_ANIMATION) && (sipo->flag & SIPO_DRAWTIME)) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE;
grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
-
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
-
+
/* start and end frame (in F-Curve mode only) */
if (sipo->mode != SIPO_MODE_DRIVERS) {
ANIM_draw_framerange(scene, v2d);
}
-
+
/* draw data */
if (ANIM_animdata_get_context(C, &ac)) {
/* draw ghost curves */
graph_draw_ghost_curves(&ac, sipo, ar);
-
+
/* draw curves twice - unselected, then selected, so that the are fewer occlusion problems */
graph_draw_curves(&ac, sipo, ar, grid, 0);
graph_draw_curves(&ac, sipo, ar, grid, 1);
-
+
/* XXX the slow way to set tot rect... but for nice sliders needed (ton) */
get_graph_keyframe_extents(&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, false, true);
/* extra offset so that these items are visible */
v2d->tot.xmin -= 10.0f;
v2d->tot.xmax += 10.0f;
}
-
+
/* only free grid after drawing data, as we need to use it to determine sampling rate */
UI_view2d_grid_free(grid);
@@ -322,28 +322,28 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
if (sipo->flag & SIPO_DRAWTIME) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
ANIM_draw_cfra(C, v2d, cfra_flag);
}
-
+
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ED_markers_draw(C, DRAW_MARKERS_MARGIN);
-
+
/* preview range */
UI_view2d_view_ortho(v2d);
ANIM_draw_previewrange(C, v2d, 0);
-
+
/* callback */
UI_view2d_view_ortho(v2d);
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
// FIXME: args for scrollers depend on the type of data being shown...
scrollers = UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
+
/* draw current frame number-indicator on top of scrollers */
if ((sipo->mode != SIPO_MODE_DRIVERS) && ((sipo->flag & SIPO_NODRAWCFRANUM) == 0)) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
@@ -354,15 +354,15 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
static void graph_channel_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
/* make sure we keep the hide flags */
ar->v2d.scroll |= V2D_SCROLL_RIGHT;
ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP | V2D_SCROLL_BOTTOM); /* prevent any noise of past */
ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-
+
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "Animation Channels", 0, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -376,22 +376,22 @@ static void graph_channel_region_draw(const bContext *C, ARegion *ar)
View2D *v2d = &ar->v2d;
View2DScrollers *scrollers;
float col[3];
-
+
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_view2d_view_ortho(v2d);
-
+
/* draw channels */
if (ANIM_animdata_get_context(C, &ac)) {
graph_draw_channel_names((bContext *)C, &ac, ar);
}
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
@@ -413,7 +413,7 @@ static void graph_header_region_draw(const bContext *C, ARegion *ar)
static void graph_buttons_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
ED_region_panels_init(wm, ar);
keymap = WM_keymap_find(wm->defaultconf, "Graph Editor Generic", SPACE_IPO, 0);
@@ -483,7 +483,7 @@ static void graph_region_listener(
if (wmn->data == ND_KEYS)
ED_region_tag_redraw(ar);
break;
-
+
}
}
@@ -525,7 +525,7 @@ static void graph_region_message_subscribe(
WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
}
}
-
+
/* All dopesheet filter settings, etc. affect the drawing of this editor,
* also same applies for all animation-related datatypes that may appear here,
* so just whitelist the entire structs for updates
@@ -534,12 +534,12 @@ static void graph_region_message_subscribe(
wmMsgParams_RNA msg_key_params = {{{0}}};
StructRNA *type_array[] = {
&RNA_DopeSheet, /* dopesheet filters */
-
+
&RNA_ActionGroup, /* channel groups */
&RNA_FCurve, /* F-Curve */
&RNA_Keyframe,
&RNA_FCurveSample,
-
+
&RNA_FModifier, /* F-Modifiers (XXX: Why can't we just do all subclasses too?) */
&RNA_FModifierCycles,
&RNA_FModifierEnvelope,
@@ -568,7 +568,7 @@ static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sc
WorkSpace *UNUSED(workspace))
{
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
-
+
/* context changes */
switch (wmn->category) {
case NC_ANIMATION:
@@ -585,7 +585,7 @@ static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sc
sipo->flag |= SIPO_TEMP_NEEDCHANSYNC;
ED_area_tag_refresh(sa);
break;
-
+
default: /* just redrawing the view will do */
ED_area_tag_redraw(sa);
break;
@@ -600,7 +600,7 @@ static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sc
break;
case ND_TRANSFORM:
break; /*do nothing*/
-
+
default: /* just redrawing the view will do */
ED_area_tag_redraw(sa);
break;
@@ -623,7 +623,7 @@ static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sc
ED_area_tag_refresh(sa);
}
break;
-
+
// XXX: restore the case below if not enough updates occur...
//default:
// if (wmn->data == ND_KEYS)
@@ -635,29 +635,29 @@ static void graph_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sc
static void graph_refresh_fcurve_colors(const bContext *C)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
size_t items;
int filter;
int i;
-
+
if (ANIM_animdata_get_context(C, &ac) == false)
return;
-
+
UI_SetTheme(SPACE_IPO, RGN_TYPE_WINDOW);
-
+
/* build list of F-Curves which will be visible as channels in channel-region
* - we don't include ANIMFILTER_CURVEVISIBLE filter, as that will result in a
* mismatch between channel-colors and the drawn curves
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* loop over F-Curves, assigning colors */
for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
FCurve *fcu = (FCurve *)ale->data;
-
+
/* set color of curve here */
switch (fcu->color_mode) {
case FCURVE_COLOR_CUSTOM:
@@ -669,11 +669,11 @@ static void graph_refresh_fcurve_colors(const bContext *C)
}
case FCURVE_COLOR_AUTO_RGB:
{
- /* F-Curve's array index is automatically mapped to RGB values. This works best of 3-value vectors.
+ /* F-Curve's array index is automatically mapped to RGB values. This works best of 3-value vectors.
* TODO: find a way to module the hue so that not all curves have same color...
*/
float *col = fcu->color;
-
+
switch (fcu->array_index) {
case 0:
UI_GetThemeColor3fv(TH_AXIS_X, col);
@@ -695,7 +695,7 @@ static void graph_refresh_fcurve_colors(const bContext *C)
{
/* Like FCURVE_COLOR_AUTO_RGB, except this is for quaternions... */
float *col = fcu->color;
-
+
switch (fcu->array_index) {
case 1:
UI_GetThemeColor3fv(TH_AXIS_X, col);
@@ -706,29 +706,29 @@ static void graph_refresh_fcurve_colors(const bContext *C)
case 3:
UI_GetThemeColor3fv(TH_AXIS_Z, col);
break;
-
+
case 0:
{
/* Special Case: "W" channel should be yellowish, so blend X and Y channel colors... */
float c1[3], c2[3];
float h1[3], h2[3];
float hresult[3];
-
+
/* - get colors (rgb) */
UI_GetThemeColor3fv(TH_AXIS_X, c1);
UI_GetThemeColor3fv(TH_AXIS_Y, c2);
-
+
/* - perform blending in HSV space (to keep brightness similar) */
rgb_to_hsv_v(c1, h1);
rgb_to_hsv_v(c2, h2);
-
+
interp_v3_v3v3(hresult, h1, h2, 0.5f);
-
+
/* - convert back to RGB for display */
hsv_to_rgb_v(hresult, col);
break;
}
-
+
default:
/* 'unknown' color - bluish so as to not conflict with handles */
col[0] = 0.3f; col[1] = 0.8f; col[2] = 1.0f;
@@ -747,7 +747,7 @@ static void graph_refresh_fcurve_colors(const bContext *C)
}
}
}
-
+
/* free temp list */
ANIM_animdata_freelist(&anim_data);
}
@@ -755,24 +755,24 @@ static void graph_refresh_fcurve_colors(const bContext *C)
static void graph_refresh(const bContext *C, ScrArea *sa)
{
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
-
+
/* updates to data needed depends on Graph Editor mode... */
switch (sipo->mode) {
case SIPO_MODE_ANIMATION: /* all animation */
{
break;
}
-
+
case SIPO_MODE_DRIVERS: /* drivers only */
{
break;
}
}
-
+
/* region updates? */
// XXX re-sizing y-extents of tot should go here?
-
- /* update the state of the animchannels in response to changes from the data they represent
+
+ /* update the state of the animchannels in response to changes from the data they represent
* NOTE: the temp flag is used to indicate when this needs to be done, and will be cleared once handled
*/
if (sipo->flag & SIPO_TEMP_NEEDCHANSYNC) {
@@ -780,7 +780,7 @@ static void graph_refresh(const bContext *C, ScrArea *sa)
sipo->flag &= ~SIPO_TEMP_NEEDCHANSYNC;
ED_area_tag_redraw(sa);
}
-
+
/* init/adjust F-Curve colors */
graph_refresh_fcurve_colors(C);
}
@@ -788,7 +788,7 @@ static void graph_refresh(const bContext *C, ScrArea *sa)
static void graph_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
{
SpaceIpo *sgraph = (SpaceIpo *)slink;
-
+
if (sgraph->ads) {
if ((ID *)sgraph->ads->filter_grp == old_id) {
sgraph->ads->filter_grp = (Collection *)new_id;
@@ -804,10 +804,10 @@ void ED_spacetype_ipo(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype ipo");
ARegionType *art;
-
+
st->spaceid = SPACE_IPO;
strncpy(st->name, "Graph", BKE_ST_MAXNAME);
-
+
st->new = graph_new;
st->free = graph_free;
st->init = graph_init;
@@ -828,7 +828,7 @@ void ED_spacetype_ipo(void)
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
art->regionid = RGN_TYPE_HEADER;
@@ -837,9 +837,9 @@ void ED_spacetype_ipo(void)
art->listener = graph_region_listener;
art->init = graph_header_region_init;
art->draw = graph_header_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: channels */
art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
art->regionid = RGN_TYPE_CHANNELS;
@@ -849,9 +849,9 @@ void ED_spacetype_ipo(void)
art->message_subscribe = graph_region_message_subscribe;
art->init = graph_channel_region_init;
art->draw = graph_channel_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: UI buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
art->regionid = RGN_TYPE_UI;
@@ -860,11 +860,11 @@ void ED_spacetype_ipo(void)
art->listener = graph_region_listener;
art->init = graph_buttons_region_init;
art->draw = graph_buttons_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
graph_buttons_register(art);
-
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index c105f40f1d6..8b8aabb2ce0 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -134,7 +134,7 @@ static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf,
struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
{
bNode *node;
-
+
if (ntree)
for (node = ntree->nodes.first; node; node = node->next)
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
@@ -147,7 +147,7 @@ struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
/* ************ panel stuff ************* */
#if 0
-/* 0: disable preview
+/* 0: disable preview
* otherwise refresh preview
*
* XXX if you put this back, also check XXX in image_main_region_draw() */
@@ -155,7 +155,7 @@ struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
void image_preview_event(int event)
{
int exec = 0;
-
+
if (event == 0) {
G.scene->r.scemode &= ~R_COMP_CROP;
exec = 1;
@@ -168,27 +168,27 @@ void image_preview_event(int event)
else
G.scene->r.scemode &= ~R_COMP_CROP;
}
-
+
if (exec && G.scene->nodetree) {
Scene *scene = G.scene;
/* should work when no node editor in screen..., so we execute right away */
-
+
ntreeCompositTagGenerators(G.scene->nodetree);
G.is_break = false;
G.scene->nodetree->timecursor = set_timecursor;
G.scene->nodetree->test_break = BKE_blender_test_break;
-
+
BIF_store_spare();
-
+
ntreeCompositExecTree(scene->nodetree, &scene->r, 1, &scene->view_settings, &scene->display_settings); /* 1 is do_previews */
-
+
G.scene->nodetree->timecursor = NULL;
G.scene->nodetree->test_break = NULL;
-
+
scrarea_do_windraw(curarea);
waitcursor(0);
-
+
WM_event_add_notifier(C, NC_IMAGE, ima_v);
}
}
@@ -203,20 +203,20 @@ static void preview_cb(ScrArea *sa, struct uiBlock *block)
int winx = (G.scene->r.size * G.scene->r.xsch) / 100;
int winy = (G.scene->r.size * G.scene->r.ysch) / 100;
int mval[2];
-
+
if (G.scene->r.mode & R_BORDER) {
winx *= BLI_rcti_size_x(&G.scene->r.border);
winy *= BLI_rctf_size_y(&G.scene->r.border);
}
-
+
/* while dragging we need to update the rects, otherwise it doesn't end with correct one */
BLI_rctf_init(&dispf, 15.0f, BLI_rcti_size_x(&block->rect) - 15.0f, 15.0f, (BLI_rctf_size_y(&block->rect)) - 15.0f);
ui_graphics_to_window_rct(sa->win, &dispf, disprect);
-
+
/* correction for gla draw */
BLI_rcti_translate(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin);
-
+
calc_image_view(sima, 'p');
// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax);
/* map to image space coordinates */
@@ -224,13 +224,13 @@ static void preview_cb(ScrArea *sa, struct uiBlock *block)
areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin);
mval[0] = disprect->xmax; mval[1] = disprect->ymax;
areamouseco_to_ipoco(v2d, mval, &dispf.xmax, &dispf.ymax);
-
+
/* map to render coordinates */
disprect->xmin = dispf.xmin;
disprect->xmax = dispf.xmax;
disprect->ymin = dispf.ymin;
disprect->ymax = dispf.ymax;
-
+
CLAMP(disprect->xmin, 0, winx);
CLAMP(disprect->xmax, 0, winx);
CLAMP(disprect->ymin, 0, winy);
@@ -254,7 +254,7 @@ static bool is_preview_allowed(ScrArea *cur)
/* check image type */
if (sima->image == NULL || sima->image->type != IMA_TYPE_COMPOSITE)
return 0;
-
+
return 1;
}
@@ -264,23 +264,23 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PRE
uiBlock *block;
SpaceImage *sima = sa->spacedata.first;
int ofsx, ofsy;
-
+
if (is_preview_allowed(sa) == 0) {
rem_blockhandler(sa, IMAGE_HANDLER_PREVIEW);
G.scene->r.scemode &= ~R_COMP_CROP; /* quite weak */
return;
}
-
+
block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc
-
+
ofsx = -150 + (sa->winx / 2) / sima->blockscale;
ofsy = -100 + (sa->winy / 2) / sima->blockscale;
if (uiNewPanel(C, ar, block, "Preview", "Image", ofsx, ofsy, 300, 200) == 0) return;
-
+
UI_but_func_drawextra_set(block, preview_cb);
-
+
}
#endif
@@ -660,7 +660,7 @@ static void image_multiview_cb(bContext *C, void *rnd_pt, void *UNUSED(arg_v))
}
#if 0
-static void image_freecache_cb(bContext *C, void *ima_v, void *unused)
+static void image_freecache_cb(bContext *C, void *ima_v, void *unused)
{
Scene *scene = CTX_data_scene(C);
BKE_image_free_anim_ibufs(ima_v, scene->r.cfra);
@@ -898,7 +898,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiDefIconTextBut(block, UI_BTYPE_BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110, 120, 100, 20, 0, 0, 0, 0, 0, "");
but = uiDefBut(block, UI_BTYPE_BUT, B_NOP, "Free Cache", 210, 120, 100, 20, 0, 0, 0, 0, 0, "");
UI_but_func_set(but, image_freecache_cb, ima, NULL);
-
+
if (iuser->frames)
BLI_snprintf(str, sizeof(str), "(%d) Frames:", iuser->framenr);
else strcpy(str, "Frames:");
@@ -929,7 +929,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiItemO(row, "", ICON_PACKAGE, "image.unpack");
else
uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
-
+
row = uiLayoutRow(row, true);
uiLayoutSetEnabled(row, BKE_image_has_packedfile(ima) == false);
uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
@@ -1043,7 +1043,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
col = uiLayoutColumn(split, true);
uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE);
uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE);
-
+
uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE);
uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
@@ -1077,7 +1077,7 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
col = uiLayoutColumn(layout, false);
split = uiLayoutSplit(col, 0.5f, false);
-
+
uiItemR(split, imfptr, "file_format", 0, "", ICON_NONE);
sub = uiLayoutRow(split, false);
uiItemR(sub, imfptr, "color_mode", UI_ITEM_R_EXPAND, IFACE_("Color"), ICON_NONE);
@@ -1109,7 +1109,7 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
if (ELEM(imf->imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
uiItemR(col, imfptr, "exr_codec", 0, NULL, ICON_NONE);
}
-
+
row = uiLayoutRow(col, false);
if (BKE_imtype_supports_zbuf(imf->imtype)) {
uiItemR(row, imfptr, "use_zbuffer", 0, NULL, ICON_NONE);
@@ -1126,7 +1126,7 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
row = uiLayoutRow(col, false);
uiItemR(row, imfptr, "use_jpeg2k_cinema_preset", 0, NULL, ICON_NONE);
uiItemR(row, imfptr, "use_jpeg2k_cinema_48", 0, NULL, ICON_NONE);
-
+
uiItemR(col, imfptr, "use_jpeg2k_ycc", 0, NULL, ICON_NONE);
}
@@ -1297,14 +1297,14 @@ void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *i
void image_buttons_register(ARegionType *UNUSED(art))
{
-
+
}
static int image_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = image_has_buttons_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -1316,10 +1316,10 @@ void IMAGE_OT_properties(wmOperatorType *ot)
ot->name = "Properties";
ot->idname = "IMAGE_OT_properties";
ot->description = "Toggle the properties region visibility";
-
+
ot->exec = image_properties_toggle_exec;
ot->poll = ED_operator_image_active;
-
+
/* flags */
ot->flag = 0;
}
@@ -1328,10 +1328,10 @@ static int image_scopes_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = image_has_tools_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
-
+
return OPERATOR_FINISHED;
}
@@ -1343,7 +1343,7 @@ void IMAGE_OT_toolshelf(wmOperatorType *ot)
ot->exec = image_scopes_toggle_exec;
ot->poll = ED_operator_image_active;
-
+
/* flags */
ot->flag = 0;
}
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index fc4d8c39e26..1e2d668018f 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -231,7 +231,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str, sizeof(str));
-
+
BLF_color3ubv(blf_mono_font, green);
if (fp)
BLI_snprintf(str, sizeof(str), " G:%-.5f", fp[1]);
@@ -242,7 +242,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str, sizeof(str));
-
+
BLF_color3ubv(blf_mono_font, blue);
if (fp)
BLI_snprintf(str, sizeof(str), " B:%-.5f", fp[2]);
@@ -253,7 +253,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
dx += BLF_width(blf_mono_font, str, sizeof(str));
-
+
if (channels == 4) {
BLF_color3ub(blf_mono_font, 255, 255, 255);
if (fp)
@@ -287,7 +287,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
dx += BLF_width(blf_mono_font, str, sizeof(str));
}
}
-
+
/* color rectangle */
if (channels == 1) {
if (fp) {
@@ -384,7 +384,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d
rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &hue, &sat, &val);
rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &lum, &u, &v, BLI_YUV_ITU_BT709);
}
-
+
BLI_snprintf(str, sizeof(str), "V:%-.4f", val);
BLF_position(blf_mono_font, dx, dy, 0);
BLF_draw_ascii(blf_mono_font, str, sizeof(str));
@@ -561,7 +561,7 @@ void draw_image_grease_pencil(bContext *C, bool onlyv2d)
else {
/* assume that UI_view2d_restore(C) has been called... */
//SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C);
-
+
/* draw grease-pencil ('screen' strokes) */
ED_gpencil_draw_view2d(C, 0);
}
@@ -647,10 +647,10 @@ void draw_image_main(const bContext *C, ARegion *ar)
/* XXX can we do this in refresh? */
#if 0
what_image(sima);
-
+
if (sima->image) {
ED_image_get_aspect(sima->image, &xuser_asp, &yuser_asp);
-
+
/* UGLY hack? until now iusers worked fine... but for flipbook viewer we need this */
if (sima->image->type == IMA_TYPE_COMPOSITE) {
ImageUser *iuser = ntree_get_active_iuser(scene->nodetree);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 19829517e00..0911bea3be4 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -323,7 +323,7 @@ void ED_space_image_scopes_update(const struct bContext *C, struct SpaceImage *s
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
-
+
/* scope update can be expensive, don't update during paint modes */
if (sima->mode == SI_MODE_PAINT)
return;
@@ -339,7 +339,7 @@ void ED_space_image_scopes_update(const struct bContext *C, struct SpaceImage *s
return;
}
}
-
+
scopes_update(&sima->scopes, ibuf, use_view_settings ? &scene->view_settings : NULL, &scene->display_settings);
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index c8cec4c7306..d17eb357ff6 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -227,7 +227,7 @@ static int space_image_file_exists_poll(bContext *C)
ibuf = ED_space_image_acquire_buffer(sima, &lock);
if (ibuf) {
BLI_strncpy(name, ibuf->name, FILE_MAX);
- BLI_path_abs(name, bmain->name);
+ BLI_path_abs(name, BKE_main_blendfile_path(bmain));
if (BLI_exists(name) == false) {
CTX_wm_operator_poll_msg_set(C, "image file not found");
@@ -366,7 +366,7 @@ static int image_view_pan_exec(bContext *C, wmOperator *op)
image_preview_event(2);
}
#endif
-
+
return OPERATOR_FINISHED;
}
@@ -375,7 +375,7 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *eve
if (event->type == MOUSEPAN) {
SpaceImage *sima = CTX_wm_space_image(C);
float offset[2];
-
+
offset[0] = (event->prevx - event->x) / sima->zoom;
offset[1] = (event->prevy - event->y) / sima->zoom;
RNA_float_set_array(op->ptr, "offset", offset);
@@ -426,7 +426,7 @@ void IMAGE_OT_view_pan(wmOperatorType *ot)
ot->name = "View Pan";
ot->idname = "IMAGE_OT_view_pan";
ot->description = "Pan the view";
-
+
/* api callbacks */
ot->exec = image_view_pan_exec;
ot->invoke = image_view_pan_invoke;
@@ -436,7 +436,7 @@ void IMAGE_OT_view_pan(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR | OPTYPE_LOCK_BYPASS;
-
+
/* properties */
RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX,
"Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX);
@@ -521,7 +521,7 @@ static int image_view_zoom_exec(bContext *C, wmOperator *op)
image_preview_event(2);
}
#endif
-
+
return OPERATOR_FINISHED;
}
@@ -549,7 +549,7 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
RNA_float_set(op->ptr, "factor", factor);
sima_zoom_set(sima, ar, sima->zoom * factor, location);
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
else {
@@ -642,7 +642,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
ot->name = "View Zoom";
ot->idname = "IMAGE_OT_view_zoom";
ot->description = "Zoom in/out the image";
-
+
/* api callbacks */
ot->exec = image_view_zoom_exec;
ot->invoke = image_view_zoom_invoke;
@@ -652,7 +652,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR | OPTYPE_LOCK_BYPASS;
-
+
/* properties */
prop = RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor",
"Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX);
@@ -701,7 +701,7 @@ void IMAGE_OT_view_ndof(wmOperatorType *ot)
ot->name = "NDOF Pan/Zoom";
ot->idname = "IMAGE_OT_view_ndof";
ot->description = "Use a 3D mouse device to pan/zoom the view";
-
+
/* api callbacks */
ot->invoke = image_view_ndof_invoke;
ot->poll = space_image_main_region_poll;
@@ -734,7 +734,7 @@ static int image_view_all_exec(bContext *C, wmOperator *op)
w = width * aspx;
h = height * aspy;
-
+
/* check if the image will fit in the image with (zoom == 1) */
width = BLI_rcti_size_x(&ar->winrct) + 1;
height = BLI_rcti_size_y(&ar->winrct) + 1;
@@ -762,7 +762,7 @@ static int image_view_all_exec(bContext *C, wmOperator *op)
sima->xof = sima->yof = 0.0f;
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -774,7 +774,7 @@ void IMAGE_OT_view_all(wmOperatorType *ot)
ot->name = "View All";
ot->idname = "IMAGE_OT_view_all";
ot->description = "View the entire image";
-
+
/* api callbacks */
ot->exec = image_view_all_exec;
ot->poll = space_image_main_region_poll;
@@ -830,7 +830,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
sima_zoom_set_from_bounds(sima, ar, &bounds);
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -845,7 +845,7 @@ void IMAGE_OT_view_selected(wmOperatorType *ot)
ot->name = "View Center";
ot->idname = "IMAGE_OT_view_selected";
ot->description = "View all selected UVs";
-
+
/* api callbacks */
ot->exec = image_view_selected_exec;
ot->poll = image_view_selected_poll;
@@ -858,13 +858,13 @@ static int image_view_zoom_in_exec(bContext *C, wmOperator *op)
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
float location[2];
-
+
RNA_float_get_array(op->ptr, "location", location);
sima_zoom_set_factor(sima, ar, powf(2.0f, 1.0f / 3.0f), location);
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -887,7 +887,7 @@ void IMAGE_OT_view_zoom_in(wmOperatorType *ot)
ot->name = "View Zoom In";
ot->idname = "IMAGE_OT_view_zoom_in";
ot->description = "Zoom in the image (centered around 2D cursor)";
-
+
/* api callbacks */
ot->invoke = image_view_zoom_in_invoke;
ot->exec = image_view_zoom_in_exec;
@@ -907,13 +907,13 @@ static int image_view_zoom_out_exec(bContext *C, wmOperator *op)
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
float location[2];
-
+
RNA_float_get_array(op->ptr, "location", location);
sima_zoom_set_factor(sima, ar, powf(0.5f, 1.0f / 3.0f), location);
-
+
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -936,7 +936,7 @@ void IMAGE_OT_view_zoom_out(wmOperatorType *ot)
ot->name = "View Zoom Out";
ot->idname = "IMAGE_OT_view_zoom_out";
ot->description = "Zoom out the image (centered around 2D cursor)";
-
+
/* api callbacks */
ot->invoke = image_view_zoom_out_invoke;
ot->exec = image_view_zoom_out_exec;
@@ -959,7 +959,7 @@ static int image_view_zoom_ratio_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
sima_zoom_set(sima, ar, RNA_float_get(op->ptr, "ratio"), NULL);
-
+
/* ensure pixel exact locations for draw */
sima->xof = (int)sima->xof;
sima->yof = (int)sima->yof;
@@ -974,7 +974,7 @@ static int image_view_zoom_ratio_exec(bContext *C, wmOperator *op)
#endif
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -984,7 +984,7 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
ot->name = "View Zoom Ratio";
ot->idname = "IMAGE_OT_view_zoom_ratio";
ot->description = "Set zoom ratio of the view";
-
+
/* api callbacks */
ot->exec = image_view_zoom_ratio_exec;
ot->poll = space_image_main_region_poll;
@@ -1057,7 +1057,7 @@ void IMAGE_OT_view_zoom_border(wmOperatorType *ot)
static void image_filesel(bContext *C, wmOperator *op, const char *path)
{
RNA_string_set(op->ptr, "filepath", path);
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
}
/******************** open image operator ********************/
@@ -1263,11 +1263,11 @@ static int image_open_exec(bContext *C, wmOperator *op)
BLI_strncpy(filepath_range, frame_range->filepath, sizeof(filepath_range));
if (was_relative) {
- BLI_path_rel(filepath_range, bmain->name);
+ BLI_path_rel(filepath_range, BKE_main_blendfile_path(bmain));
}
Image *ima_range = image_open_single(
- op, filepath_range, bmain->name,
+ op, filepath_range, BKE_main_blendfile_path(bmain),
is_relative_path, use_multiview, frame_range_seq_len);
/* take the first image */
@@ -1282,7 +1282,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
else {
/* for drag & drop etc. */
ima = image_open_single(
- op, filepath, bmain->name,
+ op, filepath, BKE_main_blendfile_path(bmain),
is_relative_path, use_multiview, 1);
}
@@ -1348,10 +1348,10 @@ static int image_open_exec(bContext *C, wmOperator *op)
/* XXX unpackImage frees image buffers */
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
-
+
BKE_image_signal(ima, iuser, IMA_SIGNAL_RELOAD);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
-
+
MEM_freeN(op->customdata);
return OPERATOR_FINISHED;
@@ -1399,7 +1399,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return image_open_exec(C, op);
-
+
image_open_init(C, op);
/* show multiview save options only if scene has multiviews */
@@ -1448,7 +1448,7 @@ void IMAGE_OT_open(wmOperatorType *ot)
ot->name = "Open Image";
ot->description = "Open image";
ot->idname = "IMAGE_OT_open";
-
+
/* api callbacks */
ot->exec = image_open_exec;
ot->invoke = image_open_invoke;
@@ -1487,7 +1487,7 @@ static int image_match_len_exec(bContext *C, wmOperator *UNUSED(op))
ima = sima->image;
iuser = &sima->iuser;
}
-
+
}
if (!ima || !iuser || !BKE_image_has_anim(ima))
@@ -1509,7 +1509,7 @@ void IMAGE_OT_match_movie_length(wmOperatorType *ot)
ot->name = "Match Movie Length";
ot->description = "Set image's user's length to the one of this video";
ot->idname = "IMAGE_OT_match_movie_length";
-
+
/* api callbacks */
ot->exec = image_match_len_exec;
@@ -1526,7 +1526,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
if (!sima->image)
return OPERATOR_CANCELLED;
-
+
RNA_string_get(op->ptr, "filepath", str);
/* we cant do much if the str is longer then FILE_MAX :/ */
@@ -1536,7 +1536,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
sima->image->source = IMA_SRC_FILE;
BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_SRC_CHANGE);
}
-
+
if (BLI_testextensie_array(str, imb_ext_movie))
sima->image->source = IMA_SRC_MOVIE;
else
@@ -1544,7 +1544,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
/* XXX unpackImage frees image buffers */
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+
BKE_icon_changed(BKE_icon_id_ensure(&sima->image->id));
BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, sima->image);
@@ -1576,7 +1576,7 @@ void IMAGE_OT_replace(wmOperatorType *ot)
ot->name = "Replace Image";
ot->idname = "IMAGE_OT_replace";
ot->description = "Replace current image by another one from disk";
-
+
/* api callbacks */
ot->exec = image_replace_exec;
ot->invoke = image_replace_invoke;
@@ -1692,12 +1692,12 @@ static int save_image_options_init(Main *bmain, SaveImageOptions *simopts, Space
}
else {
BLI_strncpy(simopts->filepath, "//untitled", sizeof(simopts->filepath));
- BLI_path_abs(simopts->filepath, bmain->name);
+ BLI_path_abs(simopts->filepath, BKE_main_blendfile_path(bmain));
}
}
else {
BLI_snprintf(simopts->filepath, sizeof(simopts->filepath), "//%s", ima->id.name + 2);
- BLI_path_abs(simopts->filepath, is_prev_save ? G.ima : bmain->name);
+ BLI_path_abs(simopts->filepath, is_prev_save ? G.ima : BKE_main_blendfile_path(bmain));
}
}
@@ -1721,7 +1721,7 @@ static void save_image_options_from_op(Main *bmain, SaveImageOptions *simopts, w
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
RNA_string_get(op->ptr, "filepath", simopts->filepath);
- BLI_path_abs(simopts->filepath, bmain->name);
+ BLI_path_abs(simopts->filepath, BKE_main_blendfile_path(bmain));
}
}
@@ -2180,7 +2180,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
ot->name = "Save As Image";
ot->idname = "IMAGE_OT_save_as";
ot->description = "Save the image with another name and/or settings";
-
+
/* api callbacks */
ot->exec = image_save_as_exec;
ot->check = image_save_as_check;
@@ -2235,7 +2235,7 @@ void IMAGE_OT_save(wmOperatorType *ot)
ot->name = "Save Image";
ot->idname = "IMAGE_OT_save";
ot->description = "Save the image with current name and settings";
-
+
/* api callbacks */
ot->exec = image_save_exec;
ot->poll = space_image_file_exists_poll;
@@ -2254,7 +2254,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
int tot = 0;
char di[FILE_MAX];
struct MovieCacheIter *iter;
-
+
if (sima->image == NULL)
return OPERATOR_CANCELLED;
@@ -2267,7 +2267,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Cannot save multilayer sequences");
return OPERATOR_CANCELLED;
}
-
+
/* get total dirty buffers and first dirty buffer which is used for menu */
ibuf = NULL;
if (sima->image->cache != NULL) {
@@ -2284,7 +2284,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
}
IMB_moviecacheIter_free(iter);
}
-
+
if (tot == 0) {
BKE_report(op->reports, RPT_WARNING, "No images have been changed");
return OPERATOR_CANCELLED;
@@ -2302,7 +2302,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
char name[FILE_MAX];
BLI_strncpy(name, ibuf->name, sizeof(name));
- BLI_path_abs(name, bmain->name);
+ BLI_path_abs(name, BKE_main_blendfile_path(bmain));
if (0 == IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat)) {
BKE_reportf(op->reports, RPT_ERROR, "Could not write image: %s", strerror(errno));
@@ -2326,7 +2326,7 @@ void IMAGE_OT_save_sequence(wmOperatorType *ot)
ot->name = "Save Sequence";
ot->idname = "IMAGE_OT_save_sequence";
ot->description = "Save a sequence of images";
-
+
/* api callbacks */
ot->exec = image_save_sequence_exec;
ot->poll = space_image_buffer_exists_poll;
@@ -2347,13 +2347,13 @@ static int image_reload_exec(bContext *C, wmOperator *UNUSED(op))
/* XXX unpackImage frees image buffers */
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+
// XXX other users?
BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_RELOAD);
DEG_id_tag_update(&ima->id, 0);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
-
+
return OPERATOR_FINISHED;
}
@@ -2363,7 +2363,7 @@ void IMAGE_OT_reload(wmOperatorType *ot)
ot->name = "Reload Image";
ot->idname = "IMAGE_OT_reload";
ot->description = "Reload current image from disk";
-
+
/* api callbacks */
ot->exec = image_reload_exec;
@@ -2446,11 +2446,11 @@ static int image_new_exec(bContext *C, wmOperator *op)
else if (gen_context == GEN_CONTEXT_PAINT_CANVAS) {
bScreen *sc;
Object *ob = CTX_data_active_object(C);
-
+
if (scene->toolsettings->imapaint.canvas)
id_us_min(&scene->toolsettings->imapaint.canvas->id);
scene->toolsettings->imapaint.canvas = ima;
-
+
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -2458,7 +2458,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima_other = (SpaceImage *)sl;
-
+
if (!sima_other->pin) {
ED_space_image_set(sima_other, scene, obedit, ima);
}
@@ -2474,8 +2474,8 @@ static int image_new_exec(bContext *C, wmOperator *op)
if (scene->toolsettings->imapaint.stencil)
id_us_min(&scene->toolsettings->imapaint.stencil->id);
scene->toolsettings->imapaint.stencil = ima;
- BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
else {
Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
@@ -2488,9 +2488,9 @@ static int image_new_exec(bContext *C, wmOperator *op)
}
BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_USER_NEW_IMAGE);
-
+
WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
-
+
return OPERATOR_FINISHED;
}
@@ -2561,17 +2561,17 @@ void IMAGE_OT_new(wmOperatorType *ot)
{GEN_CONTEXT_PAINT_STENCIL, "PAINT_STENCIL", 0, "Paint Stencil", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "New Image";
ot->description = "Create a new image";
ot->idname = "IMAGE_OT_new";
-
+
/* api callbacks */
ot->exec = image_new_exec;
ot->invoke = image_new_invoke;
ot->ui = image_new_draw;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
@@ -2633,7 +2633,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
}
/* TODO: make this into an IMB_invert_channels(ibuf,r,g,b,a) method!? */
if (ibuf->rect_float) {
-
+
float *fp = (float *) ibuf->rect_float;
for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, fp += 4) {
if (r) fp[0] = 1.0f - fp[0];
@@ -2647,7 +2647,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
}
}
else if (ibuf->rect) {
-
+
char *cp = (char *) ibuf->rect;
for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, cp += 4) {
if (r) cp[0] = 255 - cp[0];
@@ -2688,11 +2688,11 @@ void IMAGE_OT_invert(wmOperatorType *ot)
ot->name = "Invert Channels";
ot->idname = "IMAGE_OT_invert";
ot->description = "Invert image's channels";
-
+
/* api callbacks */
ot->exec = image_invert_exec;
ot->poll = image_invert_poll;
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "invert_r", 0, "Red", "Invert Red Channel");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -2702,7 +2702,7 @@ void IMAGE_OT_invert(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "invert_a", 0, "Alpha", "Invert Alpha Channel");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2736,7 +2736,7 @@ static int image_pack_exec(bContext *C, wmOperator *op)
if (!image_pack_test(C, op))
return OPERATOR_CANCELLED;
-
+
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
BKE_report(op->reports, RPT_ERROR, "Cannot pack edited image from disk, only as internal PNG");
return OPERATOR_CANCELLED;
@@ -2788,9 +2788,9 @@ void IMAGE_OT_pack(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Pack Image";
- ot->description = "Pack an image as embedded data into the .blend file";
+ ot->description = "Pack an image as embedded data into the .blend file";
ot->idname = "IMAGE_OT_pack";
-
+
/* api callbacks */
ot->exec = image_pack_exec;
ot->invoke = image_pack_invoke;
@@ -2816,7 +2816,7 @@ static int image_unpack_exec(bContext *C, wmOperator *op)
ima = BLI_findstring(&CTX_data_main(C)->image, imaname, offsetof(ID, name) + 2);
if (!ima) ima = CTX_data_edit_image(C);
}
-
+
if (!ima || !BKE_image_has_packedfile(ima))
return OPERATOR_CANCELLED;
@@ -2827,12 +2827,12 @@ static int image_unpack_exec(bContext *C, wmOperator *op)
if (G.fileflags & G_AUTOPACK)
BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
-
+
/* XXX unpackImage frees image buffers */
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+
unpackImage(CTX_data_main(C), op->reports, ima, method);
-
+
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
return OPERATOR_FINISHED;
@@ -2844,7 +2844,7 @@ static int image_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
if (RNA_struct_property_is_set(op->ptr, "id"))
return image_unpack_exec(C, op);
-
+
if (!ima || !BKE_image_has_packedfile(ima))
return OPERATOR_CANCELLED;
@@ -2865,16 +2865,16 @@ void IMAGE_OT_unpack(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Unpack Image";
- ot->description = "Save an image packed in the .blend file to disk";
+ ot->description = "Save an image packed in the .blend file to disk";
ot->idname = "IMAGE_OT_unpack";
-
+
/* api callbacks */
ot->exec = image_unpack_exec;
ot->invoke = image_unpack_invoke;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_enum(ot->srna, "method", rna_enum_unpack_method_items, PF_USE_LOCAL, "Method", "How to unpack");
RNA_def_string(ot->srna, "id", NULL, MAX_ID_NAME - 2, "Image Name", "Image data-block name to unpack"); /* XXX, weark!, will fail with library, name collisions */
@@ -3077,7 +3077,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event
#if 0
{
ScrArea *sa, *cur = curarea;
-
+
node_curvemap_sample(fp); /* sends global to node editor */
for (sa = G.curscreen->areabase.first; sa; sa = sa->next) {
if (sa->spacetype == SPACE_NODE) {
@@ -3121,7 +3121,7 @@ static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event
if (!ED_space_image_has_buffer(sima))
return OPERATOR_CANCELLED;
-
+
info = MEM_callocN(sizeof(ImageSampleInfo), "ImageSampleInfo");
info->art = ar->type;
info->draw_handle = ED_region_draw_cb_activate(ar->type, image_sample_draw, info, REGION_DRAW_POST_PIXEL);
@@ -3163,7 +3163,7 @@ void IMAGE_OT_sample(wmOperatorType *ot)
ot->name = "Sample Color";
ot->idname = "IMAGE_OT_sample";
ot->description = "Use mouse to sample a color in current image";
-
+
/* api callbacks */
ot->invoke = image_sample_invoke;
ot->modal = image_sample_modal;
@@ -3185,13 +3185,13 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
int y_start = RNA_int_get(op->ptr, "ystart");
int x_end = RNA_int_get(op->ptr, "xend");
int y_end = RNA_int_get(op->ptr, "yend");
-
+
void *lock;
ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
Histogram *hist = &sima->sample_line_hist;
-
+
float x1f, y1f, x2f, y2f;
-
+
if (ibuf == NULL) {
ED_space_image_release_buffer(sima, ibuf, lock);
return OPERATOR_CANCELLED;
@@ -3201,7 +3201,7 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
ED_space_image_release_buffer(sima, ibuf, lock);
return OPERATOR_CANCELLED;
}
-
+
UI_view2d_region_to_view(&ar->v2d, x_start, y_start, &x1f, &y1f);
UI_view2d_region_to_view(&ar->v2d, x_end, y_end, &x2f, &y2f);
@@ -3214,14 +3214,14 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
hist->flag |= HISTO_FLAG_SAMPLELINE;
BKE_histogram_update_sample_line(hist, ibuf, &scene->view_settings, &scene->display_settings);
-
+
/* reset y zoom */
hist->ymax = 1.0f;
ED_space_image_release_buffer(sima, ibuf, lock);
-
+
ED_area_tag_redraw(CTX_wm_area(C));
-
+
return OPERATOR_FINISHED;
}
@@ -3234,7 +3234,7 @@ static int image_sample_line_invoke(bContext *C, wmOperator *op, const wmEvent *
if (!ED_space_image_has_buffer(sima))
return OPERATOR_CANCELLED;
-
+
return WM_gesture_straightline_invoke(C, op, event);
}
@@ -3244,17 +3244,17 @@ void IMAGE_OT_sample_line(wmOperatorType *ot)
ot->name = "Sample Line";
ot->idname = "IMAGE_OT_sample_line";
ot->description = "Sample a line and show it in Scope panels";
-
+
/* api callbacks */
ot->invoke = image_sample_line_invoke;
ot->modal = WM_gesture_straightline_modal;
ot->exec = image_sample_line_exec;
ot->poll = space_image_main_region_poll;
ot->cancel = WM_gesture_straightline_cancel;
-
+
/* flags */
ot->flag = 0; /* no undo/register since this operates on the space */
-
+
WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT);
}
@@ -3275,7 +3275,7 @@ void IMAGE_OT_curves_point_set(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->invoke = image_sample_invoke;
ot->modal = image_sample_modal;
@@ -3301,19 +3301,19 @@ static int image_record_composite_apply(bContext *C, wmOperator *op)
RecordCompositeData *rcd = op->customdata;
Scene *scene = CTX_data_scene(C);
ImBuf *ibuf;
-
+
WM_cursor_time(CTX_wm_window(C), scene->r.cfra);
// XXX scene->nodetree->test_break = BKE_blender_test_break;
// XXX scene->nodetree->test_break = NULL;
-
+
BKE_image_all_free_anim_ibufs(scene->r.cfra);
ntreeCompositTagAnimated(scene->nodetree);
ntreeCompositExecTree(scene->nodetree, &scene->r, 0, scene->r.cfra != rcd->old_cfra,
&scene->view_settings, &scene->display_settings); /* 1 is no previews */
ED_area_tag_redraw(CTX_wm_area(C));
-
+
ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, NULL);
/* save memory in flipbooks */
if (ibuf)
@@ -3336,7 +3336,7 @@ static int image_record_composite_init(bContext *C, wmOperator *op)
return 0;
if (scene->nodetree == NULL)
return 0;
-
+
op->customdata = rcd = MEM_callocN(sizeof(RecordCompositeData), "ImageRecordCompositeData");
rcd->old_cfra = scene->r.cfra;
@@ -3372,18 +3372,18 @@ static int image_record_composite_exec(bContext *C, wmOperator *op)
{
if (!image_record_composite_init(C, op))
return OPERATOR_CANCELLED;
-
+
while (image_record_composite_apply(C, op)) {}
-
+
image_record_composite_exit(C, op);
-
+
return OPERATOR_FINISHED;
}
static int image_record_composite_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
RecordCompositeData *rcd;
-
+
if (!image_record_composite_init(C, op))
return OPERATOR_CANCELLED;
@@ -3429,7 +3429,7 @@ void IMAGE_OT_record_composite(wmOperatorType *ot)
/* identifiers */
ot->name = "Record Composite";
ot->idname = "IMAGE_OT_record_composite";
-
+
/* api callbacks */
ot->exec = image_record_composite_exec;
ot->invoke = image_record_composite_invoke;
@@ -3463,7 +3463,7 @@ static int image_cycle_render_slot_exec(bContext *C, wmOperator *op)
/* no undo push for browsing existing */
if (ima->renders[ima->render_slot] || ima->render_slot == ima->last_render_slot)
return OPERATOR_CANCELLED;
-
+
return OPERATOR_FINISHED;
}
@@ -3473,7 +3473,7 @@ void IMAGE_OT_cycle_render_slot(wmOperatorType *ot)
ot->name = "Cycle Render Slot";
ot->idname = "IMAGE_OT_cycle_render_slot";
ot->description = "Cycle through all non-void render slots";
-
+
/* api callbacks */
ot->exec = image_cycle_render_slot_exec;
ot->poll = image_cycle_render_slot_poll;
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index e04354529e4..c143ebbcd67 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -117,21 +117,21 @@ ARegion *image_has_buttons_region(ScrArea *sa)
ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
if (ar) return ar;
-
+
/* add subdiv level; after header */
ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "buttons for image");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_UI;
arnew->alignment = RGN_ALIGN_RIGHT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
-
+
return arnew;
}
@@ -147,17 +147,17 @@ ARegion *image_has_tools_region(ScrArea *sa)
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "scopes for image");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_TOOLS;
arnew->alignment = RGN_ALIGN_LEFT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
image_scopes_tag_refresh(sa);
-
+
return arnew;
}
@@ -167,7 +167,7 @@ static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(sce
{
ARegion *ar;
SpaceImage *simage;
-
+
simage = MEM_callocN(sizeof(SpaceImage), "initimage");
simage->spacetype = SPACE_IMAGE;
simage->zoom = 1.0f;
@@ -184,22 +184,22 @@ static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(sce
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for image");
-
+
BLI_addtail(&simage->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
/* buttons/list view */
ar = MEM_callocN(sizeof(ARegion), "buttons for image");
-
+
BLI_addtail(&simage->regionbase, ar);
ar->regiontype = RGN_TYPE_UI;
ar->alignment = RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
-
+
/* scopes/uv sculpt/paint */
ar = MEM_callocN(sizeof(ARegion), "buttons for image");
-
+
BLI_addtail(&simage->regionbase, ar);
ar->regiontype = RGN_TYPE_TOOLS;
ar->alignment = RGN_ALIGN_LEFT;
@@ -207,16 +207,16 @@ static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(sce
/* main area */
ar = MEM_callocN(sizeof(ARegion), "main area for image");
-
+
BLI_addtail(&simage->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
return (SpaceLink *)simage;
}
/* not spacelink itself */
static void image_free(SpaceLink *sl)
-{
+{
SpaceImage *simage = (SpaceImage *) sl;
scopes_free(&simage->scopes);
@@ -230,13 +230,13 @@ static void image_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
/* add drop boxes */
WM_event_add_dropbox_handler(&sa->handlers, lb);
-
+
}
static SpaceLink *image_duplicate(SpaceLink *sl)
{
SpaceImage *simagen = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
scopes_new(&simagen->scopes);
@@ -268,7 +268,7 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_save_sequence);
WM_operatortype_append(IMAGE_OT_pack);
WM_operatortype_append(IMAGE_OT_unpack);
-
+
WM_operatortype_append(IMAGE_OT_invert);
WM_operatortype_append(IMAGE_OT_cycle_render_slot);
@@ -292,7 +292,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_keymap_find(keyconf, "Image Generic", SPACE_IMAGE, 0);
wmKeyMapItem *kmi;
int i;
-
+
WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
@@ -302,11 +302,13 @@ static void image_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_toolshelf", TKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_menu(keymap, "IMAGE_MT_specials", WKEY, KM_PRESS, 0, 0);
+
WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, KM_ALT, 0)->ptr, "reverse", true);
-
+
keymap = WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0);
-
+
WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "IMAGE_OT_view_all", HOMEKEY, KM_PRESS, KM_SHIFT, 0);
@@ -399,7 +401,7 @@ static void image_drop_copy(wmDrag *drag, wmDropBox *drop)
static void image_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Image", SPACE_IMAGE, 0);
-
+
WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy);
}
@@ -416,7 +418,7 @@ static void image_refresh(const bContext *C, ScrArea *sa)
ima = ED_space_image(sima);
BKE_image_user_check_frame_calc(&sima->iuser, scene->r.cfra, 0);
-
+
/* check if we have to set the image from the editmesh */
if (ima && (ima->source == IMA_SRC_VIEWER && sima->mode == SI_MODE_MASK)) {
if (scene->nodetree) {
@@ -432,7 +434,7 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Sc
WorkSpace *workspace)
{
SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
-
+
/* context changes */
switch (wmn->category) {
case NC_WINDOW:
@@ -605,7 +607,7 @@ static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar)
Image *ima = ED_space_image(sima);
float x1, y1, w, h;
int width, height, winx, winy;
-
+
#if 0
if (image_preview_active(curarea, &width, &height)) {}
else
@@ -614,18 +616,18 @@ static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar)
w = width;
h = height;
-
+
if (ima)
h *= ima->aspy / ima->aspx;
winx = BLI_rcti_size_x(&ar->winrct) + 1;
winy = BLI_rcti_size_y(&ar->winrct) + 1;
-
+
ar->v2d.tot.xmin = 0;
ar->v2d.tot.ymin = 0;
ar->v2d.tot.xmax = w;
ar->v2d.tot.ymax = h;
-
+
ar->v2d.mask.xmin = ar->v2d.mask.ymin = 0;
ar->v2d.mask.xmax = winx;
ar->v2d.mask.ymax = winy;
@@ -636,15 +638,15 @@ static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar)
x1 -= sima->zoom * sima->xof;
y1 -= sima->zoom * sima->yof;
-
+
/* relative display right */
ar->v2d.cur.xmin = ((ar->winrct.xmin - (float)x1) / sima->zoom);
ar->v2d.cur.xmax = ar->v2d.cur.xmin + ((float)winx / sima->zoom);
-
+
/* relative display left */
ar->v2d.cur.ymin = ((ar->winrct.ymin - (float)y1) / sima->zoom);
ar->v2d.cur.ymax = ar->v2d.cur.ymin + ((float)winy / sima->zoom);
-
+
/* normalize 0.0..1.0 */
ar->v2d.cur.xmin /= w;
ar->v2d.cur.xmax /= w;
@@ -656,7 +658,7 @@ static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar)
static void image_main_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
// image space manages own v2d
// UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
@@ -686,7 +688,7 @@ static void image_main_region_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_find(wm->defaultconf, "UV Editor", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
-
+
keymap = WM_keymap_find(wm->defaultconf, "UV Sculpt", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -714,7 +716,7 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
/* XXX not supported yet, disabling for now */
scene->r.scemode &= ~R_COMP_CROP;
-
+
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
@@ -860,7 +862,7 @@ static void image_buttons_region_init(wmWindowManager *wm, ARegion *ar)
ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
ED_region_panels_init(wm, ar);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -911,10 +913,10 @@ static void image_buttons_region_listener(
static void image_tools_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
ED_region_panels_init(wm, ar);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -941,7 +943,7 @@ static void image_tools_region_draw(const bContext *C, ARegion *ar)
}
}
ED_space_image_release_buffer(sima, ibuf, lock);
-
+
ED_region_panels(C, ar, NULL, -1, true);
}
@@ -976,7 +978,7 @@ static void image_tools_region_listener(
case NC_NODE:
ED_region_tag_redraw(ar);
break;
-
+
}
}
@@ -1070,10 +1072,10 @@ void ED_spacetype_image(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype image");
ARegionType *art;
-
+
st->spaceid = SPACE_IMAGE;
strncpy(st->name, "Image", BKE_ST_MAXNAME);
-
+
st->new = image_new;
st->free = image_free;
st->init = image_init;
@@ -1096,7 +1098,7 @@ void ED_spacetype_image(void)
art->listener = image_main_region_listener;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: listview/buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype image region");
art->regionid = RGN_TYPE_UI;
@@ -1129,9 +1131,8 @@ void ED_spacetype_image(void)
art->listener = image_header_region_listener;
art->init = image_header_region_init;
art->draw = image_header_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
BKE_spacetype_register(st);
}
-
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 6f8d380d231..9421567b6ba 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -236,7 +236,7 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, Re
int draw, int mval[2], void **mouse_pick, int *pos_pick)
{
int ret = 0;
-
+
View2D *v2d = &ar->v2d;
TextViewContext tvc = {0};
@@ -260,7 +260,7 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, Re
tvc.winx = ar->winx - V2D_SCROLL_WIDTH;
ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick);
-
+
return ret;
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 4b70daa3649..acd0a856f1a 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -87,7 +87,7 @@ void FILE_OT_pack_libraries(wmOperatorType *ot)
ot->name = "Pack Blender Libraries";
ot->idname = "FILE_OT_pack_libraries";
ot->description = "Pack all used Blender library files into the current .blend";
-
+
/* api callbacks */
ot->exec = pack_libraries_exec;
@@ -98,9 +98,9 @@ void FILE_OT_pack_libraries(wmOperatorType *ot)
static int unpack_libraries_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
-
+
unpackLibraries(bmain, op->reports);
-
+
return OPERATOR_FINISHED;
}
@@ -115,11 +115,11 @@ void FILE_OT_unpack_libraries(wmOperatorType *ot)
ot->name = "Unpack Blender Libraries";
ot->idname = "FILE_OT_unpack_libraries";
ot->description = "Unpack all used Blender library files from this .blend file";
-
+
/* api callbacks */
ot->invoke = unpack_libraries_invoke;
ot->exec = unpack_libraries_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -131,13 +131,13 @@ static int autopack_toggle_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
if (G.fileflags & G_AUTOPACK) {
- G.fileflags &= ~G_AUTOPACK;
+ G.fileflags &= ~G_AUTOPACK;
}
else {
packAll(bmain, op->reports, true);
G.fileflags |= G_AUTOPACK;
}
-
+
return OPERATOR_FINISHED;
}
@@ -147,10 +147,10 @@ void FILE_OT_autopack_toggle(wmOperatorType *ot)
ot->name = "Automatically Pack Into .blend";
ot->idname = "FILE_OT_autopack_toggle";
ot->description = "Automatically pack all external files into the .blend file";
-
+
/* api callbacks */
ot->exec = autopack_toggle_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -160,9 +160,9 @@ void FILE_OT_autopack_toggle(wmOperatorType *ot)
static int pack_all_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
-
+
packAll(bmain, op->reports, true);
-
+
return OPERATOR_FINISHED;
}
@@ -171,25 +171,25 @@ static int pack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev
Main *bmain = CTX_data_main(C);
Image *ima;
ImBuf *ibuf;
-
+
// first check for dirty images
for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (BKE_image_has_loaded_ibuf(ima)) { /* XXX FIX */
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
-
+
if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
BKE_image_release_ibuf(ima, ibuf, NULL);
break;
}
-
+
BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
-
+
if (ima) {
return WM_operator_confirm_message(C, op, "Some images are painted on. These changes will be lost. Continue?");
}
-
+
return pack_all_exec(C, op);
}
@@ -199,11 +199,11 @@ void FILE_OT_pack_all(wmOperatorType *ot)
ot->name = "Pack All Into .blend";
ot->idname = "FILE_OT_pack_all";
ot->description = "Pack all used external files into the .blend";
-
+
/* api callbacks */
ot->exec = pack_all_exec;
ot->invoke = pack_all_invoke;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -238,9 +238,9 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
uiLayout *layout;
char title[64];
int count = 0;
-
+
count = countPackedFiles(bmain);
-
+
if (!count) {
BKE_report(op->reports, RPT_WARNING, "No packed files to unpack");
G.fileflags &= ~G_AUTOPACK;
@@ -251,7 +251,7 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
BLI_strncpy(title, IFACE_("Unpack 1 File"), sizeof(title));
else
BLI_snprintf(title, sizeof(title), IFACE_("Unpack %d Files"), count);
-
+
pup = UI_popup_menu_begin(C, title, ICON_NONE);
layout = UI_popup_menu_layout(pup);
@@ -269,7 +269,7 @@ void FILE_OT_unpack_all(wmOperatorType *ot)
ot->name = "Unpack All Into Files";
ot->idname = "FILE_OT_unpack_all";
ot->description = "Unpack all files packed into this .blend to external ones";
-
+
/* api callbacks */
ot->exec = unpack_all_exec;
ot->invoke = unpack_all_invoke;
@@ -307,12 +307,12 @@ static int unpack_item_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No packed file");
return OPERATOR_CANCELLED;
}
-
+
if (method != PF_KEEP)
BKE_unpack_id(bmain, id, op->reports, method); /* XXX PF_ASK can't work here */
-
+
G.fileflags &= ~G_AUTOPACK;
-
+
return OPERATOR_FINISHED;
}
@@ -320,15 +320,15 @@ static int unpack_item_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
{
uiPopupMenu *pup;
uiLayout *layout;
-
+
pup = UI_popup_menu_begin(C, IFACE_("Unpack"), ICON_NONE);
layout = UI_popup_menu_layout(pup);
-
+
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
uiItemsFullEnumO(layout, op->type->idname, "method", op->ptr->data, WM_OP_EXEC_REGION_WIN, 0);
-
+
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -338,14 +338,14 @@ void FILE_OT_unpack_item(wmOperatorType *ot)
ot->name = "Unpack Item";
ot->idname = "FILE_OT_unpack_item";
ot->description = "Unpack this file to an external file";
-
+
/* api callbacks */
ot->exec = unpack_item_exec;
ot->invoke = unpack_item_invoke;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
RNA_def_enum(ot->srna, "method", unpack_item_method_items, PF_USE_LOCAL, "Method", "How to unpack");
RNA_def_string(ot->srna, "id_name", NULL, BKE_ST_MAXNAME, "ID name", "Name of ID block to unpack");
@@ -364,7 +364,7 @@ static int make_paths_relative_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_bpath_relative_convert(bmain, bmain->name, op->reports);
+ BKE_bpath_relative_convert(bmain, BKE_main_blendfile_path(bmain), op->reports);
/* redraw everything so any changed paths register */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -378,7 +378,7 @@ void FILE_OT_make_paths_relative(wmOperatorType *ot)
ot->name = "Make All Paths Relative";
ot->idname = "FILE_OT_make_paths_relative";
ot->description = "Make all paths to external files relative to current .blend";
-
+
/* api callbacks */
ot->exec = make_paths_relative_exec;
@@ -397,7 +397,7 @@ static int make_paths_absolute_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_bpath_absolute_convert(bmain, bmain->name, op->reports);
+ BKE_bpath_absolute_convert(bmain, BKE_main_blendfile_path(bmain), op->reports);
/* redraw everything so any changed paths register */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -411,7 +411,7 @@ void FILE_OT_make_paths_absolute(wmOperatorType *ot)
ot->name = "Make All Paths Absolute";
ot->idname = "FILE_OT_make_paths_absolute";
ot->description = "Make all paths to external files absolute";
-
+
/* api callbacks */
ot->exec = make_paths_absolute_exec;
@@ -427,7 +427,7 @@ static int report_missing_files_exec(bContext *C, wmOperator *op)
/* run the missing file check */
BKE_bpath_missing_files_check(bmain, op->reports);
-
+
return OPERATOR_FINISHED;
}
@@ -437,7 +437,7 @@ void FILE_OT_report_missing_files(wmOperatorType *ot)
ot->name = "Report Missing Files";
ot->idname = "FILE_OT_report_missing_files";
ot->description = "Report all missing external files";
-
+
/* api callbacks */
ot->exec = report_missing_files_exec;
@@ -462,7 +462,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op)
static int find_missing_files_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* XXX file open button text "Find Missing Files" */
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -472,7 +472,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot)
ot->name = "Find Missing Files";
ot->idname = "FILE_OT_find_missing_files";
ot->description = "Try to find missing external files";
-
+
/* api callbacks */
ot->exec = find_missing_files_exec;
ot->invoke = find_missing_files_invoke;
@@ -490,7 +490,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot)
/********************* report box operator *********************/
-/* Hard to decide whether to keep this as an operator,
+/* Hard to decide whether to keep this as an operator,
* or turn it into a hardcoded ui control feature,
* handling TIMER events for all regions in interface_handlers.c
* Not sure how good that is to be accessing UI data from
@@ -513,7 +513,7 @@ static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), co
float neutral_gray = 0.6;
float timeout = 0.0, color_timeout = 0.0;
int send_note = 0;
-
+
/* escape if not our timer */
if ((reports->reporttimer == NULL) ||
(reports->reporttimer != event->customdata) ||
@@ -524,17 +524,17 @@ static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), co
}
rti = (ReportTimerInfo *)reports->reporttimer->customdata;
-
+
timeout = (report->type & RPT_ERROR_ALL) ? ERROR_TIMEOUT : INFO_TIMEOUT;
color_timeout = (report->type & RPT_ERROR_ALL) ? ERROR_COLOR_TIMEOUT : INFO_COLOR_TIMEOUT;
-
+
/* clear the report display after timeout */
if ((float)reports->reporttimer->duration > timeout) {
WM_event_remove_timer(wm, NULL, reports->reporttimer);
reports->reporttimer = NULL;
-
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL);
-
+
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
}
@@ -558,14 +558,14 @@ static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), co
rti->grayscale = 0.75;
rti->widthfac = 1.0;
}
-
+
progress = (float)reports->reporttimer->duration / timeout;
color_progress = (float)reports->reporttimer->duration / color_timeout;
-
+
/* save us from too many draws */
if (color_progress <= 1.0f) {
send_note = 1;
-
+
/* fade colors out sharply according to progress through fade-out duration */
interp_v3_v3v3(rti->col, rti->col, neutral_col, color_progress);
rti->grayscale = interpf(neutral_gray, rti->grayscale, color_progress);
@@ -577,11 +577,11 @@ static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), co
rti->widthfac = 1.0f - rti->widthfac;
send_note = 1;
}
-
+
if (send_note) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL);
}
-
+
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
}
@@ -591,13 +591,13 @@ void INFO_OT_reports_display_update(wmOperatorType *ot)
ot->name = "Update Reports Display";
ot->idname = "INFO_OT_reports_display_update";
ot->description = "Update the display of reports in Blender UI (internal use)";
-
+
/* api callbacks */
ot->invoke = update_reports_display_invoke;
-
+
/* flags */
ot->flag = 0;
-
+
/* properties */
}
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index b2e969ef433..481c9031a73 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -70,7 +70,7 @@ typedef struct SceneStats {
int totface, totfacesel;
int totbone, totbonesel;
int totobj, totobjsel;
- int totlamp, totlampsel;
+ int totlamp, totlampsel;
int tottri;
char infostr[MAX_INFO_LEN];
@@ -154,10 +154,10 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
stats->totvert = em->bm->totvert;
stats->totvertsel = em->bm->totvertsel;
-
+
stats->totedge = em->bm->totedge;
stats->totedgesel = em->bm->totedgesel;
-
+
stats->totface = em->bm->totface;
stats->totfacesel = em->bm->totfacesel;
@@ -170,15 +170,15 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
stats->totbone++;
-
+
if ((ebo->flag & BONE_CONNECTED) && ebo->parent)
stats->totvert--;
-
+
if (ebo->flag & BONE_TIPSEL)
stats->totvertsel++;
if (ebo->flag & BONE_ROOTSEL)
stats->totvertsel++;
-
+
if (ebo->flag & BONE_SELECTED) stats->totbonesel++;
/* if this is a connected child and it's parent is being moved, remove our root */
@@ -227,7 +227,7 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
/* MetaBall Edit */
MetaBall *mball = obedit->data;
MetaElem *ml;
-
+
for (ml = mball->editelems->first; ml; ml = ml->next) {
stats->totvert++;
if (ml->flag & SELECT) stats->totvertsel++;
@@ -241,7 +241,7 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
int a;
bp = editlatt->def;
-
+
a = editlatt->pntsu * editlatt->pntsv * editlatt->pntsw;
while (a--) {
stats->totvert++;
@@ -319,7 +319,7 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
stats_dupli_object_group_doit(collection, stats, psys, totgroup, &cur);
}
}
-
+
stats_object(ob, base->flag & BASE_SELECTED, 1, stats);
stats->totobj++;
}
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index cb17be5e351..65b3c7bb9fd 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -67,7 +67,7 @@ static SpaceLink *info_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
{
ARegion *ar;
SpaceInfo *sinfo;
-
+
sinfo = MEM_callocN(sizeof(SpaceInfo), "initinfo");
sinfo->spacetype = SPACE_INFO;
@@ -75,17 +75,17 @@ static SpaceLink *info_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for info");
-
+
BLI_addtail(&sinfo->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for info");
-
+
BLI_addtail(&sinfo->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
/* keep in sync with console */
ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
ar->v2d.align |= V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y; /* align bottom left */
@@ -96,15 +96,15 @@ static SpaceLink *info_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
/* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
//ar->v2d.keepzoom = (V2D_KEEPASPECT|V2D_LIMITZOOM);
-
+
return (SpaceLink *)sinfo;
}
/* not spacelink itself */
static void info_free(SpaceLink *UNUSED(sl))
-{
+{
// SpaceInfo *sinfo = (SpaceInfo *) sl;
-
+
}
@@ -117,9 +117,9 @@ static void info_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
static SpaceLink *info_duplicate(SpaceLink *sl)
{
SpaceInfo *sinfon = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
-
+
return (SpaceLink *)sinfon;
}
@@ -132,7 +132,7 @@ static void info_main_region_init(wmWindowManager *wm, ARegion *ar)
/* force it on init, for old files, until it becomes config */
ar->v2d.scroll = (V2D_SCROLL_RIGHT);
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
/* own keymap */
@@ -162,7 +162,7 @@ static void info_main_region_draw(const bContext *C, ARegion *ar)
/* quick way to avoid drawing if not bug enough */
if (ar->winy < 16)
return;
-
+
info_textview_update_rect(C, ar);
/* worlks best with no view2d matrix set */
@@ -172,7 +172,7 @@ static void info_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_GRID_CLAMP);
UI_view2d_scrollers_draw(C, v2d, scrollers);
@@ -187,7 +187,7 @@ static void info_operatortypes(void)
WM_operatortype_append(FILE_OT_unpack_all);
WM_operatortype_append(FILE_OT_unpack_item);
WM_operatortype_append(FILE_OT_unpack_libraries);
-
+
WM_operatortype_append(FILE_OT_make_paths_relative);
WM_operatortype_append(FILE_OT_make_paths_absolute);
WM_operatortype_append(FILE_OT_report_missing_files);
@@ -207,13 +207,13 @@ static void info_operatortypes(void)
static void info_keymap(struct wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Window", 0, 0);
-
+
WM_keymap_verify_item(keymap, "INFO_OT_reports_display_update", TIMERREPORT, KM_ANY, KM_ANY, 0);
/* info space */
keymap = WM_keymap_find(keyconf, "Info", SPACE_INFO, 0);
-
-
+
+
/* report selection */
WM_keymap_add_item(keymap, "INFO_OT_select_pick", SELECTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "INFO_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
@@ -284,7 +284,7 @@ static void info_header_listener(
ED_region_tag_redraw(ar);
break;
}
-
+
}
static void info_header_region_message_subscribe(
@@ -337,17 +337,17 @@ void ED_spacetype_info(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype info");
ARegionType *art;
-
+
st->spaceid = SPACE_INFO;
strncpy(st->name, "Info", BKE_ST_MAXNAME);
-
+
st->new = info_new;
st->free = info_free;
st->init = info_init;
st->duplicate = info_duplicate;
st->operatortypes = info_operatortypes;
st->keymap = info_keymap;
-
+
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype info region");
art->regionid = RGN_TYPE_WINDOW;
@@ -358,20 +358,20 @@ void ED_spacetype_info(void)
art->listener = info_main_region_listener;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype info region");
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
-
+
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
art->listener = info_header_listener;
art->message_subscribe = info_header_region_message_subscribe;
art->init = info_header_region_init;
art->draw = info_header_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
recent_files_menu_register();
BKE_spacetype_register(st);
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 3f35cadd820..85de70c020f 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -63,7 +63,7 @@ typedef struct ConsoleDrawContext {
int ymin, ymax;
int *xy; // [2]
int *sel; // [2]
- int *pos_pick; // bottom of view == 0, top of file == combine chars, end of line is lower then start.
+ int *pos_pick; // bottom of view == 0, top of file == combine chars, end of line is lower then start.
const int *mval; // [2]
int draw;
} ConsoleDrawContext;
@@ -181,14 +181,14 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
size_t len = str_len - initial_offset;
const char *s = str + initial_offset;
int i;
-
+
int sel_orig[2];
copy_v2_v2_int(sel_orig, cdc->sel);
/* invert and swap for wrapping */
cdc->sel[0] = str_len - sel_orig[1];
cdc->sel[1] = str_len - sel_orig[0];
-
+
if (bg) {
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
@@ -219,7 +219,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
BLF_position(cdc->font_id, cdc->xy[0], cdc->lofs + cdc->xy[1], 0);
BLF_draw_mono(cdc->font_id, s, len, cdc->cwidth);
-
+
if (cdc->sel[0] != cdc->sel[1]) {
console_step_sel(cdc, len);
/* BLF_color3ub(cdc->font_id, 0, 255, 0); // debug */
@@ -227,7 +227,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
}
cdc->xy[1] += cdc->lheight;
-
+
/* check if were out of view bounds */
if (cdc->xy[1] > cdc->ymax) {
MEM_freeN(offsets);
@@ -254,7 +254,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
BLF_color3ubv(cdc->font_id, fg);
BLF_position(cdc->font_id, cdc->xy[0], cdc->lofs + cdc->xy[1], 0);
BLF_draw_mono(cdc->font_id, str, str_len, cdc->cwidth);
-
+
if (cdc->sel[0] != cdc->sel[1]) {
int isel[2];
diff --git a/source/blender/editors/space_info/textview.h b/source/blender/editors/space_info/textview.h
index 2f9e518ed47..55f69fbf444 100644
--- a/source/blender/editors/space_info/textview.h
+++ b/source/blender/editors/space_info/textview.h
@@ -37,7 +37,7 @@ typedef struct TextViewContext {
int winx;
int ymin, ymax;
-
+
/* callbacks */
int (*begin)(struct TextViewContext *tvc);
void (*end)(struct TextViewContext *tvc);
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index c173aac1a26..a26e6b0280e 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -87,27 +87,27 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
ListBase anim_data = {NULL, NULL};
short found = 0; /* not bool, since we need to indicate "found but not ideal" status */
int filter;
-
- /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
+
+ /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
* to work correctly is able to be correctly retrieved. There's no point showing empty panels?
*/
- if (ANIM_animdata_get_context(C, &ac) == 0)
+ if (ANIM_animdata_get_context(C, &ac) == 0)
return false;
-
- /* extract list of active channel(s), of which we should only take the first one
+
+ /* extract list of active channel(s), of which we should only take the first one
* - we need the channels flag to get the active AnimData block when there are no NLA Tracks
*/
// XXX: double-check active!
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
switch (ale->type) {
case ANIMTYPE_NLATRACK: /* NLA Track - The primary data type which should get caught */
{
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
-
+
/* found it, now set the pointers */
if (adt_ptr) {
/* AnimData pointer */
@@ -122,7 +122,7 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
NlaStrip *strip = BKE_nlastrip_find_active(nlt);
RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr);
}
-
+
found = 1;
break;
}
@@ -149,7 +149,7 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
/* for these channels, we only do AnimData */
if (ale->adt && adt_ptr) {
ID *id;
-
+
if ((ale->data == NULL) || (ale->type == ANIMTYPE_OBJECT)) {
/* ale->data is not an ID block! */
id = ale->id;
@@ -158,13 +158,13 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
/* ale->data is always the proper ID block we need, but ale->id may not be (i.e. for textures) */
id = (ID *)ale->data;
}
-
+
/* AnimData pointer */
if (adt_ptr) {
RNA_pointer_create(id, &RNA_AnimData, ale->adt, adt_ptr);
}
-
- /* set found status to -1, since setting to 1 would break the loop
+
+ /* set found status to -1, since setting to 1 would break the loop
* and potentially skip an active NLA-Track in some cases...
*/
found = -1;
@@ -172,14 +172,14 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
break;
}
}
-
+
if (found > 0)
break;
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
return (found != 0);
}
@@ -212,12 +212,12 @@ static int nla_strip_actclip_panel_poll(const bContext *C, PanelType *UNUSED(pt)
{
PointerRNA ptr;
NlaStrip *strip;
-
+
if (!nla_panel_context(C, NULL, NULL, &ptr))
return 0;
if (ptr.data == NULL)
return 0;
-
+
strip = ptr.data;
return (strip->type == NLASTRIP_TYPE_CLIP);
}
@@ -226,17 +226,17 @@ static int nla_strip_eval_panel_poll(const bContext *C, PanelType *UNUSED(pt))
{
PointerRNA ptr;
NlaStrip *strip;
-
+
if (!nla_panel_context(C, NULL, NULL, &ptr))
return 0;
if (ptr.data == NULL)
return 0;
-
+
strip = ptr.data;
-
+
if (strip->type == NLASTRIP_TYPE_SOUND)
return 0;
-
+
return 1;
}
@@ -250,53 +250,53 @@ static void nla_panel_animdata(const bContext *C, Panel *pa)
uiLayout *layout = pa->layout;
uiLayout *row;
uiBlock *block;
-
+
/* check context and also validity of pointer */
if (!nla_panel_context(C, &adt_ptr, NULL, NULL))
return;
/* adt = adt_ptr.data; */
-
+
block = uiLayoutGetBlock(layout);
UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
-
+
/* AnimData Source Properties ----------------------------------- */
-
- /* icon + id-block name of block where AnimData came from to prevent
+
+ /* icon + id-block name of block where AnimData came from to prevent
* accidentally changing the properties of the wrong action
*/
if (adt_ptr.id.data) {
ID *id = adt_ptr.id.data;
PointerRNA id_ptr;
-
+
RNA_id_pointer_create(id, &id_ptr);
-
+
/* ID-block name > AnimData */
row = uiLayoutRow(layout, true);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
-
+
uiItemL(row, id->name + 2, RNA_struct_ui_icon(id_ptr.type)); /* id-block (src) */
uiItemL(row, "", VICO_SMALL_TRI_RIGHT_VEC); /* expander */
uiItemL(row, IFACE_("Animation Data"), ICON_ANIM_DATA); /* animdata */
-
+
uiItemS(layout);
}
-
+
/* Active Action Properties ------------------------------------- */
/* action */
row = uiLayoutRow(layout, true);
uiTemplateID(
row, (bContext *)C, &adt_ptr, "action",
"ACTION_OT_new", NULL, "NLA_OT_action_unlink", UI_TEMPLATE_ID_FILTER_ALL);
-
+
/* extrapolation */
row = uiLayoutRow(layout, true);
uiItemR(row, &adt_ptr, "action_extrapolation", 0, NULL, ICON_NONE);
-
+
/* blending */
row = uiLayoutRow(layout, true);
uiItemR(row, &adt_ptr, "action_blend_type", 0, NULL, ICON_NONE);
-
+
/* influence */
row = uiLayoutRow(layout, true);
uiItemR(row, &adt_ptr, "action_influence", 0, NULL, ICON_NONE);
@@ -309,14 +309,14 @@ static void nla_panel_track(const bContext *C, Panel *pa)
uiLayout *layout = pa->layout;
uiLayout *row;
uiBlock *block;
-
+
/* check context and also validity of pointer */
if (!nla_panel_context(C, NULL, &nlt_ptr, NULL))
return;
-
+
block = uiLayoutGetBlock(layout);
UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
-
+
/* Info - Active NLA-Context:Track ---------------------- */
row = uiLayoutRow(layout, true);
uiItemR(row, &nlt_ptr, "name", 0, NULL, ICON_NLA);
@@ -330,41 +330,41 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
uiLayout *column, *row, *sub;
uiBlock *block;
short showEvalProps = 1;
-
+
if (!nla_panel_context(C, NULL, NULL, &strip_ptr))
return;
-
+
block = uiLayoutGetBlock(layout);
UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
-
+
/* Strip Properties ------------------------------------- */
/* strip type */
row = uiLayoutColumn(layout, true);
uiItemR(row, &strip_ptr, "name", 0, NULL, ICON_NLA); // XXX icon?
uiItemR(row, &strip_ptr, "type", 0, NULL, ICON_NONE);
-
+
/* strip extents */
column = uiLayoutColumn(layout, true);
uiItemL(column, IFACE_("Strip Extents:"), ICON_NONE);
uiItemR(column, &strip_ptr, "frame_start", 0, NULL, ICON_NONE);
uiItemR(column, &strip_ptr, "frame_end", 0, NULL, ICON_NONE);
-
+
/* Evaluation-Related Strip Properties ------------------ */
-
+
/* sound properties strips don't have these settings */
if (RNA_enum_get(&strip_ptr, "type") == NLASTRIP_TYPE_SOUND)
showEvalProps = 0;
-
+
/* only show if allowed to... */
if (showEvalProps) {
/* extrapolation */
row = uiLayoutRow(layout, true);
uiItemR(row, &strip_ptr, "extrapolation", 0, NULL, ICON_NONE);
-
+
/* blending */
row = uiLayoutRow(layout, true);
uiItemR(row, &strip_ptr, "blend_type", 0, NULL, ICON_NONE);
-
+
/* blend in/out + autoblending
* - blend in/out can only be set when autoblending is off
*/
@@ -376,7 +376,7 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
uiLayoutSetActive(sub, RNA_boolean_get(&strip_ptr, "use_auto_blend") == false);
uiItemR(sub, &strip_ptr, "blend_in", 0, NULL, ICON_NONE);
uiItemR(sub, &strip_ptr, "blend_out", 0, NULL, ICON_NONE);
-
+
/* settings */
column = uiLayoutColumn(layout, true);
uiLayoutSetActive(column, !(RNA_boolean_get(&strip_ptr, "use_animated_influence") || RNA_boolean_get(&strip_ptr, "use_animated_time")));
@@ -398,27 +398,27 @@ static void nla_panel_actclip(const bContext *C, Panel *pa)
/* check context and also validity of pointer */
if (!nla_panel_context(C, NULL, NULL, &strip_ptr))
return;
-
+
block = uiLayoutGetBlock(layout);
UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
-
+
/* Strip Properties ------------------------------------- */
/* action pointer */
row = uiLayoutRow(layout, true);
uiItemR(row, &strip_ptr, "action", 0, NULL, ICON_ACTION);
-
+
/* action extents */
// XXX custom names were used here (to avoid the prefixes)... probably not necessary in future?
column = uiLayoutColumn(layout, true);
uiItemL(column, IFACE_("Action Extents:"), ICON_NONE);
uiItemR(column, &strip_ptr, "action_frame_start", 0, IFACE_("Start Frame"), ICON_NONE);
uiItemR(column, &strip_ptr, "action_frame_end", 0, IFACE_("End Frame"), ICON_NONE);
-
+
// XXX: this layout may actually be too abstract and confusing, and may be better using standard column layout
row = uiLayoutRow(layout, false);
uiItemR(row, &strip_ptr, "use_sync_length", 0, IFACE_("Sync Length"), ICON_NONE);
uiItemO(row, IFACE_("Now"), ICON_FILE_REFRESH, "NLA_OT_action_sync_length");
-
+
/* action usage */
column = uiLayoutColumn(layout, true);
uiLayoutSetActive(column, RNA_boolean_get(&strip_ptr, "use_animated_time") == false);
@@ -438,13 +438,13 @@ static void nla_panel_evaluation(const bContext *C, Panel *pa)
/* check context and also validity of pointer */
if (!nla_panel_context(C, NULL, NULL, &strip_ptr))
return;
-
+
block = uiLayoutGetBlock(layout);
UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, &strip_ptr, "use_animated_influence", 0, NULL, ICON_NONE);
-
+
sub = uiLayoutColumn(col, true);
uiLayoutSetEnabled(sub, RNA_boolean_get(&strip_ptr, "use_animated_influence"));
uiItemR(sub, &strip_ptr, "influence", 0, NULL, ICON_NONE);
@@ -472,28 +472,28 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa)
if (!nla_panel_context(C, NULL, NULL, &strip_ptr))
return;
strip = strip_ptr.data;
-
+
block = uiLayoutGetBlock(pa->layout);
UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
-
+
/* 'add modifier' button at top of panel */
{
row = uiLayoutRow(pa->layout, false);
block = uiLayoutGetBlock(row);
-
+
// FIXME: we need to set the only-active property so that this will only add modifiers for the active strip (not all selected)
uiItemMenuEnumO(row, (bContext *)C, "NLA_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE);
-
+
/* copy/paste (as sub-row) */
row = uiLayoutRow(row, true);
uiItemO(row, "", ICON_COPYDOWN, "NLA_OT_fmodifier_copy");
uiItemO(row, "", ICON_PASTEDOWN, "NLA_OT_fmodifier_paste");
}
-
+
/* draw each modifier */
for (fcm = strip->modifiers.first; fcm; fcm = fcm->next) {
col = uiLayoutColumn(pa->layout, true);
-
+
ANIM_uiTemplate_fmodifier_draw(col, strip_ptr.id.data, &strip->modifiers, fcm);
}
}
@@ -565,7 +565,7 @@ static int nla_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = nla_has_buttons_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -577,7 +577,7 @@ void NLA_OT_properties(wmOperatorType *ot)
ot->name = "Properties";
ot->idname = "NLA_OT_properties";
ot->description = "Toggle the properties region visibility";
-
+
ot->exec = nla_properties_toggle_exec;
ot->poll = ED_operator_nla_active;
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 9b7a49ec624..d782fe4d7ef 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -80,26 +80,26 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
View2D *v2d = &ac->ar->v2d;
int notifierFlags = 0;
-
+
/* get the channel that was clicked on */
/* filter channels */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* get channel from index */
ale = BLI_findlink(&anim_data, channel_index);
if (ale == NULL) {
/* channel not found */
if (G.debug & G_DEBUG)
printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n", channel_index);
-
+
ANIM_animdata_freelist(&anim_data);
return 0;
}
-
+
/* action to take depends on what channel we've got */
// WARNING: must keep this in sync with the equivalent function in anim_channels_edit.c
switch (ale->type) {
@@ -107,7 +107,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
{
Scene *sce = (Scene *)ale->data;
AnimData *adt = sce->adt;
-
+
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
@@ -118,7 +118,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
sce->flag |= SCE_DS_SELECTED;
if (adt) adt->flag |= ADT_UI_SELECTED;
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
@@ -128,14 +128,14 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
Base *base = (Base *)ale->data;
Object *ob = base->object;
AnimData *adt = ob->adt;
-
+
if (nlaedit_is_tweakmode_on(ac) == 0 && (base->flag & BASE_SELECTABLED)) {
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
ED_object_base_select(base, BA_INVERT);
BKE_scene_object_base_flag_sync_from_base(base);
-
+
if (adt) adt->flag ^= ADT_UI_SELECTED;
}
else {
@@ -146,19 +146,19 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
BKE_scene_object_base_flag_sync_from_base(b);
if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
}
-
+
/* select object now */
ED_object_base_select(base, BA_SELECT);
BKE_scene_object_base_flag_sync_from_base(base);
if (adt) adt->flag |= ADT_UI_SELECTED;
}
-
+
/* change active object - regardless of whether it is now selected [T37883] */
ED_object_base_activate(C, base); /* adds notifier */
-
+
if ((adt) && (adt->flag & ADT_UI_SELECTED))
adt->flag |= ADT_UI_ACTIVE;
-
+
/* notifiers - channel was selected */
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
}
@@ -195,12 +195,12 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
ale->adt->flag |= ADT_UI_SELECTED;
}
-
+
/* set active? */
if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
ale->adt->flag |= ADT_UI_ACTIVE;
}
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
break;
}
@@ -209,7 +209,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
short offset;
-
+
/* offset for start of channel (on LHS of channel-list) */
if (ale->id) {
/* special exception for materials and particles */
@@ -220,25 +220,25 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
}
else
offset = 0;
-
+
if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) {
/* toggle protection (only if there's a toggle there) */
nlt->flag ^= NLATRACK_PROTECTED;
-
+
/* notifier flags - channel was edited */
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
}
else if (x >= (v2d->cur.xmax - 2 * NLACHANNEL_BUTTON_WIDTH)) {
/* toggle mute */
nlt->flag ^= NLATRACK_MUTED;
-
+
/* notifier flags - channel was edited */
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
}
else if (x <= ((NLACHANNEL_BUTTON_WIDTH * 2) + offset)) {
/* toggle 'solo' */
BKE_nlatrack_solo_toggle(adt, nlt);
-
+
/* notifier flags - channel was edited */
notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
}
@@ -253,11 +253,11 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
nlt->flag |= NLATRACK_SELECTED;
}
-
+
/* if NLA-Track is selected now, make NLA-Track the 'active' one in the visible list */
if (nlt->flag & NLATRACK_SELECTED)
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
-
+
/* notifier flags - channel was selected */
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
}
@@ -266,7 +266,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
case ANIMTYPE_NLAACTION:
{
AnimData *adt = BKE_animdata_from_id(ale->id);
-
+
/* button region... */
if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) {
if (nlaedit_is_tweakmode_on(ac) == 0) {
@@ -279,13 +279,13 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
/* when in tweakmode, this button becomes the toggle for mapped editing */
adt->flag ^= ADT_NLA_EDIT_NOMAP;
}
-
+
/* changes to NLA-Action occurred */
notifierFlags |= ND_NLA_ACTCHANGE;
}
/* OR rest of name... */
else {
- /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
+ /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
* - this is useful when there's no clear divider, and makes more sense in
* the case of users trying to use this to change actions
* - in tweakmode, clicking here gets us out of tweakmode, as changing selection
@@ -296,7 +296,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
if (nlaedit_is_tweakmode_on(ac)) {
/* exit tweakmode immediately */
nlaedit_disable_tweakmode(ac, true);
-
+
/* changes to NLA-Action occurred */
notifierFlags |= ND_NLA_ACTCHANGE;
}
@@ -311,11 +311,11 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
adt->flag |= ADT_UI_SELECTED;
}
-
+
/* set active? */
if (adt->flag & ADT_UI_SELECTED)
adt->flag |= ADT_UI_ACTIVE;
-
+
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
}
}
@@ -326,10 +326,10 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
printf("Error: Invalid channel type in mouse_nla_channels()\n");
break;
}
-
+
/* free channels */
ANIM_animdata_freelist(&anim_data);
-
+
/* return the notifier-flags set */
return notifierFlags;
}
@@ -347,55 +347,55 @@ static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEv
int notifierFlags = 0;
short selectmode;
float x, y;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get useful pointers from animation context data */
snla = (SpaceNla *)ac.sl;
ar = ac.ar;
v2d = &ar->v2d;
-
+
/* select mode is either replace (deselect all, then add) or add/extend */
if (RNA_boolean_get(op->ptr, "extend"))
selectmode = SELECT_INVERT;
else
selectmode = SELECT_REPLACE;
-
- /* figure out which channel user clicked in
+
+ /* figure out which channel user clicked in
* Note: although channels technically start at y= NLACHANNEL_FIRST, we need to adjust by half a channel's height
* so that the tops of channels get caught ok. Since NLACHANNEL_FIRST is really NLACHANNEL_HEIGHT, we simply use
* NLACHANNEL_HEIGHT_HALF.
*/
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
UI_view2d_listview_view_to_cell(v2d, NLACHANNEL_NAMEWIDTH, NLACHANNEL_STEP(snla), 0, (float)NLACHANNEL_HEIGHT_HALF(snla), x, y, NULL, &channel_index);
-
+
/* handle mouse-click in the relevant channel then */
notifierFlags = mouse_nla_channels(C, &ac, x, channel_index, selectmode);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void NLA_OT_channels_click(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Mouse Click on NLA Channels";
ot->idname = "NLA_OT_channels_click";
ot->description = "Handle clicks to select NLA channels";
-
+
/* api callbacks */
ot->invoke = nlachannels_mouseclick_invoke;
ot->poll = ED_operator_nla_active;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* props */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -411,15 +411,15 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
bAnimContext ac;
AnimData *adt = NULL;
int channel_index = RNA_int_get(op->ptr, "channel_index");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get anim-channel to use (or more specifically, the animdata block behind it) */
if (channel_index == -1) {
PointerRNA adt_ptr = {{NULL}};
-
+
/* active animdata block */
if (nla_panel_context(C, &adt_ptr, NULL, NULL) == 0 || (adt_ptr.data == NULL)) {
BKE_report(op->reports, RPT_ERROR, "No active AnimData block to use "
@@ -435,11 +435,11 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* filter channels */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* get channel from index */
ale = BLI_findlink(&anim_data, channel_index);
if (ale == NULL) {
@@ -452,14 +452,14 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
ANIM_animdata_freelist(&anim_data);
return OPERATOR_CANCELLED;
}
-
+
/* grab AnimData from the channel */
adt = ale->adt;
-
+
/* we don't need anything here anymore, so free it all */
ANIM_animdata_freelist(&anim_data);
}
-
+
/* double-check that we are free to push down here... */
if (adt == NULL) {
BKE_report(op->reports, RPT_WARNING, "Internal Error - AnimData block is not valid");
@@ -478,7 +478,7 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
/* 'push-down' action - only usable when not in TweakMode */
BKE_nla_action_pushdown(adt);
}
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
return OPERATOR_FINISHED;
@@ -490,14 +490,14 @@ void NLA_OT_action_pushdown(wmOperatorType *ot)
ot->name = "Push Down Action";
ot->idname = "NLA_OT_action_pushdown";
ot->description = "Push action down onto the top of the NLA stack as a new strip";
-
+
/* callbacks */
ot->exec = nlachannels_pushdown_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_int(ot->srna, "channel_index", -1, -1, INT_MAX, "Channel Index",
"Index of NLA action channel to perform pushdown operation on",
@@ -512,7 +512,7 @@ static int nla_action_unlink_poll(bContext *C)
if (ED_operator_nla_active(C)) {
return nla_panel_context(C, NULL, NULL, NULL);
}
-
+
/* something failed... */
return false;
}
@@ -521,22 +521,22 @@ static int nla_action_unlink_exec(bContext *C, wmOperator *op)
{
PointerRNA adt_ptr;
AnimData *adt;
-
+
/* check context and also validity of pointer */
if (!nla_panel_context(C, &adt_ptr, NULL, NULL))
return OPERATOR_CANCELLED;
-
+
/* get animdata */
adt = adt_ptr.data;
if (adt == NULL)
return OPERATOR_CANCELLED;
-
+
/* do unlinking */
if (adt && adt->action) {
bool force_delete = RNA_boolean_get(op->ptr, "force_delete");
ED_animedit_unlink_action(C, adt_ptr.id.data, adt, adt->action, op->reports, force_delete);
}
-
+
return OPERATOR_FINISHED;
}
@@ -550,19 +550,19 @@ static int nla_action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *
void NLA_OT_action_unlink(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Unlink Action";
ot->idname = "NLA_OT_action_unlink";
ot->description = "Unlink this action from the active action slot (and/or exit Tweak Mode)";
-
+
/* callbacks */
ot->invoke = nla_action_unlink_invoke;
ot->exec = nla_action_unlink_exec;
ot->poll = nla_action_unlink_poll;
-
+
/* properties */
- prop = RNA_def_boolean(ot->srna, "force_delete", false, "Force Delete",
+ prop = RNA_def_boolean(ot->srna, "force_delete", false, "Force Delete",
"Clear Fake User and remove copy stashed in this datablock's NLA stack");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -578,17 +578,17 @@ bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
int filter;
AnimData *lastAdt = NULL;
bool added = false;
-
+
/* get a list of the (selected) NLA Tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* add tracks... */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_NLATRACK) {
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
-
+
/* check if just adding a new track above this one,
* or whether we're adding a new one to the top of the stack that this one belongs to
*/
@@ -605,10 +605,10 @@ bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
return added;
}
@@ -619,18 +619,18 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac)
bAnimListElem *ale;
int filter;
bool added = false;
-
+
/* get a list of the selected AnimData blocks in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* check if selected AnimData blocks are empty, and add tracks if so... */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->adt;
-
+
/* sanity check */
BLI_assert(adt->flag & ADT_UI_SELECTED);
-
+
/* ensure it is empty */
if (BLI_listbase_is_empty(&adt->nla_tracks)) {
/* add new track to this AnimData block then */
@@ -638,10 +638,10 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac)
added = true;
}
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
-
+
return added;
}
@@ -652,20 +652,20 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
bAnimContext ac;
bool above_sel = RNA_boolean_get(op->ptr, "above_selected");
bool op_done = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* perform adding in two passes - existing first so that we don't double up for empty */
op_done |= nlaedit_add_tracks_existing(&ac, above_sel);
op_done |= nlaedit_add_tracks_empty(&ac);
-
+
/* done? */
if (op_done) {
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -673,7 +673,7 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
/* failed to add any tracks */
BKE_report(op->reports, RPT_WARNING,
"Select an existing NLA Track or an empty action line first");
-
+
/* not done */
return OPERATOR_CANCELLED;
}
@@ -685,14 +685,14 @@ void NLA_OT_tracks_add(wmOperatorType *ot)
ot->name = "Add Tracks";
ot->idname = "NLA_OT_tracks_add";
ot->description = "Add NLA-Tracks above/after the selected tracks";
-
+
/* api callbacks */
ot->exec = nlaedit_add_tracks_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "above_selected", 0, "Above Selected", "Add a new NLA Track above every existing selected one");
}
@@ -703,42 +703,42 @@ void NLA_OT_tracks_add(wmOperatorType *ot)
static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the AnimData blocks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* delete tracks */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_NLATRACK) {
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
-
+
/* if track is currently 'solo', then AnimData should have its
* 'has solo' flag disabled
*/
if (nlt->flag & NLATRACK_SOLO)
adt->flag &= ~ADT_NLA_SOLO_TRACK;
-
+
/* call delete on this track - deletes all strips too */
BKE_nlatrack_free(&adt->nla_tracks, nlt);
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -749,11 +749,11 @@ void NLA_OT_tracks_delete(wmOperatorType *ot)
ot->name = "Delete Tracks";
ot->idname = "NLA_OT_tracks_delete";
ot->description = "Delete selected NLA-Tracks and the strips they contain";
-
+
/* api callbacks */
ot->exec = nlaedit_delete_tracks_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -762,7 +762,7 @@ void NLA_OT_tracks_delete(wmOperatorType *ot)
/* AnimData Related Operators */
/* ******************** Include Objects Operator ***************************** */
-/* Include selected objects in NLA Editor, by giving them AnimData blocks
+/* Include selected objects in NLA Editor, by giving them AnimData blocks
* NOTE: This doesn't help for non-object AnimData, where we do not have any effective
* selection mechanism in place. Unfortunately, this means that non-object AnimData
* once again becomes a second-class citizen here. However, at least for the most
@@ -773,28 +773,28 @@ static int nlaedit_objects_add_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
SpaceNla *snla;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* ensure that filters are set so that the effect will be immediately visible */
snla = (SpaceNla *)ac.sl;
if (snla && snla->ads) {
snla->ads->filterflag &= ~ADS_FILTER_NLA_NOACT;
}
-
- /* operate on selected objects... */
+
+ /* operate on selected objects... */
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
/* ensure that object has AnimData... that's all */
BKE_animdata_add_id(&ob->id);
}
CTX_DATA_END;
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -805,11 +805,11 @@ void NLA_OT_selected_objects_add(wmOperatorType *ot)
ot->name = "Include Selected Objects";
ot->idname = "NLA_OT_selected_objects_add";
ot->description = "Make selected objects appear in NLA Editor by adding Animation Data";
-
+
/* api callbacks */
ot->exec = nlaedit_objects_add_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 3a6e54bb7f3..3f1ab059a91 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -74,7 +74,7 @@
/* Action-Line ---------------------- */
-/* get colors for drawing Action-Line
+/* get colors for drawing Action-Line
* NOTE: color returned includes fine-tuned alpha!
*/
void nla_action_get_color(AnimData *adt, bAction *act, float color[4])
@@ -93,7 +93,7 @@ void nla_action_get_color(AnimData *adt, bAction *act, float color[4])
UI_GetThemeColor4fv(TH_ANIM_INACTIVE, color);
}
}
-
+
/* when an NLA track is tagged "solo", action doesn't contribute, so shouldn't be as prominent */
if (adt && (adt->flag & ADT_NLA_SOLO_TRACK))
color[3] *= 0.15f;
@@ -111,8 +111,8 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa
if (ELEM(NULL, act, keys.first))
return;
- /* draw a darkened region behind the strips
- * - get and reset the background color, this time without the alpha to stand out better
+ /* draw a darkened region behind the strips
+ * - get and reset the background color, this time without the alpha to stand out better
* (amplified alpha is used instead)
*/
float color[4];
@@ -213,7 +213,7 @@ static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymax
static void nla_strip_draw_markers(NlaStrip *strip, float yminc, float ymaxc)
{
glLineWidth(2.0f);
-
+
if (strip->type == NLASTRIP_TYPE_CLIP) {
/* try not to be too conspicuous, while being visible enough when transforming */
int shade = (strip->flag & NLASTRIP_FLAG_SELECT) ? -60 : -40;
@@ -231,7 +231,7 @@ static void nla_strip_draw_markers(NlaStrip *strip, float yminc, float ymaxc)
}
}
}
-
+
glLineWidth(1.0f);
}
@@ -303,18 +303,18 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col
static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, unsigned int pos)
{
const float yheight = ymaxc - yminc;
-
+
immUniformColor3f(0.7f, 0.7f, 0.7f);
-
+
/* draw with AA'd line */
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
-
+
/* influence -------------------------- */
if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) {
FCurve *fcu = list_find_fcurve(&strip->fcurves, "influence", 0);
float cfra;
-
+
/* plot the curve (over the strip's main region) */
if (fcu) {
immBegin(GWN_PRIM_LINE_STRIP, abs((int)(strip->end - strip->start) + 1));
@@ -343,7 +343,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns
}
else
immVertex2f(pos, strip->start, ymaxc);
-
+
/* end of strip */
if (IS_EQF(strip->blendout, 0.0f) == 0) {
immVertex2f(pos, strip->end - strip->blendout, ymaxc);
@@ -367,14 +367,14 @@ static uint nla_draw_use_dashed_outlines(float color[4], bool muted)
/* Note that we use dashed shader here, and make it draw solid lines if not muted... */
uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
-
+
float viewport_size[4];
glGetFloatv(GL_VIEWPORT, viewport_size);
immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
-
+
immUniform1i("num_colors", 0); /* Simple dashes. */
immUniformColor3fv(color);
-
+
/* line style: dotted for muted */
if (muted) {
/* dotted - and slightly thicker for readability of the dashes */
@@ -387,7 +387,7 @@ static uint nla_draw_use_dashed_outlines(float color[4], bool muted)
immUniform1f("dash_factor", 2.0f);
glLineWidth(1.0f);
}
-
+
return shdr_pos;
}
@@ -398,13 +398,13 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
const bool muted = ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED));
float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
uint shdr_pos;
-
+
/* get color of strip */
nla_strip_get_color_inside(adt, strip, color);
-
+
shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
+
/* draw extrapolation info first (as backdrop)
* - but this should only be drawn if track has some contribution
*/
@@ -415,9 +415,9 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
switch (strip->extendmode) {
/* since this does both sides, only do the 'before' side, and leave the rest to the next case */
- case NLASTRIP_EXTEND_HOLD:
- /* only need to draw here if there's no strip before since
- * it only applies in such a situation
+ case NLASTRIP_EXTEND_HOLD:
+ /* only need to draw here if there's no strip before since
+ * it only applies in such a situation
*/
if (strip->prev == NULL) {
/* set the drawing color to the color of the strip, but with very faint alpha */
@@ -429,12 +429,12 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
ATTR_FALLTHROUGH;
/* this only draws after the strip */
- case NLASTRIP_EXTEND_HOLD_FORWARD:
+ case NLASTRIP_EXTEND_HOLD_FORWARD:
/* only need to try and draw if the next strip doesn't occur immediately after */
if ((strip->next == NULL) || (IS_EQF(strip->next->start, strip->end) == 0)) {
/* set the drawing color to the color of the strip, but this time less faint */
immUniformColor3fvAlpha(color, 0.3f);
-
+
/* draw the rect to the next strip or the edge of the screen */
float x2 = strip->next ? strip->next->start : v2d->cur.xmax;
immRectf(shdr_pos, strip->end, yminc, x2, ymaxc);
@@ -461,7 +461,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
else {
/* strip is in disabled track - make less visible */
immUniformColor3fvAlpha(color, 0.1f);
-
+
glEnable(GL_BLEND);
immRectf(shdr_pos, strip->start, yminc, strip->end, ymaxc);
glDisable(GL_BLEND);
@@ -494,7 +494,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
color[0] = color[1] = color[2] = 0.0f; /* FIXME: or 1.0f ?? */
}
- /* draw outline
+ /* draw outline
* - dashed-line shader is loaded after this block
*/
if (muted) {
@@ -505,7 +505,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
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);
-
+
/* restore current vertex format & program (roundbox trashes it) */
shdr_pos = nla_draw_use_dashed_outlines(color, muted);
}
@@ -537,7 +537,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
/* only draw first-level of child-strips, but don't draw any lines on the endpoints */
for (NlaStrip *cs = strip->strips.first; cs; cs = cs->next) {
- /* draw start-line if not same as end of previous (and only if not the first strip)
+ /* draw start-line if not same as end of previous (and only if not the first strip)
* - on upper half of strip
*/
if ((cs->prev) && IS_EQF(cs->prev->end, cs->start) == 0) {
@@ -569,7 +569,7 @@ static void nla_draw_strip_text(
char str[256];
size_t str_len;
char col[4];
-
+
/* just print the name and the range */
if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
str_len = BLI_snprintf_rlen(str, sizeof(str), "%d) Temp-Meta", index);
@@ -577,7 +577,7 @@ static void nla_draw_strip_text(
else {
str_len = BLI_strncpy_rlen(str, strip->name, sizeof(str));
}
-
+
/* set text color - if colors (see above) are light, draw black text, otherwise draw white */
if (strip->flag & (NLASTRIP_FLAG_ACTIVE | NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_TWEAKUSER)) {
col[0] = col[1] = col[2] = 0;
@@ -585,14 +585,14 @@ static void nla_draw_strip_text(
else {
col[0] = col[1] = col[2] = 255;
}
-
+
/* text opacity depends on whether if there's a solo'd track, this isn't it */
if (non_solo == 0)
col[3] = 255;
else
col[3] = 128;
- /* set bounding-box for text
+ /* set bounding-box for text
* - padding of 2 'units' on either side
*/
/* TODO: make this centered? */
@@ -618,8 +618,8 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
size_t numstr_len;
/* Always draw times above the strip, whereas sequencer drew below + above.
- * However, we should be fine having everything on top, since these tend to be
- * quite spaced out.
+ * However, we should be fine having everything on top, since these tend to be
+ * quite spaced out.
* - 1 dp is compromise between lack of precision (ints only, as per sequencer)
* while also preserving some accuracy, since we do use floats
*/
@@ -639,32 +639,32 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
View2D *v2d = &ar->v2d;
const float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
const float text_margin_x = (8 * UI_DPI_FAC) * pixelx;
-
+
/* build list of channels to draw */
ListBase anim_data = {NULL, NULL};
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* Update max-extent of channels here (taking into account scrollers):
* - this is done to allow the channel list to be scrollable, but must be done here
* to avoid regenerating the list again and/or also because channels list is drawn first
- * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
+ * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
int height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2));
-
- /* don't use totrect set, as the width stays the same
- * (NOTE: this is ok here, the configuration is pretty straightforward)
+
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
*/
v2d->tot.ymin = (float)(-height);
-
+
/* loop through channels, and set up drawing depending on their type */
float y = (float)(-NLACHANNEL_HEIGHT(snla));
-
+
for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next) {
const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
@@ -677,7 +677,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
int index;
-
+
/* draw each strip in the track (if visible) */
for (strip = nlt->strips.first, index = 1; strip; strip = strip->next, index++) {
if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
@@ -686,13 +686,13 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
/* draw the visualization of the strip */
nla_draw_strip(snla, adt, nlt, strip, v2d, yminc, ymaxc);
-
+
/* add the text for this strip to the cache */
if (xminc < xmaxc) {
nla_draw_strip_text(adt, nlt, strip, index, v2d, xminc, xmaxc, yminc, ymaxc);
}
-
- /* if transforming strips (only real reason for temp-metas currently),
+
+ /* if transforming strips (only real reason for temp-metas currently),
* add to the cache the frame numbers of the strip's extents
*/
if (strip->flag & NLASTRIP_FLAG_TEMP_META)
@@ -723,7 +723,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
* but also slightly shorter for some more contrast when viewing the strips
*/
immRectf(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP);
-
+
/* draw 'embossed' lines above and below the strip for effect */
/* white base-lines */
glLineWidth(2.0f);
@@ -761,7 +761,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
/* adjust y-position for next one */
y -= NLACHANNEL_STEP(snla);
}
-
+
/* free tempolary channels */
ANIM_animdata_freelist(&anim_data);
}
@@ -774,40 +774,40 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
SpaceNla *snla = (SpaceNla *)ac->sl;
View2D *v2d = &ar->v2d;
float y = 0.0f;
size_t items;
-
+
/* build list of channels to draw */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* Update max-extent of channels here (taking into account scrollers):
* - this is done to allow the channel list to be scrollable, but must be done here
* to avoid regenerating the list again and/or also because channels list is drawn first
- * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
+ * - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
int height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2));
- /* don't use totrect set, as the width stays the same
- * (NOTE: this is ok here, the configuration is pretty straightforward)
+ /* don't use totrect set, as the width stays the same
+ * (NOTE: this is ok here, the configuration is pretty straightforward)
*/
v2d->tot.ymin = (float)(-height);
/* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */
UI_view2d_sync(NULL, ac->sa, v2d, V2D_LOCK_COPY);
-
+
/* draw channels */
{ /* first pass: just the standard GL-drawing for backdrop + text */
size_t channel_index = 0;
-
+
y = (float)(-NLACHANNEL_HEIGHT(snla));
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
@@ -815,7 +815,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
/* draw all channels using standard channel-drawing API */
ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index);
}
-
+
/* adjust y-position for next one */
y -= NLACHANNEL_STEP(snla);
channel_index++;
@@ -824,18 +824,18 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
{ /* second pass: UI widgets */
uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
size_t channel_index = 0;
-
+
y = (float)(-NLACHANNEL_HEIGHT(snla));
-
+
/* set blending again, as may not be set in previous step */
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
+
/* loop through channels, and set up drawing depending on their type */
for (ale = anim_data.first; ale; ale = ale->next) {
const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla));
const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla));
-
+
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
@@ -843,18 +843,18 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
/* draw all channels using standard channel-drawing API */
ANIM_channel_draw_widgets(C, ac, ale, block, yminc, ymaxc, channel_index);
}
-
+
/* adjust y-position for next one */
y -= NLACHANNEL_STEP(snla);
channel_index++;
}
-
+
UI_block_end(C, block);
UI_block_draw(C, block);
-
+
glDisable(GL_BLEND);
}
-
+
/* free temporary channels */
ANIM_animdata_freelist(&anim_data);
}
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 4fabd1ded46..26ac06446c4 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -83,15 +83,15 @@ void ED_nla_postop_refresh(bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
short filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_FOREDIT);
-
+
/* get blocks to work on */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
/* performing auto-blending, extend-mode validation, etc. */
BKE_nla_validate_state(ale->data);
}
-
+
/* free temp memory */
ANIM_animdata_freelist(&anim_data);
}
@@ -100,62 +100,62 @@ void ED_nla_postop_refresh(bAnimContext *ac)
/* 'Special' Editing */
/* ******************** Tweak-Mode Operators ***************************** */
-/* 'Tweak mode' allows the action referenced by the active NLA-strip to be edited
+/* 'Tweak mode' allows the action referenced by the active NLA-strip to be edited
* as if it were the normal Active-Action of its AnimData block.
*/
static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
const bool do_solo = RNA_boolean_get(op->ptr, "isolate_action");
bool ok = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the AnimData blocks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* if no blocks, popup error? */
if (BLI_listbase_is_empty(&anim_data)) {
BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for");
return OPERATOR_CANCELLED;
}
-
+
/* for each AnimData block with NLA-data, try setting it in tweak-mode */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->data;
-
+
/* try entering tweakmode if valid */
ok |= BKE_nla_tweakmode_enter(adt);
-
+
/* mark the active track as being "solo"? */
if (do_solo && adt->actstrip) {
NlaTrack *nlt = BKE_nlatrack_find_tweaked(adt);
-
+
if (nlt && !(nlt->flag & NLATRACK_SOLO)) {
BKE_nlatrack_solo_toggle(adt, nlt);
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
- /* if we managed to enter tweakmode on at least one AnimData block,
+
+ /* if we managed to enter tweakmode on at least one AnimData block,
* set the flag for this in the active scene and send notifiers
*/
if (ac.scene && ok) {
/* set editing flag */
ac.scene->flag |= SCE_NLA_EDIT_ON;
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
}
@@ -163,27 +163,27 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweak mode on");
return OPERATOR_CANCELLED;
}
-
+
/* done */
return OPERATOR_FINISHED;
}
-
+
void NLA_OT_tweakmode_enter(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Enter Tweak Mode";
ot->idname = "NLA_OT_tweakmode_enter";
ot->description = "Enter tweaking mode for the action referenced by the active strip to edit its keyframes";
-
+
/* api callbacks */
ot->exec = nlaedit_enable_tweakmode_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "isolate_action", 0, "Isolate Action",
"Enable 'solo' on the NLA Track containing the active strip, "
@@ -198,47 +198,47 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
- int filter;
-
+ int filter;
+
/* get a list of the AnimData blocks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* if no blocks, popup error? */
if (BLI_listbase_is_empty(&anim_data)) {
BKE_report(ac->reports, RPT_ERROR, "No AnimData blocks in tweak mode to exit from");
return false;
}
-
+
/* for each AnimData block with NLA-data, try exitting tweak-mode */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->data;
-
+
/* clear solo flags */
if ((do_solo) & (adt->flag & ADT_NLA_SOLO_TRACK) &&
- (adt->flag & ADT_NLA_EDIT_ON))
+ (adt->flag & ADT_NLA_EDIT_ON))
{
BKE_nlatrack_solo_toggle(adt, NULL);
}
-
+
/* to be sure that we're doing everything right, just exit tweakmode... */
BKE_nla_tweakmode_exit(adt);
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
- /* if we managed to enter tweakmode on at least one AnimData block,
+
+ /* if we managed to enter tweakmode on at least one AnimData block,
* set the flag for this in the active scene and send notifiers
*/
if (ac->scene) {
/* clear editing flag */
ac->scene->flag &= ~SCE_NLA_EDIT_ON;
-
+
/* set notifier that things have changed */
WM_main_add_notifier(NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
}
-
+
/* done */
return true;
}
@@ -247,40 +247,40 @@ bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
const bool do_solo = RNA_boolean_get(op->ptr, "isolate_action");
bool ok = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* perform operation */
ok = nlaedit_disable_tweakmode(&ac, do_solo);
-
+
/* success? */
if (ok)
return OPERATOR_FINISHED;
else
return OPERATOR_CANCELLED;
}
-
+
void NLA_OT_tweakmode_exit(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Exit Tweak Mode";
ot->idname = "NLA_OT_tweakmode_exit";
ot->description = "Exit tweaking mode for the action referenced by the active strip";
-
+
/* api callbacks */
ot->exec = nlaedit_disable_tweakmode_exec;
ot->poll = nlaop_poll_tweakmode_on;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "isolate_action", 0, "Isolate Action",
"Disable 'solo' on any of the NLA Tracks after exiting tweak mode "
@@ -300,38 +300,38 @@ static void get_nlastrip_extents(bAnimContext *ac, float *min, float *max, const
bAnimListElem *ale;
int filter;
bool found_bounds = false;
-
+
/* get data to filter */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* set large values to try to override */
*min = 999999999.0f;
*max = -999999999.0f;
-
+
/* check if any channels to set range with */
if (anim_data.first) {
/* go through channels, finding max extents */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* only consider selected strips? */
if ((only_sel == false) || (strip->flag & NLASTRIP_FLAG_SELECT)) {
/* extend range if appropriate */
*min = min_ff(*min, strip->start);
*max = max_ff(*max, strip->end);
-
+
found_bounds = true;
}
}
}
-
+
/* free memory */
ANIM_animdata_freelist(&anim_data);
}
-
+
/* set default range if nothing happened */
if (found_bounds == false) {
if (ac->scene) {
@@ -352,40 +352,40 @@ static int nlaedit_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
bAnimContext ac;
Scene *scene;
float min, max;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
if (ac.scene == NULL)
return OPERATOR_CANCELLED;
else
scene = ac.scene;
-
+
/* set the range directly */
get_nlastrip_extents(&ac, &min, &max, true);
scene->r.flag |= SCER_PRV_RANGE;
scene->r.psfra = round_fl_to_int(min);
scene->r.pefra = round_fl_to_int(max);
-
+
/* set notifier that things have changed */
// XXX err... there's nothing for frame ranges yet, but this should do fine too
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
-
+
return OPERATOR_FINISHED;
}
-
+
void NLA_OT_previewrange_set(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Auto-Set Preview Range";
ot->idname = "NLA_OT_previewrange_set";
ot->description = "Automatically set Preview Range based on range of keyframes";
-
+
/* api callbacks */
ot->exec = nlaedit_previewrange_exec;
ot->poll = ED_operator_nla_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -404,33 +404,33 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
SpaceNla *snla = (SpaceNla *)ac->sl;
const float half_height = NLACHANNEL_HEIGHT_HALF(snla);
short found = 0; /* NOTE: not bool, since we want prioritise individual channels over expanders */
float y;
-
+
/* get all items - we need to do it this way */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* loop through all channels, finding the first one that's selected */
y = (float)NLACHANNEL_FIRST;
-
+
for (ale = anim_data.first; ale; ale = ale->next) {
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
+
/* must be selected... */
- if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
+ if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT))
{
/* update best estimate */
*min = (float)(y - half_height);
*max = (float)(y + half_height);
-
+
/* is this high enough priority yet? */
found = acf->channel_role;
-
+
/* only stop our search when we've found an actual channel
* - datablock expanders get less priority so that we don't abort prematurely
*/
@@ -438,14 +438,14 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa
break;
}
}
-
+
/* adjust y-position for next one */
y -= NLACHANNEL_STEP(snla);
}
-
+
/* free all temp data */
ANIM_animdata_freelist(&anim_data);
-
+
return (found != 0);
}
@@ -454,19 +454,19 @@ static int nlaedit_viewall(bContext *C, const bool only_sel)
bAnimContext ac;
View2D *v2d;
float extra;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
v2d = &ac.ar->v2d;
-
+
/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
get_nlastrip_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, only_sel);
-
+
extra = 0.1f * BLI_rctf_size_x(&v2d->cur);
v2d->cur.xmin -= extra;
v2d->cur.xmax += extra;
-
+
/* set vertical range */
if (only_sel == false) {
/* view all -> the summary channel is usually the shows everything, and resides right at the top... */
@@ -477,30 +477,30 @@ static int nlaedit_viewall(bContext *C, const bool only_sel)
/* locate first selected channel (or the active one), and frame those */
float ymin = v2d->cur.ymin;
float ymax = v2d->cur.ymax;
-
+
if (nla_channels_get_selected_extents(&ac, &ymin, &ymax)) {
/* recenter the view so that this range is in the middle */
float ymid = (ymax - ymin) / 2.0f + ymin;
float x_center;
-
+
UI_view2d_center_get(v2d, &x_center, NULL);
UI_view2d_center_set(v2d, x_center, ymid);
}
}
-
+
/* do View2D syncing */
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
-
+
/* just redraw this view */
ED_area_tag_redraw(CTX_wm_area(C));
-
+
return OPERATOR_FINISHED;
}
/* ......... */
static int nlaedit_viewall_exec(bContext *C, wmOperator *UNUSED(op))
-{
+{
/* whole range */
return nlaedit_viewall(C, false);
}
@@ -510,18 +510,18 @@ static int nlaedit_viewsel_exec(bContext *C, wmOperator *UNUSED(op))
/* only selected */
return nlaedit_viewall(C, true);
}
-
+
void NLA_OT_view_all(wmOperatorType *ot)
{
/* identifiers */
ot->name = "View All";
ot->idname = "NLA_OT_view_all";
ot->description = "Reset viewable area to show full strips range";
-
+
/* api callbacks */
ot->exec = nlaedit_viewall_exec;
ot->poll = ED_operator_nla_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -532,11 +532,11 @@ void NLA_OT_view_selected(wmOperatorType *ot)
ot->name = "View Selected";
ot->idname = "NLA_OT_view_selected";
ot->description = "Reset viewable area to show selected strips range";
-
+
/* api callbacks */
ot->exec = nlaedit_viewsel_exec;
ot->poll = ED_operator_nla_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -556,11 +556,11 @@ void NLA_OT_view_frame(wmOperatorType *ot)
ot->name = "View Frame";
ot->idname = "NLA_OT_view_frame";
ot->description = "Reset viewable area to show range around current frame";
-
+
/* api callbacks */
ot->exec = nlaedit_viewframe_exec;
ot->poll = ED_operator_nla_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -577,7 +577,7 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
Scene *scene;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
size_t items;
@@ -586,17 +586,17 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
bAction *act;
float cfra;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
scene = ac.scene;
cfra = (float)CFRA;
-
+
/* get action to use */
act = BLI_findlink(&CTX_data_main(C)->action, RNA_enum_get(op->ptr, "action"));
-
+
if (act == NULL) {
BKE_report(op->reports, RPT_ERROR, "No valid action to add");
//printf("Add strip - actname = '%s'\n", actname);
@@ -610,68 +610,68 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
"for this action to avoid future problems)",
act->id.name + 2);
}
-
+
/* add tracks to empty but selected animdata blocks so that strips can be added to those directly
* without having to manually add tracks first
*/
nlaedit_add_tracks_empty(&ac);
-
+
/* get a list of the editable tracks being shown in the NLA
- * - this is limited to active ones for now, but could be expanded to
+ * - this is limited to active ones for now, but could be expanded to
*/
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT);
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
if (items == 0) {
- BKE_report(op->reports, RPT_ERROR,
+ BKE_report(op->reports, RPT_ERROR,
"No active track(s) to add strip to, select an existing track or add one before trying again");
return OPERATOR_CANCELLED;
}
-
+
/* for every active track, try to add strip to free space in track or to the top of the stack if no space */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
NlaStrip *strip = NULL;
-
- /* sanity check: only apply actions of the right type for this ID
+
+ /* sanity check: only apply actions of the right type for this ID
* NOTE: in the case that this hasn't been set, we've already warned the user about this already
*/
if ((act->idroot) && (act->idroot != GS(ale->id->name))) {
- BKE_reportf(op->reports, RPT_ERROR,
+ BKE_reportf(op->reports, RPT_ERROR,
"Could not add action '%s' as it cannot be used relative to ID-blocks of type '%s'",
act->id.name + 2, ale->id->name);
continue;
}
-
+
/* create a new strip, and offset it to start on the current frame */
strip = BKE_nlastrip_new(act);
-
+
strip->end += (cfra - strip->start);
strip->start = cfra;
-
+
/* firstly try adding strip to our current track, but if that fails, add to a new track */
if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
- /* trying to add to the current failed (no space),
+ /* trying to add to the current failed (no space),
* so add a new track to the stack, and add to that...
*/
nlt = BKE_nlatrack_add(adt, NULL);
BKE_nlatrack_add_strip(nlt, strip);
}
-
+
/* auto-name it */
BKE_nlastrip_validate_name(adt, strip);
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -684,15 +684,15 @@ void NLA_OT_actionclip_add(wmOperatorType *ot)
ot->name = "Add Action Strip";
ot->idname = "NLA_OT_actionclip_add";
ot->description = "Add an Action-Clip strip (i.e. an NLA Strip referencing an Action) to the active track";
-
+
/* api callbacks */
ot->invoke = WM_enum_search_invoke;
ot->exec = nlaedit_add_actionclip_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
// TODO: this would be nicer as an ID-pointer...
prop = RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", "");
@@ -707,45 +707,45 @@ void NLA_OT_actionclip_add(wmOperatorType *ot)
static int nlaedit_add_transition_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
bool done = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each track, find pairs of strips to add transitions to */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
NlaStrip *s1, *s2;
-
+
/* get initial pair of strips */
if (ELEM(nlt->strips.first, NULL, nlt->strips.last))
continue;
s1 = nlt->strips.first;
s2 = s1->next;
-
+
/* loop over strips */
for (; s1 && s2; s1 = s2, s2 = s2->next) {
NlaStrip *strip;
-
+
/* check if both are selected */
if (ELEM(0, (s1->flag & NLASTRIP_FLAG_SELECT), (s2->flag & NLASTRIP_FLAG_SELECT)))
continue;
/* check if there's space between the two */
if (IS_EQF(s1->end, s2->start))
continue;
- /* make sure neither one is a transition
- * - although this is impossible to create with the standard tools,
+ /* make sure neither one is a transition
+ * - although this is impossible to create with the standard tools,
* the user may have altered the settings
*/
if (ELEM(NLASTRIP_TYPE_TRANSITION, s1->type, s2->type))
@@ -753,48 +753,48 @@ static int nlaedit_add_transition_exec(bContext *C, wmOperator *op)
/* also make sure neither one is a soundclip */
if (ELEM(NLASTRIP_TYPE_SOUND, s1->type, s2->type))
continue;
-
+
/* allocate new strip */
strip = MEM_callocN(sizeof(NlaStrip), "NlaStrip");
BLI_insertlinkafter(&nlt->strips, s1, strip);
-
+
/* set the type */
strip->type = NLASTRIP_TYPE_TRANSITION;
-
- /* generic settings
+
+ /* generic settings
* - selected flag to highlight this to the user
- * - auto-blends to ensure that blend in/out values are automatically
+ * - auto-blends to ensure that blend in/out values are automatically
* determined by overlaps of strips
*/
strip->flag = NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_AUTO_BLENDS;
-
+
/* range is simply defined as the endpoints of the adjacent strips */
strip->start = s1->end;
strip->end = s2->start;
-
+
/* scale and repeat aren't of any use, but shouldn't ever be 0 */
strip->scale = 1.0f;
strip->repeat = 1.0f;
-
+
/* auto-name it */
BKE_nlastrip_validate_name(adt, strip);
-
+
/* make note of this */
done = true;
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* was anything added? */
if (done) {
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -810,11 +810,11 @@ void NLA_OT_transition_add(wmOperatorType *ot)
ot->name = "Add Transition";
ot->idname = "NLA_OT_transition_add";
ot->description = "Add a transition strip between two adjacent selected strips";
-
+
/* api callbacks */
ot->exec = nlaedit_add_transition_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -825,66 +825,66 @@ void NLA_OT_transition_add(wmOperatorType *ot)
static int nlaedit_add_sound_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
Scene *scene;
int cfra;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
scene = ac.scene;
cfra = CFRA;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each track, add sound clips if it belongs to a speaker */
// TODO: what happens if there aren't any tracks... well that's a more general problem for later
for (ale = anim_data.first; ale; ale = ale->next) {
Object *ob = (Object *)ale->id; /* may not be object until we actually check! */
-
+
AnimData *adt = ale->adt;
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
/* does this belong to speaker - assumed to live on Object level only */
if ((GS(ale->id->name) != ID_OB) || (ob->type != OB_SPEAKER))
continue;
-
+
/* create a new strip, and offset it to start on the current frame */
strip = BKE_nla_add_soundstrip(ac.scene, ob->data);
-
+
strip->start += cfra;
strip->end += cfra;
-
+
/* firstly try adding strip to our current track, but if that fails, add to a new track */
if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
- /* trying to add to the current failed (no space),
+ /* trying to add to the current failed (no space),
* so add a new track to the stack, and add to that...
*/
nlt = BKE_nlatrack_add(adt, NULL);
BKE_nlatrack_add_strip(nlt, strip);
}
-
+
/* auto-name it */
BKE_nlastrip_validate_name(adt, strip);
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -895,11 +895,11 @@ void NLA_OT_soundclip_add(wmOperatorType *ot)
ot->name = "Add Sound Clip";
ot->idname = "NLA_OT_soundclip_add";
ot->description = "Add a strip for controlling when speaker plays its sound clip";
-
+
/* api callbacks */
ot->exec = nlaedit_add_sound_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -911,28 +911,28 @@ void NLA_OT_soundclip_add(wmOperatorType *ot)
static int nlaedit_add_meta_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each track, find pairs of strips to add transitions to */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
NlaStrip *strip;
-
+
/* create meta-strips from the continuous chains of selected strips */
BKE_nlastrips_make_metas(&nlt->strips, 0);
-
+
/* name the metas */
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* auto-name this strip if selected (that means it is a meta) */
@@ -940,13 +940,13 @@ static int nlaedit_add_meta_exec(bContext *C, wmOperator *UNUSED(op))
BKE_nlastrip_validate_name(adt, strip);
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -957,11 +957,11 @@ void NLA_OT_meta_add(wmOperatorType *ot)
ot->name = "Add Meta-Strips";
ot->idname = "NLA_OT_meta_add";
ot->description = "Add new meta-strips incorporating the selected strips";
-
+
/* api callbacks */
ot->exec = nlaedit_add_meta_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -972,33 +972,33 @@ void NLA_OT_meta_add(wmOperatorType *ot)
static int nlaedit_remove_meta_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each track, find pairs of strips to add transitions to */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
-
+
/* clear all selected meta-strips, regardless of whether they are temporary or not */
BKE_nlastrips_clear_metas(&nlt->strips, 1, 0);
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1009,11 +1009,11 @@ void NLA_OT_meta_remove(wmOperatorType *ot)
ot->name = "Remove Meta-Strips";
ot->idname = "NLA_OT_meta_remove";
ot->description = "Separate out the strips held by the selected meta-strips";
-
+
/* api callbacks */
ot->exec = nlaedit_remove_meta_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1022,27 +1022,27 @@ void NLA_OT_meta_remove(wmOperatorType *ot)
/* Duplicates the selected NLA-Strips, putting them on new tracks above the one
* the originals were housed in.
*/
-
+
static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
bool linked = RNA_boolean_get(op->ptr, "linked");
bool done = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* duplicate strips in tracks starting from the last one so that we're
+
+ /* duplicate strips in tracks starting from the last one so that we're
* less likely to duplicate strips we just duplicated...
*/
for (ale = anim_data.last; ale; ale = ale->prev) {
@@ -1050,46 +1050,46 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
AnimData *adt = ale->adt;
NlaStrip *strip, *nstrip, *next;
NlaTrack *track;
-
+
for (strip = nlt->strips.first; strip; strip = next) {
next = strip->next;
-
+
/* if selected, split the strip at its midpoint */
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* make a copy (assume that this is possible) */
nstrip = BKE_nlastrip_copy(strip, linked);
-
+
/* in case there's no space in the track above, or we haven't got a reference to it yet, try adding */
if (BKE_nlatrack_add_strip(nlt->next, nstrip) == 0) {
/* need to add a new track above the one above the current one
- * - if the current one is the last one, nlt->next will be NULL, which defaults to adding
+ * - if the current one is the last one, nlt->next will be NULL, which defaults to adding
* at the top of the stack anyway...
*/
track = BKE_nlatrack_add(adt, nlt->next);
BKE_nlatrack_add_strip(track, nstrip);
}
-
+
/* deselect the original and the active flag */
strip->flag &= ~(NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_ACTIVE);
-
+
/* auto-name newly created strip */
BKE_nlastrip_validate_name(adt, nstrip);
-
+
done = true;
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
if (done) {
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1100,7 +1100,7 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
static int nlaedit_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
nlaedit_duplicate_exec(C, op);
-
+
RNA_enum_set(op->ptr, "mode", TFM_TRANSLATION);
WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
@@ -1113,18 +1113,18 @@ void NLA_OT_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Strips";
ot->idname = "NLA_OT_duplicate";
ot->description = "Duplicate selected NLA-Strips, adding the new strips in new tracks above the originals";
-
+
/* api callbacks */
ot->invoke = nlaedit_duplicate_invoke;
ot->exec = nlaedit_duplicate_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* own properties */
ot->prop = RNA_def_boolean(ot->srna, "linked", false, "Linked", "When duplicating strips, assign new copies of the actions they use");
-
+
/* to give to transform */
RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
}
@@ -1135,52 +1135,52 @@ void NLA_OT_duplicate(wmOperatorType *ot)
static int nlaedit_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each NLA-Track, delete all selected strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip, *nstrip;
-
+
for (strip = nlt->strips.first; strip; strip = nstrip) {
nstrip = strip->next;
-
+
/* if selected, delete */
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* if a strip either side of this was a transition, delete those too */
- if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION))
+ if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION))
BKE_nlastrip_free(&nlt->strips, strip->prev);
if ((nstrip) && (nstrip->type == NLASTRIP_TYPE_TRANSITION)) {
nstrip = nstrip->next;
BKE_nlastrip_free(&nlt->strips, strip->next);
}
-
+
/* finally, delete this strip */
BKE_nlastrip_free(&nlt->strips, strip);
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1191,18 +1191,18 @@ void NLA_OT_delete(wmOperatorType *ot)
ot->name = "Delete Strips";
ot->idname = "NLA_OT_delete";
ot->description = "Delete selected strips";
-
+
/* api callbacks */
ot->exec = nlaedit_delete_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Split Strips Operator ***************************** */
/* Splits the selected NLA-Strips into two strips at the midpoint of the strip */
-// TODO's?
+// TODO's?
// - multiple splits
// - variable-length splits?
@@ -1211,9 +1211,9 @@ static void nlaedit_split_strip_actclip(AnimData *adt, NlaTrack *nlt, NlaStrip *
{
NlaStrip *nstrip;
float splitframe, splitaframe;
-
- /* calculate the frames to do the splitting at
- * - use current frame if within extents of strip
+
+ /* calculate the frames to do the splitting at
+ * - use current frame if within extents of strip
*/
if ((cfra > strip->start) && (cfra < strip->end)) {
/* use the current frame */
@@ -1223,14 +1223,14 @@ static void nlaedit_split_strip_actclip(AnimData *adt, NlaTrack *nlt, NlaStrip *
else {
/* split in the middle */
float len;
-
+
/* strip extents */
len = strip->end - strip->start;
if (IS_EQF(len, 0.0f))
return;
else
splitframe = strip->start + (len / 2.0f);
-
+
/* action range */
len = strip->actend - strip->actstart;
if (IS_EQF(len, 0.0f))
@@ -1238,28 +1238,28 @@ static void nlaedit_split_strip_actclip(AnimData *adt, NlaTrack *nlt, NlaStrip *
else
splitaframe = strip->actstart + (len / 2.0f);
}
-
+
/* make a copy (assume that this is possible) and append
* it immediately after the current strip
*/
nstrip = BKE_nlastrip_copy(strip, true);
BLI_insertlinkafter(&nlt->strips, strip, nstrip);
-
- /* set the endpoint of the first strip and the start of the new strip
+
+ /* set the endpoint of the first strip and the start of the new strip
* to the splitframe values calculated above
*/
strip->end = splitframe;
nstrip->start = splitframe;
-
+
if ((splitaframe > strip->actstart) && (splitaframe < strip->actend)) {
/* only do this if we're splitting down the middle... */
strip->actend = splitaframe;
nstrip->actstart = splitaframe;
}
-
+
/* clear the active flag from the copy */
nstrip->flag &= ~NLASTRIP_FLAG_ACTIVE;
-
+
/* auto-name the new strip */
BKE_nlastrip_validate_name(adt, nstrip);
}
@@ -1276,28 +1276,28 @@ static void nlaedit_split_strip_meta(NlaTrack *nlt, NlaStrip *strip)
static int nlaedit_split_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each NLA-Track, split all selected strips into two strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
NlaStrip *strip, *next;
-
+
for (strip = nlt->strips.first; strip; strip = next) {
next = strip->next;
-
+
/* if selected, split the strip at its midpoint */
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* splitting method depends on the type of strip */
@@ -1305,27 +1305,27 @@ static int nlaedit_split_exec(bContext *C, wmOperator *UNUSED(op))
case NLASTRIP_TYPE_CLIP: /* action-clip */
nlaedit_split_strip_actclip(adt, nlt, strip, (float)ac.scene->r.cfra);
break;
-
+
case NLASTRIP_TYPE_META: /* meta-strips need special handling */
nlaedit_split_strip_meta(nlt, strip);
break;
-
+
default: /* for things like Transitions, do not split! */
break;
}
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1336,11 +1336,11 @@ void NLA_OT_split(wmOperatorType *ot)
ot->name = "Split Strips";
ot->idname = "NLA_OT_split";
ot->description = "Split selected strips at their midpoints";
-
+
/* api callbacks */
ot->exec = nlaedit_split_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1351,34 +1351,34 @@ void NLA_OT_split(wmOperatorType *ot)
static int nlaedit_bake_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
// int flag = 0;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each AnimData block, bake strips to animdata... */
for (ale = anim_data.first; ale; ale = ale->next) {
//BKE_nla_bake(ac.scene, ale->id, ale->data, flag);
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1390,11 +1390,11 @@ static void UNUSED_FUNCTION(NLA_OT_bake)(wmOperatorType *ot)
ot->name = "Bake Strips";
ot->idname = "NLA_OT_bake";
ot->description = "Bake all strips of selected AnimData blocks";
-
+
/* api callbacks */
ot->exec = nlaedit_bake_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1408,44 +1408,44 @@ static void UNUSED_FUNCTION(NLA_OT_bake)(wmOperatorType *ot)
static int nlaedit_toggle_mute_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* go over all selected strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
/* for every selected strip, toggle muting */
for (strip = nlt->strips.first; strip; strip = strip->next) {
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* just flip the mute flag for now */
// TODO: have a pre-pass to check if mute all or unmute all?
strip->flag ^= NLASTRIP_FLAG_MUTED;
-
+
/* tag AnimData to get recalculated */
ale->update |= ANIM_UPDATE_DEPS;
}
}
}
-
+
/* cleanup */
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1456,11 +1456,11 @@ void NLA_OT_mute_toggle(wmOperatorType *ot)
ot->name = "Toggle Muting";
ot->idname = "NLA_OT_mute_toggle";
ot->description = "Mute or un-mute selected strips";
-
+
/* api callbacks */
ot->exec = nlaedit_toggle_mute_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1471,35 +1471,35 @@ void NLA_OT_mute_toggle(wmOperatorType *ot)
static int nlaedit_swap_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* consider each track in turn */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
-
+
NlaStrip *strip, *stripN = NULL;
NlaStrip *sa = NULL, *sb = NULL;
-
+
/* make temporary metastrips 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 (i.e. temp meta BUT NOT unselected/normal/normal-meta strips) left after this,
+
+ /* special case: if there is only 1 island (i.e. temp meta BUT NOT unselected/normal/normal-meta strips) left after this,
* and this island has two strips inside it, then we should be able to just swap these still...
*/
if (BLI_listbase_is_empty(&nlt->strips) == false) {
NlaStrip *mstrip = (NlaStrip *)nlt->strips.first;
-
+
if ((mstrip->flag & NLASTRIP_FLAG_TEMP_META) &&
(BLI_listbase_count_at_most(&mstrip->strips, 3) == 2))
{
@@ -1507,13 +1507,13 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
BKE_nlastrips_clear_metas(&nlt->strips, 0, 1);
}
}
-
+
/* get two selected strips only (these will be metas due to prev step) to operate on
* - only allow swapping 2, as with more the context becomes unclear
*/
for (strip = nlt->strips.first; strip; strip = stripN) {
stripN = strip->next;
-
+
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* first or second strip? */
if (sa == NULL) {
@@ -1530,10 +1530,10 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
}
}
}
-
+
if (strip) {
/* too many selected warning */
- BKE_reportf(op->reports, RPT_WARNING,
+ BKE_reportf(op->reports, RPT_WARNING,
"Too many clusters of strips selected in NLA Track (%s): needs exactly 2 to be selected",
nlt->name);
}
@@ -1548,11 +1548,11 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
}
else {
float nsa[2], nsb[2];
-
+
/* remove these strips from the track, so that we can test if they can fit in the proposed places */
BLI_remlink(&nlt->strips, sa);
BLI_remlink(&nlt->strips, sb);
-
+
/* calculate new extents for strips */
/* a --> b */
nsa[0] = sb->start;
@@ -1560,16 +1560,16 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
/* b --> a */
nsb[0] = sa->start;
nsb[1] = sa->start + (sb->end - sb->start);
-
+
/* check if the track has room for the strips to be swapped */
- if (BKE_nlastrips_has_space(&nlt->strips, nsa[0], nsa[1]) &&
+ if (BKE_nlastrips_has_space(&nlt->strips, nsa[0], nsa[1]) &&
BKE_nlastrips_has_space(&nlt->strips, nsb[0], nsb[1]))
{
/* set new extents for strips then */
sa->start = nsa[0];
sa->end = nsa[1];
BKE_nlameta_flush_transforms(sa);
-
+
sb->start = nsb[0];
sb->end = nsb[1];
BKE_nlameta_flush_transforms(sb);
@@ -1586,25 +1586,25 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
sa->name, sb->name);
}
}
-
+
/* add strips back to track now */
BKE_nlatrack_add_strip(nlt, sa);
BKE_nlatrack_add_strip(nlt, sb);
}
-
+
/* clear (temp) metastrips */
BKE_nlastrips_clear_metas(&nlt->strips, 0, 1);
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1615,11 +1615,11 @@ void NLA_OT_swap(wmOperatorType *ot)
ot->name = "Swap Strips";
ot->idname = "NLA_OT_swap";
ot->description = "Swap order of selected strips within tracks";
-
+
/* api callbacks */
ot->exec = nlaedit_swap_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1630,19 +1630,19 @@ void NLA_OT_swap(wmOperatorType *ot)
static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* since we're potentially moving strips from lower tracks to higher tracks, we should
* loop over the tracks in reverse order to avoid moving earlier strips up multiple tracks
*/
@@ -1650,15 +1650,15 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op))
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaTrack *nltn = nlt->next;
NlaStrip *strip, *stripn;
-
+
/* if this track has no tracks after it, skip for now... */
if (nltn == NULL)
continue;
-
+
/* for every selected strip, try to move */
for (strip = nlt->strips.first; strip; strip = stripn) {
stripn = strip->next;
-
+
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* check if the track above has room for this strip */
if (BKE_nlatrack_has_space(nltn, strip->start, strip->end)) {
@@ -1669,16 +1669,16 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op))
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1689,11 +1689,11 @@ void NLA_OT_move_up(wmOperatorType *ot)
ot->name = "Move Strips Up";
ot->idname = "NLA_OT_move_up";
ot->description = "Move selected strips up a track if there's room";
-
+
/* api callbacks */
ot->exec = nlaedit_move_up_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1704,19 +1704,19 @@ void NLA_OT_move_up(wmOperatorType *ot)
static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* loop through the tracks in normal order, since we're pushing strips down,
* strips won't get operated on twice
*/
@@ -1724,15 +1724,15 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op))
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaTrack *nltp = nlt->prev;
NlaStrip *strip, *stripn;
-
+
/* if this track has no tracks before it, skip for now... */
if (nltp == NULL)
continue;
-
+
/* for every selected strip, try to move */
for (strip = nlt->strips.first; strip; strip = stripn) {
stripn = strip->next;
-
+
if (strip->flag & NLASTRIP_FLAG_SELECT) {
/* check if the track below has room for this strip */
if (BKE_nlatrack_has_space(nltp, strip->start, strip->end)) {
@@ -1743,16 +1743,16 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op))
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1763,11 +1763,11 @@ void NLA_OT_move_down(wmOperatorType *ot)
ot->name = "Move Strips Down";
ot->idname = "NLA_OT_move_down";
ot->description = "Move selected strips down a track if there's room";
-
+
/* api callbacks */
ot->exec = nlaedit_move_down_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1778,26 +1778,26 @@ void NLA_OT_move_down(wmOperatorType *ot)
static int nlaedit_sync_actlen_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
const bool active_only = RNA_boolean_get(op->ptr, "active");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
if (active_only) filter |= ANIMFILTER_ACTIVE;
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each NLA-Track, apply scale of all selected strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* strip selection/active status check */
if (active_only) {
@@ -1808,27 +1808,27 @@ static int nlaedit_sync_actlen_exec(bContext *C, wmOperator *op)
if ((strip->flag & NLASTRIP_FLAG_SELECT) == 0)
continue;
}
-
+
/* must be action-clip only (transitions don't have scale) */
if (strip->type == NLASTRIP_TYPE_CLIP) {
- if (strip->act == NULL)
+ if (strip->act == NULL)
continue;
-
+
/* recalculate the length of the action */
calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
-
+
/* adjust the strip extents in response to this */
BKE_nlastrip_recalculate_bounds(strip);
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1839,14 +1839,14 @@ void NLA_OT_action_sync_length(wmOperatorType *ot)
ot->name = "Sync Action Length";
ot->idname = "NLA_OT_action_sync_length";
ot->description = "Synchronize the length of the referenced Action with the length used in the strip";
-
+
/* api callbacks */
ot->exec = nlaedit_sync_actlen_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_boolean(ot->srna, "active", 1, "Active Strip Only", "Only sync the active length for the active strip");
}
@@ -1858,19 +1858,19 @@ static int nlaedit_make_single_user_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* Ensure that each action used only has a single user
* - This is done in reverse order so that the original strips are
* likely to still get to keep their action
@@ -1878,34 +1878,34 @@ static int nlaedit_make_single_user_exec(bContext *C, wmOperator *UNUSED(op))
for (ale = anim_data.last; ale; ale = ale->prev) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
for (strip = nlt->strips.last; strip; strip = strip->prev) {
/* must be action-clip only (as only these have actions) */
if ((strip->flag & NLASTRIP_FLAG_SELECT) && (strip->type == NLASTRIP_TYPE_CLIP)) {
- if (strip->act == NULL)
+ if (strip->act == NULL)
continue;
-
+
/* multi-user? */
if (ID_REAL_USERS(strip->act) > 1) {
/* make a new copy of the action for us to use (it will have 1 user already) */
bAction *new_action = BKE_action_copy(bmain, strip->act);
-
+
/* decrement user count of our existing action */
id_us_min(&strip->act->id);
-
+
/* switch to the new copy */
strip->act = new_action;
}
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1916,12 +1916,12 @@ void NLA_OT_make_single_user(wmOperatorType *ot)
ot->name = "Make Single User";
ot->idname = "NLA_OT_make_single_user";
ot->description = "Ensure that each action is only used once in the set of strips selected";
-
+
/* api callbacks */
ot->invoke = WM_operator_confirm;
ot->exec = nlaedit_make_single_user_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1934,12 +1934,12 @@ static short bezt_apply_nlamapping(KeyframeEditData *ked, BezTriple *bezt)
{
/* NLA-strip which has this scaling is stored in ked->data */
NlaStrip *strip = (NlaStrip *)ked->data;
-
+
/* adjust all the times */
bezt->vec[0][0] = nlastrip_get_frame(strip, bezt->vec[0][0], NLATIME_CONVERT_MAP);
bezt->vec[1][0] = nlastrip_get_frame(strip, bezt->vec[1][0], NLATIME_CONVERT_MAP);
bezt->vec[2][0] = nlastrip_get_frame(strip, bezt->vec[2][0], NLATIME_CONVERT_MAP);
-
+
/* nothing to return or else we exit */
return 0;
}
@@ -1948,61 +1948,61 @@ static int nlaedit_apply_scale_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
KeyframeEditData ked = {{NULL}};
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each NLA-Track, apply scale of all selected strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* strip must be selected, and must be action-clip only (transitions don't have scale) */
if ((strip->flag & NLASTRIP_FLAG_SELECT) && (strip->type == NLASTRIP_TYPE_CLIP)) {
/* if the referenced action is used by other strips, make this strip use its own copy */
- if (strip->act == NULL)
+ if (strip->act == NULL)
continue;
if (strip->act->id.us > 1) {
/* make a copy of the Action to work on */
bAction *act = BKE_action_copy(bmain, strip->act);
-
+
/* set this as the new referenced action, decrementing the users of the old one */
id_us_min(&strip->act->id);
strip->act = act;
}
-
+
/* setup iterator, and iterate over all the keyframes in the action, applying this scaling */
ked.data = strip;
ANIM_animchanneldata_keyframes_loop(&ked, ac.ads, strip->act, ALE_ACT, NULL, bezt_apply_nlamapping, calchandles_fcurve);
-
+
/* clear scale of strip now that it has been applied,
* and recalculate the extents of the action now that it has been scaled
- * but leave everything else alone
+ * but leave everything else alone
*/
strip->scale = 1.0f;
calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -2013,11 +2013,11 @@ void NLA_OT_apply_scale(wmOperatorType *ot)
ot->name = "Apply Scale";
ot->idname = "NLA_OT_apply_scale";
ot->description = "Apply scaling of selected strips to their referenced Actions";
-
+
/* api callbacks */
ot->exec = nlaedit_apply_scale_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2028,44 +2028,44 @@ void NLA_OT_apply_scale(wmOperatorType *ot)
static int nlaedit_clear_scale_exec(bContext *C, wmOperator *UNUSED(op))
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each NLA-Track, reset scale of all selected strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* strip must be selected, and must be action-clip only (transitions don't have scale) */
if ((strip->flag & NLASTRIP_FLAG_SELECT) && (strip->type == NLASTRIP_TYPE_CLIP)) {
PointerRNA strip_ptr;
-
+
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
RNA_float_set(&strip_ptr, "scale", 1.0f);
}
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -2076,11 +2076,11 @@ void NLA_OT_clear_scale(wmOperatorType *ot)
ot->name = "Clear Scale";
ot->idname = "NLA_OT_clear_scale";
ot->description = "Reset scaling of selected strips";
-
+
/* api callbacks */
ot->exec = nlaedit_clear_scale_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2100,27 +2100,27 @@ static const EnumPropertyItem prop_nlaedit_snap_types[] = {
static int nlaedit_snap_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
Scene *scene;
int mode = RNA_enum_get(op->ptr, "type");
float secf;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* get some necessary vars */
scene = ac.scene;
secf = (float)FPS;
-
+
/* since we may add tracks, perform this in reverse order */
for (ale = anim_data.last; ale; ale = ale->prev) {
ListBase tmp_strips = {NULL, NULL};
@@ -2128,23 +2128,23 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op)
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip, *stripn;
NlaTrack *track;
-
+
/* create meta-strips from the continuous chains of selected strips */
BKE_nlastrips_make_metas(&nlt->strips, 1);
-
+
/* apply the snapping to all the temp meta-strips, then put them in a separate list to be added
* back to the original only if they still fit
*/
for (strip = nlt->strips.first; strip; strip = stripn) {
stripn = strip->next;
-
+
if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
float start, end;
-
+
/* get the existing end-points */
start = strip->start;
end = strip->end;
-
+
/* calculate new start position based on snapping mode */
switch (mode) {
case NLAEDIT_SNAP_CFRA: /* to current frame */
@@ -2163,54 +2163,54 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op)
strip->start = start;
break;
}
-
+
/* get new endpoint based on start-point (and old length) */
strip->end = strip->start + (end - start);
-
+
/* apply transforms to meta-strip to its children */
BKE_nlameta_flush_transforms(strip);
-
+
/* remove strip from track, and add to the temp buffer */
BLI_remlink(&nlt->strips, strip);
BLI_addtail(&tmp_strips, strip);
}
}
-
+
/* try adding each meta-strip back to the track one at a time, to make sure they'll fit */
for (strip = tmp_strips.first; strip; strip = stripn) {
stripn = strip->next;
-
+
/* remove from temp-strips list */
BLI_remlink(&tmp_strips, strip);
-
+
/* in case there's no space in the current track, try adding */
if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
/* need to add a new track above the current one */
track = BKE_nlatrack_add(adt, nlt);
BKE_nlatrack_add_strip(track, strip);
-
+
/* clear temp meta-strips on this new track, as we may not be able to get back to it */
BKE_nlastrips_clear_metas(&track->strips, 0, 1);
}
}
-
+
/* remove the meta-strips now that we're done */
BKE_nlastrips_clear_metas(&nlt->strips, 0, 1);
-
+
/* tag for recalculating the animation */
ale->update |= ANIM_UPDATE_DEPS;
}
-
+
/* cleanup */
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
-
+
/* refresh auto strip properties */
ED_nla_postop_refresh(&ac);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -2221,15 +2221,15 @@ void NLA_OT_snap(wmOperatorType *ot)
ot->name = "Snap Strips";
ot->idname = "NLA_OT_snap";
ot->description = "Move start of strips to specified time";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = nlaedit_snap_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", prop_nlaedit_snap_types, 0, "Type", "");
}
@@ -2244,31 +2244,31 @@ static const EnumPropertyItem *nla_fmodifier_itemf(bContext *C, PointerRNA *UNUS
EnumPropertyItem *item = NULL;
int totitem = 0;
int i = 0;
-
+
if (C == NULL) {
return rna_enum_fmodifier_type_items;
}
-
+
/* start from 1 to skip the 'Invalid' modifier type */
for (i = 1; i < FMODIFIER_NUM_TYPES; i++) {
const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i);
int index;
-
+
/* check if modifier is valid for this context */
if (fmi == NULL)
continue;
if (i == FMODIFIER_TYPE_CYCLES) /* we already have repeat... */
continue;
-
+
index = RNA_enum_from_value(rna_enum_fmodifier_type_items, fmi->type);
if (index != -1) { /* Not all types are implemented yet... */
RNA_enum_item_add(&item, &totitem, &rna_enum_fmodifier_type_items[index]);
}
}
-
+
RNA_enum_item_end(&item, &totitem);
*r_free = true;
-
+
return item;
}
@@ -2276,28 +2276,28 @@ static const EnumPropertyItem *nla_fmodifier_itemf(bContext *C, PointerRNA *UNUS
static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
FModifier *fcm;
int type = RNA_enum_get(op->ptr, "type");
const bool active_only = RNA_boolean_get(op->ptr, "only_active");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each NLA-Track, add the specified modifier to all selected strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* can F-Modifier be added to the current strip? */
if (active_only) {
@@ -2310,14 +2310,14 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
if ((strip->flag & NLASTRIP_FLAG_SELECT) == 0)
continue;
}
-
+
/* sound clips are not affected by FModifiers */
if (strip->type == NLASTRIP_TYPE_SOUND)
continue;
-
+
/* add F-Modifier of specified type to selected, and make it the active one */
fcm = add_fmodifier(&strip->modifiers, type, NULL);
-
+
if (fcm) {
set_active_fmodifier(&strip->modifiers, fcm);
ale->update |= ANIM_UPDATE_DEPS;
@@ -2329,37 +2329,37 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* free temp data */
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
-
+
/* done */
return OPERATOR_FINISHED;
}
-
+
void NLA_OT_fmodifier_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add F-Modifier";
ot->idname = "NLA_OT_fmodifier_add";
ot->description = "Add F-Modifier to the active/selected NLA-Strips";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = nla_fmodifier_add_exec;
- ot->poll = nlaop_poll_tweakmode_off;
-
+ ot->poll = nlaop_poll_tweakmode_off;
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_fmodifier_type_items, 0, "Type", "");
RNA_def_enum_funcs(ot->prop, nla_fmodifier_itemf);
-
+
RNA_def_boolean(ot->srna, "only_active", true, "Only Active", "Only add a F-Modifier of the specified type to the active strip");
}
@@ -2372,36 +2372,36 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op)
bAnimListElem *ale;
int filter;
bool ok = false;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* clear buffer first */
ANIM_fmodifiers_copybuf_free();
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each NLA-Track, add the specified modifier to all selected strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* only add F-Modifier if on active strip? */
if ((strip->flag & NLASTRIP_FLAG_ACTIVE) == 0)
continue;
-
+
// TODO: when 'active' vs 'all' boolean is added, change last param!
ok |= ANIM_fmodifiers_copy_to_buf(&strip->modifiers, 0);
}
}
-
+
/* free temp data */
ANIM_animdata_freelist(&anim_data);
-
+
/* successful or not? */
if (ok == 0) {
BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
@@ -2412,21 +2412,21 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
}
-
+
void NLA_OT_fmodifier_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Copy F-Modifiers";
ot->idname = "NLA_OT_fmodifier_copy";
ot->description = "Copy the F-Modifier(s) of the active NLA-Strip";
-
+
/* api callbacks */
ot->exec = nla_fmodifier_copy_exec;
- ot->poll = nlaop_poll_tweakmode_off;
-
+ ot->poll = nlaop_poll_tweakmode_off;
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* id-props */
//ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All F-Modifiers", "Copy all the F-Modifiers, instead of just the active one");
}
@@ -2439,23 +2439,23 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter, ok = 0;
-
+
const bool active_only = RNA_boolean_get(op->ptr, "only_active");
const bool replace = RNA_boolean_get(op->ptr, "replace");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get a list of the editable tracks being shown in the NLA */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* for each NLA-Track, add the specified modifier to all selected strips */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* can F-Modifier be added to the current strip? */
if (active_only) {
@@ -2468,17 +2468,17 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op)
if ((strip->flag & NLASTRIP_FLAG_SELECT) == 0)
continue;
}
-
+
/* paste FModifiers from buffer */
ok += ANIM_fmodifiers_paste_from_buf(&strip->modifiers, replace, NULL);
ale->update |= ANIM_UPDATE_DEPS;
}
}
-
+
/* clean up */
ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
-
+
/* successful or not? */
if (ok) {
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
@@ -2489,24 +2489,24 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
}
-
+
void NLA_OT_fmodifier_paste(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Paste F-Modifiers";
ot->idname = "NLA_OT_fmodifier_paste";
ot->description = "Add copied F-Modifiers to the selected NLA-Strips";
-
+
/* api callbacks */
ot->exec = nla_fmodifier_paste_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "only_active", true, "Only Active", "Only paste F-Modifiers on active strip");
- RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
+ RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
"Replace existing F-Modifiers, instead of just appending to the end of the existing list");
}
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 921d2e9c088..0c087fa67b9 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -55,21 +55,21 @@
int nlaop_poll_tweakmode_off(bContext *C)
{
Scene *scene;
-
- /* for now, we check 2 things:
+
+ /* for now, we check 2 things:
* 1) active editor must be NLA
- * 2) tweakmode is currently set as a 'per-scene' flag
+ * 2) tweakmode is currently set as a 'per-scene' flag
* so that it will affect entire NLA data-sets,
- * but not all AnimData blocks will be in tweakmode for
+ * but not all AnimData blocks will be in tweakmode for
* various reasons
*/
if (ED_operator_nla_active(C) == 0)
return 0;
-
+
scene = CTX_data_scene(C);
if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON))
return 0;
-
+
return 1;
}
@@ -77,21 +77,21 @@ int nlaop_poll_tweakmode_off(bContext *C)
int nlaop_poll_tweakmode_on(bContext *C)
{
Scene *scene;
-
- /* for now, we check 2 things:
+
+ /* for now, we check 2 things:
* 1) active editor must be NLA
- * 2) tweakmode is currently set as a 'per-scene' flag
+ * 2) tweakmode is currently set as a 'per-scene' flag
* so that it will affect entire NLA data-sets,
- * but not all AnimData blocks will be in tweakmode for
+ * but not all AnimData blocks will be in tweakmode for
* various reasons
*/
if (ED_operator_nla_active(C) == 0)
return 0;
-
+
scene = CTX_data_scene(C);
if ((scene == NULL) || !(scene->flag & SCE_NLA_EDIT_ON))
return 0;
-
+
return 1;
}
@@ -109,61 +109,61 @@ void nla_operatortypes(void)
{
/* view */
WM_operatortype_append(NLA_OT_properties);
-
+
/* channels */
WM_operatortype_append(NLA_OT_channels_click);
-
+
WM_operatortype_append(NLA_OT_action_pushdown);
WM_operatortype_append(NLA_OT_action_unlink);
-
+
WM_operatortype_append(NLA_OT_tracks_add);
WM_operatortype_append(NLA_OT_tracks_delete);
-
+
WM_operatortype_append(NLA_OT_selected_objects_add);
-
+
/* select */
WM_operatortype_append(NLA_OT_click_select);
WM_operatortype_append(NLA_OT_select_border);
WM_operatortype_append(NLA_OT_select_all_toggle);
WM_operatortype_append(NLA_OT_select_leftright);
-
+
/* view */
WM_operatortype_append(NLA_OT_view_all);
WM_operatortype_append(NLA_OT_view_selected);
WM_operatortype_append(NLA_OT_view_frame);
-
+
WM_operatortype_append(NLA_OT_previewrange_set);
-
+
/* edit */
WM_operatortype_append(NLA_OT_tweakmode_enter);
WM_operatortype_append(NLA_OT_tweakmode_exit);
-
+
WM_operatortype_append(NLA_OT_actionclip_add);
WM_operatortype_append(NLA_OT_transition_add);
WM_operatortype_append(NLA_OT_soundclip_add);
-
+
WM_operatortype_append(NLA_OT_meta_add);
WM_operatortype_append(NLA_OT_meta_remove);
-
+
WM_operatortype_append(NLA_OT_duplicate);
WM_operatortype_append(NLA_OT_delete);
WM_operatortype_append(NLA_OT_split);
-
+
WM_operatortype_append(NLA_OT_mute_toggle);
-
+
WM_operatortype_append(NLA_OT_swap);
WM_operatortype_append(NLA_OT_move_up);
WM_operatortype_append(NLA_OT_move_down);
-
+
WM_operatortype_append(NLA_OT_action_sync_length);
-
+
WM_operatortype_append(NLA_OT_make_single_user);
-
+
WM_operatortype_append(NLA_OT_apply_scale);
WM_operatortype_append(NLA_OT_clear_scale);
-
+
WM_operatortype_append(NLA_OT_snap);
-
+
WM_operatortype_append(NLA_OT_fmodifier_add);
WM_operatortype_append(NLA_OT_fmodifier_copy);
WM_operatortype_append(NLA_OT_fmodifier_paste);
@@ -176,7 +176,7 @@ static void nla_keymap_channels(wmKeyMap *keymap)
wmKeyMapItem *kmi;
/* keymappings here are NLA-specific (different to standard channels keymap) */
-
+
/* selection --------------------------------------------------------------------- */
/* click-select */
// XXX for now, only leftmouse....
@@ -184,14 +184,14 @@ static void nla_keymap_channels(wmKeyMap *keymap)
RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_channels_click", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", true);
-
+
/* channel operations ------------------------------------------------------------ */
/* add tracks */
kmi = WM_keymap_add_item(keymap, "NLA_OT_tracks_add", AKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "above_selected", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_tracks_add", AKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "above_selected", true);
-
+
/* delete tracks */
WM_keymap_add_item(keymap, "NLA_OT_tracks_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NLA_OT_tracks_delete", DELKEY, KM_PRESS, 0, 0);
@@ -200,14 +200,14 @@ static void nla_keymap_channels(wmKeyMap *keymap)
static void nla_keymap_main(wmKeyConfig *keyconf, wmKeyMap *keymap)
{
wmKeyMapItem *kmi;
-
+
/* selection ------------------------------------------------ */
/* click select */
kmi = WM_keymap_add_item(keymap, "NLA_OT_click_select", SELECTMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_click_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", true);
-
+
/* select left/right */
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
@@ -215,92 +215,92 @@ static void nla_keymap_main(wmKeyConfig *keyconf, wmKeyMap *keymap)
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", true);
RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_TEST);
-
+
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_LEFT);
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", false);
RNA_enum_set(kmi->ptr, "mode", NLAEDIT_LRSEL_RIGHT);
-
-
+
+
/* deselect all */
/* TODO: uniformize with other select_all ops? */
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "invert", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "invert", true);
-
+
/* borderselect */
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_border", BKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "axis_range", false);
kmi = WM_keymap_add_item(keymap, "NLA_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "axis_range", true);
-
+
/* view ---------------------------------------------------- */
/* auto-set range */
WM_keymap_add_item(keymap, "NLA_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "NLA_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
#ifdef WITH_INPUT_NDOF
WM_keymap_add_item(keymap, "NLA_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
#endif
WM_keymap_add_item(keymap, "NLA_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NLA_OT_view_frame", PAD0, KM_PRESS, 0, 0);
-
+
/* editing ------------------------------------------------ */
-
+
/* add strips */
WM_keymap_add_item(keymap, "NLA_OT_actionclip_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "NLA_OT_transition_add", TKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "NLA_OT_soundclip_add", KKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* meta-strips */
WM_keymap_add_item(keymap, "NLA_OT_meta_add", GKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "NLA_OT_meta_remove", GKEY, KM_PRESS, KM_ALT, 0);
-
+
/* duplicate */
kmi = WM_keymap_add_item(keymap, "NLA_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "linked", false);
-
+
kmi = WM_keymap_add_item(keymap, "NLA_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "linked", true);
-
+
/* single user */
WM_keymap_add_item(keymap, "NLA_OT_make_single_user", UKEY, KM_PRESS, 0, 0);
-
+
/* delete */
WM_keymap_add_item(keymap, "NLA_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NLA_OT_delete", DELKEY, KM_PRESS, 0, 0);
/* split */
WM_keymap_add_item(keymap, "NLA_OT_split", YKEY, KM_PRESS, 0, 0);
-
+
/* toggles */
WM_keymap_add_item(keymap, "NLA_OT_mute_toggle", HKEY, KM_PRESS, 0, 0);
-
+
/* swap */
WM_keymap_add_item(keymap, "NLA_OT_swap", FKEY, KM_PRESS, KM_ALT, 0);
-
+
/* move up */
WM_keymap_add_item(keymap, "NLA_OT_move_up", PAGEUPKEY, KM_PRESS, 0, 0);
/* move down */
WM_keymap_add_item(keymap, "NLA_OT_move_down", PAGEDOWNKEY, KM_PRESS, 0, 0);
-
+
/* apply scale */
WM_keymap_add_item(keymap, "NLA_OT_apply_scale", AKEY, KM_PRESS, KM_CTRL, 0);
/* clear scale */
WM_keymap_add_item(keymap, "NLA_OT_clear_scale", SKEY, KM_PRESS, KM_ALT, 0);
-
+
/* snap */
WM_keymap_add_item(keymap, "NLA_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* add f-modifier */
WM_keymap_add_item(keymap, "NLA_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
-
+
/* transform system */
transform_keymap_for_space(keyconf, keymap, SPACE_NLA);
-
+
/* special markers hotkeys for anim editors: see note in definition of this function */
ED_marker_keymap_animedit_conflictfree(keymap);
}
@@ -311,35 +311,35 @@ void nla_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
/* keymap for all regions ------------------------------------------- */
keymap = WM_keymap_find(keyconf, "NLA Generic", SPACE_NLA, 0);
-
+
/* region management */
WM_keymap_add_item(keymap, "NLA_OT_properties", NKEY, KM_PRESS, 0, 0);
-
+
/* tweakmode
* - enter and exit are separate operators with the same hotkey...
* This works as they use different poll()'s
*/
WM_keymap_add_item(keymap, "NLA_OT_tweakmode_enter", TABKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NLA_OT_tweakmode_exit", TABKEY, KM_PRESS, 0, 0);
-
+
/* tweakmode for stashed actions
* - similar to normal tweakmode, except we mark the tracks as being "solo"
* too so that the action can be edited in isolation
*/
kmi = WM_keymap_add_item(keymap, "NLA_OT_tweakmode_enter", TABKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "isolate_action", true);
-
+
kmi = WM_keymap_add_item(keymap, "NLA_OT_tweakmode_exit", TABKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "isolate_action", true);
-
+
/* find (i.e. a shortcut for setting the name filter) */
WM_keymap_add_item(keymap, "ANIM_OT_channels_find", FKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* channels ---------------------------------------------------------- */
- /* Channels are not directly handled by the NLA Editor module, but are inherited from the Animation module.
+ /* Channels are not directly handled by the NLA Editor module, but are inherited from the Animation module.
* Most of the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as there
* are many similarities with the other Animation Editors.
*
@@ -347,7 +347,7 @@ void nla_keymap(wmKeyConfig *keyconf)
*/
keymap = WM_keymap_find(keyconf, "NLA Channels", SPACE_NLA, 0);
nla_keymap_channels(keymap);
-
+
/* data ------------------------------------------------------------- */
keymap = WM_keymap_find(keyconf, "NLA Editor", SPACE_NLA, 0);
nla_keymap_main(keyconf, keymap);
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index 2057fe5c022..8c9372f0612 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -89,7 +89,7 @@ enum {
DESELECT_STRIPS_TEST,
DESELECT_STRIPS_CLEARACTIVE,
} /*eDeselectNlaStrips*/;
-
+
/* Deselects strips in the NLA Editor
* - This is called by the deselect all operator, as well as other ones!
*
@@ -105,20 +105,20 @@ static void deselect_nla_strips(bAnimContext *ac, short test, short sel)
bAnimListElem *ale;
int filter;
short smode;
-
+
/* determine type-based settings */
// FIXME: double check whether ANIMFILTER_LIST_VISIBLE is needed!
filter = (ANIMFILTER_DATA_VISIBLE);
-
+
/* filter data */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* See if we should be selecting or deselecting */
if (test == DESELECT_STRIPS_TEST) {
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
/* if any strip is selected, break out, since we should now be deselecting */
for (strip = nlt->strips.first; strip; strip = strip->next) {
if (strip->flag & NLASTRIP_FLAG_SELECT) {
@@ -126,32 +126,32 @@ static void deselect_nla_strips(bAnimContext *ac, short test, short sel)
break;
}
}
-
+
if (sel == SELECT_SUBTRACT)
break;
}
}
-
+
/* convert selection modes to selection modes */
smode = selmodes_to_flagmodes(sel);
-
+
/* Now set the flags */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
/* apply same selection to all strips */
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* set selection */
if (test != DESELECT_STRIPS_CLEARACTIVE)
ACHANNEL_SET_FLAG(strip, smode, NLASTRIP_FLAG_SELECT);
-
+
/* clear active flag */
// TODO: for clear active, do we want to limit this to only doing this on a certain set of tracks though?
strip->flag &= ~NLASTRIP_FLAG_ACTIVE;
}
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -161,37 +161,37 @@ static void deselect_nla_strips(bAnimContext *ac, short test, short sel)
static int nlaedit_deselectall_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* 'standard' behavior - check if selected, then apply relevant selection */
if (RNA_boolean_get(op->ptr, "invert"))
deselect_nla_strips(&ac, DESELECT_STRIPS_NOTEST, SELECT_INVERT);
else
deselect_nla_strips(&ac, DESELECT_STRIPS_TEST, SELECT_ADD);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
-
+
void NLA_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name = "(De)select All";
ot->idname = "NLA_OT_select_all_toggle";
ot->description = "Select or deselect all NLA-Strips";
-
+
/* api callbacks */
ot->exec = nlaedit_deselectall_exec;
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
-
+
/* props */
ot->prop = RNA_def_boolean(ot->srna, "invert", 0, "Invert", "");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
@@ -218,27 +218,27 @@ static void borderselect_nla_strips(bAnimContext *ac, rcti rect, short mode, sho
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
SpaceNla *snla = (SpaceNla *)ac->sl;
View2D *v2d = &ac->ar->v2d;
rctf rectf;
float ymin /* =(float)(-NLACHANNEL_HEIGHT(snla)) */ /* UNUSED */, ymax = 0;
-
+
/* convert border-region to view coordinates */
UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin + 2, &rectf.xmin, &rectf.ymin);
UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax - 2, &rectf.xmax, &rectf.ymax);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* convert selection modes to selection modes */
selectmode = selmodes_to_flagmodes(selectmode);
-
+
/* loop over data, doing border select */
for (ale = anim_data.first; ale; ale = ale->next) {
ymin = ymax - NLACHANNEL_STEP(snla);
-
+
/* perform vertical suitability check (if applicable) */
if ((mode == NLA_BORDERSEL_FRAMERANGE) ||
!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
@@ -247,7 +247,7 @@ static void borderselect_nla_strips(bAnimContext *ac, rcti rect, short mode, sho
if (ale->type == ANIMTYPE_NLATRACK) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
/* only select strips if they fall within the required ranges (if applicable) */
for (strip = nlt->strips.first; strip; strip = strip->next) {
if ((mode == NLA_BORDERSEL_CHANNELS) ||
@@ -255,18 +255,18 @@ static void borderselect_nla_strips(bAnimContext *ac, rcti rect, short mode, sho
{
/* set selection */
ACHANNEL_SET_FLAG(strip, selectmode, NLASTRIP_FLAG_SELECT);
-
+
/* clear active flag */
strip->flag &= ~NLASTRIP_FLAG_ACTIVE;
}
}
}
}
-
+
/* set minimum extent to be the maximum of the next channel */
ymax = ymin;
}
-
+
/* cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -280,7 +280,7 @@ static int nlaedit_borderselect_exec(bContext *C, wmOperator *op)
short mode = 0, selectmode = 0;
const bool select = !RNA_boolean_get(op->ptr, "deselect");
const bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
@@ -302,7 +302,7 @@ static int nlaedit_borderselect_exec(bContext *C, wmOperator *op)
/* selection 'mode' depends on whether borderselect region only matters on one axis */
if (RNA_boolean_get(op->ptr, "axis_range")) {
- /* mode depends on which axis of the range is larger to determine which axis to use
+ /* mode depends on which axis of the range is larger to determine which axis to use
* - checking this in region-space is fine, as it's fundamentally still going to be a different rect size
* - the frame-range select option is favored over the channel one (x over y), as frame-range one is often
* used for tweaking timing when "blocking", while channels is not that useful...
@@ -312,17 +312,17 @@ static int nlaedit_borderselect_exec(bContext *C, wmOperator *op)
else
mode = NLA_BORDERSEL_CHANNELS;
}
- else
+ else
mode = NLA_BORDERSEL_ALLSTRIPS;
-
+
/* apply borderselect action */
borderselect_nla_strips(&ac, rect, mode, selectmode);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
-}
+}
void NLA_OT_select_border(wmOperatorType *ot)
{
@@ -330,21 +330,21 @@ void NLA_OT_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->idname = "NLA_OT_select_border";
ot->description = "Use box selection to grab NLA-Strips";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = nlaedit_borderselect_exec;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = nlaop_poll_tweakmode_off;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
-
+
RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
}
@@ -366,24 +366,24 @@ static void nlaedit_select_leftright(bContext *C, bAnimContext *ac, short leftri
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
Scene *scene = ac->scene;
float xmin, xmax;
-
+
/* if currently in tweakmode, exit tweakmode first */
if (scene->flag & SCE_NLA_EDIT_ON)
WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL);
-
+
/* if select mode is replace, deselect all keyframes (and channels) first */
if (select_mode == SELECT_REPLACE) {
select_mode = SELECT_ADD;
-
+
/* - deselect all other keyframes, so that just the newly selected remain
* - channels aren't deselected, since we don't re-select any as a consequence
*/
deselect_nla_strips(ac, 0, SELECT_SUBTRACT);
}
-
+
/* get range, and get the right flag-setting mode */
if (leftright == NLAEDIT_LRSEL_LEFT) {
xmin = MINAFRAMEF;
@@ -393,19 +393,19 @@ static void nlaedit_select_leftright(bContext *C, bAnimContext *ac, short leftri
xmin = (float)(CFRA - 0.1f);
xmax = MAXFRAMEF;
}
-
+
select_mode = selmodes_to_flagmodes(select_mode);
-
-
+
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* select strips on the side where most data occurs */
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
/* check each strip to see if it is appropriate */
for (strip = nlt->strips.first; strip; strip = strip->next) {
if (BKE_nlastrip_within_bounds(strip, xmin, xmax)) {
@@ -413,7 +413,7 @@ static void nlaedit_select_leftright(bContext *C, bAnimContext *ac, short leftri
}
}
}
-
+
/* Cleanup */
ANIM_animdata_freelist(&anim_data);
}
@@ -425,28 +425,28 @@ static int nlaedit_select_leftright_exec(bContext *C, wmOperator *op)
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
short selectmode;
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* select mode is either replace (deselect all, then add) or add/extend */
if (RNA_boolean_get(op->ptr, "extend"))
selectmode = SELECT_INVERT;
else
selectmode = SELECT_REPLACE;
-
+
/* if "test" mode is set, we don't have any info to set this with */
if (leftright == NLAEDIT_LRSEL_TEST)
return OPERATOR_CANCELLED;
-
+
/* do the selecting now */
nlaedit_select_leftright(C, &ac, leftright, selectmode);
-
+
/* set notifier that keyframe selection (and channels too) have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -454,18 +454,18 @@ static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, const wm
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
-
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* handle mode-based testing */
if (leftright == NLAEDIT_LRSEL_TEST) {
Scene *scene = ac.scene;
ARegion *ar = ac.ar;
View2D *v2d = &ar->v2d;
float x;
-
+
/* determine which side of the current frame mouse is on */
x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
if (x < CFRA)
@@ -473,7 +473,7 @@ static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, const wm
else
RNA_enum_set(op->ptr, "mode", NLAEDIT_LRSEL_RIGHT);
}
-
+
/* perform selection */
return nlaedit_select_leftright_exec(C, op);
}
@@ -481,24 +481,24 @@ static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, const wm
void NLA_OT_select_leftright(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Select Left/Right";
ot->idname = "NLA_OT_select_leftright";
ot->description = "Select strips to the left or the right of the current frame";
-
+
/* api callbacks */
ot->invoke = nlaedit_select_leftright_invoke;
ot->exec = nlaedit_select_leftright_exec;
ot->poll = ED_operator_nla_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_nlaedit_leftright_select_types, NLAEDIT_LRSEL_TEST, "Mode", "");
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
-
+
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -512,7 +512,7 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale = NULL;
int filter;
-
+
SpaceNla *snla = (SpaceNla *)ac->sl;
View2D *v2d = &ac->ar->v2d;
Scene *scene = ac->scene;
@@ -520,22 +520,22 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
int channel_index;
float xmin, xmax;
float x, y;
-
-
+
+
/* use View2D to determine the index of the channel (i.e a row in the list) where keyframe was */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
UI_view2d_listview_view_to_cell(v2d, 0, NLACHANNEL_STEP(snla), 0, (float)NLACHANNEL_HEIGHT_HALF(snla), x, y, NULL, &channel_index);
-
- /* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click
- * (that is the size of keyframe icons, so user should be expecting similar tolerances)
+
+ /* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click
+ * (that is the size of keyframe icons, so user should be expecting similar tolerances)
*/
xmin = UI_view2d_region_to_view_x(v2d, mval[0] - 7);
xmax = UI_view2d_region_to_view_x(v2d, mval[0] + 7);
-
+
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
+
/* try to get channel */
ale = BLI_findlink(&anim_data, channel_index);
if (ale == NULL) {
@@ -548,65 +548,65 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
/* found some channel - we only really should do somethign when its an Nla-Track */
if (ale->type == ANIMTYPE_NLATRACK) {
NlaTrack *nlt = (NlaTrack *)ale->data;
-
+
/* loop over NLA-strips in this track, trying to find one which occurs in the necessary bounds */
for (strip = nlt->strips.first; strip; strip = strip->next) {
if (BKE_nlastrip_within_bounds(strip, xmin, xmax))
break;
}
}
-
+
/* remove active channel from list of channels for separate treatment (since it's needed later on) */
BLI_remlink(&anim_data, ale);
-
+
/* free list of channels, since it's not used anymore */
ANIM_animdata_freelist(&anim_data);
}
-
+
/* if currently in tweakmode, exit tweakmode before changing selection states
* now that we've found our target...
*/
if (scene->flag & SCE_NLA_EDIT_ON)
WM_operator_name_call(C, "NLA_OT_tweakmode_exit", WM_OP_EXEC_DEFAULT, NULL);
-
+
/* for replacing selection, firstly need to clear existing selection */
if (select_mode == SELECT_REPLACE) {
/* reset selection mode for next steps */
select_mode = SELECT_ADD;
-
+
/* deselect all strips */
deselect_nla_strips(ac, 0, SELECT_SUBTRACT);
-
+
/* deselect all other channels first */
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
}
-
+
/* only select strip if we clicked on a valid channel and hit something */
if (ale) {
/* select the strip accordingly (if a matching one was found) */
if (strip) {
select_mode = selmodes_to_flagmodes(select_mode);
ACHANNEL_SET_FLAG(strip, select_mode, NLASTRIP_FLAG_SELECT);
-
+
/* if we selected it, we can make it active too
- * - we always need to clear the active strip flag though...
+ * - we always need to clear the active strip flag though...
* - as well as selecting its track...
*/
deselect_nla_strips(ac, DESELECT_STRIPS_CLEARACTIVE, 0);
-
+
if (strip->flag & NLASTRIP_FLAG_SELECT) {
strip->flag |= NLASTRIP_FLAG_ACTIVE;
-
+
/* Highlight NLA-Track */
if (ale->type == ANIMTYPE_NLATRACK) {
NlaTrack *nlt = (NlaTrack *)ale->data;
-
+
nlt->flag |= NLATRACK_SELECTED;
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
}
}
}
-
+
/* free this channel */
MEM_freeN(ale);
}
@@ -626,7 +626,7 @@ static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
-
+
/* get useful pointers from animation context data */
/* scene= ac.scene; */ /* UNUSED */
/* ar= ac.ar; */ /* UNUSED */
@@ -637,33 +637,33 @@ static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent
selectmode = SELECT_INVERT;
else
selectmode = SELECT_REPLACE;
-
+
/* select strips based upon mouse position */
mouse_nla_strips(C, &ac, event->mval, selectmode);
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_SELECTED, NULL);
-
+
/* for tweak grab to work */
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
-
+
void NLA_OT_click_select(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Mouse Select";
ot->idname = "NLA_OT_click_select";
ot->description = "Handle clicks to select NLA Strips";
-
+
/* api callbacks - absolutely no exec() this yet... */
ot->invoke = nlaedit_clickselect_invoke;
ot->poll = ED_operator_nla_active;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 73f14e36d14..318d8bf777b 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -78,15 +78,15 @@ ARegion *nla_has_buttons_region(ScrArea *sa)
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "buttons for nla");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_UI;
arnew->alignment = RGN_ALIGN_RIGHT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
-
+
return arnew;
}
@@ -98,58 +98,58 @@ static SpaceLink *nla_new(const ScrArea *sa, const Scene *scene)
{
ARegion *ar;
SpaceNla *snla;
-
+
snla = MEM_callocN(sizeof(SpaceNla), "initnla");
snla->spacetype = SPACE_NLA;
-
+
/* allocate DopeSheet data for NLA Editor */
snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
snla->ads->source = (ID *)scene;
-
+
/* set auto-snapping settings */
snla->autosnap = SACTSNAP_FRAME;
-
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for nla");
-
+
BLI_addtail(&snla->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
/* channel list region */
ar = MEM_callocN(sizeof(ARegion), "channel list for nla");
BLI_addtail(&snla->regionbase, ar);
ar->regiontype = RGN_TYPE_CHANNELS;
ar->alignment = RGN_ALIGN_LEFT;
-
+
/* only need to set these settings since this will use the 'stack' configuration */
ar->v2d.scroll = V2D_SCROLL_BOTTOM;
ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
-
+
/* ui buttons */
ar = MEM_callocN(sizeof(ARegion), "buttons region for nla");
-
+
BLI_addtail(&snla->regionbase, ar);
ar->regiontype = RGN_TYPE_UI;
ar->alignment = RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
-
+
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for nla");
-
+
BLI_addtail(&snla->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
ar->v2d.tot.xmin = (float)(SFRA - 10);
ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
ar->v2d.tot.xmax = (float)(EFRA + 10);
ar->v2d.tot.ymax = 0.0f;
-
+
ar->v2d.cur = ar->v2d.tot;
-
+
ar->v2d.min[0] = 0.0f;
ar->v2d.min[1] = 0.0f;
-
+
ar->v2d.max[0] = MAXFRAMEF;
ar->v2d.max[1] = 10000.0f;
@@ -161,15 +161,15 @@ static SpaceLink *nla_new(const ScrArea *sa, const Scene *scene)
ar->v2d.keepofs = V2D_KEEPOFS_Y;
ar->v2d.align = V2D_ALIGN_NO_POS_Y;
ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
-
+
return (SpaceLink *)snla;
}
/* not spacelink itself */
static void nla_free(SpaceLink *sl)
-{
+{
SpaceNla *snla = (SpaceNla *) sl;
-
+
if (snla->ads) {
BLI_freelistN(&snla->ads->chanbase);
MEM_freeN(snla->ads);
@@ -181,7 +181,7 @@ static void nla_free(SpaceLink *sl)
static void nla_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
{
SpaceNla *snla = (SpaceNla *)sa->spacedata.first;
-
+
/* init dopesheet data if non-existent (i.e. for old files) */
if (snla->ads == NULL) {
snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
@@ -194,10 +194,10 @@ static void nla_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
static SpaceLink *nla_duplicate(SpaceLink *sl)
{
SpaceNla *snlan = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
snlan->ads = MEM_dupallocN(snlan->ads);
-
+
return (SpaceLink *)snlan;
}
@@ -205,12 +205,12 @@ static SpaceLink *nla_duplicate(SpaceLink *sl)
static void nla_channel_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
/* ensure the 2d view sync works - main region has bottom scroller */
ar->v2d.scroll = V2D_SCROLL_BOTTOM;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-
+
/* own keymap */
/* own channels map first to override some channel keymaps */
keymap = WM_keymap_find(wm->defaultconf, "NLA Channels", SPACE_NLA, 0);
@@ -218,7 +218,7 @@ static void nla_channel_region_init(wmWindowManager *wm, ARegion *ar)
/* now generic channels map for everything else that can apply */
keymap = WM_keymap_find(wm->defaultconf, "Animation Channels", 0, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
-
+
keymap = WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -229,21 +229,21 @@ static void nla_channel_region_draw(const bContext *C, ARegion *ar)
bAnimContext ac;
View2D *v2d = &ar->v2d;
View2DScrollers *scrollers;
-
+
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_view2d_view_ortho(v2d);
-
+
/* data */
if (ANIM_animdata_get_context(C, &ac)) {
draw_nla_channel_list(C, &ac, ar);
}
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
@@ -255,9 +255,9 @@ static void nla_channel_region_draw(const bContext *C, ARegion *ar)
static void nla_main_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
-
+
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "NLA Editor", SPACE_NLA, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -275,59 +275,59 @@ static void nla_main_region_draw(const bContext *C, ARegion *ar)
View2DGrid *grid;
View2DScrollers *scrollers;
short unit = 0, cfra_flag = 0;
-
+
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_view2d_view_ortho(v2d);
-
+
/* time grid */
unit = (snla->flag & SNLA_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
UI_view2d_grid_free(grid);
-
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
-
+
/* start and end frame */
ANIM_draw_framerange(scene, v2d);
-
+
/* data */
if (ANIM_animdata_get_context(C, &ac)) {
/* strips and backdrops */
draw_nla_main_data(&ac, snla, ar);
-
+
/* text draw cached, in pixelspace now */
UI_view2d_text_cache_draw(ar);
}
-
+
UI_view2d_view_ortho(v2d);
-
+
/* current frame */
if (snla->flag & SNLA_DRAWTIME) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
ANIM_draw_cfra(C, v2d, cfra_flag);
-
+
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ED_markers_draw(C, DRAW_MARKERS_MARGIN);
-
+
/* preview range */
UI_view2d_view_ortho(v2d);
ANIM_draw_previewrange(C, v2d, 0);
-
+
/* callback */
UI_view2d_view_ortho(v2d);
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
+
/* draw current frame number-indicator on top of scrollers */
if ((snla->flag & SNLA_NODRAWCFRANUM) == 0) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
@@ -351,9 +351,9 @@ static void nla_header_region_draw(const bContext *C, ARegion *ar)
static void nla_buttons_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
ED_region_panels_init(wm, ar);
-
+
keymap = WM_keymap_find(wm->defaultconf, "NLA Generic", SPACE_NLA, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -541,7 +541,7 @@ static void nla_channel_region_message_subscribe(
.user_data = ar,
.notify = ED_region_do_msg_notify_tag_redraw,
};
-
+
/* All dopesheet filter settings, etc. affect the drawing of this editor,
* so just whitelist the entire struct for updates
*/
@@ -603,7 +603,7 @@ static void nla_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scen
static void nla_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
{
SpaceNla *snla = (SpaceNla *)slink;
-
+
if (snla->ads) {
if ((ID *)snla->ads->filter_grp == old_id) {
snla->ads->filter_grp = (Collection *)new_id;
@@ -619,10 +619,10 @@ void ED_spacetype_nla(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype nla");
ARegionType *art;
-
+
st->spaceid = SPACE_NLA;
strncpy(st->name, "NLA", BKE_ST_MAXNAME);
-
+
st->new = nla_new;
st->free = nla_free;
st->init = nla_init;
@@ -642,31 +642,31 @@ void ED_spacetype_nla(void)
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype nla region");
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
-
+
art->init = nla_header_region_init;
art->draw = nla_header_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: channels */
art = MEM_callocN(sizeof(ARegionType), "spacetype nla region");
art->regionid = RGN_TYPE_CHANNELS;
art->prefsizex = 200;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
-
+
art->init = nla_channel_region_init;
art->draw = nla_channel_region_draw;
art->listener = nla_channel_region_listener;
art->message_subscribe = nla_channel_region_message_subscribe;
-
+
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: UI buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype nla region");
art->regionid = RGN_TYPE_UI;
@@ -675,11 +675,11 @@ void ED_spacetype_nla(void)
art->listener = nla_region_listener;
art->init = nla_buttons_region_init;
art->draw = nla_buttons_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
nla_buttons_register(art);
-
-
+
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 0267fd9da2e..a9120430128 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -94,7 +94,7 @@ static void node_buts_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *p
bNodeSocket *output = node->outputs.first;
PointerRNA sockptr;
RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, output, &sockptr);
-
+
uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NONE);
}
@@ -106,14 +106,14 @@ static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr
PointerRNA sockptr;
uiLayout *col;
RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, output, &sockptr);
-
+
col = uiLayoutColumn(layout, false);
uiTemplateColorPicker(col, &sockptr, "default_value", 1, 0, 0, 0);
uiItemR(col, &sockptr, "default_value", UI_ITEM_R_SLIDER, "", ICON_NONE);
}
static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiLayout *row, *col;
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
@@ -134,7 +134,7 @@ static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt
/* XXX no context access here .. */
bNode *node = ptr->data;
CurveMapping *cumap = node->storage;
-
+
if (cumap) {
cumap->flag |= CUMA_DRAW_CFRA;
if (node->custom1 < node->custom2)
@@ -194,7 +194,7 @@ static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA *
bNodeSocket *output = node->outputs.first;
PointerRNA sockptr;
RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, output, &sockptr);
-
+
uiItemR(layout, &sockptr, "default_value", 0, "", ICON_NONE);
}
@@ -205,9 +205,9 @@ static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v)
bNodeTree *ntree = ntree_v;
bNode *node = node_v;
Tex *tex;
-
+
if (node->menunr < 1) return;
-
+
if (node->id) {
id_us_min(node->id);
node->id = NULL;
@@ -217,16 +217,16 @@ static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v)
node->id = &tex->id;
id_us_plus(node->id);
BLI_strncpy(node->name, node->id->name + 2, sizeof(node->name));
-
+
nodeSetActive(ntree, node);
-
+
if (ntree->type == NTREE_TEXTURE)
ntreeTexCheckCyclics(ntree);
-
+
// allqueue(REDRAWBUTSSHADING, 0);
// allqueue(REDRAWNODE, 0);
- NodeTagChanged(ntree, node);
-
+ NodeTagChanged(ntree, node);
+
node->menunr = 0;
}
#endif
@@ -241,9 +241,9 @@ static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA
(node->type != CMP_NODE_TEXTURE) &&
(node->type != TEX_NODE_TEXTURE)
);
-
+
uiItemR(layout, ptr, "texture", 0, "", ICON_NONE);
-
+
if (multi) {
/* Number Drawing not optimal here, better have a list*/
uiItemR(layout, ptr, "node_output", 0, "", ICON_NONE);
@@ -251,7 +251,7 @@ static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA
}
static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
uiItemR(layout, ptr, "use_clamp", 0, NULL, ICON_NONE);
}
@@ -271,7 +271,7 @@ static int node_resize_area_default(bNode *node, int x, int y)
const float size = 10.0f;
rctf totr = node->totr;
int dir = 0;
-
+
if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax)
dir |= NODE_RESIZE_RIGHT;
if (x >= totr.xmin && x < totr.xmin + size && y >= totr.ymin && y < totr.ymax)
@@ -300,11 +300,11 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree,
bNode *tnode;
rctf rect, noderect;
float xmax, ymax;
-
+
/* init rect from current frame size */
node_to_view(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
node_to_view(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin);
-
+
/* frame can be resized manually only if shrinking is disabled or no children are attached */
data->flag |= NODE_FRAME_RESIZEABLE;
/* for shrinking bbox, initialize the rect from first child node */
@@ -313,14 +313,14 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree,
for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) {
if (tnode->parent != node)
continue;
-
+
/* add margin to node rect */
noderect = tnode->totr;
noderect.xmin -= margin;
noderect.xmax += margin;
noderect.ymin -= margin;
noderect.ymax += margin;
-
+
/* first child initializes frame */
if (bbinit) {
bbinit = 0;
@@ -330,13 +330,13 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree,
else
BLI_rctf_union(&rect, &noderect);
}
-
+
/* now adjust the frame size from view-space bounding box */
node_from_view(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax);
node->width = xmax - node->offsetx;
node->height = -ymax + node->offsety;
-
+
node->totr = rect;
}
@@ -361,7 +361,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
BLF_enable(fontid, BLF_ASPECT);
BLF_aspect(fontid, aspect, aspect, 1.0f);
BLF_size(fontid, MIN2(24, font_size), U.dpi); /* clamp otherwise it can suck up a LOT of memory */
-
+
/* title color */
UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color);
BLF_color3ubv(fontid, color);
@@ -369,7 +369,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
width = BLF_width(fontid, label, sizeof(label));
ascender = BLF_ascender(fontid);
label_height = ((margin / aspect) + (ascender * aspect));
-
+
/* 'x' doesn't need aspect correction */
x = BLI_rctf_cent_x(rct) - (0.5f * width);
y = rct->ymax - label_height;
@@ -431,7 +431,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
int color_id = node_get_colorid(node);
float color[4];
float alpha;
-
+
/* skip if out of view */
if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) {
UI_block_end(C, node->block);
@@ -441,10 +441,10 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
UI_GetThemeColor4fv(TH_NODE_FRAME, color);
alpha = color[3];
-
+
/* shadow */
node_draw_shadow(snode, node, BASIS_RAD, alpha);
-
+
/* body */
if (node->flag & NODE_CUSTOM_COLOR) {
rgba_float_args_set(color, node->color[0], node->color[1], node->color[2], alpha);
@@ -467,9 +467,9 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
/* label */
node_draw_frame_label(ntree, node, snode->aspect);
-
+
UI_ThemeClearColor(color_id);
-
+
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
node->block = NULL;
@@ -481,11 +481,11 @@ static int node_resize_area_frame(bNode *node, int x, int y)
NodeFrame *data = (NodeFrame *)node->storage;
rctf totr = node->totr;
int dir = 0;
-
+
/* shrinking frame size is determined by child nodes */
if (!(data->flag & NODE_FRAME_RESIZEABLE))
return 0;
-
+
if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax)
dir |= NODE_RESIZE_RIGHT;
if (x >= totr.xmin && x < totr.xmin + size && y >= totr.ymin && y < totr.ymax)
@@ -494,7 +494,7 @@ static int node_resize_area_frame(bNode *node, int x, int y)
dir |= NODE_RESIZE_TOP;
if (x >= totr.xmin && x < totr.xmax && y >= totr.ymin && y < totr.ymin + size)
dir |= NODE_RESIZE_BOTTOM;
-
+
return dir;
}
@@ -513,10 +513,10 @@ static void node_draw_reroute_prepare(const bContext *UNUSED(C), bNodeTree *UNUS
bNodeSocket *nsock;
float locx, locy;
float size = NODE_REROUTE_SIZE;
-
+
/* get "global" coords */
node_to_view(node, 0.0f, 0.0f, &locx, &locy);
-
+
/* reroute node has exactly one input and one output, both in the same place */
nsock = node->outputs.first;
nsock->locx = locx;
@@ -604,7 +604,7 @@ static int node_tweak_area_reroute(bNode *node, int x, int y)
{
/* square of tweak radius */
const float tweak_radius_sq = SQUARE(24);
-
+
bNodeSocket *sock = node->inputs.first;
float dx = sock->locx - x;
float dy = sock->locy - y;
@@ -644,9 +644,9 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr,
return;
col = uiLayoutColumn(layout, false);
-
+
uiItemR(col, imaptr, "source", 0, "", ICON_NONE);
-
+
source = RNA_enum_get(imaptr, "source");
if (source == IMA_SRC_SEQUENCE) {
@@ -715,12 +715,12 @@ static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), Poin
}
static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
}
static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiItemR(layout, ptr, "vector_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiItemR(layout, ptr, "convert_from", 0, "", ICON_NONE);
uiItemR(layout, ptr, "convert_to", 0, "", ICON_NONE);
@@ -827,7 +827,7 @@ static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, P
}
static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiItemR(layout, ptr, "sky_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "sun_direction", 0, "", ICON_NONE);
uiItemR(layout, ptr, "turbidity", 0, NULL, ICON_NONE);
@@ -849,11 +849,11 @@ static void node_shader_buts_tex_magic(uiLayout *layout, bContext *UNUSED(C), Po
static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "offset", UI_ITEM_R_SLIDER, IFACE_("Offset"), ICON_NONE);
uiItemR(col, ptr, "offset_frequency", 0, IFACE_("Frequency"), ICON_NONE);
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "squash", 0, IFACE_("Squash"), ICON_NONE);
uiItemR(col, ptr, "squash_frequency", 0, IFACE_("Frequency"), ICON_NONE);
@@ -1108,15 +1108,15 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_VALTORGB:
ntype->draw_buttons = node_buts_colorramp;
break;
- case SH_NODE_MATH:
+ case SH_NODE_MATH:
ntype->draw_buttons = node_buts_math;
- break;
- case SH_NODE_VECT_MATH:
+ break;
+ case SH_NODE_VECT_MATH:
ntype->draw_buttons = node_shader_buts_vect_math;
- break;
- case SH_NODE_VECT_TRANSFORM:
+ break;
+ case SH_NODE_VECT_TRANSFORM:
ntype->draw_buttons = node_shader_buts_vect_transform;
- break;
+ break;
case SH_NODE_ATTRIBUTE:
ntype->draw_buttons = node_shader_buts_attribute;
break;
@@ -1237,14 +1237,14 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
{
bNode *node = ptr->data;
PointerRNA imaptr, iuserptr;
-
+
RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr);
uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
uiTemplateID(
layout, C, ptr, "image",
NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL);
if (!node->id) return;
-
+
imaptr = RNA_pointer_get(ptr, "image");
node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr, true);
@@ -1273,17 +1273,17 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer
char scene_name[MAX_ID_NAME - 2];
uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL);
-
+
if (!node->id) return;
col = uiLayoutColumn(layout, false);
row = uiLayoutRow(col, true);
uiItemR(row, ptr, "layer", 0, "", ICON_NONE);
-
+
prop = RNA_struct_find_property(ptr, "layer");
if (!(RNA_property_enum_identifier(C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name)))
return;
-
+
scn_ptr = RNA_pointer_get(ptr, "scene");
RNA_string_get(&scn_ptr, "name", scene_name);
@@ -1298,7 +1298,7 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point
uiLayout *col, *row;
int reference;
int filter;
-
+
col = uiLayoutColumn(layout, false);
filter = RNA_enum_get(ptr, "filter_type");
reference = RNA_boolean_get(ptr, "use_variable_size");
@@ -1311,14 +1311,14 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point
}
uiItemR(col, ptr, "use_gamma_correction", 0, NULL, ICON_NONE);
}
-
+
uiItemR(col, ptr, "use_relative", 0, NULL, ICON_NONE);
-
+
if (RNA_boolean_get(ptr, "use_relative")) {
uiItemL(col, IFACE_("Aspect Correction"), ICON_NONE);
row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "aspect_correction", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "factor_x", 0, IFACE_("X"), ICON_NONE);
uiItemR(col, ptr, "factor_y", 0, IFACE_("Y"), ICON_NONE);
@@ -1334,31 +1334,31 @@ static void node_composit_buts_blur(uiLayout *layout, bContext *UNUSED(C), Point
static void node_composit_buts_dblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "use_wrap", 0, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Center:"), ICON_NONE);
uiItemR(col, ptr, "center_x", 0, IFACE_("X"), ICON_NONE);
uiItemR(col, ptr, "center_y", 0, IFACE_("Y"), ICON_NONE);
-
+
uiItemS(layout);
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "distance", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "angle", 0, NULL, ICON_NONE);
-
+
uiItemS(layout);
-
+
uiItemR(layout, ptr, "spin", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "zoom", 0, NULL, ICON_NONE);
}
static void node_composit_buts_bilateralblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "iterations", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "sigma_color", 0, NULL, ICON_NONE);
@@ -1368,7 +1368,7 @@ static void node_composit_buts_bilateralblur(uiLayout *layout, bContext *UNUSED(
static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
uiLayout *sub, *col;
-
+
col = uiLayoutColumn(layout, false);
uiItemL(col, IFACE_("Bokeh Type:"), ICON_NONE);
uiItemR(col, ptr, "bokeh", 0, "", ICON_NONE);
@@ -1397,17 +1397,17 @@ static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA
/* qdn: glare node */
static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiItemR(layout, ptr, "glare_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "quality", 0, "", ICON_NONE);
if (RNA_enum_get(ptr, "glare_type") != 1) {
uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE);
-
+
if (RNA_enum_get(ptr, "glare_type") != 0)
uiItemR(layout, ptr, "color_modulation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
-
+
uiItemR(layout, ptr, "mix", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NONE);
@@ -1417,7 +1417,7 @@ static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), Poin
}
if (RNA_enum_get(ptr, "glare_type") == 0 || RNA_enum_get(ptr, "glare_type") == 2) {
uiItemR(layout, ptr, "fade", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
-
+
if (RNA_enum_get(ptr, "glare_type") == 0)
uiItemR(layout, ptr, "use_rotate_45", 0, NULL, ICON_NONE);
}
@@ -1427,7 +1427,7 @@ static void node_composit_buts_glare(uiLayout *layout, bContext *UNUSED(C), Poin
}
static void node_composit_buts_tonemap(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiLayout *col;
col = uiLayoutColumn(layout, false);
@@ -1461,11 +1461,11 @@ static void node_composit_buts_lensdist(uiLayout *layout, bContext *UNUSED(C), P
static void node_composit_buts_vecblur(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "samples", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "factor", 0, IFACE_("Blur"), ICON_NONE);
-
+
col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Speed:"), ICON_NONE);
uiItemR(col, ptr, "speed_min", 0, IFACE_("Min"), ICON_NONE);
@@ -1509,7 +1509,7 @@ static void node_composit_buts_crop(uiLayout *layout, bContext *UNUSED(C), Point
static void node_composit_buts_splitviewer(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row, *col;
-
+
col = uiLayoutColumn(layout, false);
row = uiLayoutRow(col, false);
uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
@@ -1539,17 +1539,17 @@ static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C),
static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *sub, *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "offset", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "size", 0, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_min", 0, NULL, ICON_NONE);
sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min"));
uiItemR(sub, ptr, "min", 0, "", ICON_NONE);
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_max", 0, NULL, ICON_NONE);
sub = uiLayoutColumn(col, false);
@@ -1558,18 +1558,18 @@ static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C),
}
static void node_composit_buts_alphaover(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_premultiply", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "premul", 0, NULL, ICON_NONE);
}
static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_antialias_z", 0, NULL, ICON_NONE);
@@ -1606,7 +1606,7 @@ static void node_composit_buts_despeckle(uiLayout *layout, bContext *UNUSED(C),
static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "falloff", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1615,7 +1615,7 @@ static void node_composit_buts_diff_matte(uiLayout *layout, bContext *UNUSED(C),
static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col, *row;
-
+
col = uiLayoutColumn(layout, true);
uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
@@ -1629,7 +1629,7 @@ static void node_composit_buts_distance_matte(uiLayout *layout, bContext *UNUSED
static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row, *col;
-
+
uiItemL(layout, IFACE_("Despill Channel:"), ICON_NONE);
row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "channel", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
@@ -1655,11 +1655,11 @@ static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C)
static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "tolerance", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "threshold", 0, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(layout, true);
/*uiItemR(col, ptr, "lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); Removed for now */
uiItemR(col, ptr, "gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1669,7 +1669,7 @@ static void node_composit_buts_chroma_matte(uiLayout *layout, bContext *UNUSED(C
static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "color_hue", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "color_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1677,7 +1677,7 @@ static void node_composit_buts_color_matte(uiLayout *layout, bContext *UNUSED(C)
}
static void node_composit_buts_channel_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiLayout *col, *row;
uiItemL(layout, IFACE_("Color Space:"), ICON_NONE);
@@ -1705,7 +1705,7 @@ static void node_composit_buts_channel_matte(uiLayout *layout, bContext *UNUSED(
static void node_composit_buts_luma_matte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "limit_max", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, ptr, "limit_min", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -1743,22 +1743,22 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
int active_index;
const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER;
const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
-
+
node_composit_buts_file_output(layout, C, ptr);
uiTemplateImageSettings(layout, &imfptr, false);
-
+
/* disable stereo output for multilayer, too much work for something that no one will use */
/* if someone asks for that we can implement it */
if (is_multiview)
uiTemplateImageFormatViews(layout, &imfptr, NULL);
uiItemS(layout);
-
+
uiItemO(layout, IFACE_("Add Input"), ICON_ZOOMIN, "NODE_OT_output_file_add_socket");
-
+
row = uiLayoutRow(layout, false);
col = uiLayoutColumn(row, true);
-
+
active_index = RNA_int_get(ptr, "active_input_index");
/* using different collection properties if multilayer format is enabled */
if (multilayer) {
@@ -1775,18 +1775,18 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
}
/* XXX collection lookup does not return the ID part of the pointer, setting this manually here */
active_input_ptr.id.data = ptr->id.data;
-
+
col = uiLayoutColumn(row, true);
ot = WM_operatortype_find("NODE_OT_output_file_move_active_socket", false);
uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
RNA_enum_set(&op_ptr, "direction", 1);
uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
RNA_enum_set(&op_ptr, "direction", 2);
-
+
if (active_input_ptr.data) {
if (multilayer) {
col = uiLayoutColumn(layout, true);
-
+
uiItemL(col, IFACE_("Layer:"), ICON_NONE);
row = uiLayoutRow(col, false);
uiItemR(row, &active_input_ptr, "name", 0, "", ICON_NONE);
@@ -1795,20 +1795,20 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
}
else {
col = uiLayoutColumn(layout, true);
-
+
uiItemL(col, IFACE_("File Subpath:"), ICON_NONE);
row = uiLayoutRow(col, false);
uiItemR(row, &active_input_ptr, "path", 0, "", ICON_NONE);
uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "",
ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY, NULL);
-
+
/* format details for individual files */
imfptr = RNA_pointer_get(&active_input_ptr, "format");
-
+
col = uiLayoutColumn(layout, true);
uiItemL(col, IFACE_("Format:"), ICON_NONE);
uiItemR(col, &active_input_ptr, "use_node_format", 0, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, RNA_boolean_get(&active_input_ptr, "use_node_format") == false);
uiTemplateImageSettings(col, &imfptr, false);
@@ -1840,7 +1840,7 @@ static void node_composit_buts_rotate(uiLayout *layout, bContext *UNUSED(C), Poi
static void node_composit_buts_invert(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "invert_rgb", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "invert_alpha", 0, NULL, ICON_NONE);
@@ -1859,22 +1859,22 @@ static void node_composit_buts_view_levels(uiLayout *layout, bContext *UNUSED(C)
static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *split, *col, *row;
-
+
uiItemR(layout, ptr, "correction_method", 0, NULL, ICON_NONE);
-
+
if (RNA_enum_get(ptr, "correction_method") == 0) {
-
+
split = uiLayoutSplit(layout, 0.0f, false);
col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "lift", 1, 1, 0, 1);
row = uiLayoutRow(col, false);
uiItemR(row, ptr, "lift", 0, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "gamma", 1, 1, 1, 1);
row = uiLayoutRow(col, false);
uiItemR(row, ptr, "gamma", 0, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "gain", 1, 1, 1, 1);
row = uiLayoutRow(col, false);
@@ -1882,19 +1882,19 @@ static void node_composit_buts_colorbalance(uiLayout *layout, bContext *UNUSED(C
}
else {
-
+
split = uiLayoutSplit(layout, 0.0f, false);
col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "offset", 1, 1, 0, 1);
row = uiLayoutRow(col, false);
uiItemR(row, ptr, "offset", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "offset_basis", 0, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "power", 1, 1, 0, 1);
row = uiLayoutRow(col, false);
uiItemR(row, ptr, "power", 0, NULL, ICON_NONE);
-
+
col = uiLayoutColumn(split, false);
uiTemplateColorPicker(col, ptr, "slope", 1, 1, 0, 1);
row = uiLayoutRow(col, false);
@@ -1947,7 +1947,7 @@ static void node_composit_buts_huecorrect(uiLayout *layout, bContext *UNUSED(C),
}
static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
+{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
@@ -2010,7 +2010,7 @@ static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, Po
static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row;
-
+
row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "red", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "green", 0, NULL, ICON_NONE);
@@ -2064,7 +2064,7 @@ static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSE
static void node_composit_buts_colorcorrection_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row;
-
+
row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "red", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "green", 0, NULL, ICON_NONE);
@@ -2093,7 +2093,7 @@ static void node_composit_buts_colorcorrection_ex(uiLayout *layout, bContext *UN
uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
-
+
uiItemL(row, IFACE_("Lift"), ICON_NONE);
uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -2120,11 +2120,11 @@ static void node_composit_buts_switch_view_ex(uiLayout *layout, bContext *UNUSED
static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row;
-
+
row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "x", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "y", 0, NULL, ICON_NONE);
-
+
row = uiLayoutRow(layout, true);
uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
@@ -2293,7 +2293,7 @@ static void node_composit_buts_viewer(uiLayout *layout, bContext *UNUSED(C), Poi
static void node_composit_buts_viewer_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
uiItemR(layout, ptr, "use_alpha", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "tile_order", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "tile_order") == 0) {
@@ -2691,11 +2691,11 @@ static void node_composit_set_butfunc(bNodeType *ntype)
static void node_texture_buts_bricks(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *col;
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "offset", UI_ITEM_R_SLIDER, IFACE_("Offset"), ICON_NONE);
uiItemR(col, ptr, "offset_frequency", 0, IFACE_("Frequency"), ICON_NONE);
-
+
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "squash", 0, IFACE_("Squash"), ICON_NONE);
uiItemR(col, ptr, "squash_frequency", 0, IFACE_("Frequency"), ICON_NONE);
@@ -2708,7 +2708,7 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
ID *id = ptr->id.data;
Tex *tex = (Tex *)node->storage;
uiLayout *col, *row;
-
+
RNA_pointer_create(id, &RNA_Texture, tex, &tex_ptr);
col = uiLayoutColumn(layout, false);
@@ -2752,7 +2752,7 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
uiLayoutSetActive(row, !(ELEM(tex->stype, TEX_BAND, TEX_RING)));
uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
break;
-
+
case TEX_CLOUDS:
uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
row = uiLayoutRow(col, false);
@@ -2761,7 +2761,7 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe
uiItemR(row, &tex_ptr, "noise_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiItemR(col, &tex_ptr, "noise_depth", UI_ITEM_R_EXPAND, IFACE_("Depth"), ICON_NONE);
break;
-
+
case TEX_DISTNOISE:
uiItemR(col, &tex_ptr, "noise_basis", 0, "", ICON_NONE);
uiItemR(col, &tex_ptr, "noise_distortion", 0, "", ICON_NONE);
@@ -2862,7 +2862,7 @@ static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocket
{
StructRNA *srna = ntype->ext.srna;
PropertyRNA *prop = RNA_struct_type_find_property(srna, stemp->identifier);
-
+
if (prop)
RNA_def_property_update_runtime(prop, node_property_update_default);
}
@@ -2870,7 +2870,7 @@ static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocket
static void node_template_properties_update(bNodeType *ntype)
{
bNodeSocketTemplate *stemp;
-
+
if (ntype->inputs) {
for (stemp = ntype->inputs; stemp->type >= 0; ++stemp)
node_socket_template_properties_update(ntype, stemp);
@@ -2916,7 +2916,7 @@ void ED_node_init_butfuncs(void)
/*extern bNodeTreeType NodeTreeTypeUndefined;*/
extern bNodeType NodeTypeUndefined;
extern bNodeSocketType NodeSocketTypeUndefined;
-
+
/* default ui functions */
NodeTypeUndefined.draw_nodetype = node_draw_default;
NodeTypeUndefined.draw_nodetype_prepare = node_update_default;
@@ -2925,12 +2925,12 @@ void ED_node_init_butfuncs(void)
NodeTypeUndefined.draw_buttons = NULL;
NodeTypeUndefined.draw_buttons_ex = NULL;
NodeTypeUndefined.resize_area_func = node_resize_area_default;
-
+
NodeSocketTypeUndefined.draw = node_socket_undefined_draw;
NodeSocketTypeUndefined.draw_color = node_socket_undefined_draw_color;
NodeSocketTypeUndefined.interface_draw = node_socket_undefined_interface_draw;
NodeSocketTypeUndefined.interface_draw_color = node_socket_undefined_interface_draw_color;
-
+
/* node type ui functions */
NODE_TYPES_BEGIN(ntype)
/* default ui functions */
@@ -2941,17 +2941,17 @@ void ED_node_init_butfuncs(void)
ntype->draw_buttons = NULL;
ntype->draw_buttons_ex = NULL;
ntype->resize_area_func = node_resize_area_default;
-
+
node_common_set_butfunc(ntype);
-
+
node_composit_set_butfunc(ntype);
node_shader_set_butfunc(ntype);
node_texture_set_butfunc(ntype);
-
+
/* define update callbacks for socket properties */
node_template_properties_update(ntype);
NODE_TYPES_END
-
+
/* tree type icons */
ntreeType_Composite->ui_icon = ICON_RENDERLAYERS;
ntreeType_Shader->ui_icon = ICON_MATERIAL;
@@ -3008,16 +3008,16 @@ static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerR
uiLayout *row;
PointerRNA inputptr, imfptr;
int imtype;
-
+
row = uiLayoutRow(layout, false);
-
+
imfptr = RNA_pointer_get(node_ptr, "format");
imtype = RNA_enum_get(&imfptr, "file_format");
if (imtype == R_IMF_IMTYPE_MULTILAYER) {
NodeImageMultiFileSocket *input = sock->storage;
RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr);
-
+
uiItemL(row, input->layer, ICON_NONE);
}
else {
@@ -3026,12 +3026,12 @@ static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerR
const char *imtype_name;
uiBlock *block;
RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotFile, input, &inputptr);
-
+
uiItemL(row, input->path, ICON_NONE);
-
+
if (!RNA_boolean_get(&inputptr, "use_node_format"))
imfptr = RNA_pointer_get(&inputptr, "format");
-
+
imtype_prop = RNA_struct_find_property(&imfptr, "file_format");
RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop,
RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name);
@@ -3048,7 +3048,7 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr,
bNodeSocket *sock = ptr->data;
int type = sock->typeinfo->type;
/*int subtype = sock->typeinfo->subtype;*/
-
+
/* XXX not nice, eventually give this node its own socket type ... */
if (node->type == CMP_NODE_OUTPUT_FILE) {
node_file_output_socket_draw(C, layout, ptr, node_ptr);
@@ -3059,7 +3059,7 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr,
node_socket_button_label(C, layout, ptr, node_ptr, text);
return;
}
-
+
switch (type) {
case SOCK_FLOAT:
case SOCK_INT:
@@ -3088,7 +3088,7 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout
bNodeSocket *sock = ptr->data;
int type = sock->typeinfo->type;
/*int subtype = sock->typeinfo->subtype;*/
-
+
switch (type) {
case SOCK_FLOAT:
{
@@ -3156,33 +3156,33 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
Image *ima;
void *lock;
ImBuf *ibuf;
-
+
if (!(snode->flag & SNODE_BACKDRAW) || !ED_node_is_compositor(snode))
return;
-
+
if (parent_key.value != active_viewer_key.value)
return;
-
+
ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
if (ibuf) {
- float x, y;
+ float x, y;
gpuPushProjectionMatrix();
gpuPushMatrix();
/* somehow the offset has to be calculated inverse */
wmOrtho2_region_pixelspace(ar);
-
+
x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof;
y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof;
-
+
if (ibuf->rect || ibuf->rect_float) {
unsigned char *display_buffer = NULL;
void *cache_handle = NULL;
-
+
if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B | SNODE_SHOW_ALPHA)) {
-
+
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
if (snode->flag & SNODE_SHOW_R)
@@ -3213,11 +3213,11 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
else {
glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
}
-
+
if (cache_handle)
IMB_display_buffer_release(cache_handle);
}
-
+
/** \note draw selected info on backdrop */
if (snode->edittree) {
bNode *node = snode->edittree->nodes.first;
@@ -3230,7 +3230,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
}
node = node->next;
}
-
+
if ((snode->nodetree->flag & NTREE_VIEWER_BORDER) &&
viewer_border->xmin < viewer_border->xmax &&
viewer_border->ymin < viewer_border->ymax)
@@ -3255,7 +3255,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
gpuPopProjectionMatrix();
gpuPopMatrix();
}
-
+
BKE_image_release_ibuf(ima, ibuf, lock);
}
@@ -3266,14 +3266,14 @@ static bool node_link_bezier_handles(View2D *v2d, SpaceNode *snode, bNodeLink *l
float deltax, deltay;
float cursor[2] = {0.0f, 0.0f};
int toreroute, fromreroute;
-
+
/* this function can be called with snode null (via cut_links_intersect) */
/* XXX map snode->cursor back to view space */
if (snode) {
cursor[0] = snode->cursor[0] * UI_DPI_FAC;
cursor[1] = snode->cursor[1] * UI_DPI_FAC;
}
-
+
/* in v0 and v3 we put begin/end points */
if (link->fromsock) {
vec[0][0] = link->fromsock->locx;
@@ -3352,7 +3352,7 @@ bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, flo
coord_array[0] + 0, resol, sizeof(float) * 2);
BKE_curve_forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1],
coord_array[0] + 1, resol, sizeof(float) * 2);
-
+
return 1;
}
return 0;
@@ -3595,10 +3595,10 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
{
int th_col1 = TH_WIRE_INNER, th_col2 = TH_WIRE_INNER, th_col3 = TH_WIRE;
-
+
if (link->fromsock == NULL && link->tosock == NULL)
return;
-
+
/* new connection */
if (!link->fromsock || !link->tosock) {
th_col1 = th_col2 = TH_ACTIVE;
@@ -3636,7 +3636,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos)
{
immBegin(GWN_PRIM_LINES, 4);
-
+
if (border & (NODE_LEFT | NODE_RIGHT)) {
immVertex2f(pos, cent[0], v2d->cur.ymin);
immVertex2f(pos, cent[0], v2d->cur.ymax);
@@ -3645,7 +3645,7 @@ void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder
immVertex2f(pos, cent[0], cent[1] - size);
immVertex2f(pos, cent[0], cent[1] + size);
}
-
+
if (border & (NODE_TOP | NODE_BOTTOM)) {
immVertex2f(pos, v2d->cur.xmin, cent[1]);
immVertex2f(pos, v2d->cur.xmax, cent[1]);
@@ -3654,6 +3654,6 @@ void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder
immVertex2f(pos, cent[0] - size, cent[1]);
immVertex2f(pos, cent[0] + size, cent[1]);
}
-
+
immEnd();
}
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 956fea9b44a..0a8cc838ce5 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -70,32 +70,32 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx
SpaceNode *snode = CTX_wm_space_node(C);
Main *bmain = CTX_data_main(C);
bNode *node = NULL;
-
+
node_deselect_all(snode);
-
+
if (idname)
node = nodeAddNode(C, snode->edittree, idname);
else
node = nodeAddStaticNode(C, snode->edittree, type);
BLI_assert(node && node->typeinfo);
-
+
/* generics */
node->locx = locx;
node->locy = locy + 60.0f; /* arbitrary... so its visible, (0,0) is top of node */
nodeSetSelected(node, true);
-
+
node->locx = locx;
node->locy = locy + 60.0f;
-
+
ntreeUpdateTree(bmain, snode->edittree);
ED_node_set_active(bmain, snode->edittree, node);
-
+
snode_update(snode, node);
-
+
if (snode->nodetree->type == NTREE_TEXTURE) {
ntreeTexCheckCyclics(snode->edittree);
}
-
+
return node;
}
@@ -122,7 +122,7 @@ static bool add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int
typedef struct bNodeSocketLink {
struct bNodeSocketLink *next, *prev;
-
+
struct bNodeSocket *sock;
struct bNodeLink *link;
float point[2];
@@ -131,12 +131,12 @@ typedef struct bNodeSocketLink {
static bNodeSocketLink *add_reroute_insert_socket_link(ListBase *lb, bNodeSocket *sock, bNodeLink *link, const float point[2])
{
bNodeSocketLink *socklink, *prev;
-
+
socklink = MEM_callocN(sizeof(bNodeSocketLink), "socket link");
socklink->sock = sock;
socklink->link = link;
copy_v2_v2(socklink->point, point);
-
+
for (prev = lb->last; prev; prev = prev->prev) {
if (prev->sock == sock)
break;
@@ -153,18 +153,18 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi
bNodeSocket *cursock = socklink->sock;
float insert_point[2];
int num_links;
-
+
zero_v2(insert_point);
num_links = 0;
-
+
while (socklink && socklink->sock == cursock) {
if (!(socklink->link->flag & NODE_LINK_TEST)) {
socklink->link->flag |= NODE_LINK_TEST;
-
+
/* create the reroute node for this cursock */
if (!reroute_node) {
reroute_node = nodeAddStaticNode(C, ntree, NODE_REROUTE);
-
+
/* add a single link to/from the reroute node to replace multiple links */
if (in_out == SOCK_OUT) {
nodeAddLink(ntree, socklink->link->fromnode, socklink->link->fromsock, reroute_node, reroute_node->inputs.first);
@@ -173,7 +173,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi
nodeAddLink(ntree, reroute_node, reroute_node->outputs.first, socklink->link->tonode, socklink->link->tosock);
}
}
-
+
/* insert the reroute node into the link */
if (in_out == SOCK_OUT) {
socklink->link->fromnode = reroute_node;
@@ -183,21 +183,21 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi
socklink->link->tonode = reroute_node;
socklink->link->tosock = reroute_node->inputs.first;
}
-
+
add_v2_v2(insert_point, socklink->point);
num_links++;
}
socklink = socklink->next;
}
-
+
if (num_links > 0) {
/* average cut point from shared links */
mul_v2_fl(insert_point, 1.0f / num_links);
-
+
reroute_node->locx = insert_point[0] / UI_DPI_FAC;
reroute_node->locy = insert_point[1] / UI_DPI_FAC;
}
-
+
return socklink;
}
@@ -208,7 +208,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
bNodeTree *ntree = snode->edittree;
float mcoords[256][2];
int i = 0;
-
+
/* Get the cut path */
RNA_BEGIN (op->ptr, itemptr, "path")
{
@@ -227,12 +227,12 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
bNodeLink *link;
bNodeSocketLink *socklink;
float insert_point[2];
-
+
/* always first */
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+
node_deselect_all(snode);
-
+
/* Find cut links and sort them by sockets */
BLI_listbase_clear(&output_links);
BLI_listbase_clear(&input_links);
@@ -243,12 +243,12 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
if (add_reroute_intersect_check(link, mcoords, i, insert_point)) {
add_reroute_insert_socket_link(&output_links, link->fromsock, link, insert_point);
add_reroute_insert_socket_link(&input_links, link->tosock, link, insert_point);
-
+
/* Clear flag */
link->flag &= ~NODE_LINK_TEST;
}
}
-
+
/* Create reroute nodes for intersected links.
* Only one reroute if links share the same input/output socket.
*/
@@ -260,18 +260,18 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
while (socklink) {
socklink = add_reroute_do_socket_section(C, socklink, SOCK_IN);
}
-
+
BLI_freelistN(&output_links);
BLI_freelistN(&input_links);
-
+
/* always last */
ntreeUpdateTree(CTX_data_main(C), ntree);
snode_notify(C, snode);
snode_dag_update(C, snode);
-
+
return OPERATOR_FINISHED;
}
-
+
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
@@ -327,16 +327,16 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
default:
return OPERATOR_CANCELLED;
}
-
+
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]);
-
+
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
return OPERATOR_CANCELLED;
}
-
+
node->id = (ID *)ima;
/* When adding new image file via drag-drop we need to load imbuf in order
@@ -349,7 +349,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
snode_notify(C, snode);
snode_dag_update(C, snode);
-
+
return OPERATOR_FINISHED;
}
@@ -357,11 +357,11 @@ static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *even
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
-
+
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->cursor[0], &snode->cursor[1]);
-
+
if (RNA_struct_property_is_set(op->ptr, "filepath") || RNA_struct_property_is_set(op->ptr, "name"))
return node_add_file_exec(C, op);
else
@@ -461,7 +461,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
const char *idname;
char treename_buf[MAX_ID_NAME - 2];
const char *treename;
-
+
if (RNA_struct_property_is_set(op->ptr, "type")) {
prop = RNA_struct_find_property(op->ptr, "type");
RNA_property_enum_identifier(C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &idname);
@@ -470,7 +470,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
idname = snode->tree_idname;
else
return OPERATOR_CANCELLED;
-
+
if (RNA_struct_property_is_set(op->ptr, "name")) {
RNA_string_get(op->ptr, "name", treename_buf);
treename = treename_buf;
@@ -478,14 +478,14 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
else {
treename = DATA_("NodeTree");
}
-
+
if (!ntreeTypeFind(idname)) {
BKE_reportf(op->reports, RPT_ERROR, "Node tree type %s undefined", idname);
return OPERATOR_CANCELLED;
}
-
+
ntree = ntreeAddTree(bmain, treename, idname);
-
+
/* hook into UI */
UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
@@ -501,10 +501,10 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
}
else if (snode) {
snode->nodetree = ntree;
-
+
ED_node_tree_update(C);
}
-
+
return OPERATOR_FINISHED;
}
@@ -516,18 +516,18 @@ static const EnumPropertyItem *new_node_tree_type_itemf(bContext *UNUSED(C), Poi
void NODE_OT_new_node_tree(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "New Node Tree";
ot->idname = "NODE_OT_new_node_tree";
ot->description = "Create a new node tree";
-
+
/* api callbacks */
ot->exec = new_node_tree_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Tree Type", "");
RNA_def_enum_funcs(prop, new_node_tree_type_itemf);
RNA_def_string(ot->srna, "name", "NodeTree", MAX_ID_NAME - 2, "Name", "");
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index 564176edc7e..0a656ee1deb 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -62,7 +62,7 @@
static int active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt))
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
return (snode && snode->nodetree);
}
#endif
@@ -70,7 +70,7 @@ static int active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt))
static int node_sockets_poll(const bContext *C, PanelType *UNUSED(pt))
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
return (snode && snode->nodetree && G.debug_value == 777);
}
@@ -82,10 +82,10 @@ static void node_sockets_panel(const bContext *C, Panel *pa)
bNodeSocket *sock;
uiLayout *layout = pa->layout, *split;
char name[UI_MAX_NAME_STR];
-
+
if (ELEM(NULL, ntree, node))
return;
-
+
for (sock = node->inputs.first; sock; sock = sock->next) {
BLI_snprintf(name, sizeof(name), "%s:", sock->name);
@@ -98,7 +98,7 @@ static void node_sockets_panel(const bContext *C, Panel *pa)
static int node_tree_interface_poll(const bContext *C, PanelType *UNUSED(pt))
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
return (snode && snode->edittree && (snode->edittree->inputs.first || snode->edittree->outputs.first));
}
@@ -119,7 +119,7 @@ static bool node_tree_find_active_socket(bNodeTree *ntree, bNodeSocket **r_sock,
return true;
}
}
-
+
*r_sock = NULL;
*r_in_out = 0;
return false;
@@ -137,14 +137,14 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa)
if (!ntree)
return;
-
+
RNA_id_pointer_create((ID *)ntree, &ptr);
-
+
node_tree_find_active_socket(ntree, &sock, &in_out);
RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, sock, &sockptr);
-
+
row = uiLayoutRow(layout, false);
-
+
split = uiLayoutRow(row, true);
col = uiLayoutColumn(split, true);
ot = WM_operatortype_find("NODE_OT_tree_socket_add", false);
@@ -153,26 +153,26 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa)
NULL, 0, 0, 0, 0);
uiItemFullO_ptr(col, ot, "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
RNA_enum_set(&opptr, "in_out", SOCK_IN);
-
+
col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("Outputs:"), ICON_NONE);
uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "outputs", &ptr, "outputs", &ptr, "active_output",
NULL, 0, 0, 0, 0);
uiItemFullO_ptr(col, ot, "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
RNA_enum_set(&opptr, "in_out", SOCK_OUT);
-
+
ot = WM_operatortype_find("NODE_OT_tree_socket_move", false);
col = uiLayoutColumn(row, true);
uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
RNA_enum_set(&opptr, "direction", 1);
uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr);
RNA_enum_set(&opptr, "direction", 2);
-
+
if (sock) {
row = uiLayoutRow(layout, true);
uiItemR(row, &sockptr, "name", 0, NULL, ICON_NONE);
uiItemO(row, "", ICON_X, "NODE_OT_tree_socket_remove");
-
+
if (sock->typeinfo->interface_draw) {
uiItemS(layout);
sock->typeinfo->interface_draw((bContext *)C, layout, &sockptr);
@@ -185,7 +185,7 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa)
void node_buttons_register(ARegionType *art)
{
PanelType *pt;
-
+
pt = MEM_callocN(sizeof(PanelType), "spacetype node panel node sockets");
strcpy(pt->idname, "NODE_PT_sockets");
strcpy(pt->label, N_("Sockets"));
@@ -208,7 +208,7 @@ static int node_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = node_has_buttons_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -227,10 +227,10 @@ void NODE_OT_properties(wmOperatorType *ot)
ot->name = "Properties";
ot->description = "Toggle the properties region visibility";
ot->idname = "NODE_OT_properties";
-
+
ot->exec = node_properties_toggle_exec;
ot->poll = node_properties_poll;
-
+
/* flags */
ot->flag = 0;
}
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index c1159ccad73..8089f47bce4 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -100,7 +100,7 @@ static bNodeTree *node_tree_from_ID(ID *id)
{
if (id) {
short idtype = GS(id->name);
-
+
switch (idtype) {
case ID_NT:
return (bNodeTree *)id;
@@ -118,7 +118,7 @@ static bNodeTree *node_tree_from_ID(ID *id)
return ((FreestyleLineStyle *)id)->nodetree;
}
}
-
+
return NULL;
}
@@ -137,7 +137,7 @@ void ED_node_tag_update_id(ID *id)
if (ntree->type == NTREE_SHADER) {
DEG_id_tag_update(id, 0);
-
+
if (GS(id->name) == ID_MA)
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, id);
else if (GS(id->name) == ID_LA)
@@ -165,7 +165,7 @@ void ED_node_tag_update_nodetree(Main *bmain, bNodeTree *ntree, bNode *node)
bool do_tag_update = true;
if (node != NULL) {
- if (!node_connected_to_output(ntree, node)) {
+ if (!node_connected_to_output(bmain, ntree, node)) {
do_tag_update = false;
}
}
@@ -191,7 +191,7 @@ static bool compare_nodes(const bNode *a, const bNode *b)
*/
bool a_select = (a->flag & NODE_SELECT) != 0, b_select = (b->flag & NODE_SELECT) != 0;
bool a_active = (a->flag & NODE_ACTIVE) != 0, b_active = (b->flag & NODE_ACTIVE) != 0;
-
+
/* if one is an ancestor of the other */
/* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */
for (parent = a->parent; parent; parent = parent->parent) {
@@ -220,13 +220,13 @@ static bool compare_nodes(const bNode *a, const bNode *b)
return 0;
else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND))
return 1;
-
+
/* if one has a higher selection state (active > selected > nothing) */
if (!b_active && a_active)
return 1;
else if (!b_select && (a_active || a_select))
return 1;
-
+
return 0;
}
@@ -239,11 +239,11 @@ void ED_node_sort(bNodeTree *ntree)
bNode *first_a, *first_b, *node_a, *node_b, *tmp;
int totnodes = BLI_listbase_count(&ntree->nodes);
int k, a, b;
-
+
k = 1;
while (k < totnodes) {
first_a = first_b = ntree->nodes.first;
-
+
do {
/* setup first_b pointer */
for (b = 0; b < k && first_b; ++b) {
@@ -252,7 +252,7 @@ void ED_node_sort(bNodeTree *ntree)
/* all batches merged? */
if (first_b == NULL)
break;
-
+
/* merge batches */
node_a = first_a;
node_b = first_b;
@@ -281,7 +281,7 @@ void ED_node_sort(bNodeTree *ntree)
}
first_a = first_b;
} while (first_b);
-
+
k = k << 1;
}
}
@@ -300,9 +300,9 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree)
{
bNode *node;
char uiblockstr[32];
-
+
/* add node uiBlocks in drawing order - prevents events going to overlapping nodes */
-
+
for (node = ntree->nodes.first; node; node = node->next) {
/* ui block */
BLI_snprintf(uiblockstr, sizeof(uiblockstr), "node buttons %p", (void *)node);
@@ -344,52 +344,52 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
float locx, locy;
float dy;
int buty;
-
+
RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr);
-
+
/* get "global" coords */
node_to_view(node, 0.0f, 0.0f, &locx, &locy);
dy = locy;
-
+
/* header */
dy -= NODE_DY;
-
+
/* little bit space in top */
if (node->outputs.first)
dy -= NODE_DYS / 2;
-
+
/* output sockets */
bool add_output_space = false;
for (nsock = node->outputs.first; nsock; nsock = nsock->next) {
if (nodeSocketIsHidden(nsock))
continue;
-
+
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr);
-
+
layout = UI_block_layout(
node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_style_get());
/* context pointers for current node and socket */
uiLayoutSetContextPointer(layout, "node", &nodeptr);
uiLayoutSetContextPointer(layout, "socket", &sockptr);
-
+
/* align output buttons to the right */
row = uiLayoutRow(layout, 1);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
-
+
nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name));
-
+
UI_block_align_end(node->block);
UI_block_layout_resolve(node->block, NULL, &buty);
-
+
/* ensure minimum socket height in case layout is empty */
buty = min_ii(buty, dy - NODE_DY);
-
+
nsock->locx = locx + NODE_WIDTH(node);
/* place the socket circle in the middle of the layout */
nsock->locy = 0.5f * (dy + buty);
-
+
dy = buty;
if (nsock->next)
dy -= NODE_SOCKDY;
@@ -407,28 +407,28 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* preview rect? */
if (node->flag & NODE_PREVIEW) {
float aspect = 1.0f;
-
- if (node->preview_xsize && node->preview_ysize)
+
+ if (node->preview_xsize && node->preview_ysize)
aspect = (float)node->preview_ysize / (float)node->preview_xsize;
-
+
dy -= NODE_DYS / 2;
node->prvr.ymax = dy;
-
+
if (aspect <= 1.0f)
node->prvr.ymin = dy - aspect * (NODE_WIDTH(node) - NODE_DY);
else {
/* width correction of image */
/* XXX huh? (ton) */
float dx = (NODE_WIDTH(node) - NODE_DYS) - (NODE_WIDTH(node) - NODE_DYS) / aspect;
-
+
node->prvr.ymin = dy - (NODE_WIDTH(node) - NODE_DY);
-
+
node->prvr.xmin += 0.5f * dx;
node->prvr.xmax -= 0.5f * dx;
}
-
+
dy = node->prvr.ymin - NODE_DYS / 2;
-
+
/* make sure that maximums are bigger or equal to minimums */
if (node->prvr.xmax < node->prvr.xmin) SWAP(float, node->prvr.xmax, node->prvr.xmin);
if (node->prvr.ymax < node->prvr.ymin) SWAP(float, node->prvr.ymax, node->prvr.ymin);
@@ -443,18 +443,18 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
node->butr.xmax = NODE_WIDTH(node) - 2 * NODE_DYS;
node->butr.ymin = 0;
node->butr.ymax = 0;
-
-
+
+
layout = UI_block_layout(
node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
locx + NODE_DYS, dy, node->butr.xmax, 0, 0, UI_style_get());
uiLayoutSetContextPointer(layout, "node", &nodeptr);
-
+
node->typeinfo->draw_buttons(layout, (bContext *)C, &nodeptr);
-
+
UI_block_align_end(node->block);
UI_block_layout_resolve(node->block, NULL, &buty);
-
+
dy = buty - NODE_DYS / 2;
}
@@ -462,35 +462,35 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
for (nsock = node->inputs.first; nsock; nsock = nsock->next) {
if (nodeSocketIsHidden(nsock))
continue;
-
+
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr);
-
+
layout = UI_block_layout(
node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_style_get());
/* context pointers for current node and socket */
uiLayoutSetContextPointer(layout, "node", &nodeptr);
uiLayoutSetContextPointer(layout, "socket", &sockptr);
-
+
row = uiLayoutRow(layout, 1);
-
+
nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name));
-
+
UI_block_align_end(node->block);
UI_block_layout_resolve(node->block, NULL, &buty);
-
+
/* ensure minimum socket height in case layout is empty */
buty = min_ii(buty, dy - NODE_DY);
-
+
nsock->locx = locx;
/* place the socket circle in the middle of the layout */
nsock->locy = 0.5f * (dy + buty);
-
+
dy = buty;
if (nsock->next)
dy -= NODE_SOCKDY;
}
-
+
/* little bit space in end */
if (node->inputs.first || (node->flag & (NODE_OPTIONS | NODE_PREVIEW)) == 0)
dy -= NODE_DYS / 2;
@@ -499,7 +499,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
node->totr.xmax = locx + NODE_WIDTH(node);
node->totr.ymax = locy;
node->totr.ymin = min_ff(dy, locy - 2 * NODE_DY);
-
+
/* Set the block bounds to clip mouse events from underlying nodes.
* Add a margin for sockets on each side.
*/
@@ -518,7 +518,7 @@ static void node_update_hidden(bNode *node)
float locx, locy;
float rad, drad, hiddenrad = HIDDEN_RAD;
int totin = 0, totout = 0, tot;
-
+
/* get "global" coords */
node_to_view(node, 0.0f, 0.0f, &locx, &locy);
@@ -529,20 +529,20 @@ static void node_update_hidden(bNode *node)
for (nsock = node->outputs.first; nsock; nsock = nsock->next)
if (!nodeSocketIsHidden(nsock))
totout++;
-
+
tot = MAX2(totin, totout);
if (tot > 4) {
hiddenrad += 5.0f * (float)(tot - 4);
}
-
+
node->totr.xmin = locx;
node->totr.xmax = locx + 3 * hiddenrad + node->miniwidth;
node->totr.ymax = locy + (hiddenrad - 0.5f * NODE_DY);
node->totr.ymin = node->totr.ymax - 2 * hiddenrad;
-
+
/* output sockets */
rad = drad = (float)M_PI / (1.0f + (float)totout);
-
+
for (nsock = node->outputs.first; nsock; nsock = nsock->next) {
if (!nodeSocketIsHidden(nsock)) {
nsock->locx = node->totr.xmax - hiddenrad + sinf(rad) * hiddenrad;
@@ -550,10 +550,10 @@ static void node_update_hidden(bNode *node)
rad += drad;
}
}
-
+
/* input sockets */
rad = drad = -(float)M_PI / (1.0f + (float)totin);
-
+
for (nsock = node->inputs.first; nsock; nsock = nsock->next) {
if (!nodeSocketIsHidden(nsock)) {
nsock->locx = node->totr.xmin + hiddenrad + sinf(rad) * hiddenrad;
@@ -632,10 +632,10 @@ static void node_socket_circle_draw(const bContext *C, bNodeTree *ntree, Pointer
{
PointerRNA ptr;
float color[4];
-
+
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
sock->typeinfo->draw_color((bContext *)C, &ptr, &node_ptr, color);
-
+
immAttrib4fv(col, color);
immVertex2f(pos, sock->locx, sock->locy);
}
@@ -645,7 +645,7 @@ static void node_socket_circle_draw(const bContext *C, bNodeTree *ntree, Pointer
static void node_draw_preview_background(float tile, rctf *rect)
{
float x, y;
-
+
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -655,7 +655,7 @@ static void node_draw_preview_background(float tile, rctf *rect)
immUniformColor3ub(120, 120, 120);
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
immUniformColor3ub(160, 160, 160);
-
+
for (y = rect->ymin; y < rect->ymax; y += tile * 2) {
for (x = rect->xmin; x < rect->xmax; x += tile * 2) {
float tilex = tile, tiley = tile;
@@ -692,7 +692,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
float yscale = yrect / ((float)preview->ysize);
float scale;
rctf draw_rect;
-
+
/* uniform scale and offset */
draw_rect = *prv;
if (xscale < yscale) {
@@ -707,16 +707,16 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
draw_rect.xmax -= offset;
scale = yscale;
}
-
+
node_draw_preview_background(BLI_rctf_size_x(prv) / 10.0f, &draw_rect);
-
+
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */
-
+
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
immDrawPixelsTex(&state, draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect,
scale, scale, NULL);
-
+
glDisable(GL_BLEND);
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -731,23 +731,23 @@ static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_
{
bNode *node = (bNode *)node_argv;
const char *opname = (const char *)op_argv;
-
+
/* select & activate only the button's node */
node_select_single(C, node);
-
+
WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, NULL);
}
void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
{
rctf *rct = &node->totr;
-
+
UI_draw_roundbox_corner_set(UI_CNR_ALL);
if (node->parent == NULL)
ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT);
else {
const float margin = 3.0f;
-
+
float color[4] = {0.0f, 0.0f, 0.0f, 0.33f};
UI_draw_roundbox_aa(true, rct->xmin - margin, rct->ymin - margin,
rct->xmax + margin, rct->ymax + margin, radius + margin, color);
@@ -802,7 +802,7 @@ void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode *
node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
}
-
+
/* socket outputs */
short selected_output_ct = 0;
if (draw_outputs) {
@@ -878,17 +878,17 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
float color[4];
char showname[128]; /* 128 used below */
View2D *v2d = &ar->v2d;
-
+
/* skip if out of view */
if (BLI_rctf_isect(&node->totr, &v2d->cur, NULL) == false) {
UI_block_end(C, node->block);
node->block = NULL;
return;
}
-
+
/* shadow */
node_draw_shadow(snode, node, BASIS_RAD, 1.0f);
-
+
if (node->flag & NODE_MUTED) {
UI_GetThemeColorBlendShade4fv(color_id, TH_REDALERT, 0.5f, 0, color);
}
@@ -907,10 +907,10 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
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);
-
+
/* show/hide icons */
iconofs = rct->xmax - 0.35f * U.widget_unit;
-
+
/* preview */
if (node->typeinfo->flag & NODE_PREVIEW) {
uiBut *but;
@@ -937,7 +937,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_group_edit");
UI_block_emboss_set(node->block, UI_EMBOSS);
}
-
+
/* title */
if (node->flag & SELECT) {
UI_GetThemeColor4fv(TH_SELECT, color);
@@ -945,7 +945,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
else {
UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color);
}
-
+
/* open/close entirely? */
{
uiBut *but;
@@ -957,16 +957,16 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
but_size, but_size, NULL, 0, 0, 0, 0, "");
UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
UI_block_emboss_set(node->block, UI_EMBOSS);
-
+
/* custom draw function for this button */
UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v', color);
}
-
+
nodeLabel(ntree, node, showname, sizeof(showname));
-
+
//if (node->flag & NODE_MUTED)
// BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */
-
+
uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname,
(int)(rct->xmin + (NODE_MARGIN_X)), (int)(rct->ymax - NODE_DY),
(short)(iconofs - rct->xmin - 18.0f), (short)NODE_DY,
@@ -991,7 +991,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD, color);
}
-
+
/* disable lines */
if (node->flag & NODE_MUTED)
node_draw_mute_line(v2d, snode, node);
@@ -1007,9 +1007,9 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
}
}
}
-
+
UI_ThemeClearColor(color_id);
-
+
UI_block_end(C, node->block);
UI_block_draw(C, node->block);
node->block = NULL;
@@ -1027,7 +1027,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
float scale;
UI_view2d_scale_get(v2d, &scale, NULL);
-
+
/* shadow */
node_draw_shadow(snode, node, hiddenrad, 1.0f);
@@ -1036,9 +1036,9 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
UI_GetThemeColorBlendShade4fv(color_id, TH_REDALERT, 0.5f, 0, color);
else
UI_GetThemeColor4fv(color_id, color);
-
+
UI_draw_roundbox_aa(true, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad, color);
-
+
/* outline active and selected emphasis */
if (node->flag & SELECT) {
UI_GetThemeColorShadeAlpha4fv((node->flag & NODE_ACTIVE) ? TH_ACTIVE : TH_SELECT, 0, -40, color);
@@ -1064,7 +1064,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
else {
UI_GetThemeColorBlendShade4fv(TH_SELECT, color_id, 0.4f, 10, color);
}
-
+
/* open entirely icon */
{
uiBut *but;
@@ -1076,11 +1076,11 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
but_size, but_size, NULL, 0, 0, 0, 0, "");
UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
UI_block_emboss_set(node->block, UI_EMBOSS);
-
+
/* custom draw function for this button */
UI_draw_icon_tri(rct->xmin + 10.0f, centy, 'h', color);
}
-
+
/* disable lines */
if (node->flag & NODE_MUTED)
node_draw_mute_line(&ar->v2d, snode, node);
@@ -1150,7 +1150,7 @@ void node_set_cursor(wmWindow *win, SpaceNode *snode, float cursor[2])
bNode *node;
bNodeSocket *sock;
int wmcursor = CURSOR_STD;
-
+
if (ntree) {
if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN | SOCK_OUT)) {
/* pass */
@@ -1167,7 +1167,7 @@ void node_set_cursor(wmWindow *win, SpaceNode *snode, float cursor[2])
}
}
}
-
+
WM_cursor_set(win, wmcursor);
}
@@ -1188,10 +1188,10 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node)
void node_update_nodetree(const bContext *C, bNodeTree *ntree)
{
bNode *node;
-
+
/* make sure socket "used" tags are correct, for displaying value buttons */
ntreeTagUsedSockets(ntree);
-
+
/* update nodes front to back, so children sizes get updated before parents */
for (node = ntree->nodes.last; node; node = node->prev) {
node_update(C, ntree, node);
@@ -1211,7 +1211,7 @@ void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeT
bNode *node;
bNodeLink *link;
int a;
-
+
if (ntree == NULL) return; /* groups... */
#ifdef USE_DRAW_TOT_UPDATE
@@ -1237,7 +1237,7 @@ void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeT
node->nr = a; /* index of node in list, used for exec event code */
node_draw(C, ar, snode, ntree, node, key);
}
-
+
/* node lines */
glEnable(GL_BLEND);
nodelink_batch_start(snode);
@@ -1247,7 +1247,7 @@ void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeT
}
nodelink_batch_end(snode);
glDisable(GL_BLEND);
-
+
/* draw foreground nodes, last nodes in front */
for (a = 0, node = ntree->nodes.first; node; node = node->next, a++) {
bNodeInstanceKey key;
@@ -1264,9 +1264,9 @@ void node_draw_nodetree(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeT
static void draw_tree_path(SpaceNode *snode)
{
char info[256];
-
+
ED_node_tree_path_get_fixedbuf(snode, info, sizeof(info));
-
+
UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
BLF_draw_default(1.5f * UI_UNIT_X, 1.5f * UI_UNIT_Y, 0.0f, info, sizeof(info));
}
@@ -1274,11 +1274,11 @@ static void draw_tree_path(SpaceNode *snode)
static void snode_setup_v2d(SpaceNode *snode, ARegion *ar, const float center[2])
{
View2D *v2d = &ar->v2d;
-
+
/* shift view to node tree center */
UI_view2d_center_set(v2d, center[0], center[1]);
UI_view2d_view_ortho(v2d);
-
+
/* aspect+font, set each time */
snode->aspect = BLI_rctf_size_x(&v2d->cur) / (float)ar->winx;
// XXX snode->curfont = uiSetCurFont_ext(snode->aspect);
@@ -1309,7 +1309,7 @@ static void draw_group_overlay(const bContext *C, ARegion *ar)
UI_draw_roundbox_corner_set(UI_CNR_NONE);
UI_draw_roundbox_4fv(true, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0, color);
glDisable(GL_BLEND);
-
+
/* set the block bounds to clip mouse events from underlying nodes */
block = UI_block_begin(C, ar, "node tree bounds block", UI_EMBOSS);
UI_block_bounds_set_explicit(block, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
@@ -1328,21 +1328,21 @@ void drawnodespace(const bContext *C, ARegion *ar)
glClear(GL_COLOR_BUFFER_BIT);
UI_view2d_view_ortho(v2d);
-
+
/* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */
UI_view2d_region_to_view(&ar->v2d, win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin,
&snode->cursor[0], &snode->cursor[1]);
snode->cursor[0] /= UI_DPI_FAC;
snode->cursor[1] /= UI_DPI_FAC;
-
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
/* only set once */
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
+
/* nodes */
snode_set_context(C);
-
+
/* draw parent node trees */
if (snode->treepath.last) {
static const int max_depth = 2;
@@ -1352,50 +1352,50 @@ void drawnodespace(const bContext *C, ARegion *ar)
bNodeTree *ntree;
bNodeLinkDrag *nldrag;
LinkData *linkdata;
-
+
path = snode->treepath.last;
-
+
/* update tree path name (drawn in the bottom left) */
ID *name_id = (path->nodetree && path->nodetree != snode->nodetree) ? &path->nodetree->id : snode->id;
if (name_id && UNLIKELY(!STREQ(path->node_name, name_id->name + 2))) {
BLI_strncpy(path->node_name, name_id->name + 2, sizeof(path->node_name));
}
-
+
/* current View2D center, will be set temporarily for parent node trees */
UI_view2d_center_get(v2d, &center[0], &center[1]);
-
+
/* store new view center in path and current edittree */
copy_v2_v2(path->view_center, center);
if (snode->edittree)
copy_v2_v2(snode->edittree->view_center, center);
-
+
depth = 0;
while (path->prev && depth < max_depth) {
path = path->prev;
++depth;
}
-
+
/* parent node trees in the background */
for (curdepth = depth; curdepth > 0; path = path->next, --curdepth) {
ntree = path->nodetree;
if (ntree) {
snode_setup_v2d(snode, ar, path->view_center);
-
+
draw_nodetree(C, ar, ntree, path->parent_key);
-
+
draw_group_overlay(C, ar);
}
}
-
+
/* top-level edit tree */
ntree = path->nodetree;
if (ntree) {
snode_setup_v2d(snode, ar, center);
-
+
/* grid, uses theme color based on node path depth */
UI_view2d_multi_grid_draw(v2d, (depth > 0 ? TH_NODE_GROUP : TH_BACK), ED_node_grid_size(), NODE_GRID_STEPS, 2);
-
+
/* backdrop */
draw_nodespace_back_pix(C, ar, snode, path->parent_key);
@@ -1416,7 +1416,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
draw_nodetree(C, ar, ntree, path->parent_key);
}
-
+
/* temporary links */
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
@@ -1426,7 +1426,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
}
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
-
+
if (snode->flag & SNODE_SHOW_GPENCIL) {
/* draw grease-pencil ('canvas' strokes) */
ED_gpencil_draw_view2d(C, true);
@@ -1435,16 +1435,16 @@ void drawnodespace(const bContext *C, ARegion *ar)
else {
/* default grid */
UI_view2d_multi_grid_draw(v2d, TH_BACK, ED_node_grid_size(), NODE_GRID_STEPS, 2);
-
+
/* backdrop */
draw_nodespace_back_pix(C, ar, snode, NODE_INSTANCE_KEY_NONE);
}
-
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
if (snode->treepath.last) {
if (snode->flag & SNODE_SHOW_GPENCIL) {
/* draw grease-pencil (screen strokes, and also paintbuffer) */
@@ -1454,7 +1454,7 @@ void drawnodespace(const bContext *C, ARegion *ar)
/* tree path info */
draw_tree_path(snode);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, 10, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index a26bdfbf037..69a372c70c4 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -152,7 +152,7 @@ static int compo_get_recalc_flags(const bContext *C)
static int compo_breakjob(void *cjv)
{
CompoJob *cj = cjv;
-
+
/* without G.is_break 'ESC' wont quit - which annoys users */
return (*(cj->stop)
#ifdef USE_ESC_COMPO
@@ -166,7 +166,7 @@ static int compo_breakjob(void *cjv)
static void compo_statsdrawjob(void *cjv, const char *UNUSED(str))
{
CompoJob *cj = cjv;
-
+
*(cj->do_update) = true;
}
@@ -174,7 +174,7 @@ static void compo_statsdrawjob(void *cjv, const char *UNUSED(str))
static void compo_redrawjob(void *cjv)
{
CompoJob *cj = cjv;
-
+
*(cj->do_update) = true;
}
@@ -209,7 +209,7 @@ static void compo_updatejob(void *UNUSED(cjv))
static void compo_progressjob(void *cjv, float progress)
{
CompoJob *cj = cjv;
-
+
*(cj->progress) = progress;
}
@@ -223,7 +223,7 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog
if (scene->use_nodes == false)
return;
-
+
cj->stop = stop;
cj->do_update = do_update;
cj->progress = progress;
@@ -388,7 +388,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
bNodeTree *ntree;
int output_type, shader_type;
float color[4] = { 0.0f, 0.0f, 0.0f, 1.0f }, strength = 1.0f;
-
+
ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
switch (GS(id->name)) {
@@ -435,14 +435,14 @@ void ED_node_shader_default(const bContext *C, ID *id)
printf("ED_node_shader_default called on wrong ID type.\n");
return;
}
-
+
out = nodeAddStaticNode(C, ntree, output_type);
out->locx = 300.0f; out->locy = 300.0f;
-
+
in = nodeAddStaticNode(C, ntree, shader_type);
in->locx = 10.0f; in->locy = 300.0f;
nodeSetActive(ntree, in);
-
+
/* only a link from color to color */
fromsock = in->outputs.first;
tosock = out->inputs.first;
@@ -452,7 +452,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
PointerRNA sockptr;
sock = in->inputs.first;
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr);
-
+
RNA_float_set_array(&sockptr, "default_value", color);
if (strength != 0.0f) {
@@ -460,7 +460,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr);
RNA_float_set(&sockptr, "default_value", strength);
}
-
+
ntreeUpdateTree(CTX_data_main(C), ntree);
}
@@ -470,32 +470,32 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce)
{
bNode *in, *out;
bNodeSocket *fromsock, *tosock;
-
+
/* but lets check it anyway */
if (sce->nodetree) {
if (G.debug & G_DEBUG)
printf("error in composite initialize\n");
return;
}
-
+
sce->nodetree = ntreeAddTree(NULL, "Compositing Nodetree", ntreeType_Composite->idname);
-
+
sce->nodetree->chunksize = 256;
sce->nodetree->edit_quality = NTREE_QUALITY_HIGH;
sce->nodetree->render_quality = NTREE_QUALITY_HIGH;
-
+
out = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_COMPOSITE);
out->locx = 300.0f; out->locy = 400.0f;
-
+
in = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_R_LAYERS);
in->locx = 10.0f; in->locy = 400.0f;
nodeSetActive(sce->nodetree, in);
-
+
/* links from color to color */
fromsock = in->outputs.first;
tosock = out->inputs.first;
nodeAddLink(sce->nodetree, in, fromsock, out, tosock);
-
+
ntreeUpdateTree(CTX_data_main(C), sce->nodetree);
}
@@ -505,27 +505,27 @@ void ED_node_texture_default(const bContext *C, Tex *tx)
{
bNode *in, *out;
bNodeSocket *fromsock, *tosock;
-
+
/* but lets check it anyway */
if (tx->nodetree) {
if (G.debug & G_DEBUG)
printf("error in texture initialize\n");
return;
}
-
+
tx->nodetree = ntreeAddTree(NULL, "Texture Nodetree", ntreeType_Texture->idname);
-
+
out = nodeAddStaticNode(C, tx->nodetree, TEX_NODE_OUTPUT);
out->locx = 300.0f; out->locy = 300.0f;
-
+
in = nodeAddStaticNode(C, tx->nodetree, TEX_NODE_CHECKER);
in->locx = 10.0f; in->locy = 300.0f;
nodeSetActive(tx->nodetree, in);
-
+
fromsock = in->outputs.first;
tosock = out->inputs.first;
nodeAddLink(tx->nodetree, in, fromsock, out, tosock);
-
+
ntreeUpdateTree(CTX_data_main(C), tx->nodetree);
}
@@ -536,7 +536,7 @@ void snode_set_context(const bContext *C)
bNodeTreeType *treetype = ntreeTypeFind(snode->tree_idname);
bNodeTree *ntree = snode->nodetree;
ID *id = snode->id, *from = snode->from;
-
+
/* check the tree type */
if (!treetype ||
(treetype->poll && !treetype->poll(C, treetype)))
@@ -547,25 +547,25 @@ void snode_set_context(const bContext *C)
*/
return;
}
-
+
if (snode->nodetree && !STREQ(snode->nodetree->idname, snode->tree_idname)) {
/* current tree does not match selected type, clear tree path */
ntree = NULL;
id = NULL;
from = NULL;
}
-
+
if (!(snode->flag & SNODE_PIN) || ntree == NULL) {
if (treetype->get_from_context) {
/* reset and update from context */
ntree = NULL;
id = NULL;
from = NULL;
-
+
treetype->get_from_context(C, treetype, &ntree, &id, &from);
}
}
-
+
if (snode->nodetree != ntree || snode->id != id || snode->from != from ||
(snode->treepath.last == NULL && ntree))
{
@@ -576,12 +576,12 @@ void snode_set_context(const bContext *C)
void snode_update(SpaceNode *snode, bNode *node)
{
bNodeTreePath *path;
-
+
/* XXX this only updates nodes in the current node space tree path.
* The function supposedly should update any potential group node linking to changed tree,
* this really requires a working depsgraph ...
*/
-
+
/* update all edited group nodes */
path = snode->treepath.last;
if (path) {
@@ -601,38 +601,38 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
const bool was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE) != 0;
nodeSetActive(ntree, node);
-
+
if (node->type != NODE_GROUP) {
const bool was_output = (node->flag & NODE_DO_OUTPUT) != 0;
bool do_update = false;
-
+
/* generic node group output: set node as active output */
if (node->type == NODE_GROUP_OUTPUT) {
bNode *tnode;
for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
if (tnode->type == NODE_GROUP_OUTPUT)
tnode->flag &= ~NODE_DO_OUTPUT;
-
+
node->flag |= NODE_DO_OUTPUT;
if (!was_output)
do_update = 1;
}
-
+
/* tree specific activate calls */
if (ntree->type == NTREE_SHADER) {
/* when we select a material, active texture is cleared, for buttons */
if (node->id && ELEM(GS(node->id->name), ID_MA, ID_LA, ID_WO))
nodeClearActiveID(ntree, ID_TE);
-
+
if (ELEM(node->type, SH_NODE_OUTPUT_MATERIAL,
SH_NODE_OUTPUT_WORLD, SH_NODE_OUTPUT_LAMP, SH_NODE_OUTPUT_LINESTYLE))
{
bNode *tnode;
-
+
for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
if (tnode->type == node->type)
tnode->flag &= ~NODE_DO_OUTPUT;
-
+
node->flag |= NODE_DO_OUTPUT;
if (was_output == 0)
ED_node_tag_update_nodetree(bmain, ntree, node);
@@ -652,7 +652,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
for (wo = bmain->world.first; wo; wo = wo->id.next)
if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree))
GPU_material_free(&wo->gpumaterial);
-
+
WM_main_add_notifier(NC_IMAGE, NULL);
}
@@ -662,27 +662,27 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
/* make active viewer, currently only 1 supported... */
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
bNode *tnode;
-
+
for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
if (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
tnode->flag &= ~NODE_DO_OUTPUT;
-
+
node->flag |= NODE_DO_OUTPUT;
if (was_output == 0)
ED_node_tag_update_nodetree(bmain, ntree, node);
-
+
/* addnode() doesnt link this yet... */
node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
}
else if (node->type == CMP_NODE_COMPOSITE) {
if (was_output == 0) {
bNode *tnode;
-
+
for (tnode = ntree->nodes.first; tnode; tnode = tnode->next)
if (tnode->type == CMP_NODE_COMPOSITE)
tnode->flag &= ~NODE_DO_OUTPUT;
-
+
node->flag |= NODE_DO_OUTPUT;
ED_node_tag_update_nodetree(bmain, ntree, node);
}
@@ -737,13 +737,13 @@ static int edit_node_invoke_properties(bContext *C, wmOperator *op)
else
RNA_string_set(op->ptr, "node", node->name);
}
-
+
if (!RNA_struct_property_is_set(op->ptr, "in_out"))
RNA_enum_set(op->ptr, "in_out", SOCK_IN);
-
+
if (!RNA_struct_property_is_set(op->ptr, "socket"))
RNA_int_set(op->ptr, "socket", 0);
-
+
return 1;
}
@@ -754,18 +754,18 @@ static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **r
char nodename[MAX_NAME];
int sockindex;
int in_out;
-
+
RNA_string_get(op->ptr, "node", nodename);
node = nodeFindNodebyName(ntree, nodename);
-
+
in_out = RNA_enum_get(op->ptr, "in_out");
-
+
sockindex = RNA_int_get(op->ptr, "socket");
switch (in_out) {
case SOCK_IN: sock = BLI_findlink(&node->inputs, sockindex); break;
case SOCK_OUT: sock = BLI_findlink(&node->outputs, sockindex); break;
}
-
+
if (rnode)
*rnode = node;
if (rsock)
@@ -781,7 +781,7 @@ static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **r
static bNode *visible_node(SpaceNode *snode, const rctf *rct)
{
bNode *node;
-
+
for (node = snode->edittree->nodes.last; node; node = node->prev) {
if (BLI_rctf_isect(&node->totr, rct, NULL))
break;
@@ -803,13 +803,13 @@ typedef struct NodeSizeWidget {
static void node_resize_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(event), bNode *node, int dir)
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
NodeSizeWidget *nsw = MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
-
+
op->customdata = nsw;
nsw->mxstart = snode->cursor[0];
nsw->mystart = snode->cursor[1];
-
+
/* store old */
nsw->oldlocx = node->locx;
nsw->oldlocy = node->locy;
@@ -819,7 +819,7 @@ static void node_resize_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(
nsw->oldheight = node->height;
nsw->oldminiwidth = node->miniwidth;
nsw->directions = dir;
-
+
WM_cursor_modal_set(CTX_wm_window(C), node_get_resize_cursor(dir));
/* add modal handler */
WM_event_add_modal_handler(C, op);
@@ -828,7 +828,7 @@ static void node_resize_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(
static void node_resize_exit(bContext *C, wmOperator *op, bool UNUSED(cancel))
{
WM_cursor_modal_restore(CTX_wm_window(C));
-
+
MEM_freeN(op->customdata);
op->customdata = NULL;
}
@@ -840,14 +840,14 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
bNode *node = nodeGetActive(snode->edittree);
NodeSizeWidget *nsw = op->customdata;
float mx, my, dx, dy;
-
+
switch (event->type) {
case MOUSEMOVE:
-
+
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my);
dx = (mx - nsw->mxstart) / UI_DPI_FAC;
dy = (my - nsw->mystart) / UI_DPI_FAC;
-
+
if (node) {
/* width can use node->width or node->miniwidth (hidden nodes) */
float *pwidth;
@@ -865,7 +865,7 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
widthmin = node->typeinfo->minwidth;
}
widthmax = node->typeinfo->maxwidth;
-
+
{
if (nsw->directions & NODE_RESIZE_RIGHT) {
*pwidth = oldwidth + dx;
@@ -873,20 +873,20 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (nsw->directions & NODE_RESIZE_LEFT) {
float locmax = nsw->oldlocx + oldwidth;
-
+
node->locx = nsw->oldlocx + dx;
CLAMP(node->locx, locmax - widthmax, locmax - widthmin);
*pwidth = locmax - node->locx;
}
}
-
+
/* height works the other way round ... */
{
float heightmin = UI_DPI_FAC * node->typeinfo->minheight;
float heightmax = UI_DPI_FAC * node->typeinfo->maxheight;
if (nsw->directions & NODE_RESIZE_TOP) {
float locmin = nsw->oldlocy - nsw->oldheight;
-
+
node->locy = nsw->oldlocy + dy;
CLAMP(node->locy, locmin + heightmin, locmin + heightmax);
node->height = node->locy - locmin;
@@ -896,7 +896,7 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
CLAMP(node->height, heightmin, heightmax);
}
}
-
+
/* XXX make callback? */
if (node->type == NODE_FRAME) {
/* keep the offset symmetric around center point */
@@ -918,21 +918,21 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
}
-
+
ED_region_tag_redraw(ar);
break;
-
+
case LEFTMOUSE:
case MIDDLEMOUSE:
case RIGHTMOUSE:
-
+
node_resize_exit(C, op, false);
ED_node_post_apply_transform(C, snode->edittree);
-
+
return OPERATOR_FINISHED;
}
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -942,7 +942,7 @@ static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ARegion *ar = CTX_wm_region(C);
bNode *node = nodeGetActive(snode->edittree);
int dir;
-
+
if (node) {
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
@@ -967,13 +967,13 @@ void NODE_OT_resize(wmOperatorType *ot)
ot->name = "Resize Node";
ot->idname = "NODE_OT_resize";
ot->description = "Resize a node";
-
+
/* api callbacks */
ot->invoke = node_resize_invoke;
ot->modal = node_resize_modal;
ot->poll = ED_operator_node_active;
ot->cancel = node_resize_cancel;
-
+
/* flags */
ot->flag = OPTYPE_BLOCKING;
}
@@ -984,7 +984,7 @@ void NODE_OT_resize(wmOperatorType *ot)
int node_has_hidden_sockets(bNode *node)
{
bNodeSocket *sock;
-
+
for (sock = node->inputs.first; sock; sock = sock->next)
if (sock->flag & SOCK_HIDDEN)
return 1;
@@ -1025,10 +1025,10 @@ int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **so
bNode *node;
bNodeSocket *sock;
rctf rect;
-
+
*nodep = NULL;
*sockp = NULL;
-
+
/* check if we click in a socket */
for (node = snode->edittree->nodes.first; node; node = node->next) {
@@ -1045,7 +1045,7 @@ int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **so
rect.xmin -= NODE_SOCKSIZE;
}
}
-
+
if (in_out & SOCK_IN) {
for (sock = node->inputs.first; sock; sock = sock->next) {
if (!nodeSocketIsHidden(sock)) {
@@ -1073,7 +1073,7 @@ int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **so
}
}
}
-
+
return 0;
}
@@ -1082,9 +1082,9 @@ int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **so
static void node_duplicate_reparent_recursive(bNode *node)
{
bNode *parent;
-
+
node->flag |= NODE_TEST;
-
+
/* find first selected parent */
for (parent = node->parent; parent; parent = parent->parent) {
if (parent->flag & SELECT) {
@@ -1102,6 +1102,7 @@ static void node_duplicate_reparent_recursive(bNode *node)
static int node_duplicate_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNode *node, *newnode, *lastnode;
@@ -1109,13 +1110,13 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
bool do_tag_update = false;
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
+
lastnode = ntree->nodes.last;
for (node = ntree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
newnode = nodeCopyNode(ntree, node);
-
+
if (newnode->id) {
/* simple id user adjustment, node internal functions don't touch this
* but operators and readfile.c do. */
@@ -1124,12 +1125,12 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
ED_node_tag_update_id(snode->id);
}
}
-
+
/* make sure we don't copy new nodes again! */
if (node == lastnode)
break;
}
-
+
/* copy links between selected nodes
* NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
*/
@@ -1154,15 +1155,15 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
newlink->fromnode = link->fromnode;
newlink->fromsock = link->fromsock;
}
-
+
BLI_addtail(&ntree->links, newlink);
}
-
+
/* make sure we don't copy new links again! */
if (link == lastlink)
break;
}
-
+
/* clear flags for recursive depth-first iteration */
for (node = ntree->nodes.first; node; node = node->next)
node->flag &= ~NODE_TEST;
@@ -1170,32 +1171,32 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
for (node = ntree->nodes.first; node; node = node->next) {
if ((node->flag & SELECT) && !(node->flag & NODE_TEST))
node_duplicate_reparent_recursive(node);
-
+
/* only has to check old nodes */
if (node == lastnode)
break;
}
-
+
/* deselect old nodes, select the copies instead */
for (node = ntree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
/* has been set during copy above */
newnode = node->new_node;
-
+
nodeSetSelected(node, false);
node->flag &= ~NODE_ACTIVE;
nodeSetSelected(newnode, true);
- do_tag_update |= (do_tag_update || node_connected_to_output(ntree, newnode));
+ do_tag_update |= (do_tag_update || node_connected_to_output(bmain, ntree, newnode));
}
-
+
/* make sure we don't copy new nodes again! */
if (node == lastnode)
break;
}
-
+
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
-
+
snode_notify(C, snode);
if (do_tag_update) {
snode_dag_update(C, snode);
@@ -1210,14 +1211,14 @@ void NODE_OT_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Nodes";
ot->description = "Duplicate selected nodes";
ot->idname = "NODE_OT_duplicate";
-
+
/* api callbacks */
ot->exec = node_duplicate_exec;
ot->poll = ED_operator_node_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "keep_inputs", 0, "Keep Inputs", "Keep the input links to duplicated nodes");
}
@@ -1264,7 +1265,7 @@ static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
}
}
}
-
+
snode_notify(C, snode);
snode_dag_update(C, snode);
@@ -1273,15 +1274,15 @@ static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
void NODE_OT_read_viewlayers(wmOperatorType *ot)
{
-
+
ot->name = "Read View Layers";
ot->idname = "NODE_OT_read_viewlayers";
ot->description = "Read all render layers of all used scenes";
-
+
ot->exec = node_read_viewlayers_exec;
-
+
ot->poll = composite_node_active;
-
+
/* flags */
ot->flag = 0;
}
@@ -1290,7 +1291,7 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *sce = CTX_data_scene(C);
bNode *node;
-
+
for (node = sce->nodetree->nodes.first; node; node = node->next) {
if (node->id == (ID *)sce && node->need_exec) {
break;
@@ -1298,21 +1299,21 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
}
if (node) {
ViewLayer *view_layer = BLI_findlink(&sce->view_layers, node->custom1);
-
+
if (view_layer) {
PointerRNA op_ptr;
-
+
WM_operator_properties_create(&op_ptr, "RENDER_OT_render");
RNA_string_set(&op_ptr, "layer", view_layer->name);
RNA_string_set(&op_ptr, "scene", sce->id.name + 2);
-
+
/* to keep keypositions */
sce->r.scemode |= R_NO_FRAME_UPDATE;
-
+
WM_operator_name_call(C, "RENDER_OT_render", WM_OP_INVOKE_DEFAULT, &op_ptr);
WM_operator_properties_free(&op_ptr);
-
+
return OPERATOR_FINISHED;
}
}
@@ -1324,11 +1325,11 @@ void NODE_OT_render_changed(wmOperatorType *ot)
ot->name = "Render Changed Layer";
ot->idname = "NODE_OT_render_changed";
ot->description = "Render current scene, when input node's layer has been changed";
-
+
ot->exec = node_render_changed_exec;
-
+
ot->poll = composite_node_active;
-
+
/* flags */
ot->flag = 0;
}
@@ -1347,12 +1348,12 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
*/
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
-
+
if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0)
continue;
if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->draw_buttons || node->typeinfo->draw_buttons_ex))
continue;
-
+
if (node->flag & toggle_flag)
tot_eq++;
else
@@ -1361,12 +1362,12 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
}
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
-
+
if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0)
continue;
if (toggle_flag == NODE_OPTIONS && !(node->typeinfo->draw_buttons || node->typeinfo->draw_buttons_ex))
continue;
-
+
if ((tot_eq && tot_neq) || tot_eq == 0)
node->flag |= toggle_flag;
else
@@ -1378,11 +1379,11 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
/* sanity checking (poll callback checks this already) */
if ((snode == NULL) || (snode->edittree == NULL))
return OPERATOR_CANCELLED;
-
+
node_flag_toggle_exec(snode, NODE_HIDDEN);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
@@ -1396,7 +1397,7 @@ void NODE_OT_hide_toggle(wmOperatorType *ot)
ot->name = "Hide";
ot->description = "Toggle hiding of selected nodes";
ot->idname = "NODE_OT_hide_toggle";
-
+
/* callbacks */
ot->exec = node_hide_toggle_exec;
ot->poll = ED_operator_node_active;
@@ -1489,7 +1490,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
}
}
}
-
+
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
node_set_hidden_sockets(snode, node, !hidden);
@@ -1522,26 +1523,27 @@ void NODE_OT_hide_socket_toggle(wmOperatorType *ot)
static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node;
bool do_tag_update = false;
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
for (node = snode->edittree->nodes.first; node; node = node->next) {
/* Only allow muting of nodes having a mute func! */
if ((node->flag & SELECT) && node->typeinfo->update_internal_links) {
node->flag ^= NODE_MUTED;
snode_update(snode, node);
- do_tag_update |= (do_tag_update || node_connected_to_output(snode->edittree, node));
+ do_tag_update |= (do_tag_update || node_connected_to_output(bmain, snode->edittree, node));
}
}
-
+
snode_notify(C, snode);
if (do_tag_update) {
snode_dag_update(C, snode);
}
-
+
return OPERATOR_FINISHED;
}
@@ -1551,11 +1553,11 @@ void NODE_OT_mute_toggle(wmOperatorType *ot)
ot->name = "Toggle Node Mute";
ot->description = "Toggle muting of the nodes";
ot->idname = "NODE_OT_mute_toggle";
-
+
/* callbacks */
ot->exec = node_mute_exec;
ot->poll = ED_operator_node_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1564,30 +1566,31 @@ void NODE_OT_mute_toggle(wmOperatorType *ot)
static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node, *next;
bool do_tag_update = false;
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
for (node = snode->edittree->nodes.first; node; node = next) {
next = node->next;
if (node->flag & SELECT) {
/* check id user here, nodeFreeNode is called for free dbase too */
- do_tag_update |= (do_tag_update || node_connected_to_output(snode->edittree, node));
+ do_tag_update |= (do_tag_update || node_connected_to_output(bmain, snode->edittree, node));
if (node->id)
id_us_min(node->id);
nodeFreeNode(snode->edittree, node);
}
}
-
+
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
snode_notify(C, snode);
if (do_tag_update) {
snode_dag_update(C, snode);
}
-
+
return OPERATOR_FINISHED;
}
@@ -1597,11 +1600,11 @@ void NODE_OT_delete(wmOperatorType *ot)
ot->name = "Delete";
ot->description = "Delete selected nodes";
ot->idname = "NODE_OT_delete";
-
+
/* api callbacks */
ot->exec = node_delete_exec;
ot->poll = ED_operator_node_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1666,7 +1669,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
next = node->next;
if (node->flag & SELECT) {
nodeInternalRelink(snode->edittree, node);
-
+
/* check id user here, nodeFreeNode is called for free dbase too */
if (node->id)
id_us_min(node->id);
@@ -1754,7 +1757,7 @@ static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *U
PointerRNA ptr = CTX_data_pointer_get(C, "node");
bNodeTree *ntree = NULL;
bNode *node = NULL;
-
+
if (ptr.data) {
node = ptr.data;
ntree = ptr.id.data;
@@ -1766,12 +1769,12 @@ static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *U
if (!node || node->type != CMP_NODE_OUTPUT_FILE)
return OPERATOR_CANCELLED;
-
+
if (!ntreeCompositOutputFileRemoveActiveSocket(ntree, node))
return OPERATOR_CANCELLED;
-
+
snode_notify(C, snode);
-
+
return OPERATOR_FINISHED;
}
@@ -1781,11 +1784,11 @@ void NODE_OT_output_file_remove_active_socket(wmOperatorType *ot)
ot->name = "Remove File Node Socket";
ot->description = "Remove active input from a file output node";
ot->idname = "NODE_OT_output_file_remove_active_socket";
-
+
/* callbacks */
ot->exec = node_output_file_remove_active_socket_exec;
ot->poll = composite_node_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1800,7 +1803,7 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
NodeImageMultiFile *nimf;
bNodeSocket *sock;
int direction;
-
+
if (ptr.data)
node = ptr.data;
else if (snode && snode->edittree)
@@ -1810,13 +1813,13 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
nimf = node->storage;
-
+
sock = BLI_findlink(&node->inputs, nimf->active_input);
if (!sock)
return OPERATOR_CANCELLED;
-
+
direction = RNA_enum_get(op->ptr, "direction");
-
+
if (direction == 1) {
bNodeSocket *before = sock->prev;
if (!before)
@@ -1833,9 +1836,9 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
BLI_insertlinkafter(&node->inputs, after, sock);
nimf->active_input++;
}
-
+
snode_notify(C, snode);
-
+
return OPERATOR_FINISHED;
}
@@ -1846,19 +1849,19 @@ void NODE_OT_output_file_move_active_socket(wmOperatorType *ot)
{2, "DOWN", 0, "Down", ""},
{ 0, NULL, 0, NULL, NULL }
};
-
+
/* identifiers */
ot->name = "Move File Node Socket";
ot->description = "Move the active input of a file output node up or down the list";
ot->idname = "NODE_OT_output_file_move_active_socket";
-
+
/* callbacks */
ot->exec = node_output_file_move_active_socket_exec;
ot->poll = composite_node_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_enum(ot->srna, "direction", direction_items, 2, "Direction", "");
}
@@ -1869,13 +1872,13 @@ static int node_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNode *node, *tnode;
-
+
if (!ntree)
return OPERATOR_CANCELLED;
node = nodeGetActive(ntree);
if (!node)
return OPERATOR_CANCELLED;
-
+
for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) {
if (tnode->flag & NODE_SELECT && tnode != node) {
if (node->flag & NODE_CUSTOM_COLOR) {
@@ -1934,7 +1937,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
for (node = ntree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
bNode *new_node = node->new_node;
-
+
/* ensure valid pointers */
if (new_node->parent) {
/* parent pointer must be redirected to new node or detached if parent is not copied */
@@ -2053,7 +2056,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
/* pasted nodes are selected */
nodeSetSelected(new_node, true);
}
-
+
/* reparent copied nodes */
for (node = clipboard_nodes_lb->first; node; node = node->next) {
bNode *new_node = node->new_node;
@@ -2108,9 +2111,9 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
PointerRNA ntree_ptr;
bNodeSocket *sock, *tsock, *active_sock;
const char *default_name;
-
+
RNA_id_pointer_create((ID *)ntree, &ntree_ptr);
-
+
if (in_out == SOCK_IN) {
active_sock = ntree_get_active_interface_socket(&ntree->inputs);
default_name = "Input";
@@ -2119,7 +2122,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
active_sock = ntree_get_active_interface_socket(&ntree->outputs);
default_name = "Output";
}
-
+
if (active_sock) {
/* insert a copy of the active socket right after it */
sock = ntreeInsertSocketInterface(ntree, in_out, active_sock->idname, active_sock->next, active_sock->name);
@@ -2130,7 +2133,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
/* XXX TODO define default socket type for a tree! */
sock = ntreeAddSocketInterface(ntree, in_out, "NodeSocketFloat", default_name);
}
-
+
/* deactivate sockets (has to check both lists) */
for (tsock = ntree->inputs.first; tsock; tsock = tsock->next)
tsock->flag &= ~SELECT;
@@ -2138,11 +2141,11 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
tsock->flag &= ~SELECT;
/* make the new socket active */
sock->flag |= SELECT;
-
+
ntreeUpdateTree(CTX_data_main(C), ntree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2152,14 +2155,14 @@ void NODE_OT_tree_socket_add(wmOperatorType *ot)
ot->name = "Add Node Tree Interface Socket";
ot->description = "Add an input or output socket to the current node tree";
ot->idname = "NODE_OT_tree_socket_add";
-
+
/* api callbacks */
ot->exec = ntree_socket_add_exec;
ot->poll = ED_operator_node_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", "");
}
@@ -2170,25 +2173,25 @@ static int ntree_socket_remove_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNodeSocket *iosock, *active_sock;
-
+
iosock = ntree_get_active_interface_socket(&ntree->inputs);
if (!iosock)
iosock = ntree_get_active_interface_socket(&ntree->outputs);
if (!iosock)
return OPERATOR_CANCELLED;
-
+
/* preferably next socket becomes active, otherwise try previous socket */
active_sock = (iosock->next ? iosock->next : iosock->prev);
ntreeRemoveSocketInterface(ntree, iosock);
-
+
/* set active socket */
if (active_sock)
active_sock->flag |= SELECT;
-
+
ntreeUpdateTree(CTX_data_main(C), ntree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2198,11 +2201,11 @@ void NODE_OT_tree_socket_remove(wmOperatorType *ot)
ot->name = "Remove Node Tree Interface Socket";
ot->description = "Remove an input or output socket to the current node tree";
ot->idname = "NODE_OT_tree_socket_remove";
-
+
/* api callbacks */
ot->exec = ntree_socket_remove_exec;
ot->poll = ED_operator_node_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2222,7 +2225,7 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op)
int direction = RNA_enum_get(op->ptr, "direction");
bNodeSocket *iosock;
ListBase *lb;
-
+
lb = &ntree->inputs;
iosock = ntree_get_active_interface_socket(lb);
if (!iosock) {
@@ -2231,7 +2234,7 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op)
}
if (!iosock)
return OPERATOR_CANCELLED;
-
+
switch (direction) {
case 1:
{ /* up */
@@ -2254,11 +2257,11 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op)
break;
}
}
-
+
ntreeUpdateTree(CTX_data_main(C), ntree);
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2268,14 +2271,14 @@ void NODE_OT_tree_socket_move(wmOperatorType *ot)
ot->name = "Move Node Tree Socket";
ot->description = "Move a socket up or down in the current node tree's sockets stack";
ot->idname = "NODE_OT_tree_socket_move";
-
+
/* api callbacks */
ot->exec = ntree_socket_move_exec;
ot->poll = ED_operator_node_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_enum(ot->srna, "direction", move_direction_items, 1, "Direction", "");
}
@@ -2322,9 +2325,9 @@ static bool node_shader_script_update_text_recursive(RenderEngine *engine, Rende
{
bool found = false;
bNode *node;
-
+
ntree->done = true;
-
+
/* update each script that is using this text datablock */
for (node = ntree->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP) {
@@ -2337,7 +2340,7 @@ static bool node_shader_script_update_text_recursive(RenderEngine *engine, Rende
found = true;
}
}
-
+
return found;
}
@@ -2384,7 +2387,7 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op)
if (ntree->type == NTREE_SHADER)
ntree->done = false;
} FOREACH_NODETREE_END
-
+
FOREACH_NODETREE(bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
if (!ntree->done)
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 7eaf35c6c4f..5d326a0be38 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -69,7 +69,7 @@ static int node_group_operator_active(bContext *C)
{
if (ED_operator_node_active(C)) {
SpaceNode *snode = CTX_wm_space_node(C);
-
+
/* Group operators only defined for standard node tree types.
* Disabled otherwise to allow pynodes define their own operators
* with same keymap.
@@ -88,7 +88,7 @@ static int node_group_operator_editable(bContext *C)
{
if (ED_operator_node_editable(C)) {
SpaceNode *snode = CTX_wm_space_node(C);
-
+
/* Group operators only defined for standard node tree types.
* Disabled otherwise to allow pynodes define their own operators
* with same keymap.
@@ -112,14 +112,14 @@ static const char *group_ntree_idname(bContext *C)
static const char *group_node_idname(bContext *C)
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
if (ED_node_is_shader(snode))
return "ShaderNodeGroup";
else if (ED_node_is_compositor(snode))
return "CompositorNodeGroup";
else if (ED_node_is_texture(snode))
return "TextureNodeGroup";
-
+
return "";
}
@@ -127,7 +127,7 @@ static bNode *node_group_get_active(bContext *C, const char *node_idname)
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node = nodeGetActive(snode->edittree);
-
+
if (node && STREQ(node->idname, node_idname))
return node;
else
@@ -142,22 +142,22 @@ static int node_group_edit_exec(bContext *C, wmOperator *op)
const char *node_idname = group_node_idname(C);
bNode *gnode;
const bool exit = RNA_boolean_get(op->ptr, "exit");
-
+
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+
gnode = node_group_get_active(C, node_idname);
-
+
if (gnode && !exit) {
bNodeTree *ngroup = (bNodeTree *)gnode->id;
-
+
if (ngroup)
ED_node_tree_push(snode, ngroup, gnode);
}
else
ED_node_tree_pop(snode);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -167,45 +167,45 @@ void NODE_OT_group_edit(wmOperatorType *ot)
ot->name = "Edit Group";
ot->description = "Edit node group";
ot->idname = "NODE_OT_group_edit";
-
+
/* api callbacks */
ot->exec = node_group_edit_exec;
ot->poll = node_group_operator_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "exit", false, "Exit", "");
}
/* ******************** Ungroup operator ********************** */
/* returns 1 if its OK */
-static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
+static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
{
bNodeLink *link, *linkn, *tlink;
bNode *node, *nextnode;
bNodeTree *ngroup, *wgroup;
ListBase anim_basepaths = {NULL, NULL};
LinkNode *nodes_delayed_free = NULL;
-
+
ngroup = (bNodeTree *)gnode->id;
-
+
/* clear new pointers, set in copytree */
for (node = ntree->nodes.first; node; node = node->next)
node->new_node = NULL;
-
+
/* wgroup is a temporary copy of the NodeTree we're merging in
* - all of wgroup's nodes are transferred across to their new home
* - ngroup (i.e. the source NodeTree) is left unscathed
* - temp copy. don't change ID usercount
*/
- wgroup = ntreeCopyTree_ex(ngroup, G.main, false);
-
+ wgroup = ntreeCopyTree_ex(ngroup, bmain, false);
+
/* Add the nodes into the ntree */
for (node = wgroup->nodes.first; node; node = nextnode) {
nextnode = node->next;
-
+
/* Remove interface nodes.
* This also removes remaining links to and from interface nodes.
*/
@@ -213,43 +213,43 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
/* We must delay removal since sockets will reference this node. see: T52092 */
BLI_linklist_prepend(&nodes_delayed_free, node);
}
-
- /* keep track of this node's RNA "base" path (the part of the path identifying the node)
+
+ /* keep track of this node's RNA "base" path (the part of the path identifying the node)
* if the old nodetree has animation data which potentially covers this node
*/
if (wgroup->adt) {
PointerRNA ptr;
char *path;
-
+
RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
path = RNA_path_from_ID_to_struct(&ptr);
-
+
if (path)
BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
}
-
+
/* migrate node */
BLI_remlink(&wgroup->nodes, node);
BLI_addtail(&ntree->nodes, node);
-
+
/* ensure unique node name in the node tree */
nodeUniqueName(ntree, node);
-
+
if (!node->parent) {
node->locx += gnode->locx;
node->locy += gnode->locy;
}
-
+
node->flag |= NODE_SELECT;
}
-
+
/* Add internal links to the ntree */
for (link = wgroup->links.first; link; link = linkn) {
linkn = link->next;
BLI_remlink(&wgroup->links, link);
BLI_addtail(&ntree->links, link);
}
-
+
/* and copy across the animation,
* note that the animation data's action can be NULL here */
if (wgroup->adt) {
@@ -257,40 +257,40 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
bAction *waction;
/* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
- waction = wgroup->adt->action = BKE_action_copy(G.main, wgroup->adt->action);
-
+ waction = wgroup->adt->action = BKE_action_copy(bmain, wgroup->adt->action);
+
/* now perform the moving */
BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
-
+
/* paths + their wrappers need to be freed */
for (ld = anim_basepaths.first; ld; ld = ldn) {
ldn = ld->next;
-
+
MEM_freeN(ld->data);
BLI_freelinkN(&anim_basepaths, ld);
}
-
+
/* free temp action too */
if (waction) {
- BKE_libblock_free(G.main, waction);
+ BKE_libblock_free(bmain, waction);
wgroup->adt->action = NULL;
}
}
-
+
/* free the group tree (takes care of user count) */
- BKE_libblock_free(G.main, wgroup);
-
+ BKE_libblock_free(bmain, wgroup);
+
/* restore external links to and from the gnode */
/* note: the nodes have been copied to intermediate wgroup first (so need to use new_node),
* then transferred to ntree (new_node pointers remain valid).
*/
-
+
/* input links */
for (link = ngroup->links.first; link; link = link->next) {
if (link->fromnode->type == NODE_GROUP_INPUT) {
const char *identifier = link->fromsock->identifier;
int num_external_links = 0;
-
+
/* find external links to this input */
for (tlink = ntree->links.first; tlink; tlink = tlink->next) {
if (tlink->tonode == gnode && STREQ(tlink->tosock->identifier, identifier)) {
@@ -298,24 +298,24 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
++num_external_links;
}
}
-
+
/* if group output is not externally linked,
* convert the constant input value to ensure somewhat consistent behavior */
if (num_external_links == 0) {
/* XXX TODO bNodeSocket *sock = node_group_find_input_socket(gnode, identifier);
BLI_assert(sock);*/
-
+
/* XXX TODO nodeSocketCopy(ntree, link->tosock->new_sock, link->tonode->new_node, ntree, sock, gnode);*/
}
}
}
-
+
/* output links */
for (link = ntree->links.first; link; link = link->next) {
if (link->fromnode == gnode) {
const char *identifier = link->fromsock->identifier;
int num_internal_links = 0;
-
+
/* find internal links to this output */
for (tlink = ngroup->links.first; tlink; tlink = tlink->next) {
/* only use active output node */
@@ -326,18 +326,18 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
}
}
}
-
+
/* if group output is not internally linked,
* convert the constant output value to ensure somewhat consistent behavior */
if (num_internal_links == 0) {
/* XXX TODO bNodeSocket *sock = node_group_find_output_socket(gnode, identifier);
BLI_assert(sock);*/
-
+
/* XXX TODO nodeSocketCopy(ntree, link->tosock, link->tonode, ntree, sock, gnode); */
}
}
}
-
+
while (nodes_delayed_free) {
node = BLI_linklist_pop(&nodes_delayed_free);
nodeFreeNode(ntree, node);
@@ -345,27 +345,28 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
/* delete the group instance */
nodeFreeNode(ntree, gnode);
-
+
ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
-
+
return 1;
}
static int node_group_ungroup_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
const char *node_idname = group_node_idname(C);
bNode *gnode;
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
gnode = node_group_get_active(C, node_idname);
if (!gnode)
return OPERATOR_CANCELLED;
-
- if (gnode->id && node_group_ungroup(snode->edittree, gnode)) {
- ntreeUpdateTree(CTX_data_main(C), snode->nodetree);
+
+ if (gnode->id && node_group_ungroup(bmain, snode->edittree, gnode)) {
+ ntreeUpdateTree(bmain, snode->nodetree);
}
else {
BKE_report(op->reports, RPT_WARNING, "Cannot ungroup");
@@ -384,11 +385,11 @@ void NODE_OT_group_ungroup(wmOperatorType *ot)
ot->name = "Ungroup";
ot->description = "Ungroup selected nodes";
ot->idname = "NODE_OT_group_ungroup";
-
+
/* api callbacks */
ot->exec = node_group_ungroup_exec;
ot->poll = node_group_operator_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -401,27 +402,27 @@ static int node_group_separate_selected(bNodeTree *ntree, bNodeTree *ngroup, flo
bNodeLink *link, *link_next;
bNode *node, *node_next, *newnode;
ListBase anim_basepaths = {NULL, NULL};
-
+
/* deselect all nodes in the target tree */
for (node = ntree->nodes.first; node; node = node->next)
nodeSetSelected(node, false);
-
+
/* clear new pointers, set in nodeCopyNode */
for (node = ngroup->nodes.first; node; node = node->next)
node->new_node = NULL;
-
+
/* add selected nodes into the ntree */
for (node = ngroup->nodes.first; node; node = node_next) {
node_next = node->next;
if (!(node->flag & NODE_SELECT))
continue;
-
+
/* ignore interface nodes */
if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
nodeSetSelected(node, false);
continue;
}
-
+
if (make_copy) {
/* make a copy */
newnode = nodeCopyNode(ngroup, node);
@@ -430,44 +431,44 @@ static int node_group_separate_selected(bNodeTree *ntree, bNodeTree *ngroup, flo
/* use the existing node */
newnode = node;
}
-
- /* keep track of this node's RNA "base" path (the part of the path identifying the node)
+
+ /* keep track of this node's RNA "base" path (the part of the path identifying the node)
* if the old nodetree has animation data which potentially covers this node
*/
if (ngroup->adt) {
PointerRNA ptr;
char *path;
-
+
RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr);
path = RNA_path_from_ID_to_struct(&ptr);
-
+
if (path)
BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
}
-
+
/* ensure valid parent pointers, detach if parent stays inside the group */
if (newnode->parent && !(newnode->parent->flag & NODE_SELECT))
nodeDetachNode(newnode);
-
+
/* migrate node */
BLI_remlink(&ngroup->nodes, newnode);
BLI_addtail(&ntree->nodes, newnode);
-
+
/* ensure unique node name in the node tree */
nodeUniqueName(ntree, newnode);
if (!newnode->parent) {
newnode->locx += offx;
- newnode->locy += offy;
+ newnode->locy += offy;
}
}
-
+
/* add internal links to the ntree */
for (link = ngroup->links.first; link; link = link_next) {
const bool fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT));
const bool toselect = (link->tonode && (link->tonode->flag & NODE_SELECT));
link_next = link->next;
-
+
if (make_copy) {
/* make a copy of internal links */
if (fromselect && toselect)
@@ -484,28 +485,28 @@ static int node_group_separate_selected(bNodeTree *ntree, bNodeTree *ngroup, flo
}
}
}
-
+
/* and copy across the animation,
* note that the animation data's action can be NULL here */
if (ngroup->adt) {
LinkData *ld, *ldn = NULL;
-
+
/* now perform the moving */
BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths);
-
+
/* paths + their wrappers need to be freed */
for (ld = anim_basepaths.first; ld; ld = ldn) {
ldn = ld->next;
-
+
MEM_freeN(ld->data);
BLI_freelinkN(&anim_basepaths, ld);
}
}
-
+
ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
if (!make_copy)
ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
-
+
return 1;
}
@@ -539,7 +540,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
}
/* get node tree offset */
snode_group_offset(snode, &offx, &offy);
-
+
switch (type) {
case NODE_GS_COPY:
if (!node_group_separate_selected(nparent, ngroup, offx, offy, 1)) {
@@ -554,12 +555,12 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
}
break;
}
-
+
/* switch to parent tree */
ED_node_tree_pop(snode);
-
+
ntreeUpdateTree(CTX_data_main(C), snode->nodetree);
-
+
snode_notify(C, snode);
snode_dag_update(C, snode);
@@ -570,13 +571,13 @@ static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), const
{
uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE);
uiLayout *layout = UI_popup_menu_layout(pup);
-
+
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY);
uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE);
-
+
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -586,15 +587,15 @@ void NODE_OT_group_separate(wmOperatorType *ot)
ot->name = "Separate";
ot->description = "Separate selected nodes from the node group";
ot->idname = "NODE_OT_group_separate";
-
+
/* api callbacks */
ot->invoke = node_group_separate_invoke;
ot->exec = node_group_separate_exec;
ot->poll = node_group_operator_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", "");
}
@@ -613,10 +614,10 @@ static bool node_group_make_test_selected(bNodeTree *ntree, bNode *gnode, const
bNode *node;
bNodeLink *link;
int ok = true;
-
+
/* make a local pseudo node tree to pass to the node poll functions */
ngroup = ntreeAddTree(NULL, "Pseudo Node Group", ntree_idname);
-
+
/* check poll functions for selected nodes */
for (node = ntree->nodes.first; node; node = node->next) {
if (node_group_make_use_node(node, gnode)) {
@@ -629,13 +630,13 @@ static bool node_group_make_test_selected(bNodeTree *ntree, bNode *gnode, const
node->done = 0;
}
-
+
/* free local pseudo node tree again */
ntreeFreeTree(ngroup);
MEM_freeN(ngroup);
if (!ok)
return false;
-
+
/* check if all connections are OK, no unselected node has both
* inputs and outputs to a selection */
for (link = ntree->links.first; link; link = link->next) {
@@ -660,7 +661,7 @@ static int node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min,
bNode *node;
float loc[2];
int totselect = 0;
-
+
INIT_MINMAX2(min, max);
for (node = ntree->nodes.first; node; node = node->next) {
if (node_group_make_use_node(node, gnode)) {
@@ -669,12 +670,12 @@ static int node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min,
++totselect;
}
}
-
+
/* sane min/max if no selected nodes */
if (totselect == 0) {
min[0] = min[1] = max[0] = max[1] = 0.0f;
}
-
+
return totselect;
}
@@ -689,89 +690,89 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
int totselect;
bool expose_all = false;
bNode *input_node, *output_node;
-
+
/* XXX rough guess, not nice but we don't have access to UI constants here ... */
static const float offsetx = 200;
static const float offsety = 0.0f;
-
+
/* deselect all nodes in the target tree */
for (node = ngroup->nodes.first; node; node = node->next)
nodeSetSelected(node, false);
-
+
totselect = node_get_selected_minmax(ntree, gnode, min, max);
add_v2_v2v2(center, min, max);
mul_v2_fl(center, 0.5f);
-
+
/* auto-add interface for "solo" nodes */
if (totselect == 1)
expose_all = true;
-
+
/* move nodes over */
for (node = ntree->nodes.first; node; node = nextn) {
nextn = node->next;
if (node_group_make_use_node(node, gnode)) {
- /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
+ /* keep track of this node's RNA "base" path (the part of the pat identifying the node)
* if the old nodetree has animation data which potentially covers this node
*/
if (ntree->adt) {
PointerRNA ptr;
char *path;
-
+
RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
path = RNA_path_from_ID_to_struct(&ptr);
-
+
if (path)
BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
}
-
+
/* ensure valid parent pointers, detach if parent stays outside the group */
if (node->parent && !(node->parent->flag & NODE_SELECT))
nodeDetachNode(node);
-
+
/* change node-collection membership */
BLI_remlink(&ntree->nodes, node);
BLI_addtail(&ngroup->nodes, node);
-
+
/* ensure unique node name in the ngroup */
nodeUniqueName(ngroup, node);
}
}
-
+
/* move animation data over */
if (ntree->adt) {
LinkData *ld, *ldn = NULL;
-
+
BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths);
-
+
/* paths + their wrappers need to be freed */
for (ld = anim_basepaths.first; ld; ld = ldn) {
ldn = ld->next;
-
+
MEM_freeN(ld->data);
BLI_freelinkN(&anim_basepaths, ld);
}
}
-
+
/* node groups don't use internal cached data */
ntreeFreeCache(ngroup);
-
+
/* create input node */
input_node = nodeAddStaticNode(C, ngroup, NODE_GROUP_INPUT);
input_node->locx = min[0] - center[0] - offsetx;
input_node->locy = -offsety;
-
+
/* create output node */
output_node = nodeAddStaticNode(C, ngroup, NODE_GROUP_OUTPUT);
output_node->locx = max[0] - center[0] + offsetx;
output_node->locy = -offsety;
-
+
/* relink external sockets */
for (link = ntree->links.first; link; link = linkn) {
int fromselect = node_group_make_use_node(link->fromnode, gnode);
int toselect = node_group_make_use_node(link->tonode, gnode);
-
+
linkn = link->next;
-
+
if ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode)) {
/* remove all links to/from the gnode.
* this can remove link information, but there's no general way to preserve it.
@@ -785,17 +786,17 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
else if (toselect) {
bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link->tonode, link->tosock);
bNodeSocket *input_sock;
-
+
/* update the group node and interface node sockets,
* so the new interface socket can be linked.
*/
node_group_verify(ntree, gnode, (ID *)ngroup);
node_group_input_verify(ngroup, input_node, (ID *)ngroup);
-
+
/* create new internal link */
input_sock = node_group_input_find_socket(input_node, iosock->identifier);
nodeAddLink(ngroup, input_node, input_sock, link->tonode, link->tosock);
-
+
/* redirect external link */
link->tonode = gnode;
link->tosock = node_group_find_input_socket(gnode, iosock->identifier);
@@ -842,7 +843,7 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
node->locy -= center[1];
}
}
-
+
/* expose all unlinked sockets too */
if (expose_all) {
for (node = ngroup->nodes.first; node; node = node->next) {
@@ -858,16 +859,16 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
}
if (skip)
continue;
-
+
iosock = ntreeAddSocketInterfaceFromSocket(ngroup, node, sock);
-
+
node_group_input_verify(ngroup, input_node, (ID *)ngroup);
-
+
/* create new internal link */
input_sock = node_group_input_find_socket(input_node, iosock->identifier);
nodeAddLink(ngroup, input_node, input_sock, node, sock);
}
-
+
for (sock = node->outputs.first; sock; sock = sock->next) {
bNodeSocket *iosock, *output_sock;
bool skip = false;
@@ -876,11 +877,11 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
skip = true;
if (skip)
continue;
-
+
iosock = ntreeAddSocketInterfaceFromSocket(ngroup, node, sock);
-
+
node_group_output_verify(ngroup, output_node, (ID *)ngroup);
-
+
/* create new internal link */
output_sock = node_group_output_find_socket(output_node, iosock->identifier);
nodeAddLink(ngroup, node, sock, output_node, output_sock);
@@ -902,22 +903,22 @@ static bNode *node_group_make_from_selected(const bContext *C, bNodeTree *ntree,
bNodeTree *ngroup;
float min[2], max[2];
int totselect;
-
+
totselect = node_get_selected_minmax(ntree, NULL, min, max);
/* don't make empty group */
if (totselect == 0)
return NULL;
-
+
/* new nodetree */
ngroup = ntreeAddTree(bmain, "NodeGroup", ntreetype);
-
+
/* make group node */
gnode = nodeAddNode(C, ntree, ntype);
gnode->id = (ID *)ngroup;
-
+
gnode->locx = 0.5f * (min[0] + max[0]);
gnode->locy = 0.5f * (min[1] + max[1]);
-
+
node_group_make_insert_selected(C, ntree, gnode);
/* update of the tree containing the group instance node */
@@ -935,29 +936,29 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
bNodeTree *ngroup;
bNode *gnode;
Main *bmain = CTX_data_main(C);
-
+
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+
if (!node_group_make_test_selected(ntree, NULL, ntree_idname, op->reports))
return OPERATOR_CANCELLED;
-
+
gnode = node_group_make_from_selected(C, ntree, node_idname, ntree_idname);
-
+
if (gnode) {
ngroup = (bNodeTree *)gnode->id;
-
+
nodeSetActive(ntree, gnode);
if (ngroup) {
ED_node_tree_push(snode, ngroup, gnode);
ntreeUpdateTree(bmain, ngroup);
}
}
-
+
ntreeUpdateTree(bmain, ntree);
snode_notify(C, snode);
snode_dag_update(C, snode);
-
+
return OPERATOR_FINISHED;
}
@@ -967,11 +968,11 @@ void NODE_OT_group_make(wmOperatorType *ot)
ot->name = "Make Group";
ot->description = "Make group from selected nodes";
ot->idname = "NODE_OT_group_make";
-
+
/* api callbacks */
ot->exec = node_group_make_exec;
ot->poll = node_group_operator_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -986,29 +987,29 @@ static int node_group_insert_exec(bContext *C, wmOperator *op)
const char *node_idname = group_node_idname(C);
bNode *gnode;
Main *bmain = CTX_data_main(C);
-
+
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+
gnode = node_group_get_active(C, node_idname);
-
+
if (!gnode || !gnode->id)
return OPERATOR_CANCELLED;
-
+
ngroup = (bNodeTree *)gnode->id;
if (!node_group_make_test_selected(ntree, gnode, ngroup->idname, op->reports))
return OPERATOR_CANCELLED;
-
+
node_group_make_insert_selected(C, ntree, gnode);
-
+
nodeSetActive(ntree, gnode);
ED_node_tree_push(snode, ngroup, gnode);
ntreeUpdateTree(bmain, ngroup);
-
+
ntreeUpdateTree(bmain, ntree);
-
+
snode_notify(C, snode);
snode_dag_update(C, snode);
-
+
return OPERATOR_FINISHED;
}
@@ -1018,11 +1019,11 @@ void NODE_OT_group_insert(wmOperatorType *ot)
ot->name = "Group Insert";
ot->description = "Insert selected nodes into a node group";
ot->idname = "NODE_OT_group_insert";
-
+
/* api callbacks */
ot->exec = node_group_insert_exec;
ot->poll = node_group_operator_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 3539a36d497..2cc37a4e0fe 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -41,6 +41,7 @@ struct ARegion;
struct ARegionType;
struct View2D;
struct bContext;
+struct Main;
struct wmWindow;
struct bNode;
struct bNodeSocket;
@@ -50,7 +51,7 @@ struct wmKeyConfig;
/* temp data to pass on to modal */
typedef struct bNodeLinkDrag {
struct bNodeLinkDrag *next, *prev;
-
+
/* List of links dragged by the operator.
* Note: This is a list of LinkData structs on top of the actual bNodeLinks.
* This way the links can be added to the node tree while being stored in this list.
@@ -157,7 +158,7 @@ void NODE_OT_group_edit(struct wmOperatorType *ot);
/* node_relationships.c */
-bool node_connected_to_output(struct bNodeTree *ntree, struct bNode *node);
+bool node_connected_to_output(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node);
void NODE_OT_link(struct wmOperatorType *ot);
void NODE_OT_link_make(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 36df855b9d6..3b6cc8a89cf 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -50,7 +50,7 @@ void node_operatortypes(void)
{
WM_operatortype_append(NODE_OT_properties);
WM_operatortype_append(NODE_OT_toolbar);
-
+
WM_operatortype_append(NODE_OT_select);
WM_operatortype_append(NODE_OT_select_all);
WM_operatortype_append(NODE_OT_select_linked_to);
@@ -60,9 +60,9 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_select_lasso);
WM_operatortype_append(NODE_OT_select_grouped);
WM_operatortype_append(NODE_OT_select_same_type_step);
-
+
WM_operatortype_append(NODE_OT_find_node);
-
+
WM_operatortype_append(NODE_OT_view_all);
WM_operatortype_append(NODE_OT_view_selected);
@@ -72,12 +72,12 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_options_toggle);
WM_operatortype_append(NODE_OT_hide_socket_toggle);
WM_operatortype_append(NODE_OT_node_copy_color);
-
+
WM_operatortype_append(NODE_OT_duplicate);
WM_operatortype_append(NODE_OT_delete);
WM_operatortype_append(NODE_OT_delete_reconnect);
WM_operatortype_append(NODE_OT_resize);
-
+
WM_operatortype_append(NODE_OT_link);
WM_operatortype_append(NODE_OT_link_make);
WM_operatortype_append(NODE_OT_links_cut);
@@ -89,36 +89,36 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_group_ungroup);
WM_operatortype_append(NODE_OT_group_separate);
WM_operatortype_append(NODE_OT_group_edit);
-
+
WM_operatortype_append(NODE_OT_link_viewer);
-
+
WM_operatortype_append(NODE_OT_insert_offset);
-
+
WM_operatortype_append(NODE_OT_read_viewlayers);
WM_operatortype_append(NODE_OT_render_changed);
-
+
WM_operatortype_append(NODE_OT_backimage_move);
WM_operatortype_append(NODE_OT_backimage_zoom);
WM_operatortype_append(NODE_OT_backimage_fit);
WM_operatortype_append(NODE_OT_backimage_sample);
-
+
WM_operatortype_append(NODE_OT_add_file);
WM_operatortype_append(NODE_OT_add_mask);
-
+
WM_operatortype_append(NODE_OT_new_node_tree);
-
+
WM_operatortype_append(NODE_OT_output_file_add_socket);
WM_operatortype_append(NODE_OT_output_file_remove_active_socket);
WM_operatortype_append(NODE_OT_output_file_move_active_socket);
-
+
WM_operatortype_append(NODE_OT_parent_set);
WM_operatortype_append(NODE_OT_join);
WM_operatortype_append(NODE_OT_attach);
WM_operatortype_append(NODE_OT_detach);
-
+
WM_operatortype_append(NODE_OT_clipboard_copy);
WM_operatortype_append(NODE_OT_clipboard_paste);
-
+
WM_operatortype_append(NODE_OT_shader_script_update);
WM_operatortype_append(NODE_OT_viewer_border);
@@ -135,7 +135,7 @@ void ED_operatormacros_node(void)
{
wmOperatorType *ot;
wmOperatorTypeMacro *mot;
-
+
ot = WM_operatortype_append_macro("NODE_OT_select_link_viewer", "Link Viewer",
"Select node and link it to a viewer node",
OPTYPE_UNDO);
@@ -149,7 +149,7 @@ void ED_operatormacros_node(void)
RNA_boolean_set(mot->ptr, "release_confirm", true);
WM_operatortype_macro_define(ot, "NODE_OT_attach");
WM_operatortype_macro_define(ot, "NODE_OT_insert_offset");
-
+
/* NODE_OT_translate_attach with remove_on_canel set to true */
ot = WM_operatortype_append_macro("NODE_OT_translate_attach_remove_on_cancel", "Move and Attach",
"Move nodes and attach to frame",
@@ -212,7 +212,7 @@ static void node_select_keymap(wmKeyMap *keymap, int extend)
const int *mod = (extend ? mod_extend : mod_single);
wmKeyMapItem *kmi;
int i;
-
+
for (i = 0; mod[i] >= 0; ++i) {
kmi = WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, mod[i], 0);
RNA_boolean_set(kmi->ptr, "extend", extend);
@@ -225,17 +225,17 @@ void node_keymap(struct wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
/* Entire Editor only ----------------- */
keymap = WM_keymap_find(keyconf, "Node Generic", SPACE_NODE, 0);
-
+
WM_keymap_add_item(keymap, "NODE_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_toolbar", TKEY, KM_PRESS, 0, 0);
-
+
/* Main Region only ----------------- */
keymap = WM_keymap_find(keyconf, "Node Editor", SPACE_NODE, 0);
-
- /* mouse select in nodes used to be both keys, but perhaps this should be reduced?
+
+ /* mouse select in nodes used to be both keys, but perhaps this should be reduced?
* NOTE: mouse-clicks on left-mouse will fall through to allow transform-tweak, but also link/resize
* NOTE 2: socket select is part of the node select operator, to handle overlapping cases
* NOTE 3: select op is registered for various combinations of modifier key, so the specialized
@@ -243,10 +243,10 @@ void node_keymap(struct wmKeyConfig *keyconf)
*/
node_select_keymap(keymap, false);
node_select_keymap(keymap, true);
-
+
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_border", EVT_TWEAK_S, KM_ANY, 0, 0);
RNA_boolean_set(kmi->ptr, "tweak", true);
-
+
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "deselect", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
@@ -259,13 +259,13 @@ void node_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "detach", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "detach", true);
-
+
WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "NODE_OT_add_reroute", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_select_link_viewer", LEFTMOUSE, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "NODE_OT_backimage_move", MIDDLEMOUSE, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "NODE_OT_backimage_zoom", VKEY, KM_PRESS, 0, 0);
RNA_float_set(kmi->ptr, "factor", 0.83333f);
@@ -274,6 +274,8 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_backimage_fit", HOMEKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "NODE_OT_backimage_sample", ACTIONMOUSE, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_menu(keymap, "NODE_MT_specials", WKEY, KM_PRESS, 0, 0);
+
kmi = WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "replace", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_link_make", FKEY, KM_PRESS, KM_SHIFT, 0);
@@ -283,16 +285,16 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
/* modified operator call for duplicating with input links */
WM_keymap_add_item(keymap, "NODE_OT_duplicate_move_keep_inputs", DKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "NODE_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_detach", PKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "NODE_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "NODE_OT_hide_toggle", HKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_mute_toggle", MKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_preview_toggle", HKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "NODE_OT_hide_socket_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "NODE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
#ifdef WITH_INPUT_NDOF
WM_keymap_add_item(keymap, "NODE_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
@@ -322,9 +324,9 @@ void node_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "prev", false);
kmi = WM_keymap_add_item(keymap, "NODE_OT_select_same_type_step", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "prev", true);
-
+
WM_keymap_add_item(keymap, "NODE_OT_find_node", FKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* node group operators */
WM_keymap_add_item(keymap, "NODE_OT_group_make", GKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_group_ungroup", GKEY, KM_PRESS, KM_ALT, 0);
@@ -336,7 +338,7 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_read_viewlayers", RKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_render_changed", ZKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_clipboard_paste", VKEY, KM_PRESS, KM_CTRL, 0);
#ifdef __APPLE__
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 70f7553cf41..e4c59bc9508 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -131,9 +131,8 @@ static bool node_group_has_output_dfs(bNode *node)
return false;
}
-static bool node_group_has_output(bNode *node)
+static bool node_group_has_output(Main *bmain, bNode *node)
{
- Main *bmain = G.main;
BLI_assert(node->type == NODE_GROUP);
bNodeTree *ntree = (bNodeTree *)node->id;
if (ntree == NULL) {
@@ -143,7 +142,7 @@ static bool node_group_has_output(bNode *node)
return node_group_has_output_dfs(node);
}
-bool node_connected_to_output(bNodeTree *ntree, bNode *node)
+bool node_connected_to_output(Main *bmain, bNodeTree *ntree, bNode *node)
{
/* Special case for drivers: if node tree has any drivers we assume it is
* always to be tagged for update when node changes. Otherwise we will be
@@ -170,7 +169,7 @@ bool node_connected_to_output(bNodeTree *ntree, bNode *node)
return true;
}
if (ntree_check_nodes_connected(ntree, node, current_node) &&
- node_group_has_output(current_node))
+ node_group_has_output(bmain, current_node))
{
return true;
}
@@ -313,7 +312,7 @@ static bool snode_autoconnect_input(SpaceNode *snode, bNode *node_fr, bNodeSocke
return true;
}
-static void snode_autoconnect(SpaceNode *snode, const bool allow_multiple, const bool replace)
+static void snode_autoconnect(Main *bmain, SpaceNode *snode, const bool allow_multiple, const bool replace)
{
bNodeTree *ntree = snode->edittree;
ListBase *nodelist = MEM_callocN(sizeof(ListBase), "items_list");
@@ -390,7 +389,7 @@ static void snode_autoconnect(SpaceNode *snode, const bool allow_multiple, const
}
if (numlinks > 0) {
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
}
BLI_freelistN(nodelist);
@@ -556,12 +555,12 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
bNodeLink *tlink, *tlink_next;
int to_count = node_count_links(ntree, to);
int from_count = node_count_links(ntree, from);
-
+
for (tlink = ntree->links.first; tlink; tlink = tlink_next) {
tlink_next = tlink->next;
if (tlink == link)
continue;
-
+
if (tlink && tlink->fromsock == from) {
if (from_count > from->limit) {
nodeRemLink(ntree, tlink);
@@ -569,7 +568,7 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
--from_count;
}
}
-
+
if (tlink && tlink->tosock == to) {
if (to_count > to->limit) {
nodeRemLink(ntree, tlink);
@@ -582,6 +581,7 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
{
+ Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
bNodeLinkDrag *nldrag = op->customdata;
@@ -607,20 +607,20 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
link->fromnode->typeinfo->insert_link(ntree, link->fromnode, link);
if (link->tonode->typeinfo->insert_link)
link->tonode->typeinfo->insert_link(ntree, link->tonode, link);
-
+
/* add link to the node tree */
BLI_addtail(&ntree->links, link);
-
+
ntree->update |= NTREE_UPDATE_LINKS;
-
+
/* tag tonode for update */
link->tonode->update |= NODE_UPDATE;
-
+
/* we might need to remove a link */
node_remove_extra_links(snode, link);
if (link->tonode) {
- do_tag_update |= (do_tag_update || node_connected_to_output(ntree, link->tonode));
+ do_tag_update |= (do_tag_update || node_connected_to_output(bmain, ntree, link->tonode));
}
}
else {
@@ -628,13 +628,13 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
}
}
ntree->is_updating = false;
-
- ntreeUpdateTree(CTX_data_main(C), ntree);
+
+ ntreeUpdateTree(bmain, ntree);
snode_notify(C, snode);
if (do_tag_update) {
snode_dag_update(C, snode);
}
-
+
BLI_remlink(&snode->linkdrag, nldrag);
/* links->data pointers are either held by the tree or freed already */
BLI_freelistN(&nldrag->links);
@@ -653,14 +653,14 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) {
for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
bNodeLink *link = linkdata->data;
-
+
/* skip if this is already the target socket */
if (link->tosock == tsock)
continue;
/* skip if socket is on the same node as the fromsock */
if (tnode && link->fromnode == tnode)
continue;
-
+
/* attach links to the socket */
link->tonode = tnode;
link->tosock = tsock;
@@ -669,7 +669,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
else {
for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
bNodeLink *link = linkdata->data;
-
+
link->tonode = NULL;
link->tosock = NULL;
}
@@ -679,14 +679,14 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_OUT)) {
for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
bNodeLink *link = linkdata->data;
-
+
/* skip if this is already the target socket */
if (link->fromsock == tsock)
continue;
/* skip if socket is on the same node as the fromsock */
if (tnode && link->tonode == tnode)
continue;
-
+
/* attach links to the socket */
link->fromnode = tnode;
link->fromsock = tsock;
@@ -695,7 +695,7 @@ static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
else {
for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
bNodeLink *link = linkdata->data;
-
+
link->fromnode = NULL;
link->fromsock = NULL;
}
@@ -710,35 +710,38 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
bNodeLinkDrag *nldrag = op->customdata;
ARegion *ar = CTX_wm_region(C);
float cursor[2];
-
+
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&cursor[0], &cursor[1]);
-
+
switch (event->type) {
case MOUSEMOVE:
node_link_find_socket(C, op, cursor);
-
+
node_link_update_header(C, nldrag);
ED_region_tag_redraw(ar);
break;
-
+
case LEFTMOUSE:
case RIGHTMOUSE:
case MIDDLEMOUSE:
{
- node_link_exit(C, op, true);
-
- ED_area_headerprint(CTX_wm_area(C), NULL);
- ED_region_tag_redraw(ar);
- return OPERATOR_FINISHED;
+ if (event->val == KM_RELEASE) {
+ node_link_exit(C, op, true);
+
+ ED_area_headerprint(CTX_wm_area(C), NULL);
+ ED_region_tag_redraw(ar);
+ return OPERATOR_FINISHED;
+ }
+ break;
}
}
-
+
return OPERATOR_RUNNING_MODAL;
}
/* return 1 when socket clicked */
-static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool detach)
+static bNodeLinkDrag *node_link_init(Main *bmain, SpaceNode *snode, float cursor[2], bool detach)
{
bNode *node;
bNodeSocket *sock;
@@ -772,7 +775,7 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool det
* using TEST flag.
*/
oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(snode->edittree, link->tonode)) {
+ if (node_connected_to_output(bmain, snode->edittree, link->tonode)) {
oplink->flag |= NODE_LINK_TEST;
}
@@ -791,7 +794,7 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool det
oplink->fromsock = sock;
oplink->flag |= NODE_LINK_VALID;
oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(snode->edittree, node)) {
+ if (node_connected_to_output(bmain, snode->edittree, node)) {
oplink->flag |= NODE_LINK_TEST;
}
@@ -816,13 +819,13 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool det
oplink->next = oplink->prev = NULL;
oplink->flag |= NODE_LINK_VALID;
oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(snode->edittree, link->tonode)) {
+ if (node_connected_to_output(bmain, snode->edittree, link->tonode)) {
oplink->flag |= NODE_LINK_TEST;
}
BLI_addtail(&nldrag->links, linkdata);
nodeRemLink(snode->edittree, link);
-
+
/* send changed event to original link->tonode */
if (node)
snode_update(snode, node);
@@ -839,32 +842,33 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool det
oplink->tosock = sock;
oplink->flag |= NODE_LINK_VALID;
oplink->flag &= ~NODE_LINK_TEST;
- if (node_connected_to_output(snode->edittree, node)) {
+ if (node_connected_to_output(bmain, snode->edittree, node)) {
oplink->flag |= NODE_LINK_TEST;
}
BLI_addtail(&nldrag->links, linkdata);
}
}
-
+
return nldrag;
}
static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
bNodeLinkDrag *nldrag;
float cursor[2];
-
+
bool detach = RNA_boolean_get(op->ptr, "detach");
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&cursor[0], &cursor[1]);
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
- nldrag = node_link_init(snode, cursor, detach);
+ nldrag = node_link_init(bmain, snode, cursor, detach);
if (nldrag) {
op->customdata = nldrag;
@@ -915,12 +919,13 @@ void NODE_OT_link(wmOperatorType *ot)
/* makes a link between selected output and input sockets */
static int node_make_link_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
const bool replace = RNA_boolean_get(op->ptr, "replace");
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
- snode_autoconnect(snode, 1, replace);
+ snode_autoconnect(bmain, snode, 1, replace);
/* deselect sockets after linking */
node_deselect_all_input_sockets(snode, 0);
@@ -968,6 +973,7 @@ static bool cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot)
static int cut_links_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
float mcoords[256][2];
@@ -989,9 +995,9 @@ static int cut_links_exec(bContext *C, wmOperator *op)
if (i > 1) {
bool found = false;
bNodeLink *link, *next;
-
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
+
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
+
for (link = snode->edittree->links.first; link; link = next) {
next = link->next;
if (nodeLinkIsHidden(link))
@@ -1001,11 +1007,11 @@ static int cut_links_exec(bContext *C, wmOperator *op)
if (found == false) {
/* TODO(sergey): Why did we kill jobs twice? */
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
found = true;
}
- do_tag_update |= (do_tag_update || node_connected_to_output(snode->edittree, link->tonode));
+ do_tag_update |= (do_tag_update || node_connected_to_output(bmain, snode->edittree, link->tonode));
snode_update(snode, link->tonode);
nodeRemLink(snode->edittree, link);
@@ -1294,7 +1300,7 @@ void NODE_OT_attach(wmOperatorType *ot)
ot->idname = "NODE_OT_attach";
/* api callbacks */
-
+
ot->invoke = node_attach_invoke;
ot->poll = ED_operator_node_editable;
@@ -1413,7 +1419,7 @@ static bool ed_node_link_conditions(ScrArea *sa, bool test, SpaceNode **r_snode,
for (link = snode->edittree->links.first; link; link = link->next) {
if (nodeLinkIsHidden(link))
continue;
-
+
if (link->tonode == select || link->fromnode == select)
return false;
}
@@ -1830,7 +1836,7 @@ void NODE_OT_insert_offset(wmOperatorType *ot)
}
/* assumes link with NODE_LINKFLAG_HILITE set */
-void ED_node_link_insert(ScrArea *sa)
+void ED_node_link_insert(Main *bmain, ScrArea *sa)
{
bNode *node, *select;
SpaceNode *snode;
@@ -1847,18 +1853,18 @@ void ED_node_link_insert(ScrArea *sa)
if (link) {
bNodeSocket *best_input = socket_best_match(&select->inputs);
bNodeSocket *best_output = socket_best_match(&select->outputs);
-
+
if (best_input && best_output) {
node = link->tonode;
sockto = link->tosock;
-
+
link->tonode = select;
link->tosock = best_input;
node_remove_extra_links(snode, link);
link->flag &= ~NODE_LINKFLAG_HILITE;
-
+
nodeAddLink(snode->edittree, select, best_output, node, sockto);
-
+
/* set up insert offset data, it needs stuff from here */
if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) {
NodeInsertOfsData *iofsd = MEM_callocN(sizeof(NodeInsertOfsData), __func__);
@@ -1870,7 +1876,7 @@ void ED_node_link_insert(ScrArea *sa)
snode->iofsd = iofsd;
}
- ntreeUpdateTree(G.main, snode->edittree); /* needed for pointers */
+ ntreeUpdateTree(bmain, snode->edittree); /* needed for pointers */
snode_update(snode, select);
ED_node_tag_update_id(snode->id);
}
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index b1656ac89ee..3ae542c48db 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -65,7 +65,7 @@
static bNode *node_under_mouse_select(bNodeTree *ntree, int mx, int my)
{
bNode *node;
-
+
for (node = ntree->nodes.last; node; node = node->prev) {
if (node->typeinfo->select_area_func) {
if (node->typeinfo->select_area_func(node, mx, my))
@@ -78,7 +78,7 @@ static bNode *node_under_mouse_select(bNodeTree *ntree, int mx, int my)
static bNode *node_under_mouse_tweak(bNodeTree *ntree, int mx, int my)
{
bNode *node;
-
+
for (node = ntree->nodes.last; node; node = node->prev) {
if (node->typeinfo->tweak_area_func) {
if (node->typeinfo->tweak_area_func(node, mx, my))
@@ -96,7 +96,7 @@ static void node_toggle(bNode *node)
void node_socket_select(bNode *node, bNodeSocket *sock)
{
sock->flag |= SELECT;
-
+
/* select node too */
if (node)
node->flag |= SELECT;
@@ -105,10 +105,10 @@ void node_socket_select(bNode *node, bNodeSocket *sock)
void node_socket_deselect(bNode *node, bNodeSocket *sock, const bool deselect_node)
{
sock->flag &= ~SELECT;
-
+
if (node && deselect_node) {
bool sel = 0;
-
+
/* if no selected sockets remain, also deselect the node */
for (sock = node->inputs.first; sock; sock = sock->next) {
if (sock->flag & SELECT) {
@@ -122,7 +122,7 @@ void node_socket_deselect(bNode *node, bNodeSocket *sock, const bool deselect_no
break;
}
}
-
+
if (!sel)
node->flag &= ~SELECT;
}
@@ -140,7 +140,7 @@ static void node_socket_toggle(bNode *node, bNodeSocket *sock, int deselect_node
void node_deselect_all(SpaceNode *snode)
{
bNode *node;
-
+
for (node = snode->edittree->nodes.first; node; node = node->next)
nodeSetSelected(node, false);
}
@@ -149,18 +149,18 @@ void node_deselect_all_input_sockets(SpaceNode *snode, const bool deselect_nodes
{
bNode *node;
bNodeSocket *sock;
-
+
/* XXX not calling node_socket_deselect here each time, because this does iteration
* over all node sockets internally to check if the node stays selected.
* We can do that more efficiently here.
*/
-
+
for (node = snode->edittree->nodes.first; node; node = node->next) {
int sel = 0;
-
+
for (sock = node->inputs.first; sock; sock = sock->next)
sock->flag &= ~SELECT;
-
+
/* if no selected sockets remain, also deselect the node */
if (deselect_nodes) {
for (sock = node->outputs.first; sock; sock = sock->next) {
@@ -169,7 +169,7 @@ void node_deselect_all_input_sockets(SpaceNode *snode, const bool deselect_nodes
break;
}
}
-
+
if (!sel)
node->flag &= ~SELECT;
}
@@ -180,18 +180,18 @@ void node_deselect_all_output_sockets(SpaceNode *snode, const bool deselect_node
{
bNode *node;
bNodeSocket *sock;
-
+
/* XXX not calling node_socket_deselect here each time, because this does iteration
* over all node sockets internally to check if the node stays selected.
* We can do that more efficiently here.
*/
-
+
for (node = snode->edittree->nodes.first; node; node = node->next) {
bool sel = false;
-
+
for (sock = node->outputs.first; sock; sock = sock->next)
sock->flag &= ~SELECT;
-
+
/* if no selected sockets remain, also deselect the node */
if (deselect_nodes) {
for (sock = node->inputs.first; sock; sock = sock->next) {
@@ -200,7 +200,7 @@ void node_deselect_all_output_sockets(SpaceNode *snode, const bool deselect_node
break;
}
}
-
+
if (!sel)
node->flag &= ~SELECT;
}
@@ -364,32 +364,32 @@ void node_select_single(bContext *C, bNode *node)
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNode *tnode;
-
+
for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next)
if (tnode != node)
nodeSetSelected(tnode, false);
nodeSetSelected(node, true);
-
+
ED_node_set_active(bmain, snode->edittree, node);
ED_node_set_active_viewer_key(snode);
-
+
ED_node_sort(snode->edittree);
-
+
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
}
/* ****** Click Select ****** */
-
+
static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const int mval[2], short extend)
{
bNode *node, *tnode;
bNodeSocket *sock, *tsock;
float cursor[2];
int selected = 0;
-
+
/* get mouse coordinates in view2d space */
UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &cursor[0], &cursor[1]);
-
+
if (extend) {
/* first do socket selection, these generally overlap with nodes.
* socket selection only in extend mode.
@@ -417,7 +417,7 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
else {
/* find the closest visible node */
node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
-
+
if (node) {
if ((node->flag & SELECT) && (node->flag & NODE_ACTIVE) == 0) {
/* if node is selected but not active make it active
@@ -435,10 +435,10 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
}
}
else { /* extend == 0 */
-
+
/* find the closest visible node */
node = node_under_mouse_select(snode->edittree, cursor[0], cursor[1]);
-
+
if (node) {
for (tnode = snode->edittree->nodes.first; tnode; tnode = tnode->next) {
nodeSetSelected(tnode, false);
@@ -448,13 +448,13 @@ static int node_mouse_select(Main *bmain, SpaceNode *snode, ARegion *ar, const i
selected = 1;
}
}
-
+
/* update node order */
if (selected) {
ED_node_set_active_viewer_key(snode);
ED_node_sort(snode->edittree);
}
-
+
return selected;
}
@@ -465,18 +465,18 @@ static int node_select_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
int mval[2];
short extend;
-
+
/* get settings from RNA properties for operator */
mval[0] = RNA_int_get(op->ptr, "mouse_x");
mval[1] = RNA_int_get(op->ptr, "mouse_y");
-
+
extend = RNA_boolean_get(op->ptr, "extend");
-
+
/* perform the select */
if (node_mouse_select(bmain, snode, ar, mval, extend)) {
/* send notifiers */
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
-
+
/* allow tweak event to work too */
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
@@ -501,15 +501,15 @@ void NODE_OT_select(wmOperatorType *ot)
ot->name = "Select";
ot->idname = "NODE_OT_select";
ot->description = "Select the node under the cursor";
-
+
/* api callbacks */
ot->invoke = node_select_invoke;
ot->exec = node_select_exec;
ot->poll = ED_operator_node_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_int(ot->srna, "mouse_x", 0, INT_MIN, INT_MAX, "Mouse X", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "mouse_y", 0, INT_MIN, INT_MAX, "Mouse Y", "", INT_MIN, INT_MAX);
@@ -526,10 +526,10 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
rctf rectf;
const bool select = !RNA_boolean_get(op->ptr, "deselect");
const bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
WM_operator_properties_border_to_rctf(op, &rectf);
UI_view2d_region_to_view_rctf(&ar->v2d, &rectf, &rectf);
-
+
for (node = snode->edittree->nodes.first; node; node = node->next) {
bool is_inside;
if (node->type == NODE_FRAME) {
@@ -546,9 +546,9 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
nodeSetSelected(node, false);
}
}
-
+
ED_node_sort(snode->edittree);
-
+
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
@@ -557,7 +557,7 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
static int node_border_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
const bool tweak = RNA_boolean_get(op->ptr, "tweak");
-
+
if (tweak) {
/* prevent initiating the border select if the mouse is over a node */
/* this allows border select on empty space, but drag-translate on nodes */
@@ -566,11 +566,11 @@ static int node_border_select_invoke(bContext *C, wmOperator *op, const wmEvent
float mx, my;
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my);
-
+
if (node_under_mouse_tweak(snode->edittree, mx, my))
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
-
+
return WM_gesture_border_invoke(C, op, event);
}
@@ -580,18 +580,18 @@ void NODE_OT_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->idname = "NODE_OT_select_border";
ot->description = "Use box selection to select nodes";
-
+
/* api callbacks */
ot->invoke = node_border_select_invoke;
ot->exec = node_borderselect_exec;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = ED_operator_node_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
RNA_def_boolean(ot->srna, "tweak", 0, "Tweak", "Only activate when mouse is not over a node - useful for tweak gesture");
@@ -767,7 +767,7 @@ static int node_select_all_exec(bContext *C, wmOperator *op)
}
ED_node_sort(snode->edittree);
-
+
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -778,11 +778,11 @@ void NODE_OT_select_all(wmOperatorType *ot)
ot->name = "(De)select All";
ot->description = "(De)select all nodes";
ot->idname = "NODE_OT_select_all";
-
+
/* api callbacks */
ot->exec = node_select_all_exec;
ot->poll = ED_operator_node_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -796,7 +796,7 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
bNodeLink *link;
bNode *node;
-
+
for (node = snode->edittree->nodes.first; node; node = node->next)
node->flag &= ~NODE_TEST;
@@ -806,14 +806,14 @@ static int node_select_linked_to_exec(bContext *C, wmOperator *UNUSED(op))
if (link->fromnode && link->tonode && (link->fromnode->flag & NODE_SELECT))
link->tonode->flag |= NODE_TEST;
}
-
+
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & NODE_TEST)
nodeSetSelected(node, true);
}
-
+
ED_node_sort(snode->edittree);
-
+
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -824,11 +824,11 @@ void NODE_OT_select_linked_to(wmOperatorType *ot)
ot->name = "Select Linked To";
ot->description = "Select nodes linked to the selected ones";
ot->idname = "NODE_OT_select_linked_to";
-
+
/* api callbacks */
ot->exec = node_select_linked_to_exec;
ot->poll = ED_operator_node_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -840,7 +840,7 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
bNodeLink *link;
bNode *node;
-
+
for (node = snode->edittree->nodes.first; node; node = node->next)
node->flag &= ~NODE_TEST;
@@ -850,14 +850,14 @@ static int node_select_linked_from_exec(bContext *C, wmOperator *UNUSED(op))
if (link->fromnode && link->tonode && (link->tonode->flag & NODE_SELECT))
link->fromnode->flag |= NODE_TEST;
}
-
+
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & NODE_TEST)
nodeSetSelected(node, true);
}
-
+
ED_node_sort(snode->edittree);
-
+
WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
@@ -868,11 +868,11 @@ void NODE_OT_select_linked_from(wmOperatorType *ot)
ot->name = "Select Linked From";
ot->description = "Select nodes linked from the selected ones";
ot->idname = "NODE_OT_select_linked_from";
-
+
/* api callbacks */
ot->exec = node_select_linked_from_exec;
ot->poll = ED_operator_node_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -886,29 +886,29 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
int totnodes;
const bool revert = RNA_boolean_get(op->ptr, "prev");
const bool same_type = 1;
-
+
ntreeGetDependencyList(snode->edittree, &node_array, &totnodes);
-
+
if (totnodes > 1) {
int a;
-
+
for (a = 0; a < totnodes; a++) {
if (node_array[a] == active)
break;
}
-
+
if (same_type) {
bNode *node = NULL;
-
+
while (node == NULL) {
if (revert) a--;
else a++;
-
+
if (a < 0 || a >= totnodes)
break;
-
+
node = node_array[a];
-
+
if (node->type == active->type)
break;
else node = NULL;
@@ -930,7 +930,7 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
active = node_array[a + 1];
}
}
-
+
node_select_single(C, active);
/* is note outside view? */
@@ -941,10 +941,10 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
space_node_view_flag(C, snode, ar, NODE_SELECT, smooth_viewtx);
}
}
-
+
if (node_array)
MEM_freeN(node_array);
-
+
return OPERATOR_FINISHED;
}
@@ -954,14 +954,14 @@ void NODE_OT_select_same_type_step(wmOperatorType *ot)
ot->name = "Activate Same Type Next/Prev";
ot->description = "Activate and view same node type, step by step";
ot->idname = "NODE_OT_select_same_type_step";
-
+
/* api callbacks */
ot->exec = node_select_same_type_step_exec;
ot->poll = ED_operator_node_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "prev", 0, "Previous", "");
}
@@ -973,12 +973,12 @@ static void node_find_cb(const struct bContext *C, void *UNUSED(arg), const char
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node;
-
+
for (node = snode->edittree->nodes.first; node; node = node->next) {
-
+
if (BLI_strcasestr(node->name, str) || BLI_strcasestr(node->label, str)) {
char name[256];
-
+
if (node->label[0])
BLI_snprintf(name, 256, "%s (%s)", node->name, node->label);
else
@@ -993,11 +993,11 @@ static void node_find_call_cb(struct bContext *C, void *UNUSED(arg1), void *arg2
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *active = arg2;
-
+
if (active) {
ARegion *ar = CTX_wm_region(C);
node_select_single(C, active);
-
+
/* is note outside view? */
if (active->totr.xmax < ar->v2d.cur.xmin || active->totr.xmin > ar->v2d.cur.xmax ||
active->totr.ymax < ar->v2d.cur.ymin || active->totr.ymin > ar->v2d.cur.ymax)
@@ -1016,18 +1016,18 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op)
uiBlock *block;
uiBut *but;
wmOperator *op = (wmOperator *)arg_op;
-
+
block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
-
+
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
UI_but_func_search_set(but, NULL, node_find_cb, op->type, node_find_call_cb, NULL);
-
+
/* fake button, it holds space for search items */
uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
-
+
UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
-
+
// UI_but_active_only(C, ar, block, but); XXX using this here makes Blender hang - investigate
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
@@ -1035,7 +1035,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op)
event.customdata = but;
event.customdatafree = false;
wm_event_add(win, &event);
-
+
return block;
}
@@ -1053,16 +1053,16 @@ void NODE_OT_find_node(wmOperatorType *ot)
ot->name = "Find Node";
ot->description = "Search for named node and allow to select and activate it";
ot->idname = "NODE_OT_find_node";
-
+
/* api callbacks */
ot->invoke = node_find_node_invoke;
ot->poll = ED_operator_node_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "prev", 0, "Previous", "");
-
+
}
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 5f48b7d7a0f..23fd793cdd3 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -64,7 +64,7 @@ typedef struct NodeLinkItem {
int socket_type; /* socket type for compatibility check */
const char *socket_name; /* ui label of the socket */
const char *node_name; /* ui label of the node */
-
+
/* extra settings */
bNodeTree *ngroup; /* group node tree */
} NodeLinkItem;
@@ -82,16 +82,16 @@ static bool node_link_item_compare(bNode *node, NodeLinkItem *item)
return true;
}
-static void node_link_item_apply(bNode *node, NodeLinkItem *item)
+static void node_link_item_apply(Main *bmain, bNode *node, NodeLinkItem *item)
{
if (node->type == NODE_GROUP) {
node->id = (ID *)item->ngroup;
- ntreeUpdateTree(G.main, item->ngroup);
+ ntreeUpdateTree(bmain, item->ngroup);
}
else {
/* nothing to do for now */
}
-
+
if (node->id)
id_us_plus(node->id);
}
@@ -191,6 +191,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN
static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to,
int type, NodeLinkItem *item)
{
+ Main *bmain = CTX_data_main(C);
bNode *node_from;
bNodeSocket *sock_from_tmp;
bNode *node_prev = NULL;
@@ -232,8 +233,8 @@ static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *
node_from->locx = node_to->locx - (node_from->typeinfo->width + 50);
node_from->locy = node_to->locy - (node_from->typeinfo->height * index);
}
-
- node_link_item_apply(node_from, item);
+
+ node_link_item_apply(bmain, node_from, item);
}
nodeSetActive(ntree, node_from);
@@ -307,19 +308,19 @@ static void ui_node_link_items(NodeLinkArg *arg, int in_out, NodeLinkItem **r_it
/* XXX this should become a callback for node types! */
NodeLinkItem *items = NULL;
int totitems = 0;
-
+
if (arg->node_type->type == NODE_GROUP) {
bNodeTree *ngroup;
int i;
-
+
for (ngroup = arg->bmain->nodetree.first; ngroup; ngroup = ngroup->id.next) {
ListBase *lb = ((in_out == SOCK_IN) ? &ngroup->inputs : &ngroup->outputs);
totitems += BLI_listbase_count(lb);
}
-
+
if (totitems > 0) {
items = MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
-
+
i = 0;
for (ngroup = arg->bmain->nodetree.first; ngroup; ngroup = ngroup->id.next) {
ListBase *lb = (in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs);
@@ -327,7 +328,7 @@ static void ui_node_link_items(NodeLinkArg *arg, int in_out, NodeLinkItem **r_it
int index;
for (stemp = lb->first, index = 0; stemp; stemp = stemp->next, ++index, ++i) {
NodeLinkItem *item = &items[i];
-
+
item->socket_index = index;
/* note: int stemp->type is not fully reliable, not used for node group
* interface sockets. use the typeinfo->type instead.
@@ -344,17 +345,17 @@ static void ui_node_link_items(NodeLinkArg *arg, int in_out, NodeLinkItem **r_it
bNodeSocketTemplate *socket_templates = (in_out == SOCK_IN ? arg->node_type->inputs : arg->node_type->outputs);
bNodeSocketTemplate *stemp;
int i;
-
+
for (stemp = socket_templates; stemp && stemp->type != -1; ++stemp)
++totitems;
-
+
if (totitems > 0) {
items = MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
-
+
i = 0;
for (stemp = socket_templates; stemp && stemp->type != -1; ++stemp, ++i) {
NodeLinkItem *item = &items[i];
-
+
item->socket_index = i;
item->socket_type = stemp->type;
item->socket_name = stemp->name;
@@ -362,7 +363,7 @@ static void ui_node_link_items(NodeLinkArg *arg, int in_out, NodeLinkItem **r_it
}
}
}
-
+
*r_items = items;
*r_totitems = totitems;
}
@@ -446,7 +447,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
NodeLinkArg *argN;
int first = 1;
int compatibility = 0;
-
+
if (ntree->type == NTREE_SHADER) {
compatibility = NODE_NEW_SHADING;
}
@@ -483,29 +484,29 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
const char *cur_node_name = NULL;
int i, num = 0;
int icon = ICON_NONE;
-
+
arg->node_type = ntype;
-
+
ui_node_link_items(arg, SOCK_OUT, &items, &totitems);
-
+
for (i = 0; i < totitems; ++i)
if (ui_compatible_sockets(items[i].socket_type, sock->type))
num++;
-
+
for (i = 0; i < totitems; ++i) {
if (!ui_compatible_sockets(items[i].socket_type, sock->type))
continue;
-
+
if (first) {
column = uiLayoutColumn(layout, 0);
UI_block_layout_set_current(block, column);
-
+
uiItemL(column, IFACE_(cname), ICON_NODE);
but = block->buttons.last;
-
+
first = 0;
}
-
+
if (num > 1) {
if (!cur_node_name || !STREQ(cur_node_name, items[i].node_name)) {
cur_node_name = items[i].node_name;
@@ -521,15 +522,15 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
BLI_strncpy(name, IFACE_(items[i].node_name), UI_MAX_NAME_STR);
icon = ICON_NONE;
}
-
+
but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input"));
-
+
argN = MEM_dupallocN(arg);
argN->item = items[i];
UI_but_funcN_set(but, ui_node_link, argN, NULL);
}
-
+
if (items)
MEM_freeN(items);
}
@@ -634,7 +635,7 @@ static void ui_node_draw_node(uiLayout *layout, bContext *C, bNodeTree *ntree, b
if (node->typeinfo->draw_buttons) {
if (node->type != NODE_GROUP) {
- split = uiLayoutSplit(layout, 0.35f, false);
+ split = uiLayoutSplit(layout, 0.5f, false);
col = uiLayoutColumn(split, false);
col = uiLayoutColumn(split, false);
@@ -677,10 +678,10 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
label[i] = ' ';
}
label[indent] = '\0';
- BLI_snprintf(label + indent, UI_MAX_NAME_STR - indent, "%s:", IFACE_(input->name));
+ BLI_snprintf(label + indent, UI_MAX_NAME_STR - indent, "%s", IFACE_(input->name));
/* split in label and value */
- split = uiLayoutSplit(layout, 0.35f, false);
+ split = uiLayoutSplit(layout, 0.5f, false);
row = uiLayoutRow(split, true);
@@ -702,7 +703,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
uiItemL(row, label, ICON_NONE);
bt = block->buttons.last;
- bt->drawflag = UI_BUT_TEXT_LEFT;
+ bt->drawflag = UI_BUT_TEXT_RIGHT;
if (dependency_loop) {
row = uiLayoutRow(split, false);
@@ -736,7 +737,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
col = uiLayoutColumn(row, false);
uiItemR(col, &inputptr, "default_value", 0, "", ICON_NONE);
break;
-
+
default:
row = uiLayoutRow(split, false);
break;
diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c
index 2656c519624..21278dd9fa5 100644
--- a/source/blender/editors/space_node/node_toolbar.c
+++ b/source/blender/editors/space_node/node_toolbar.c
@@ -55,7 +55,7 @@ static int node_toolbar_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = node_has_tools_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -74,10 +74,10 @@ void NODE_OT_toolbar(wmOperatorType *ot)
ot->name = "Tool Shelf";
ot->description = "Toggles tool shelf display";
ot->idname = "NODE_OT_toolbar";
-
+
ot->exec = node_toolbar_toggle_exec;
ot->poll = node_toolbar_poll;
-
+
/* flags */
ot->flag = 0;
}
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index b85ef02b971..d52a6a89413 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -73,7 +73,7 @@ int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar,
float oldasp, asp;
int tot = 0;
bool has_frame = false;
-
+
oldwidth = BLI_rctf_size_x(&ar->v2d.cur);
oldheight = BLI_rctf_size_y(&ar->v2d.cur);
@@ -154,11 +154,11 @@ void NODE_OT_view_all(wmOperatorType *ot)
ot->name = "View All";
ot->idname = "NODE_OT_view_all";
ot->description = "Resize view so you can see all nodes";
-
+
/* api callbacks */
ot->exec = node_view_all_exec;
ot->poll = ED_operator_node_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -225,11 +225,12 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *e
case LEFTMOUSE:
case MIDDLEMOUSE:
case RIGHTMOUSE:
-
- MEM_freeN(nvm);
- op->customdata = NULL;
-
- return OPERATOR_FINISHED;
+ if (event->val == KM_RELEASE) {
+ MEM_freeN(nvm);
+ op->customdata = NULL;
+ return OPERATOR_FINISHED;
+ }
+ break;
}
return OPERATOR_RUNNING_MODAL;
@@ -394,7 +395,7 @@ typedef struct ImageSampleInfo {
unsigned char col[4];
float colf[4];
float linearcol[4];
-
+
int z;
float zf;
@@ -545,7 +546,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
info->color_manage = true;
}
-
+
if (ibuf->zbuf) {
info->z = ibuf->zbuf[y * ibuf->x + x];
info->zp = &info->z;
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index ccac730c88f..36886d0ab32 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -73,30 +73,30 @@ void ED_node_tree_start(SpaceNode *snode, bNodeTree *ntree, ID *id, ID *from)
MEM_freeN(path);
}
BLI_listbase_clear(&snode->treepath);
-
+
if (ntree) {
path = MEM_callocN(sizeof(bNodeTreePath), "node tree path");
path->nodetree = ntree;
path->parent_key = NODE_INSTANCE_KEY_BASE;
-
+
/* copy initial offset from bNodeTree */
copy_v2_v2(path->view_center, ntree->view_center);
-
+
if (id)
BLI_strncpy(path->node_name, id->name + 2, sizeof(path->node_name));
-
+
BLI_addtail(&snode->treepath, path);
-
+
id_us_ensure_real(&ntree->id);
}
-
+
/* update current tree */
snode->nodetree = snode->edittree = ntree;
snode->id = id;
snode->from = from;
-
+
ED_node_set_active_viewer_key(snode);
-
+
WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
}
@@ -110,44 +110,44 @@ void ED_node_tree_push(SpaceNode *snode, bNodeTree *ntree, bNode *gnode)
path->parent_key = BKE_node_instance_key(prev_path->parent_key, prev_path->nodetree, gnode);
else
path->parent_key = NODE_INSTANCE_KEY_BASE;
-
+
BLI_strncpy(path->node_name, gnode->name, sizeof(path->node_name));
}
else
path->parent_key = NODE_INSTANCE_KEY_BASE;
-
+
/* copy initial offset from bNodeTree */
copy_v2_v2(path->view_center, ntree->view_center);
-
+
BLI_addtail(&snode->treepath, path);
-
+
id_us_ensure_real(&ntree->id);
-
+
/* update current tree */
snode->edittree = ntree;
-
+
ED_node_set_active_viewer_key(snode);
-
+
WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
}
void ED_node_tree_pop(SpaceNode *snode)
{
bNodeTreePath *path = snode->treepath.last;
-
+
/* don't remove root */
if (path == snode->treepath.first)
return;
-
+
BLI_remlink(&snode->treepath, path);
MEM_freeN(path);
-
+
/* update current tree */
path = snode->treepath.last;
snode->edittree = path->nodetree;
-
+
ED_node_set_active_viewer_key(snode);
-
+
/* listener updates the View2D center from edittree */
WM_main_add_notifier(NC_SCENE | ND_NODES, NULL);
}
@@ -185,7 +185,7 @@ void ED_node_tree_path_get(SpaceNode *snode, char *value)
{
bNodeTreePath *path;
int i;
-
+
value[0] = '\0';
for (path = snode->treepath.first, i = 0; path; path = path->next, ++i) {
if (i == 0) {
@@ -203,7 +203,7 @@ void ED_node_tree_path_get_fixedbuf(SpaceNode *snode, char *value, int max_lengt
{
bNodeTreePath *path;
int size, i;
-
+
value[0] = '\0';
for (path = snode->treepath.first, i = 0; path; path = path->next, ++i) {
if (i == 0) {
@@ -230,7 +230,7 @@ void ED_node_set_active_viewer_key(SpaceNode *snode)
void snode_group_offset(SpaceNode *snode, float *x, float *y)
{
bNodeTreePath *path = snode->treepath.last;
-
+
if (path && path->prev) {
float dcenter[2];
sub_v2_v2v2(dcenter, path->view_center, path->prev->view_center);
@@ -270,24 +270,24 @@ ARegion *node_has_buttons_region(ScrArea *sa)
ARegion *node_has_tools_region(ScrArea *sa)
{
ARegion *ar, *arnew;
-
+
ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
if (ar) return ar;
-
+
/* add subdiv level; after header */
ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
-
+
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "node tools");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_TOOLS;
arnew->alignment = RGN_ALIGN_LEFT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
-
+
return arnew;
}
@@ -403,7 +403,7 @@ static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn
/* shift view to node tree center */
if (ar && path)
UI_view2d_center_set(&ar->v2d, path->view_center[0], path->view_center[1]);
-
+
ED_area_tag_refresh(sa);
break;
}
@@ -528,7 +528,7 @@ static void node_area_refresh(const struct bContext *C, ScrArea *sa)
{
/* default now: refresh node is starting preview */
SpaceNode *snode = sa->spacedata.first;
-
+
snode_set_context(C);
if (snode->nodetree) {
@@ -629,14 +629,14 @@ static void node_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
/* convert mouse coordinates to v2d space */
UI_view2d_region_to_view(&ar->v2d, win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin,
&snode->cursor[0], &snode->cursor[1]);
-
+
/* here snode->cursor is used to detect the node edge for sizing */
node_set_cursor(win, snode, snode->cursor);
/* XXX snode->cursor is in placing new nodes space */
snode->cursor[0] /= UI_DPI_FAC;
snode->cursor[1] /= UI_DPI_FAC;
-
+
}
/* Initialize main region, setting handlers. */
@@ -1040,7 +1040,7 @@ void ED_spacetype_node(void)
art->init = node_toolbar_region_init;
art->draw = node_toolbar_region_draw;
BLI_addhead(&st->regiontypes, art);
-
+
node_toolbar_register(art);
BKE_spacetype_register(st);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 2a6fedde065..f07f7f18d6a 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -105,7 +105,7 @@ static void outliner_width(SpaceOops *soops, ListBase *lb, int *w)
TreeElement *te = lb->first;
while (te) {
// TreeStoreElem *tselem = TREESTORE(te);
-
+
// XXX fixme... te->xend is not set yet
if (!TSELEM_OPEN(tselem, soops)) {
if (te->xend > *w)
@@ -159,7 +159,7 @@ static void restrictbutton_recursive_ebone(bContext *C, EditBone *ebone_parent,
Object *obedit = CTX_data_edit_object(C);
bArmature *arm = obedit->data;
EditBone *ebone;
-
+
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
if (set_flag) {
@@ -197,7 +197,7 @@ static void restrictbutton_r_lay_cb(bContext *C, void *poin, void *UNUSED(poin2)
static void restrictbutton_modifier_cb(bContext *C, void *UNUSED(poin), void *poin2)
{
Object *ob = (Object *)poin2;
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
}
@@ -265,9 +265,9 @@ static void restrictbutton_gp_layer_flag_cb(bContext *C, void *UNUSED(poin), voi
static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void *UNUSED(poin2))
{
ID *id = (ID *)poin;
-
+
BLI_assert(id != NULL);
-
+
if (id->flag & LIB_FAKEUSER) {
id_us_plus(id);
}
@@ -283,13 +283,13 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
Object *obedit = CTX_data_edit_object(C);
BLI_mempool *ts = soops->treestore;
TreeStoreElem *tselem = tsep;
-
+
if (ts && tselem) {
TreeElement *te = outliner_find_tree_element(&soops->tree, tselem);
-
+
if (tselem->type == 0) {
BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
-
+
switch (GS(tselem->id->name)) {
case ID_MA:
WM_event_add_notifier(C, NC_MATERIAL, NULL); break;
@@ -310,7 +310,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
BKE_library_filepath_set(bmain, lib, lib->name);
BLI_strncpy(expanded, lib->name, sizeof(expanded));
- BLI_path_abs(expanded, bmain->name);
+ BLI_path_abs(expanded, BKE_main_blendfile_path(bmain));
if (!BLI_exists(expanded)) {
BKE_reportf(CTX_wm_reports(C), RPT_ERROR,
"Library path '%s' does not exist, correct this before saving", expanded);
@@ -340,7 +340,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
/* restore bone name */
BLI_strncpy(newname, ebone->name, sizeof(ebone->name));
BLI_strncpy(ebone->name, oldname, sizeof(ebone->name));
- ED_armature_bone_rename(obedit->data, oldname, newname);
+ ED_armature_bone_rename(bmain, obedit->data, oldname, newname);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
break;
@@ -353,14 +353,14 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
bArmature *arm = (bArmature *)tselem->id;
Bone *bone = te->directdata;
char newname[sizeof(bone->name)];
-
+
/* always make current object active */
tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, true);
-
+
/* restore bone name */
BLI_strncpy(newname, bone->name, sizeof(bone->name));
BLI_strncpy(bone->name, oldname, sizeof(bone->name));
- ED_armature_bone_rename(arm, oldname, newname);
+ ED_armature_bone_rename(bmain, arm, oldname, newname);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
break;
}
@@ -371,16 +371,16 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
Object *ob = (Object *)tselem->id;
bPoseChannel *pchan = te->directdata;
char newname[sizeof(pchan->name)];
-
+
/* always make current pose-bone active */
tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, true);
BLI_assert(ob->type == OB_ARMATURE);
-
+
/* restore bone name */
BLI_strncpy(newname, pchan->name, sizeof(pchan->name));
BLI_strncpy(pchan->name, oldname, sizeof(pchan->name));
- ED_armature_bone_rename(ob->data, oldname, newname);
+ ED_armature_bone_rename(bmain, ob->data, oldname, newname);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
break;
}
@@ -388,7 +388,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
{
Object *ob = (Object *)tselem->id; // id = object
bActionGroup *grp = te->directdata;
-
+
BLI_uniquename(&ob->pose->agroups, grp, CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "Group"), '.',
offsetof(bActionGroup, name), sizeof(grp->name));
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
@@ -398,7 +398,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
{
bGPdata *gpd = (bGPdata *)tselem->id; // id = GP Datablock
bGPDlayer *gpl = te->directdata;
-
+
// XXX: name needs translation stuff
BLI_uniquename(&gpd->layers, gpl, "GP Layer", '.',
offsetof(bGPDlayer, info), sizeof(gpl->info));
@@ -433,7 +433,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
}
static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, ListBase *lb)
-{
+{
uiBut *bt;
TreeElement *te;
TreeStoreElem *tselem;
@@ -458,19 +458,19 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
ViewLayer *view_layer = te->directdata;
UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
+
bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, VIEW_LAYER_RENDER, 0, ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &view_layer->flag, 0, 0, 0, 0, TIP_("Use view layer for rendering"));
UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
+
UI_block_emboss_set(block, UI_EMBOSS);
}
else if (tselem->type == TSE_MODIFIER) {
ModifierData *md = (ModifierData *)te->directdata;
ob = (Object *)tselem->id;
-
+
UI_block_emboss_set(block, UI_EMBOSS_NONE);
bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
@@ -478,7 +478,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
TIP_("Restrict/Allow visibility in the 3D View"));
UI_but_func_set(bt, restrictbutton_modifier_cb, scene, ob);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
+
bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
@@ -491,7 +491,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
Bone *bone = pchan->bone;
ob = (Object *)tselem->id;
-
+
UI_block_emboss_set(block, UI_EMBOSS_NONE);
bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
@@ -499,7 +499,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
TIP_("Restrict/Allow visibility in the 3D View"));
UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
+
bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
@@ -511,7 +511,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
}
else if (tselem->type == TSE_EBONE) {
EditBone *ebone = (EditBone *)te->directdata;
-
+
UI_block_emboss_set(block, UI_EMBOSS_NONE);
bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
@@ -519,7 +519,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
TIP_("Restrict/Allow visibility in the 3D View"));
UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
+
bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
@@ -531,25 +531,25 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
}
else if (tselem->type == TSE_GP_LAYER) {
bGPDlayer *gpl = (bGPDlayer *)te->directdata;
-
+
UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
+
bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE, GP_LAYER_HIDE, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &gpl->flag, 0, 0, 0, 0,
TIP_("Restrict/Allow visibility in the 3D View"));
UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, NULL, gpl);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
+
bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE, GP_LAYER_LOCKED, 0, ICON_UNLOCKED,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &gpl->flag, 0, 0, 0, 0,
TIP_("Restrict/Allow editing of strokes and keyframes in this layer"));
UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, NULL, gpl);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
-
+
/* TODO: visibility in renders */
-
+
UI_block_emboss_set(block, UI_EMBOSS);
}
else if (outliner_is_collection_tree_element(te)) {
@@ -583,7 +583,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
UI_block_emboss_set(block, UI_EMBOSS);
}
}
-
+
if (TSELEM_OPEN(tselem, soops)) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree);
}
}
@@ -622,16 +622,16 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOops *soops
&id->flag, 0, 0, 0, 0, tip);
UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
UI_but_flag_enable(bt, but_flag);
-
-
+
+
BLI_str_format_int_grouped(buf, id->us);
- bt = uiDefBut(block, UI_BTYPE_BUT, 1, buf,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys,
+ bt = uiDefBut(block, UI_BTYPE_BUT, 1, buf,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys,
UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0,
TIP_("Number of users of this data-block"));
UI_but_flag_enable(bt, but_flag);
-
-
+
+
bt = uiDefButBitS(block, UI_BTYPE_TOGGLE, LIB_FAKEUSER, 1, (id->flag & LIB_FAKEUSER) ? "F" : " ",
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
&id->flag, 0, 0, 0, 0,
@@ -639,11 +639,11 @@ static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOops *soops
"even if nothing else uses it"));
UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
UI_but_flag_enable(bt, but_flag);
-
+
UI_block_emboss_set(block, UI_EMBOSS);
}
}
-
+
if (TSELEM_OPEN(tselem, soops)) outliner_draw_userbuts(block, ar, soops, &te->subtree);
}
}
@@ -707,12 +707,12 @@ static void outliner_draw_rnabuts(uiBlock *block, ARegion *ar, SpaceOops *soops,
else if (tselem->type == TSE_RNA_ARRAY_ELEM) {
ptr = &te->rnaptr;
prop = te->directdata;
-
+
uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
UI_UNIT_Y - 1);
}
}
-
+
if (TSELEM_OPEN(tselem, soops)) outliner_draw_rnabuts(block, ar, soops, sizex, &te->subtree);
}
@@ -776,7 +776,7 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
uiBut *but = uiDefIconBut(arg->block, UI_BTYPE_LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL,
0.0, 0.0, 1.0, arg->alpha,
(arg->id && ID_IS_LINKED(arg->id)) ? arg->id->lib->name : "");
-
+
if (arg->id)
UI_but_drag_set_id(but, arg->id);
}
@@ -800,17 +800,17 @@ static void UNUSED_FUNCTION(tselem_draw_gp_icon_uibut)(struct DrawIconArg *arg,
RNA_pointer_create(id, &RNA_GPencilLayer, gpl, &ptr);
UI_block_align_begin(arg->block);
-
+
UI_block_emboss_set(arg->block, is_stroke_visible ? UI_EMBOSS : UI_EMBOSS_NONE);
uiDefButR(arg->block, UI_BTYPE_COLOR, 1, "", arg->xb, arg->yb, w, h,
&ptr, "color", -1,
0, 0, 0, 0, NULL);
-
+
UI_block_emboss_set(arg->block, is_fill_visible ? UI_EMBOSS : UI_EMBOSS_NONE);
uiDefButR(arg->block, UI_BTYPE_COLOR, 1, "", arg->xb + w, arg->yb, w, h,
&ptr, "fill_color", -1,
0, 0, 0, 0, NULL);
-
+
UI_block_emboss_set(arg->block, UI_EMBOSS_NONE);
UI_block_align_end(arg->block);
}
@@ -821,7 +821,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
{
struct DrawIconArg arg;
float aspect;
-
+
/* make function calls a bit compacter */
arg.block = block;
arg.id = tselem->id;
@@ -1294,16 +1294,16 @@ static void outliner_draw_iconrow(
color);
glEnable(GL_BLEND); /* roundbox disables */
}
-
+
tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f * alpha_fac);
te->xs = *offsx;
te->ys = ys;
te->xend = (short)*offsx + UI_UNIT_X;
te->flag |= TE_ICONROW; // for click
-
+
(*offsx) += UI_UNIT_X;
}
-
+
/* this tree element always has same amount of branches, so don't draw */
if (tselem->type != TSE_R_LAYER) {
outliner_draw_iconrow(
@@ -1311,7 +1311,7 @@ static void outliner_draw_iconrow(
&te->subtree, level + 1, xmax, offsx, ys, alpha_fac);
}
}
-
+
}
/* closed tree element */
@@ -1359,7 +1359,7 @@ static void outliner_draw_tree_element(
/* icons can be ui buts, we don't want it to overlap with restrict */
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0)
xmax -= OL_TOGW + UI_UNIT_X;
-
+
glEnable(GL_BLEND);
/* colors for active/selected data */
@@ -1378,16 +1378,16 @@ static void outliner_draw_tree_element(
if (ob == obact || is_selected) {
char col[4] = {0, 0, 0, 0};
-
+
/* outliner active ob: always white text, circle color now similar to view3d */
-
+
active = OL_DRAWSEL_ACTIVE;
if (ob == obact) {
if (is_selected) {
UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col);
col[3] = alpha;
}
-
+
active = OL_DRAWSEL_NORMAL;
}
else if (is_selected) {
@@ -1412,7 +1412,7 @@ static void outliner_draw_tree_element(
active = tree_element_type_active(C, scene, view_layer, soops, te, tselem, OL_SETSEL_NONE, false);
rgba_float_args_set(color, 0.85f, 0.85f, 1.0f, alpha);
}
-
+
/* active circle */
if (active != OL_DRAWSEL_NONE) {
UI_draw_roundbox_corner_set(UI_CNR_ALL);
@@ -1424,10 +1424,10 @@ static void outliner_draw_tree_element(
(float)*starty + UI_UNIT_Y - 1.0f * ufac,
UI_UNIT_Y / 2.0f - 1.0f * ufac, color);
glEnable(GL_BLEND); /* roundbox disables it */
-
+
te->flag |= TE_ACTIVE; // for lookup in display hierarchies
}
-
+
if (tselem->type == TSE_VIEW_COLLECTION_BASE) {
/* Scene collection in view layer can't expand/collapse. */
}
@@ -1444,16 +1444,16 @@ static void outliner_draw_tree_element(
alpha_fac);
}
offsx += UI_UNIT_X;
-
+
/* datatype icon */
-
+
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) {
tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac);
offsx += UI_UNIT_X + 2 * ufac;
}
else
offsx += 2 * ufac;
-
+
if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_LINKED(tselem->id)) {
if (tselem->id->tag & LIB_TAG_MISSING) {
UI_icon_draw_alpha((float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_BROKEN,
@@ -1475,7 +1475,7 @@ static void outliner_draw_tree_element(
offsx += UI_UNIT_X + 2 * ufac;
}
glDisable(GL_BLEND);
-
+
/* name */
if ((tselem->flag & TSE_TEXTBUT) == 0) {
unsigned char text_col[4];
@@ -1494,9 +1494,9 @@ static void outliner_draw_tree_element(
UI_fontstyle_draw_simple(fstyle, startx + offsx, *starty + 5 * ufac, te->name, text_col);
}
-
+
offsx += (int)(UI_UNIT_X + UI_fontstyle_string_width(fstyle, te->name));
-
+
/* closed item, we draw the icons, not when it's a scene, or master-server list though */
if (!TSELEM_OPEN(tselem, soops)) {
if (te->subtree.first) {
@@ -1558,7 +1558,7 @@ static void outliner_draw_tree_element(
for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) {
outliner_set_coord_tree_element(ten, startx, *starty);
}
-
+
*starty -= UI_UNIT_Y;
}
}
@@ -1650,7 +1650,7 @@ static void outliner_draw_hierarchy_lines_recursive(unsigned pos, SpaceOops *soo
}
*starty -= UI_UNIT_Y;
-
+
if (TSELEM_OPEN(tselem, soops))
outliner_draw_hierarchy_lines_recursive(pos, soops, &te->subtree, startx + UI_UNIT_X,
col, draw_childs_grayed_out, starty);
@@ -1694,7 +1694,7 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
-
+
/* selection status */
if (TSELEM_OPEN(tselem, soops))
if (tselem->type == TSE_RNA_STRUCT) {
@@ -1822,7 +1822,7 @@ static void outliner_draw_tree(
}
// gray hierarchy lines
-
+
starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET;
startx = UI_UNIT_X / 2 - 1.0f;
outliner_draw_hierarchy_lines(soops, &soops->tree, startx, &starty);
@@ -1850,7 +1850,7 @@ static void outliner_draw_tree(
static void outliner_back(ARegion *ar)
{
int ystart;
-
+
ystart = (int)ar->v2d.tot.ymax;
ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
@@ -1909,7 +1909,7 @@ static void outliner_draw_restrictcols(ARegion *ar)
void draw_outliner(const bContext *C)
{
- Main *mainvar = CTX_data_main(C);
+ Main *mainvar = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
ARegion *ar = CTX_wm_region(C);
@@ -1921,7 +1921,7 @@ void draw_outliner(const bContext *C)
bool has_restrict_icons;
outliner_build_tree(mainvar, scene, view_layer, soops, ar); // always
-
+
/* get extents of data */
outliner_height(soops, &soops->tree, &sizey);
@@ -1933,11 +1933,11 @@ void draw_outliner(const bContext *C)
*
* (*) XXX max width for now is a fixed factor of (UI_UNIT_X * (max_indention + 100))
*/
-
+
/* get actual width of column 1 */
outliner_rna_width(soops, &soops->tree, &sizex_rna, 0);
sizex_rna = max_ii(OL_RNA_COLX, sizex_rna + OL_RNA_COL_SPACEX);
-
+
/* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
sizex = sizex_rna + OL_RNA_COL_SIZEX + 50;
has_restrict_icons = false;
@@ -1947,7 +1947,7 @@ void draw_outliner(const bContext *C)
//outliner_width(soops, &soops->tree, &sizex);
// XXX should use outliner_width instead when te->xend will be set correctly...
outliner_rna_width(soops, &soops->tree, &sizex, 0);
-
+
/* constant offset for restriction columns */
// XXX this isn't that great yet...
if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) {
@@ -1956,7 +1956,7 @@ void draw_outliner(const bContext *C)
has_restrict_icons = !(soops->flag & SO_HIDE_RESTRICTCOLS);
}
-
+
/* adds vertical offset */
sizey += OL_Y_OFFSET;
@@ -1998,4 +1998,4 @@ void draw_outliner(const bContext *C)
UI_block_end(C, block);
UI_block_draw(C, block);
-}
+}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 2aa33875bd1..2a694e2e2e3 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -98,19 +98,19 @@ static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *te
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = lb->first; te; te = te->next) {
/* check if this tree-element was the one we're seeking */
if (te == teFind) {
*found = 1;
return;
}
-
+
/* try to see if sub-tree contains it then */
outliner_open_reveal(soops, &te->subtree, teFind, found);
if (*found) {
tselem = TREESTORE(te);
- if (tselem->flag & TSE_CLOSED)
+ if (tselem->flag & TSE_CLOSED)
tselem->flag &= ~TSE_CLOSED;
return;
}
@@ -193,10 +193,10 @@ void OUTLINER_OT_highlight_update(wmOperatorType *ot)
static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement *te, const bool all, const float mval[2])
{
-
+
if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
TreeStoreElem *tselem = TREESTORE(te);
-
+
/* all below close/open? */
if (all) {
tselem->flag &= ~TSE_CLOSED;
@@ -206,16 +206,16 @@ static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement
if (tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED;
else tselem->flag |= TSE_CLOSED;
}
-
+
return 1;
}
-
+
for (te = te->subtree.first; te; te = te->next) {
- if (do_outliner_item_openclose(C, soops, te, all, mval))
+ if (do_outliner_item_openclose(C, soops, te, all, mval))
return 1;
}
return 0;
-
+
}
/* event can enterkey, then it opens/closes */
@@ -226,16 +226,16 @@ static int outliner_item_openclose(bContext *C, wmOperator *op, const wmEvent *e
TreeElement *te;
float fmval[2];
const bool all = RNA_boolean_get(op->ptr, "all");
-
+
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
+
for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_openclose(C, soops, te, all, fmval))
+ if (do_outliner_item_openclose(C, soops, te, all, fmval))
break;
}
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -244,11 +244,11 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
ot->name = "Open/Close Item";
ot->idname = "OUTLINER_OT_item_openclose";
ot->description = "Toggle whether item under cursor is enabled or closed";
-
+
ot->invoke = outliner_item_openclose;
-
+
ot->poll = ED_operator_outliner_active;
-
+
RNA_def_boolean(ot->srna, "all", 1, "All", "Close or open all items");
}
@@ -311,7 +311,7 @@ static int do_outliner_item_rename(ReportList *reports, ARegion *ar, TreeElement
{
if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
TreeStoreElem *tselem = TREESTORE(te);
-
+
/* click on name */
if (mval[0] > te->xs + UI_UNIT_X * 2 && mval[0] < te->xend) {
do_item_rename(ar, te, tselem, reports);
@@ -319,7 +319,7 @@ static int do_outliner_item_rename(ReportList *reports, ARegion *ar, TreeElement
}
return 0;
}
-
+
for (te = te->subtree.first; te; te = te->next) {
if (do_outliner_item_rename(reports, ar, te, mval)) return 1;
}
@@ -333,16 +333,16 @@ static int outliner_item_rename(bContext *C, wmOperator *op, const wmEvent *even
TreeElement *te;
float fmval[2];
bool changed = false;
-
+
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
+
for (te = soops->tree.first; te; te = te->next) {
if (do_outliner_item_rename(op->reports, ar, te, fmval)) {
changed = true;
break;
}
}
-
+
return changed ? OPERATOR_FINISHED : OPERATOR_PASS_THROUGH;
}
@@ -352,9 +352,9 @@ void OUTLINER_OT_item_rename(wmOperatorType *ot)
ot->name = "Rename Item";
ot->idname = "OUTLINER_OT_item_rename";
ot->description = "Rename item under cursor";
-
+
ot->invoke = outliner_item_rename;
-
+
ot->poll = ED_operator_outliner_active;
}
@@ -775,9 +775,9 @@ static int outliner_count_levels(ListBase *lb, const int curlevel)
{
TreeElement *te;
int level = curlevel, lev;
-
+
for (te = lb->first; te; te = te->next) {
-
+
lev = outliner_count_levels(&te->subtree, curlevel + 1);
if (lev > level) level = lev;
}
@@ -789,11 +789,11 @@ int outliner_has_one_flag(ListBase *lb, short flag, const int curlevel)
TreeElement *te;
TreeStoreElem *tselem;
int level;
-
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
if (tselem->flag & flag) return curlevel;
-
+
level = outliner_has_one_flag(&te->subtree, flag, curlevel + 1);
if (level) return level;
}
@@ -850,7 +850,7 @@ int common_restrict_check(bContext *C, Object *ob)
ob->restrictflag &= ~OB_RESTRICT_SELECT;
return 0;
}
-
+
return 1;
}
@@ -863,14 +863,14 @@ static int outliner_toggle_expanded_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceOops *soops = CTX_wm_space_outliner(C);
ARegion *ar = CTX_wm_region(C);
-
+
if (outliner_has_one_flag(&soops->tree, TSE_CLOSED, 1))
outliner_set_flag(&soops->tree, TSE_CLOSED, 0);
- else
+ else
outliner_set_flag(&soops->tree, TSE_CLOSED, 1);
-
+
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -880,11 +880,11 @@ void OUTLINER_OT_expanded_toggle(wmOperatorType *ot)
ot->name = "Expand/Collapse All";
ot->idname = "OUTLINER_OT_expanded_toggle";
ot->description = "Expand/Collapse all items";
-
+
/* callbacks */
ot->exec = outliner_toggle_expanded_exec;
ot->poll = ED_operator_outliner_active;
-
+
/* no undo or registry, UI option */
}
@@ -895,15 +895,15 @@ static int outliner_toggle_selected_exec(bContext *C, wmOperator *UNUSED(op))
SpaceOops *soops = CTX_wm_space_outliner(C);
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
-
+
if (outliner_has_one_flag(&soops->tree, TSE_SELECTED, 1))
outliner_set_flag(&soops->tree, TSE_SELECTED, 0);
- else
+ else
outliner_set_flag(&soops->tree, TSE_SELECTED, 1);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
ED_region_tag_redraw_no_rebuild(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -913,11 +913,11 @@ void OUTLINER_OT_selected_toggle(wmOperatorType *ot)
ot->name = "Toggle Selected";
ot->idname = "OUTLINER_OT_selected_toggle";
ot->description = "Toggle the Outliner selection of items";
-
+
/* callbacks */
ot->exec = outliner_toggle_selected_exec;
ot->poll = ED_operator_outliner_active;
-
+
/* no undo or registry, UI option */
}
@@ -976,7 +976,7 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
ViewLayer *view_layer = CTX_data_view_layer(C);
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
-
+
TreeElement *te;
int xdelta, ytop;
@@ -1015,18 +1015,18 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
/* make te->ys center of view */
ytop = te->ys + BLI_rcti_size_y(&v2d->mask) / 2;
if (ytop > 0) ytop = 0;
-
+
v2d->cur.ymax = (float)ytop;
v2d->cur.ymin = (float)(ytop - BLI_rcti_size_y(&v2d->mask));
-
+
/* make te->xs ==> te->xend center of view */
xdelta = (int)(te->xs - v2d->cur.xmin);
v2d->cur.xmin += xdelta;
v2d->cur.xmax += xdelta;
}
-
+
ED_region_tag_redraw_no_rebuild(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -1036,7 +1036,7 @@ void OUTLINER_OT_show_active(wmOperatorType *ot)
ot->name = "Show Active";
ot->idname = "OUTLINER_OT_show_active";
ot->description = "Open up the tree and adjust the view so that the active Object is shown centered";
-
+
/* callbacks */
ot->exec = outliner_show_active_exec;
ot->poll = ED_operator_outliner_active;
@@ -1049,16 +1049,16 @@ static int outliner_scroll_page_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
int dy = BLI_rcti_size_y(&ar->v2d.mask);
int up = 0;
-
+
if (RNA_boolean_get(op->ptr, "up"))
up = 1;
if (up == 0) dy = -dy;
ar->v2d.cur.ymin += dy;
ar->v2d.cur.ymax += dy;
-
+
ED_region_tag_redraw_no_rebuild(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -1071,11 +1071,11 @@ void OUTLINER_OT_scroll_page(wmOperatorType *ot)
ot->name = "Scroll Page";
ot->idname = "OUTLINER_OT_scroll_page";
ot->description = "Scroll page up or down";
-
+
/* callbacks */
ot->exec = outliner_scroll_page_exec;
ot->poll = ED_operator_outliner_active;
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "up", 0, "Up", "Scroll up one page");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -1091,14 +1091,14 @@ static TreeElement *outliner_find_name(SpaceOops *soops, ListBase *lb, char *nam
TreeElement *prev, int *prevFound)
{
TreeElement *te, *tes;
-
+
for (te = lb->first; te; te = te->next) {
int found = outliner_filter_has_name(te, name, flags);
-
+
if (found) {
/* name is right, but is element the previous one? */
if (prev) {
- if ((te != prev) && (*prevFound))
+ if ((te != prev) && (*prevFound))
return te;
if (te == prev) {
*prevFound = 1;
@@ -1107,7 +1107,7 @@ static TreeElement *outliner_find_name(SpaceOops *soops, ListBase *lb, char *nam
else
return te;
}
-
+
tes = outliner_find_name(soops, &te->subtree, name, flags, prev, prevFound);
if (tes) return tes;
}
@@ -1116,7 +1116,7 @@ static TreeElement *outliner_find_name(SpaceOops *soops, ListBase *lb, char *nam
return NULL;
}
-static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOops *soops, int again, int flags)
+static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOops *soops, int again, int flags)
{
ReportList *reports = NULL; // CTX_wm_reports(C);
TreeElement *te = NULL;
@@ -1124,16 +1124,16 @@ static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOops *so
TreeStoreElem *tselem;
int ytop, xdelta, prevFound = 0;
char name[sizeof(soops->search_string)];
-
+
/* get last found tree-element based on stored search_tse */
last_find = outliner_find_tse(soops, &soops->search_tse);
-
+
/* determine which type of search to do */
if (again && last_find) {
/* no popup panel - previous + user wanted to search for next after previous */
BLI_strncpy(name, soops->search_string, sizeof(name));
flags = soops->search_flags;
-
+
/* try to find matching element */
te = outliner_find_name(soops, &soops->tree, name, flags, last_find, &prevFound);
if (te == NULL) {
@@ -1158,28 +1158,28 @@ static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOops *so
/* expand branches so that it will be visible, we need to get correct coordinates */
if (outliner_open_back(soops, te))
outliner_set_coordinates(ar, soops);
-
+
/* deselect all visible, and select found element */
outliner_set_flag(soops, &soops->tree, TSE_SELECTED, 0);
tselem->flag |= TSE_SELECTED;
-
+
/* make te->ys center of view */
ytop = (int)(te->ys + BLI_rctf_size_y(&ar->v2d.mask) / 2);
if (ytop > 0) ytop = 0;
ar->v2d.cur.ymax = (float)ytop;
ar->v2d.cur.ymin = (float)(ytop - BLI_rctf_size_y(&ar->v2d.mask));
-
+
/* make te->xs ==> te->xend center of view */
xdelta = (int)(te->xs - ar->v2d.cur.xmin);
ar->v2d.cur.xmin += xdelta;
ar->v2d.cur.xmax += xdelta;
-
+
/* store selection */
soops->search_tse = *tselem;
-
+
BLI_strncpy(soops->search_string, name, sizeof(soops->search_string));
soops->search_flags = flags;
-
+
/* redraw */
ED_region_tag_redraw_no_rebuild(ar);
}
@@ -1198,17 +1198,17 @@ static void outliner_openclose_level(ListBase *lb, int curlevel, int level, int
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
-
+
if (open) {
if (curlevel <= level) tselem->flag &= ~TSE_CLOSED;
}
else {
if (curlevel >= level) tselem->flag |= TSE_CLOSED;
}
-
+
outliner_openclose_level(&te->subtree, curlevel + 1, level, open);
}
}
@@ -1219,7 +1219,7 @@ static int outliner_one_level_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
const bool add = RNA_boolean_get(op->ptr, "open");
int level;
-
+
level = outliner_has_one_flag(&soops->tree, TSE_CLOSED, 1);
if (add == 1) {
if (level) outliner_openclose_level(&soops->tree, 1, level, 1);
@@ -1228,9 +1228,9 @@ static int outliner_one_level_exec(bContext *C, wmOperator *op)
if (level == 0) level = outliner_count_levels(&soops->tree, 0);
if (level) outliner_openclose_level(&soops->tree, 1, level - 1, 0);
}
-
+
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -1242,13 +1242,13 @@ void OUTLINER_OT_show_one_level(wmOperatorType *ot)
ot->name = "Show/Hide One Level";
ot->idname = "OUTLINER_OT_show_one_level";
ot->description = "Expand/collapse all entries by one level";
-
+
/* callbacks */
ot->exec = outliner_one_level_exec;
ot->poll = ED_operator_outliner_active;
-
+
/* no undo or registry, UI option */
-
+
/* properties */
prop = RNA_def_boolean(ot->srna, "open", 1, "Open", "Expand all entries one level deep");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -1261,7 +1261,7 @@ static int subtree_has_objects(ListBase *lb)
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
if (tselem->type == 0 && te->idcode == ID_OB) return 1;
@@ -1279,7 +1279,7 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase
/* open all object elems, close others */
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
-
+
if (tselem->type == 0) {
if (te->idcode == ID_SCE) {
if (tselem->id != (ID *)scene) tselem->flag |= TSE_CLOSED;
@@ -1306,12 +1306,12 @@ static int outliner_show_hierarchy_exec(bContext *C, wmOperator *UNUSED(op))
SpaceOops *soops = CTX_wm_space_outliner(C);
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
-
+
/* recursively open/close levels */
tree_element_show_hierarchy(scene, soops, &soops->tree);
-
+
ED_region_tag_redraw(ar);
-
+
return OPERATOR_FINISHED;
}
@@ -1321,11 +1321,11 @@ void OUTLINER_OT_show_hierarchy(wmOperatorType *ot)
ot->name = "Show Hierarchy";
ot->idname = "OUTLINER_OT_show_hierarchy";
ot->description = "Open all object entries and close all others";
-
+
/* callbacks */
ot->exec = outliner_show_hierarchy_exec;
ot->poll = ED_operator_outliner_active; // TODO: shouldn't be allowed in RNA views...
-
+
/* no undo or registry, UI option */
}
@@ -1345,7 +1345,7 @@ static int ed_operator_outliner_datablocks_active(bContext *C)
}
-/* Helper func to extract an RNA path from selected tree element
+/* Helper func to extract an RNA path from selected tree element
* NOTE: the caller must zero-out all values of the pointers that it passes here first, as
* this function does not do that yet
*/
@@ -1359,29 +1359,29 @@ static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
PointerRNA *ptr, *nextptr;
PropertyRNA *prop;
char *newpath = NULL;
-
+
/* optimize tricks:
* - Don't do anything if the selected item is a 'struct', but arrays are allowed
*/
if (tselem->type == TSE_RNA_STRUCT)
return;
-
+
/* Overview of Algorithm:
* 1. Go up the chain of parents until we find the 'root', taking note of the
* levels encountered in reverse-order (i.e. items are added to the start of the list
* for more convenient looping later)
* 2. Walk down the chain, adding from the first ID encountered
- * (which will become the 'ID' for the KeyingSet Path), and build a
+ * (which will become the 'ID' for the KeyingSet Path), and build a
* path as we step through the chain
*/
-
+
/* step 1: flatten out hierarchy of parents into a flat chain */
for (tem = te->parent; tem; tem = tem->parent) {
ld = MEM_callocN(sizeof(LinkData), "LinkData for tree_element_to_path()");
ld->data = tem;
BLI_addhead(&hierarchy, ld);
}
-
+
/* step 2: step down hierarchy building the path
* (NOTE: addhead in previous loop was needed so that we can loop like this) */
for (ld = hierarchy.first; ld; ld = ld->next) {
@@ -1390,10 +1390,10 @@ static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
tse = TREESTORE(tem);
ptr = &tem->rnaptr;
prop = tem->directdata;
-
+
/* check if we're looking for first ID, or appending to path */
if (*id) {
- /* just 'append' property to path
+ /* just 'append' property to path
* - to prevent memory leaks, we must write to newpath not path, then free old path + swap them
*/
if (tse->type == TSE_RNA_PROPERTY) {
@@ -1403,35 +1403,35 @@ static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
}
else if (RNA_property_type(prop) == PROP_COLLECTION) {
char buf[128], *name;
-
+
temnext = (TreeElement *)(ld->next->data);
/* tsenext = TREESTORE(temnext); */ /* UNUSED */
-
+
nextptr = &temnext->rnaptr;
name = RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf), NULL);
-
+
if (name) {
/* if possible, use name as a key in the path */
newpath = RNA_path_append(*path, NULL, prop, 0, name);
-
+
if (name != buf)
MEM_freeN(name);
}
else {
/* otherwise use index */
int index = 0;
-
+
for (temsub = tem->subtree.first; temsub; temsub = temsub->next, index++)
if (temsub == temnext)
break;
-
+
newpath = RNA_path_append(*path, NULL, prop, index, NULL);
}
-
+
ld = ld->next;
}
}
-
+
if (newpath) {
if (*path) MEM_freeN(*path);
*path = newpath;
@@ -1445,7 +1445,7 @@ static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
* since ptr->data is sometimes the owner of this ID? */
if (RNA_struct_is_ID(ptr->type)) {
*id = (ID *)ptr->data;
-
+
/* clear path */
if (*path) {
MEM_freeN(*path);
@@ -1461,7 +1461,7 @@ static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
/* add the active property to the path */
ptr = &te->rnaptr;
prop = te->directdata;
-
+
/* array checks */
if (tselem->type == TSE_RNA_ARRAY_ELEM) {
/* item is part of an array, so must set the array_index */
@@ -1471,7 +1471,7 @@ static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
/* entire array was selected, so keyframe all */
*flag |= KSP_FLAG_WHOLE_ARRAY;
}
-
+
/* path */
newpath = RNA_path_append(*path, NULL, prop, 0, NULL);
if (*path) MEM_freeN(*path);
@@ -1493,17 +1493,17 @@ enum {
DRIVERS_EDITMODE_REMOVE,
} /*eDrivers_EditModes*/;
-/* Utilities ---------------------------------- */
+/* Utilities ---------------------------------- */
/* Recursively iterate over tree, finding and working on selected items */
static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportList *reports, short mode)
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = tree->first; te; te = te->next) {
tselem = TREESTORE(te);
-
+
/* if item is selected, perform operation */
if (tselem->flag & TSE_SELECTED) {
ID *id = NULL;
@@ -1511,7 +1511,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL
int array_index = 0;
short flag = 0;
short groupmode = KSP_GROUP_KSNAME;
-
+
/* check if RNA-property described by this selected element is an animatable prop */
if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) &&
RNA_property_animateable(&te->rnaptr, te->directdata))
@@ -1520,12 +1520,12 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL
tree_element_to_path(te, tselem,
&id, &path, &array_index, &flag, &groupmode);
}
-
+
/* only if ID and path were set, should we perform any actions */
if (id && path) {
short dflags = CREATEDRIVER_WITH_DEFAULT_DVAR;
int arraylen = 1;
-
+
/* array checks */
if (flag & KSP_FLAG_WHOLE_ARRAY) {
/* entire array was selected, so add drivers for all */
@@ -1533,11 +1533,11 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL
}
else
arraylen = array_index;
-
+
/* we should do at least one step */
if (arraylen == array_index)
arraylen++;
-
+
/* for each array element we should affect, add driver */
for (; array_index < arraylen; array_index++) {
/* action depends on mode */
@@ -1556,14 +1556,14 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL
}
}
}
-
+
/* free path, since it had to be generated */
MEM_freeN(path);
}
-
-
+
+
}
-
+
/* go over sub-tree */
if (TSELEM_OPEN(tselem, soops))
do_outliner_drivers_editop(soops, &te->subtree, reports, mode);
@@ -1575,17 +1575,17 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL
static int outliner_drivers_addsel_exec(bContext *C, wmOperator *op)
{
SpaceOops *soutliner = CTX_wm_space_outliner(C);
-
+
/* check for invalid states */
if (soutliner == NULL)
return OPERATOR_CANCELLED;
-
+
/* recursively go into tree, adding selected items */
do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_ADD);
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
-
+
return OPERATOR_FINISHED;
}
@@ -1595,11 +1595,11 @@ void OUTLINER_OT_drivers_add_selected(wmOperatorType *ot)
ot->idname = "OUTLINER_OT_drivers_add_selected";
ot->name = "Add Drivers for Selected";
ot->description = "Add drivers to selected items";
-
+
/* api callbacks */
ot->exec = outliner_drivers_addsel_exec;
ot->poll = ed_operator_outliner_datablocks_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1610,17 +1610,17 @@ void OUTLINER_OT_drivers_add_selected(wmOperatorType *ot)
static int outliner_drivers_deletesel_exec(bContext *C, wmOperator *op)
{
SpaceOops *soutliner = CTX_wm_space_outliner(C);
-
+
/* check for invalid states */
if (soutliner == NULL)
return OPERATOR_CANCELLED;
-
+
/* recursively go into tree, adding selected items */
do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_REMOVE);
-
+
/* send notifiers */
WM_event_add_notifier(C, ND_KEYS, NULL); // XXX
-
+
return OPERATOR_FINISHED;
}
@@ -1630,11 +1630,11 @@ void OUTLINER_OT_drivers_delete_selected(wmOperatorType *ot)
ot->idname = "OUTLINER_OT_drivers_delete_selected";
ot->name = "Delete Drivers for Selected";
ot->description = "Delete drivers assigned to selected items";
-
+
/* api callbacks */
ot->exec = outliner_drivers_deletesel_exec;
ot->poll = ed_operator_outliner_datablocks_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1650,29 +1650,29 @@ enum {
KEYINGSET_EDITMODE_REMOVE,
} /*eKeyingSet_EditModes*/;
-/* Utilities ---------------------------------- */
-
+/* Utilities ---------------------------------- */
+
/* find the 'active' KeyingSet, and add if not found (if adding is allowed) */
// TODO: should this be an API func?
static KeyingSet *verify_active_keyingset(Scene *scene, short add)
{
KeyingSet *ks = NULL;
-
+
/* sanity check */
if (scene == NULL)
return NULL;
-
+
/* try to find one from scene */
if (scene->active_keyingset > 0)
ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
+
/* add if none found */
// XXX the default settings have yet to evolve
if ((add) && (ks == NULL)) {
ks = BKE_keyingset_add(&scene->keyingsets, NULL, NULL, KEYINGSET_ABSOLUTE, 0);
scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
}
-
+
return ks;
}
@@ -1681,10 +1681,10 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = tree->first; te; te = te->next) {
tselem = TREESTORE(te);
-
+
/* if item is selected, perform operation */
if (tselem->flag & TSE_SELECTED) {
ID *id = NULL;
@@ -1692,7 +1692,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
int array_index = 0;
short flag = 0;
short groupmode = KSP_GROUP_KSNAME;
-
+
/* check if RNA-property described by this selected element is an animatable prop */
if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) &&
RNA_property_animateable(&te->rnaptr, te->directdata))
@@ -1701,7 +1701,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
tree_element_to_path(te, tselem,
&id, &path, &array_index, &flag, &groupmode);
}
-
+
/* only if ID and path were set, should we perform any actions */
if (id && path) {
/* action depends on mode */
@@ -1719,7 +1719,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
{
/* find the relevant path, then remove it from the KeyingSet */
KS_Path *ksp = BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode);
-
+
if (ksp) {
/* free path's data */
BKE_keyingset_free_path(ks, ksp);
@@ -1729,12 +1729,12 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
break;
}
}
-
+
/* free path, since it had to be generated */
MEM_freeN(path);
}
}
-
+
/* go over sub-tree */
if (TSELEM_OPEN(tselem, soops))
do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
@@ -1748,7 +1748,7 @@ static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op)
SpaceOops *soutliner = CTX_wm_space_outliner(C);
Scene *scene = CTX_data_scene(C);
KeyingSet *ks = verify_active_keyingset(scene, 1);
-
+
/* check for invalid states */
if (ks == NULL) {
BKE_report(op->reports, RPT_ERROR, "Operation requires an active keying set");
@@ -1756,13 +1756,13 @@ static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op)
}
if (soutliner == NULL)
return OPERATOR_CANCELLED;
-
+
/* recursively go into tree, adding selected items */
do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_ADD);
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1772,11 +1772,11 @@ void OUTLINER_OT_keyingset_add_selected(wmOperatorType *ot)
ot->idname = "OUTLINER_OT_keyingset_add_selected";
ot->name = "Keying Set Add Selected";
ot->description = "Add selected items (blue-gray rows) to active Keying Set";
-
+
/* api callbacks */
ot->exec = outliner_keyingset_additems_exec;
ot->poll = ed_operator_outliner_datablocks_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1789,17 +1789,17 @@ static int outliner_keyingset_removeitems_exec(bContext *C, wmOperator *UNUSED(o
SpaceOops *soutliner = CTX_wm_space_outliner(C);
Scene *scene = CTX_data_scene(C);
KeyingSet *ks = verify_active_keyingset(scene, 1);
-
+
/* check for invalid states */
if (soutliner == NULL)
return OPERATOR_CANCELLED;
-
+
/* recursively go into tree, adding selected items */
do_outliner_keyingset_editop(soutliner, ks, &soutliner->tree, KEYINGSET_EDITMODE_REMOVE);
-
+
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1809,11 +1809,11 @@ void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot)
ot->idname = "OUTLINER_OT_keyingset_remove_selected";
ot->name = "Keying Set Remove Selected";
ot->description = "Remove selected items (blue-gray rows) from active Keying Set";
-
+
/* api callbacks */
ot->exec = outliner_keyingset_removeitems_exec;
ot->poll = ed_operator_outliner_datablocks_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1849,7 +1849,7 @@ static int outliner_orphans_purge_exec(bContext *C, wmOperator *UNUSED(op))
* are retained...
*/
WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, NULL);
-
+
/* Now, reload the file to get rid of the orphans... */
WM_operator_name_call(C, "WM_OT_revert_mainfile", WM_OP_EXEC_DEFAULT, NULL);
return OPERATOR_FINISHED;
@@ -1862,12 +1862,12 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
ot->name = "Purge All";
ot->description = "Clear all orphaned data-blocks without any users from the file "
"(cannot be undone, saves to current .blend file)";
-
+
/* callbacks */
ot->invoke = outliner_orphans_purge_invoke;
ot->exec = outliner_orphans_purge_exec;
ot->poll = ed_operator_outliner_id_orphans_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1931,7 +1931,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname);
RNA_string_get(op->ptr, "parent", parname);
par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname);
-
+
if (ELEM(NULL, ob, par)) {
if (par == NULL) printf("par==NULL\n");
return OPERATOR_CANCELLED;
@@ -1943,7 +1943,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
BKE_report(op->reports, RPT_INFO, "Can't edit library linked object");
return OPERATOR_CANCELLED;
}
-
+
scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
if (scene == NULL) {
@@ -1968,7 +1968,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE);
uiLayout *layout = UI_popup_menu_layout(pup);
PointerRNA ptr;
-
+
/* Cannot use uiItemEnumO()... have multiple properties to set. */
uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr);
RNA_string_set(&ptr, "parent", parname);
@@ -2024,9 +2024,9 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
RNA_string_set(&ptr, "child", childname);
RNA_enum_set(&ptr, "type", PAR_LATTICE);
}
-
+
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 90f2e934367..8ac09648d60 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -143,7 +143,7 @@ typedef enum {
OL_SETSEL_EXTEND = 2, /* select the item and extend (also toggles selection) */
} eOLSetState;
-/* get TreeStoreElem associated with a TreeElement
+/* get TreeStoreElem associated with a TreeElement
* < a: (TreeElement) tree element to find stored element for
*/
#define TREESTORE(a) ((a)->store_elem)
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index b5b1077a933..ecfd12618e5 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -429,16 +429,16 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_show_active);
WM_operatortype_append(OUTLINER_OT_show_hierarchy);
WM_operatortype_append(OUTLINER_OT_scroll_page);
-
+
WM_operatortype_append(OUTLINER_OT_selected_toggle);
WM_operatortype_append(OUTLINER_OT_expanded_toggle);
-
+
WM_operatortype_append(OUTLINER_OT_keyingset_add_selected);
WM_operatortype_append(OUTLINER_OT_keyingset_remove_selected);
-
+
WM_operatortype_append(OUTLINER_OT_drivers_add_selected);
WM_operatortype_append(OUTLINER_OT_drivers_delete_selected);
-
+
WM_operatortype_append(OUTLINER_OT_orphans_purge);
WM_operatortype_append(OUTLINER_OT_parent_drop);
@@ -516,41 +516,41 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OUTLINER_OT_select_border", BKEY, KM_PRESS, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "all", false);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "all", true);
-
+
WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "OUTLINER_OT_operation", RIGHTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OUTLINER_OT_item_drag_drop", EVT_TWEAK_L, KM_ANY, 0, 0);
WM_keymap_add_item(keymap, "OUTLINER_OT_show_hierarchy", HOMEKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "OUTLINER_OT_show_active", PERIODKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OUTLINER_OT_show_active", PADPERIOD, KM_PRESS, 0, 0);
-
+
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_scroll_page", PAGEDOWNKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "up", false);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_scroll_page", PAGEUPKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "up", true);
-
+
WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADPLUSKEY, KM_PRESS, 0, 0); /* open */
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_show_one_level", PADMINUS, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "open", false); /* close */
-
+
WM_keymap_verify_item(keymap, "OUTLINER_OT_selected_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_expanded_toggle", AKEY, KM_PRESS, KM_SHIFT, 0);
-
+
/* keying sets - only for databrowse */
WM_keymap_verify_item(keymap, "OUTLINER_OT_keyingset_add_selected", KKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_keyingset_remove_selected", KKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_insert", IKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_delete", IKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_verify_item(keymap, "OUTLINER_OT_drivers_add_selected", DKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_drivers_delete_selected", DKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 9f08223d11b..af1b11b28d2 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -47,6 +47,7 @@
#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_layer.h"
+#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
@@ -74,6 +75,7 @@
static void do_outliner_activate_obdata(bContext *C, Scene *scene, ViewLayer *view_layer, Base *base)
{
+ Main *bmain = CTX_data_main(C);
Object *obact = OBACT(view_layer);
bool use_all = false;
@@ -95,7 +97,7 @@ static void do_outliner_activate_obdata(bContext *C, Scene *scene, ViewLayer *vi
if (ob->type == obact->type) {
bool ok;
if (BKE_object_is_in_editmode(ob)) {
- ok = ED_object_editmode_exit_ex(scene, ob, EM_FREEDATA | EM_WAITCURSOR);
+ ok = ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA | EM_WAITCURSOR);
}
else {
ok = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_WAITCURSOR | EM_NO_CONTEXT);
@@ -156,12 +158,12 @@ static eOLDrawState active_viewlayer(
bContext *C, Scene *UNUSED(scene), ViewLayer *UNUSED(sl), TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
{
Scene *sce;
-
+
/* paranoia check */
if (te->idcode != ID_SCE)
return OL_DRAWSEL_NONE;
sce = (Scene *)tselem->id;
-
+
WorkSpace *workspace = CTX_wm_workspace(C);
ViewLayer *view_layer = te->directdata;
@@ -225,7 +227,7 @@ static eOLDrawState tree_element_set_active_object(
Scene *sce;
Base *base;
Object *ob = NULL;
-
+
/* if id is not object, we search back */
if (te->idcode == ID_OB) {
ob = (Object *)tselem->id;
@@ -239,13 +241,13 @@ static eOLDrawState tree_element_set_active_object(
if (ob == NULL) {
return OL_DRAWSEL_NONE;
}
-
+
sce = (Scene *)outliner_search_back(soops, te, ID_SCE);
if (sce && scene != sce) {
WM_window_change_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
scene = sce;
}
-
+
/* find associated base in current scene */
base = BKE_view_layer_base_find(view_layer, ob);
@@ -271,7 +273,7 @@ static eOLDrawState tree_element_set_active_object(
/* swap select */
if (base->flag & BASE_SELECTED)
ED_object_base_select(base, BA_DESELECT);
- else
+ else
ED_object_base_select(base, BA_SELECT);
}
else {
@@ -297,7 +299,7 @@ static eOLDrawState tree_element_set_active_object(
ED_object_base_activate(C, base); /* adds notifier */
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
-
+
if (ob != OBEDIT_FROM_VIEW_LAYER(view_layer)) {
ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR);
}
@@ -311,14 +313,14 @@ static eOLDrawState tree_element_active_material(
{
TreeElement *tes;
Object *ob;
-
+
/* we search for the object parent */
ob = (Object *)outliner_search_back(soops, te, ID_OB);
// note: ob->matbits can be NULL when a local object points to a library mesh.
if (ob == NULL || ob != OBACT(view_layer) || ob->matbits == NULL) {
return OL_DRAWSEL_NONE; /* just paranoia */
}
-
+
/* searching in ob mat array? */
tes = te->parent;
if (tes->idcode == ID_OB) {
@@ -363,21 +365,21 @@ static eOLDrawState tree_element_active_lamp(
TreeElement *te, const eOLSetState set)
{
Object *ob;
-
+
/* we search for the object parent */
ob = (Object *)outliner_search_back(soops, te, ID_OB);
if (ob == NULL || ob != OBACT(view_layer)) {
/* just paranoia */
return OL_DRAWSEL_NONE;
}
-
+
if (set != OL_SETSEL_NONE) {
// XXX extern_set_butspace(F5KEY, 0);
}
else {
return OL_DRAWSEL_NORMAL;
}
-
+
return OL_DRAWSEL_NONE;
}
@@ -401,21 +403,21 @@ static eOLDrawState tree_element_active_world(
TreeElement *tep;
TreeStoreElem *tselem = NULL;
Scene *sce = NULL;
-
+
tep = te->parent;
if (tep) {
tselem = TREESTORE(tep);
if (tselem->type == 0)
sce = (Scene *)tselem->id;
}
-
+
if (set != OL_SETSEL_NONE) {
/* make new scene active */
if (sce && scene != sce) {
WM_window_change_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
}
}
-
+
if (tep == NULL || tselem->id == (ID *)scene) {
if (set != OL_SETSEL_NONE) {
// XXX extern_set_butspace(F8KEY, 0);
@@ -431,7 +433,7 @@ static eOLDrawState tree_element_active_defgroup(
bContext *C, ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
{
Object *ob;
-
+
/* id in tselem is object */
ob = (Object *)tselem->id;
if (set != OL_SETSEL_NONE) {
@@ -454,7 +456,7 @@ static eOLDrawState tree_element_active_posegroup(
bContext *C, Scene *UNUSED(scene), ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set)
{
Object *ob = (Object *)tselem->id;
-
+
if (set != OL_SETSEL_NONE) {
if (ob->pose) {
ob->pose->active_group = te->index + 1;
@@ -477,10 +479,10 @@ static eOLDrawState tree_element_active_posechannel(
Object *ob = (Object *)tselem->id;
bArmature *arm = ob->data;
bPoseChannel *pchan = te->directdata;
-
+
if (set != OL_SETSEL_NONE) {
if (!(pchan->bone->flag & BONE_HIDDEN_P)) {
-
+
if (set != OL_SETSEL_EXTEND) {
bPoseChannel *pchannel;
/* single select forces all other bones to get unselected */
@@ -520,7 +522,7 @@ static eOLDrawState tree_element_active_bone(
{
bArmature *arm = (bArmature *)tselem->id;
Bone *bone = te->directdata;
-
+
if (set != OL_SETSEL_NONE) {
if (!(bone->flag & BONE_HIDDEN_P)) {
Object *ob = OBACT(view_layer);
@@ -533,7 +535,7 @@ static eOLDrawState tree_element_active_bone(
}
}
}
-
+
if (set == OL_SETSEL_EXTEND && (bone->flag & BONE_SELECTED)) {
bone->flag &= ~BONE_SELECTED;
}
@@ -547,13 +549,13 @@ static eOLDrawState tree_element_active_bone(
do_outliner_bone_select_recursive(arm, bone, (bone->flag & BONE_SELECTED) != 0);
}
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
}
}
else {
Object *ob = OBACT(view_layer);
-
+
if (ob && ob->data == arm) {
if (bone->flag & BONE_SELECTED) {
return OL_DRAWSEL_NORMAL;
@@ -629,12 +631,12 @@ static eOLDrawState tree_element_active_modifier(
{
if (set != OL_SETSEL_NONE) {
Object *ob = (Object *)tselem->id;
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
// XXX extern_set_butspace(F9KEY, 0);
}
-
+
return OL_DRAWSEL_NONE;
}
@@ -643,12 +645,12 @@ static eOLDrawState tree_element_active_psys(
{
if (set != OL_SETSEL_NONE) {
Object *ob = (Object *)tselem->id;
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_EDITED, ob);
-
+
// XXX extern_set_butspace(F7KEY, 0);
}
-
+
return OL_DRAWSEL_NONE;
}
@@ -657,11 +659,11 @@ static int tree_element_active_constraint(
{
if (set != OL_SETSEL_NONE) {
Object *ob = (Object *)tselem->id;
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
// XXX extern_set_butspace(F7KEY, 0);
}
-
+
return OL_DRAWSEL_NONE;
}
@@ -760,7 +762,7 @@ 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;
@@ -969,7 +971,7 @@ static void do_outliner_item_activate_tree_element(
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
-
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
else if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
@@ -1121,11 +1123,11 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot)
ot->name = "Activate Item";
ot->idname = "OUTLINER_OT_item_activate";
ot->description = "Handle mouse clicks to activate/select items";
-
+
ot->invoke = outliner_item_activate_invoke;
-
+
ot->poll = ED_operator_outliner_active;
-
+
RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection for activation");
RNA_def_boolean(ot->srna, "recursive", false, "Recursive", "Select Objects and their children");
}
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index b9e5bc80a3f..8a01e5a7f2f 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -101,7 +101,7 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb,
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
if (tselem->flag & TSE_SELECTED) {
@@ -121,7 +121,7 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb,
case ID_OB:
*objectlevel = 1;
break;
-
+
case ID_ME: case ID_CU: case ID_MB: case ID_LT:
case ID_LA: case ID_AR: case ID_CA: case ID_SPK:
case ID_MA: case ID_TE: case ID_IP: case ID_IM:
@@ -158,7 +158,7 @@ static void unlink_material_cb(
{
Material **matar = NULL;
int a, totcol = 0;
-
+
if (GS(tsep->id->name) == ID_OB) {
Object *ob = (Object *)tsep->id;
totcol = ob->totcol;
@@ -199,7 +199,7 @@ static void unlink_texture_cb(
{
MTex **mtex = NULL;
int a;
-
+
if (GS(tsep->id->name) == ID_LS) {
FreestyleLineStyle *ls = (FreestyleLineStyle *)tsep->id;
mtex = ls->mtex;
@@ -252,7 +252,7 @@ static void unlink_object_cb(
{
Main *bmain = CTX_data_main(C);
Object *ob = (Object *)tselem->id;
-
+
if (tsep) {
if (GS(tsep->id->name) == ID_GR) {
Collection *parent = (Collection *)tsep->id;
@@ -273,7 +273,7 @@ static void unlink_world_cb(
{
Scene *parscene = (Scene *)tsep->id;
World *wo = (World *)tselem->id;
-
+
/* need to use parent scene not just scene, otherwise may end up getting wrong one */
id_us_min(&wo->id);
parscene->world = NULL;
@@ -286,7 +286,7 @@ static void outliner_do_libdata_operation(
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
if (tselem->flag & TSE_SELECTED) {
@@ -496,7 +496,7 @@ static void id_fake_user_set_cb(
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
ID *id = tselem->id;
-
+
id_fake_user_set(id);
}
@@ -505,7 +505,7 @@ static void id_fake_user_clear_cb(
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
ID *id = tselem->id;
-
+
id_fake_user_clear(id);
}
@@ -523,15 +523,15 @@ static void singleuser_action_cb(
TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
{
ID *id = tselem->id;
-
+
if (id) {
IdAdtTemplate *iat = (IdAdtTemplate *)tsep->id;
PointerRNA ptr = {{NULL}};
PropertyRNA *prop;
-
+
RNA_pointer_create(&iat->id, &RNA_AnimData, iat->adt, &ptr);
prop = RNA_struct_find_property(&ptr, "action");
-
+
id_single_user(C, id, &ptr, prop);
}
}
@@ -541,16 +541,16 @@ static void singleuser_world_cb(
TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
{
ID *id = tselem->id;
-
+
/* need to use parent scene not just scene, otherwise may end up getting wrong one */
if (id) {
Scene *parscene = (Scene *)tsep->id;
PointerRNA ptr = {{NULL}};
PropertyRNA *prop;
-
+
RNA_id_pointer_create(&parscene->id, &ptr);
prop = RNA_struct_find_property(&ptr, "world");
-
+
id_single_user(C, id, &ptr, prop);
}
}
@@ -563,7 +563,7 @@ void outliner_do_object_operation_ex(
outliner_operation_cb operation_cb, bool select_recurse)
{
TreeElement *te;
-
+
for (te = lb->first; te; te = te->next) {
TreeStoreElem *tselem = TREESTORE(te);
bool select_handled = false;
@@ -617,7 +617,7 @@ static void cleardrivers_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te),
TreeStoreElem *tselem, void *UNUSED(arg))
{
IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
-
+
/* just free drivers - stored as a list of F-Curves */
free_fcurves(&iat->adt->drivers);
}
@@ -627,11 +627,11 @@ static void refreshdrivers_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te
{
IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
FCurve *fcu;
-
+
/* loop over drivers, performing refresh (i.e. check graph_buttons.c and rna_fcurve.c for details) */
for (fcu = iat->adt->drivers.first; fcu; fcu = fcu->next) {
fcu->flag &= ~FCURVE_DISABLED;
-
+
if (fcu->driver)
fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
}
@@ -662,7 +662,7 @@ typedef enum eOutliner_PropModifierOps {
static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
-
+
if (event == OL_DOP_SELECT)
pchan->bone->flag |= BONE_SELECTED;
else if (event == OL_DOP_DESELECT)
@@ -678,7 +678,7 @@ static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem),
static void bone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
Bone *bone = (Bone *)te->directdata;
-
+
if (event == OL_DOP_SELECT)
bone->flag |= BONE_SELECTED;
else if (event == OL_DOP_DESELECT)
@@ -694,7 +694,7 @@ static void bone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), v
static void ebone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
EditBone *ebone = (EditBone *)te->directdata;
-
+
if (event == OL_DOP_SELECT)
ebone->flag |= BONE_SELECTED;
else if (event == OL_DOP_DESELECT)
@@ -724,7 +724,7 @@ static void sequence_cb(int event, TreeElement *te, TreeStoreElem *tselem, void
static void gp_layer_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
bGPDlayer *gpl = (bGPDlayer *)te->directdata;
-
+
if (event == OL_DOP_SELECT)
gpl->flag |= GP_LAYER_SELECT;
else if (event == OL_DOP_DESELECT)
@@ -816,7 +816,7 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
if (tselem->flag & TSE_SELECTED) {
@@ -932,11 +932,11 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
SpaceOops *soops = CTX_wm_space_outliner(C);
int event;
const char *str = NULL;
-
+
/* check for invalid states */
if (soops == NULL)
return OPERATOR_CANCELLED;
-
+
event = RNA_enum_get(op->ptr, "type");
if (event == OL_OP_SELECT) {
@@ -945,7 +945,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
if (scene != sce) {
WM_window_change_active_scene(bmain, C, win, sce);
}
-
+
str = "Select Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
@@ -1005,7 +1005,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
}
ED_undo_push(C, str);
-
+
return OPERATOR_FINISHED;
}
@@ -1016,12 +1016,12 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot)
ot->name = "Outliner Object Operation";
ot->idname = "OUTLINER_OT_object_operation";
ot->description = "";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = outliner_object_operation_exec;
ot->poll = ED_operator_outliner_active;
-
+
ot->flag = 0;
ot->prop = RNA_def_enum(ot->srna, "type", prop_object_op_types, 0, "Object Operation", "");
@@ -1031,14 +1031,14 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot)
typedef enum eOutlinerIdOpTypes {
OUTLINER_IDOP_INVALID = 0,
-
+
OUTLINER_IDOP_UNLINK,
OUTLINER_IDOP_LOCAL,
OUTLINER_IDOP_STATIC_OVERRIDE,
OUTLINER_IDOP_SINGLE,
OUTLINER_IDOP_DELETE,
OUTLINER_IDOP_REMAP,
-
+
OUTLINER_IDOP_FAKE_ADD,
OUTLINER_IDOP_FAKE_CLEAR,
OUTLINER_IDOP_RENAME,
@@ -1070,15 +1070,15 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
SpaceOops *soops = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
eOutlinerIdOpTypes event;
-
+
/* check for invalid states */
if (soops == NULL)
return OPERATOR_CANCELLED;
-
+
set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
+
event = RNA_enum_get(op->ptr, "type");
-
+
switch (event) {
case OUTLINER_IDOP_UNLINK:
{
@@ -1094,25 +1094,25 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
switch (idlevel) {
case ID_AC:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_action_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
ED_undo_push(C, "Unlink action");
break;
case ID_MA:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_material_cb, NULL);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, NULL);
ED_undo_push(C, "Unlink material");
break;
case ID_TE:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_texture_cb, NULL);
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, NULL);
ED_undo_push(C, "Unlink texture");
break;
case ID_WO:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, unlink_world_cb, NULL);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_WORLD, NULL);
ED_undo_push(C, "Unlink world");
break;
@@ -1148,18 +1148,18 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
switch (idlevel) {
case ID_AC:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, singleuser_action_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
ED_undo_push(C, "Single-User Action");
break;
-
+
case ID_WO:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, singleuser_world_cb, NULL);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_WORLD, NULL);
ED_undo_push(C, "Single-User World");
break;
-
+
default:
BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
break;
@@ -1186,7 +1186,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
{
/* set fake user */
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_fake_user_set_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
ED_undo_push(C, "Add Fake User");
break;
@@ -1195,7 +1195,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
{
/* clear fake user */
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_fake_user_clear_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
ED_undo_push(C, "Clear Fake User");
break;
@@ -1204,7 +1204,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
{
/* rename */
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
ED_undo_push(C, "Rename");
break;
@@ -1213,18 +1213,18 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_select_linked_cb, NULL);
ED_undo_push(C, "Select");
break;
-
+
default:
// invalid - unhandled
break;
}
-
+
/* wrong notifier still... */
WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
-
- // XXX: this is just so that outliner is always up to date
+
+ // XXX: this is just so that outliner is always up to date
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1235,14 +1235,14 @@ void OUTLINER_OT_id_operation(wmOperatorType *ot)
ot->name = "Outliner ID data Operation";
ot->idname = "OUTLINER_OT_id_operation";
ot->description = "";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = outliner_id_operation_exec;
ot->poll = ED_operator_outliner_active;
-
+
ot->flag = 0;
-
+
ot->prop = RNA_def_enum(ot->srna, "type", prop_id_op_types, 0, "ID data Operation", "");
}
@@ -1346,7 +1346,7 @@ static void outliner_do_id_set_operation(SpaceOops *soops, int type, ListBase *l
{
TreeElement *te;
TreeStoreElem *tselem;
-
+
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
if (tselem->flag & TSE_SELECTED) {
@@ -1366,12 +1366,12 @@ static void outliner_do_id_set_operation(SpaceOops *soops, int type, ListBase *l
static void actionset_id_cb(TreeElement *UNUSED(te), TreeStoreElem *tselem, TreeStoreElem *tsep, ID *actId)
{
bAction *act = (bAction *)actId;
-
+
if (tselem->type == TSE_ANIM_DATA) {
/* "animation" entries - action is child of this */
BKE_animdata_set_action(NULL, tselem->id, act);
}
- /* TODO: if any other "expander" channels which own actions need to support this menu,
+ /* TODO: if any other "expander" channels which own actions need to support this menu,
* add: tselem->type = ...
*/
else if (tsep && (tsep->type == TSE_ANIM_DATA)) {
@@ -1385,17 +1385,17 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op)
{
SpaceOops *soops = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
-
+
bAction *act;
-
+
/* check for invalid states */
if (soops == NULL)
return OPERATOR_CANCELLED;
set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
+
/* get action to use */
act = BLI_findlink(&CTX_data_main(C)->action, RNA_enum_get(op->ptr, "action"));
-
+
if (act == NULL) {
BKE_report(op->reports, RPT_ERROR, "No valid action to add");
return OPERATOR_CANCELLED;
@@ -1408,7 +1408,7 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op)
"for this action to avoid future problems)",
act->id.name + 2);
}
-
+
/* perform action if valid channel */
if (datalevel == TSE_ANIM_DATA)
outliner_do_id_set_operation(soops, datalevel, &soops->tree, (ID *)act, actionset_id_cb);
@@ -1416,11 +1416,11 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op)
outliner_do_id_set_operation(soops, idlevel, &soops->tree, (ID *)act, actionset_id_cb);
else
return OPERATOR_CANCELLED;
-
+
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
ED_undo_push(C, "Set action");
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1433,15 +1433,15 @@ void OUTLINER_OT_action_set(wmOperatorType *ot)
ot->name = "Outliner Set Action";
ot->idname = "OUTLINER_OT_action_set";
ot->description = "Change the active action used";
-
+
/* api callbacks */
ot->invoke = WM_enum_search_invoke;
ot->exec = outliner_action_set_exec;
ot->poll = ED_operator_outliner_active;
-
+
/* flags */
ot->flag = 0;
-
+
/* props */
// TODO: this would be nicer as an ID-pointer...
prop = RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", "");
@@ -1454,15 +1454,15 @@ void OUTLINER_OT_action_set(wmOperatorType *ot)
typedef enum eOutliner_AnimDataOps {
OUTLINER_ANIMOP_INVALID = 0,
-
+
OUTLINER_ANIMOP_CLEAR_ADT,
-
+
OUTLINER_ANIMOP_SET_ACT,
OUTLINER_ANIMOP_CLEAR_ACT,
-
+
OUTLINER_ANIMOP_REFRESH_DRV,
OUTLINER_ANIMOP_CLEAR_DRV
-
+
//OUTLINER_ANIMOP_COPY_DRIVERS,
//OUTLINER_ANIMOP_PASTE_DRIVERS
} eOutliner_AnimDataOps;
@@ -1484,66 +1484,66 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
eOutliner_AnimDataOps event;
short updateDeps = 0;
-
+
/* check for invalid states */
if (soops == NULL)
return OPERATOR_CANCELLED;
-
+
event = RNA_enum_get(op->ptr, "type");
set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
+
if (datalevel != TSE_ANIM_DATA)
return OPERATOR_CANCELLED;
-
+
/* perform the core operation */
switch (event) {
case OUTLINER_ANIMOP_CLEAR_ADT:
/* Remove Animation Data - this may remove the active action, in some cases... */
outliner_do_data_operation(soops, datalevel, event, &soops->tree, clear_animdata_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
ED_undo_push(C, "Clear Animation Data");
break;
-
+
case OUTLINER_ANIMOP_SET_ACT:
/* delegate once again... */
WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL);
break;
-
+
case OUTLINER_ANIMOP_CLEAR_ACT:
/* clear active action - using standard rules */
outliner_do_data_operation(soops, datalevel, event, &soops->tree, unlinkact_animdata_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
ED_undo_push(C, "Unlink action");
break;
-
+
case OUTLINER_ANIMOP_REFRESH_DRV:
outliner_do_data_operation(soops, datalevel, event, &soops->tree, refreshdrivers_animdata_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
//ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */
updateDeps = 1;
break;
-
+
case OUTLINER_ANIMOP_CLEAR_DRV:
outliner_do_data_operation(soops, datalevel, event, &soops->tree, cleardrivers_animdata_cb, NULL);
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
ED_undo_push(C, "Clear Drivers");
updateDeps = 1;
break;
-
+
default: // invalid
break;
}
-
+
/* update dependencies */
if (updateDeps) {
/* rebuild depsgraph for the new deps */
DEG_relations_tag_update(CTX_data_main(C));
}
-
+
return OPERATOR_FINISHED;
}
@@ -1554,14 +1554,14 @@ void OUTLINER_OT_animdata_operation(wmOperatorType *ot)
ot->name = "Outliner Animation Data Operation";
ot->idname = "OUTLINER_OT_animdata_operation";
ot->description = "";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = outliner_animdata_operation_exec;
ot->poll = ED_operator_outliner_active;
-
+
ot->flag = 0;
-
+
ot->prop = RNA_def_enum(ot->srna, "type", prop_animdata_op_types, 0, "Animation Operation", "");
}
@@ -1674,14 +1674,14 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
SpaceOops *soops = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
eOutliner_PropDataOps event;
-
+
/* check for invalid states */
if (soops == NULL)
return OPERATOR_CANCELLED;
-
+
event = RNA_enum_get(op->ptr, "type");
set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
+
switch (datalevel) {
case TSE_POSE_CHANNEL:
{
@@ -1733,7 +1733,7 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
break;
}
-
+
return OPERATOR_FINISHED;
}
@@ -1744,14 +1744,14 @@ void OUTLINER_OT_data_operation(wmOperatorType *ot)
ot->name = "Outliner Data Operation";
ot->idname = "OUTLINER_OT_data_operation";
ot->description = "";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = outliner_data_operation_exec;
ot->poll = ED_operator_outliner_active;
-
+
ot->flag = 0;
-
+
ot->prop = RNA_def_enum(ot->srna, "type", prop_data_op_types, 0, "Data Operation", "");
}
@@ -1763,24 +1763,24 @@ static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soop
TreeElement *te, const float mval[2])
{
ReportList *reports = CTX_wm_reports(C); // XXX...
-
+
if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
TreeStoreElem *tselem = TREESTORE(te);
-
+
/* select object that's clicked on and popup context menu */
if (!(tselem->flag & TSE_SELECTED)) {
-
+
if (outliner_has_one_flag(&soops->tree, TSE_SELECTED, 1))
outliner_set_flag(&soops->tree, TSE_SELECTED, 0);
-
+
tselem->flag |= TSE_SELECTED;
/* Only redraw, don't rebuild here because TreeElement pointers will
* become invalid and operations will crash. */
ED_region_tag_redraw_no_rebuild(ar);
}
-
+
set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
if (scenelevel) {
@@ -1842,10 +1842,10 @@ static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soop
}
}
}
-
+
return 1;
}
-
+
for (te = te->subtree.first; te; te = te->next) {
if (do_outliner_operation_event(C, ar, soops, te, mval))
return 1;
@@ -1868,7 +1868,7 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent
}
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
-
+
for (te = soops->tree.first; te; te = te->next) {
if (do_outliner_operation_event(C, ar, soops, te, fmval)) {
found = true;
@@ -1882,7 +1882,7 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent
WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -1892,9 +1892,9 @@ void OUTLINER_OT_operation(wmOperatorType *ot)
ot->name = "Execute Operation";
ot->idname = "OUTLINER_OT_operation";
ot->description = "Context menu for item operations";
-
+
ot->invoke = outliner_operation;
-
+
ot->poll = ED_operator_outliner_active;
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 7508e8b6684..d155457a208 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -28,7 +28,7 @@
/** \file blender/editors/space_outliner/outliner_tree.c
* \ingroup spoutliner
*/
-
+
#include <math.h>
#include <string.h>
@@ -101,11 +101,11 @@ static void outliner_make_object_parent_hierarchy(ListBase *lb);
static void outliner_storage_cleanup(SpaceOops *soops)
{
BLI_mempool *ts = soops->treestore;
-
+
if (ts) {
TreeStoreElem *tselem;
int unused = 0;
-
+
/* each element used once, for ID blocks with more users to have each a treestore */
BLI_mempool_iter iter;
@@ -113,7 +113,7 @@ static void outliner_storage_cleanup(SpaceOops *soops)
while ((tselem = BLI_mempool_iterstep(&iter))) {
tselem->used = 0;
}
-
+
/* cleanup only after reading file or undo step, and always for
* RNA datablocks view in order to save memory */
if (soops->storeflag & SO_TREESTORE_CLEANUP) {
@@ -123,7 +123,7 @@ static void outliner_storage_cleanup(SpaceOops *soops)
while ((tselem = BLI_mempool_iterstep(&iter))) {
if (tselem->id == NULL) unused++;
}
-
+
if (unused) {
if (BLI_mempool_len(ts) == unused) {
BLI_mempool_destroy(ts);
@@ -162,11 +162,11 @@ static void outliner_storage_cleanup(SpaceOops *soops)
static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr)
{
TreeStoreElem *tselem;
-
+
if (soops->treestore == NULL) {
/* if treestore was not created in readfile.c, create it here */
soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
-
+
}
if (soops->treehash == NULL) {
soops->treehash = BKE_outliner_treehash_create_from_treestore(soops->treestore);
@@ -232,7 +232,7 @@ void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree)
/* ********************************************************* */
/* Prototype, see functions below */
-static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv,
+static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv,
TreeElement *parent, short type, short index);
/* -------------------------------------------------------- */
@@ -242,11 +242,11 @@ static void outliner_add_bone(SpaceOops *soops, ListBase *lb, ID *id, Bone *curB
TreeElement *parent, int *a)
{
TreeElement *te = outliner_add_element(soops, lb, id, parent, TSE_BONE, *a);
-
+
(*a)++;
te->name = curBone->name;
te->directdata = curBone;
-
+
for (curBone = curBone->childbase.first; curBone; curBone = curBone->next) {
outliner_add_bone(soops, &te->subtree, id, curBone, te, a);
}
@@ -314,11 +314,11 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
}
FOREACH_SCENE_OBJECT_END;
outliner_make_object_parent_hierarchy(&ten->subtree);
-
+
/* Animation Data */
if (outliner_animdata_test(sce->adt))
outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0);
-
+
/* Grease Pencil */
outliner_add_element(soops, lb, sce->gpd, te, 0, 0);
}
@@ -429,39 +429,39 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0);
outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this
-
+
if (ob->proxy && !ID_IS_LINKED(ob))
outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
-
+
outliner_add_element(soops, &te->subtree, ob->gpd, te, 0, 0);
-
+
outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0);
-
+
if (ob->pose) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
TreeElement *tenla = outliner_add_element(soops, &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(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
ten->name = pchan->name;
ten->directdata = pchan;
pchan->temp = (void *)ten;
-
+
if (pchan->constraints.first) {
//Object *target;
bConstraint *con;
TreeElement *ten1;
TreeElement *tenla1 = outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
//char *str;
-
+
tenla1->name = IFACE_("Constraints");
for (con = pchan->constraints.first; con; con = con->next, const_index++) {
ten1 = outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
@@ -494,7 +494,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
ten = nten;
}
}
-
+
/* Pose Groups */
if (ob->pose->agroups.first) {
bActionGroup *agrp;
@@ -510,11 +510,11 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
}
}
}
-
+
for (int a = 0; a < ob->totcol; a++) {
outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a);
}
-
+
if (ob->constraints.first) {
//Object *target;
bConstraint *con;
@@ -522,7 +522,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *tenla = outliner_add_element(soops, &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(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
@@ -537,18 +537,18 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
/* possible add all other types links? */
}
}
-
+
if (ob->modifiers.first) {
ModifierData *md;
TreeElement *ten_mod = outliner_add_element(soops, &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) {
TreeElement *ten = outliner_add_element(soops, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
ten->name = md->name;
ten->directdata = md;
-
+
if (md->type == eModifierType_Lattice) {
outliner_add_element(soops, &ten->subtree, ((LatticeModifierData *) md)->object, ten, TSE_LINKED_OB, 0);
}
@@ -564,21 +564,21 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
else if (md->type == eModifierType_ParticleSystem) {
ParticleSystem *psys = ((ParticleSystemModifierData *) md)->psys;
TreeElement *ten_psys;
-
+
ten_psys = outliner_add_element(soops, &ten->subtree, ob, te, TSE_LINKED_PSYS, 0);
ten_psys->directdata = psys;
ten_psys->name = psys->part->id.name + 2;
}
}
}
-
+
/* vertex groups */
if (ob->defbase.first) {
bDeformGroup *defgroup;
TreeElement *ten;
TreeElement *tenla = outliner_add_element(soops, &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(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
@@ -586,7 +586,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
ten->directdata = defgroup;
}
}
-
+
/* duplicated group */
if (ob->dup_group)
outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0);
@@ -598,7 +598,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
/* tuck pointer back in object, to construct hierarchy */
if (GS(id->name) == ID_OB) id->newid = (ID *)te;
-
+
/* expand specific data always */
switch (GS(id->name)) {
case ID_LI:
@@ -620,10 +620,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
Mesh *me = (Mesh *)id;
int a;
-
+
if (outliner_animdata_test(me->adt))
outliner_add_element(soops, &te->subtree, me, te, TSE_ANIM_DATA, 0);
-
+
outliner_add_element(soops, &te->subtree, me->key, te, 0, 0);
for (a = 0; a < me->totcol; a++)
outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a);
@@ -635,10 +635,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
Curve *cu = (Curve *)id;
int a;
-
+
if (outliner_animdata_test(cu->adt))
outliner_add_element(soops, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
-
+
for (a = 0; a < cu->totcol; a++)
outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a);
break;
@@ -647,10 +647,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
MetaBall *mb = (MetaBall *)id;
int a;
-
+
if (outliner_animdata_test(mb->adt))
outliner_add_element(soops, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
-
+
for (a = 0; a < mb->totcol; a++)
outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a);
break;
@@ -658,7 +658,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
case ID_MA:
{
Material *ma = (Material *)id;
-
+
if (outliner_animdata_test(ma->adt))
outliner_add_element(soops, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
break;
@@ -666,17 +666,17 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
case ID_TE:
{
Tex *tex = (Tex *)id;
-
+
if (outliner_animdata_test(tex->adt))
outliner_add_element(soops, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
-
+
outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0);
break;
}
case ID_CA:
{
Camera *ca = (Camera *)id;
-
+
if (outliner_animdata_test(ca->adt))
outliner_add_element(soops, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
break;
@@ -694,7 +694,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
case ID_LA:
{
Lamp *la = (Lamp *)id;
-
+
if (outliner_animdata_test(la->adt))
outliner_add_element(soops, &te->subtree, la, te, TSE_ANIM_DATA, 0);
break;
@@ -718,7 +718,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
case ID_WO:
{
World *wrld = (World *)id;
-
+
if (outliner_animdata_test(wrld->adt))
outliner_add_element(soops, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
break;
@@ -726,7 +726,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
case ID_KE:
{
Key *key = (Key *)id;
-
+
if (outliner_animdata_test(key->adt))
outliner_add_element(soops, &te->subtree, key, te, TSE_ANIM_DATA, 0);
break;
@@ -741,14 +741,14 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
bArmature *arm = (bArmature *)id;
int a = 0;
-
+
if (outliner_animdata_test(arm->adt))
outliner_add_element(soops, &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(soops, &te->subtree, id, te, TSE_EBONE, a);
ten->directdata = ebone;
@@ -788,7 +788,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
{
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
int a;
-
+
if (outliner_animdata_test(linestyle->adt))
outliner_add_element(soops, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
@@ -803,10 +803,10 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
bGPdata *gpd = (bGPdata *)id;
bGPDlayer *gpl;
int a = 0;
-
+
if (outliner_animdata_test(gpd->adt))
outliner_add_element(soops, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
-
+
// TODO: base element for layers?
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
outliner_add_element(soops, &te->subtree, gpl, te, TSE_GP_LAYER, a);
@@ -835,7 +835,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
TreeElement *te;
TreeStoreElem *tselem;
ID *id = idv;
-
+
if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
id = ((PointerRNA *)idv)->id.data;
if (!id) id = ((PointerRNA *)idv)->data;
@@ -864,11 +864,11 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
/* add to the storage */
check_persistent(soops, te, id, type, index);
tselem = TREESTORE(te);
-
+
/* if we are searching for something expand to see child elements */
if (SEARCHING_OUTLINER(soops))
tselem->flag |= TSE_CHILDSEARCH;
-
+
te->parent = parent;
te->index = index; // for data arays
if (ELEM(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
@@ -897,10 +897,10 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
te->name = id->name + 2; // default, can be overridden by Library or non-ID data
te->idcode = GS(id->name);
}
-
+
if (type == 0) {
TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL;
-
+
/* ID datablock */
if (tsepar == NULL || tsepar->type != TSE_ID_BASE || soops->filter_id_type) {
outliner_add_id_contents(soops, te, tselem, id);
@@ -909,30 +909,30 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
else if (type == TSE_ANIM_DATA) {
IdAdtTemplate *iat = (IdAdtTemplate *)idv;
AnimData *adt = (AnimData *)iat->adt;
-
+
/* this element's info */
te->name = IFACE_("Animation");
te->directdata = adt;
-
+
/* Action */
outliner_add_element(soops, &te->subtree, adt->action, te, 0, 0);
-
+
/* Drivers */
if (adt->drivers.first) {
TreeElement *ted = outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
ID *lastadded = NULL;
FCurve *fcu;
-
+
ted->name = IFACE_("Drivers");
-
+
for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
if (fcu->driver && fcu->driver->variables.first) {
ChannelDriver *driver = fcu->driver;
DriverVar *dvar;
-
+
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
/* loop over all targets used here */
- DRIVER_TARGETS_USED_LOOPER(dvar)
+ DRIVER_TARGETS_USED_LOOPER(dvar)
{
if (lastadded != dtar->id) {
// XXX this lastadded check is rather lame, and also fails quite badly...
@@ -945,23 +945,23 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
}
}
-
+
/* NLA Data */
if (adt->nla_tracks.first) {
TreeElement *tenla = outliner_add_element(soops, &te->subtree, adt, te, TSE_NLA, 0);
NlaTrack *nlt;
int a = 0;
-
+
tenla->name = IFACE_("NLA Tracks");
-
+
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
TreeElement *tenlt = outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
NlaStrip *strip;
TreeElement *ten;
int b = 0;
-
+
tenlt->name = nlt->name;
-
+
for (strip = nlt->strips.first; strip; strip = strip->next, b++) {
ten = outliner_add_element(soops, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b);
if (ten) ten->directdata = strip;
@@ -971,7 +971,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
else if (type == TSE_GP_LAYER) {
bGPDlayer *gpl = (bGPDlayer *)idv;
-
+
te->name = gpl->info;
te->directdata = gpl;
}
@@ -1144,31 +1144,31 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
wmKeyMap *km = (wmKeyMap *)idv;
wmKeyMapItem *kmi;
char opname[OP_MAX_TYPENAME];
-
+
te->directdata = idv;
te->name = km->idname;
-
+
if (TSELEM_OPEN(tselem, soops)) {
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(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
-
+
ten->directdata = kmi;
-
+
if (kmi->propvalue) {
ten->name = IFACE_("Modal map, not yet");
}
@@ -1181,7 +1181,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
}
}
- else
+ else
te->flag |= TE_LAZY_CLOSED;
}
@@ -1289,7 +1289,7 @@ static TreeElement *outliner_add_library_contents(Main *mainvar, SpaceOops *soop
ListBase *lbarray[MAX_LIBARRAY];
int a, tot;
short filter_id_type = (soops->filter & SO_FILTER_ID_TYPE) ? soops->filter_id_type : 0;
-
+
if (filter_id_type) {
lbarray[0] = which_libbase(mainvar, soops->filter_id_type);
tot = 1;
@@ -1301,12 +1301,12 @@ static TreeElement *outliner_add_library_contents(Main *mainvar, SpaceOops *soop
for (a = 0; a < tot; a++) {
if (lbarray[a] && lbarray[a]->first) {
ID *id = lbarray[a]->first;
-
+
/* check if there's data in current lib */
for (; id; id = id->next)
if (id->lib == lib)
break;
-
+
if (id) {
if (!tenlib) {
/* Create library tree element on demand, depending if there are any datablocks. */
@@ -1328,7 +1328,7 @@ static TreeElement *outliner_add_library_contents(Main *mainvar, SpaceOops *soop
ten->directdata = lbarray[a];
ten->name = outliner_idcode_to_plural(GS(id->name));
}
-
+
for (id = lbarray[a]->first; id; id = id->next) {
if (outliner_library_id_show(lib, id, filter_id_type)) {
outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
@@ -1347,7 +1347,7 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
ListBase *lbarray[MAX_LIBARRAY];
int a, tot;
short filter_id_type = (soops->filter & SO_FILTER_ID_TYPE) ? soops->filter_id_type : 0;
-
+
if (filter_id_type) {
lbarray[0] = which_libbase(mainvar, soops->filter_id_type);
tot = 1;
@@ -1359,13 +1359,13 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
for (a = 0; a < tot; a++) {
if (lbarray[a] && lbarray[a]->first) {
ID *id = lbarray[a]->first;
-
+
/* check if there are any datablocks of this type which are orphans */
for (; id; id = id->next) {
if (ID_REAL_USERS(id) <= 0)
break;
}
-
+
if (id) {
/* header for this type of datablock */
if (filter_id_type) {
@@ -1376,7 +1376,7 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
ten->directdata = lbarray[a];
ten->name = outliner_idcode_to_plural(GS(id->name));
}
-
+
/* add the orphaned datablocks - these will not be added with any subtrees attached */
for (id = lbarray[a]->first; id; id = id->next) {
if (ID_REAL_USERS(id) <= 0)
@@ -1568,7 +1568,7 @@ static void outliner_make_object_parent_hierarchy(ListBase *lb)
while (te) {
ten = te->next;
tselem = TREESTORE(te);
-
+
if (tselem->type == 0 && te->idcode == ID_OB) {
Object *ob = (Object *)tselem->id;
if (ob->parent && ob->parent->id.newid) {
@@ -1597,16 +1597,16 @@ 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);
if (x2->idcode == ID_OB) comp += 2;
-
+
if (comp == 1) return 1;
else if (comp == 2) return -1;
else if (comp == 3) {
comp = strcmp(x1->name, x2->name);
-
+
if (comp > 0) return 1;
else if (comp < 0) return -1;
return 0;
@@ -1619,9 +1619,9 @@ static int treesort_alpha(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
int comp;
-
+
comp = strcmp(x1->name, x2->name);
-
+
if (comp > 0) return 1;
else if (comp < 0) return -1;
return 0;
@@ -1633,7 +1633,7 @@ static int treesort_alpha(const void *v1, const void *v2)
static int treesort_obtype_alpha(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
-
+
/* first put objects last (hierarchy) */
if (x1->idcode == ID_OB && x2->idcode != ID_OB) {
return 1;
@@ -1650,7 +1650,7 @@ static int treesort_obtype_alpha(const void *v1, const void *v2)
}
else {
int comp = strcmp(x1->name, x2->name);
-
+
if (comp > 0) return 1;
else if (comp < 0) return -1;
return 0;
@@ -1683,15 +1683,15 @@ static void outliner_sort(ListBase *lb)
tp->te = te;
tp->name = te->name;
tp->idcode = te->idcode;
-
+
if (tselem->type && tselem->type != TSE_DEFGROUP)
tp->idcode = 0; // don't sort this
if (tselem->type == TSE_ID_BASE)
tp->idcode = 1; // do sort this
-
+
tp->id = tselem->id;
}
-
+
/* just sort alphabetically */
if (tear->idcode == 1) {
qsort(tear, totelem, sizeof(tTreeSort), treesort_alpha);
@@ -1700,11 +1700,11 @@ static void outliner_sort(ListBase *lb)
/* keep beginning of list */
for (tp = tear, skip = 0; skip < totelem; skip++, tp++)
if (tp->idcode) break;
-
+
if (skip < totelem)
qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha_ob);
}
-
+
BLI_listbase_clear(lb);
tp = tear;
while (totelem--) {
@@ -1714,7 +1714,7 @@ static void outliner_sort(ListBase *lb)
MEM_freeN(tear);
}
}
-
+
for (te = lb->first; te; te = te->next) {
outliner_sort(&te->subtree);
}
@@ -2052,7 +2052,7 @@ static int outliner_filter_subtree(
/* flag as not a found item */
tselem->flag &= ~TSE_SEARCHMATCH;
-
+
if ((!TSELEM_OPEN(tselem, soops)) ||
outliner_filter_subtree(soops, view_layer, &te->subtree, search_string, exclude_filter) == 0)
{
@@ -2130,11 +2130,11 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
outliner_free_tree(&soops->tree);
outliner_storage_cleanup(soops);
-
+
/* options */
if (soops->outlinevis == SO_LIBRARIES) {
Library *lib;
-
+
/* current file first - mainvar provides tselem with unique pointer - not used */
ten = outliner_add_library_contents(mainvar, soops, &soops->tree, NULL);
if (ten) {
@@ -2142,7 +2142,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
if (!tselem->used)
tselem->flag &= ~TSE_CLOSED;
}
-
+
for (lib = mainvar->library.first; lib; lib = lib->id.next) {
ten = outliner_add_library_contents(mainvar, soops, &soops->tree, lib);
if (ten) {
@@ -2178,7 +2178,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
/* restore newid pointers */
for (lib = mainvar->library.first; lib; lib = lib->id.next)
lib->id.newid = NULL;
-
+
}
else if (soops->outlinevis == SO_SCENES) {
Scene *sce;
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index b36b2903118..71ae7eeeb3d 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -68,7 +68,7 @@ static void outliner_main_region_init(wmWindowManager *wm, ARegion *ar)
{
ListBase *lb;
wmKeyMap *keymap;
-
+
/* make sure we keep the hide flags */
ar->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP); /* prevent any noise of past */
@@ -81,7 +81,7 @@ static void outliner_main_region_init(wmWindowManager *wm, ARegion *ar)
ar->v2d.minzoom = ar->v2d.maxzoom = 1.0f;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
-
+
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "Outliner", SPACE_OUTLINER, 0);
/* don't pass on view2d mask, it's always set with scrollbar space, hide fails */
@@ -286,16 +286,16 @@ static void outliner_main_region_draw(const bContext *C, ARegion *ar)
{
View2D *v2d = &ar->v2d;
View2DScrollers *scrollers;
-
+
/* clear */
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
-
+
draw_outliner(C);
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers */
scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
@@ -305,7 +305,7 @@ static void outliner_main_region_draw(const bContext *C, ARegion *ar)
static void outliner_main_region_free(ARegion *UNUSED(ar))
{
-
+
}
static void outliner_main_region_listener(
@@ -418,7 +418,7 @@ static void outliner_main_region_listener(
}
break;
}
-
+
}
static void outliner_main_region_message_subscribe(
@@ -484,20 +484,20 @@ static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(
soutliner = MEM_callocN(sizeof(SpaceOops), "initoutliner");
soutliner->spacetype = SPACE_OUTLINER;
soutliner->filter_id_type = ID_GR;
-
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for outliner");
-
+
BLI_addtail(&soutliner->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for outliner");
-
+
BLI_addtail(&soutliner->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
return (SpaceLink *)soutliner;
}
@@ -505,7 +505,7 @@ static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(
static void outliner_free(SpaceLink *sl)
{
SpaceOops *soutliner = (SpaceOops *)sl;
-
+
outliner_free_tree(&soutliner->tree);
if (soutliner->treestore) {
BLI_mempool_destroy(soutliner->treestore);
@@ -518,7 +518,7 @@ static void outliner_free(SpaceLink *sl)
/* spacetype; init callback */
static void outliner_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
{
-
+
}
static SpaceLink *outliner_duplicate(SpaceLink *sl)
@@ -529,7 +529,7 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl)
BLI_listbase_clear(&soutlinern->tree);
soutlinern->treestore = NULL;
soutlinern->treehash = NULL;
-
+
return (SpaceLink *)soutlinern;
}
@@ -571,10 +571,10 @@ void ED_spacetype_outliner(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype time");
ARegionType *art;
-
+
st->spaceid = SPACE_OUTLINER;
strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
-
+
st->new = outliner_new;
st->free = outliner_free;
st->init = outliner_init;
@@ -588,26 +588,26 @@ void ED_spacetype_outliner(void)
art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region");
art->regionid = RGN_TYPE_WINDOW;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
-
+
art->init = outliner_main_region_init;
art->draw = outliner_main_region_draw;
art->free = outliner_main_region_free;
art->listener = outliner_main_region_listener;
art->message_subscribe = outliner_main_region_message_subscribe;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype outliner header region");
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
-
+
art->init = outliner_header_region_init;
art->draw = outliner_header_region_draw;
art->free = outliner_header_region_free;
art->listener = outliner_header_region_listener;
BLI_addhead(&st->regiontypes, art);
-
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index e7a391513e9..c8e5a4bdf87 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -66,33 +66,33 @@ static SpaceLink *script_new(const ScrArea *UNUSED(area), const Scene *UNUSED(sc
{
ARegion *ar;
SpaceScript *sscript;
-
+
sscript = MEM_callocN(sizeof(SpaceScript), "initscript");
sscript->spacetype = SPACE_SCRIPT;
-
-
+
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for script");
-
+
BLI_addtail(&sscript->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for script");
-
+
BLI_addtail(&sscript->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
/* channel list region XXX */
-
+
return (SpaceLink *)sscript;
}
/* not spacelink itself */
static void script_free(SpaceLink *sl)
-{
+{
SpaceScript *sscript = (SpaceScript *) sl;
#ifdef WITH_PYTHON
@@ -116,9 +116,9 @@ static void script_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
static SpaceLink *script_duplicate(SpaceLink *sl)
{
SpaceScript *sscriptn = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
-
+
return (SpaceLink *)sscriptn;
}
@@ -128,9 +128,9 @@ static SpaceLink *script_duplicate(SpaceLink *sl)
static void script_main_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
-
+
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "Script", SPACE_SCRIPT, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -145,12 +145,12 @@ static void script_main_region_draw(const bContext *C, ARegion *ar)
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
-
+
UI_view2d_view_ortho(v2d);
-
+
/* data... */
// BPY_script_exec(C, "/root/blender-svn/blender25/test.py", NULL);
-
+
#ifdef WITH_PYTHON
if (sscript->script) {
// BPY_run_script_space_draw(C, sscript);
@@ -158,10 +158,10 @@ static void script_main_region_draw(const bContext *C, ARegion *ar)
#else
(void)sscript;
#endif
-
+
/* reset view matrix */
UI_view2d_view_restore(C);
-
+
/* scrollers? */
}
@@ -190,17 +190,17 @@ void ED_spacetype_script(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype script");
ARegionType *art;
-
+
st->spaceid = SPACE_SCRIPT;
strncpy(st->name, "Script", BKE_ST_MAXNAME);
-
+
st->new = script_new;
st->free = script_free;
st->init = script_init;
st->duplicate = script_duplicate;
st->operatortypes = script_operatortypes;
st->keymap = script_keymap;
-
+
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype script region");
art->regionid = RGN_TYPE_WINDOW;
@@ -210,19 +210,19 @@ void ED_spacetype_script(void)
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_UI | ED_KEYMAP_FRAMES; // XXX need to further test this ED_KEYMAP_UI is needed for button interaction
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype script region");
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
-
+
art->init = script_header_region_init;
art->draw = script_header_region_draw;
-
+
BLI_addhead(&st->regiontypes, art);
-
-
+
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 6968702b958..a8688b26280 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -95,12 +95,12 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
if (flag & SEQPROP_STARTFRAME)
RNA_def_int(ot->srna, "frame_start", 0, INT_MIN, INT_MAX, "Start Frame", "Start frame of the sequence strip", INT_MIN, INT_MAX);
-
+
if (flag & SEQPROP_ENDFRAME)
RNA_def_int(ot->srna, "frame_end", 0, INT_MIN, INT_MAX, "End Frame", "End frame for the color strip", INT_MIN, INT_MAX); /* not usual since most strips have a fixed length */
-
+
RNA_def_int(ot->srna, "channel", 1, 1, MAXSEQ, "Channel", "Channel to place this strip into", 1, MAXSEQ);
-
+
RNA_def_boolean(ot->srna, "replace_sel", 1, "Replace Selection", "Replace the current selection");
/* only for python scripts which import strips and place them after */
@@ -117,7 +117,7 @@ static void sequencer_generic_invoke_path__internal(bContext *C, wmOperator *op,
Main *bmain = CTX_data_main(C);
char path[FILE_MAX];
BLI_strncpy(path, last_seq->strip->dir, sizeof(path));
- BLI_path_abs(path, bmain->name);
+ BLI_path_abs(path, BKE_main_blendfile_path(bmain));
RNA_string_set(op->ptr, identifier, path);
}
}
@@ -145,7 +145,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
proximity = cfra - seq->enddisp;
}
}
-
+
if (tgt) {
return tgt->machine;
}
@@ -155,16 +155,16 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
static void sequencer_generic_invoke_xy__internal(bContext *C, wmOperator *op, int flag, int type)
{
Scene *scene = CTX_data_scene(C);
-
+
int cfra = (int) CFRA;
-
+
/* effect strips don't need a channel initialized from the mouse */
if (!(flag & SEQPROP_NOCHAN)) {
RNA_int_set(op->ptr, "channel", sequencer_generic_invoke_xy_guess_channel(C, type));
}
RNA_int_set(op->ptr, "frame_start", cfra);
-
+
if ((flag & SEQPROP_ENDFRAME) && RNA_struct_property_is_set(op->ptr, "frame_end") == 0)
RNA_int_set(op->ptr, "frame_end", cfra + 25); // XXX arbitary but ok for now.
@@ -199,9 +199,9 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, bContext *C, wmOperato
}
if ((is_file != -1) && relative)
- BLI_path_rel(seq_load->path, bmain->name);
+ BLI_path_rel(seq_load->path, BKE_main_blendfile_path(bmain));
+
-
if ((prop = RNA_struct_find_property(op->ptr, "frame_end"))) {
seq_load->end_frame = RNA_property_int_get(op->ptr, prop);
}
@@ -217,7 +217,7 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, bContext *C, wmOperato
if ((prop = RNA_struct_find_property(op->ptr, "sound")) && RNA_property_boolean_get(op->ptr, prop))
seq_load->flag |= SEQ_LOAD_MOVIE_SOUND;
-
+
if ((prop = RNA_struct_find_property(op->ptr, "use_framerate")) && RNA_property_boolean_get(op->ptr, prop))
seq_load->flag |= SEQ_LOAD_SYNC_FPS;
@@ -286,35 +286,35 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, true);
-
+
Scene *sce_seq;
Sequence *seq; /* generic strip vars */
Strip *strip;
-
+
int start_frame, channel; /* operator props */
-
+
start_frame = RNA_int_get(op->ptr, "frame_start");
channel = RNA_int_get(op->ptr, "channel");
-
+
sce_seq = BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene"));
-
+
if (sce_seq == NULL) {
BKE_report(op->reports, RPT_ERROR, "Scene not found");
return OPERATOR_CANCELLED;
}
-
+
seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
seq->type = SEQ_TYPE_SCENE;
seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */
seq->scene = sce_seq;
-
+
/* basic defaults */
seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1;
strip->us = 1;
-
+
BLI_strncpy(seq->name + 2, sce_seq->id.name + 2, sizeof(seq->name) - 2);
BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
@@ -322,12 +322,12 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
BKE_sequence_calc_disp(scene, seq);
BKE_sequencer_sort(scene);
-
+
sequencer_add_apply_replace_sel(C, op, seq);
sequencer_add_apply_overlap(C, op, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -347,7 +347,7 @@ static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, const w
void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Add Scene Strip";
ot->idname = "SEQUENCER_OT_scene_strip_add";
@@ -358,10 +358,10 @@ void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot)
ot->exec = sequencer_add_scene_strip_exec;
ot->poll = ED_operator_sequencer_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
RNA_def_enum_funcs(prop, RNA_scene_without_active_itemf);
@@ -374,24 +374,24 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, true);
-
+
MovieClip *clip;
Sequence *seq; /* generic strip vars */
Strip *strip;
-
+
int start_frame, channel; /* operator props */
-
+
start_frame = RNA_int_get(op->ptr, "frame_start");
channel = RNA_int_get(op->ptr, "channel");
-
+
clip = BLI_findlink(&CTX_data_main(C)->movieclip, RNA_enum_get(op->ptr, "clip"));
-
+
if (clip == NULL) {
BKE_report(op->reports, RPT_ERROR, "Movie clip not found");
return OPERATOR_CANCELLED;
}
-
+
seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel);
seq->type = SEQ_TYPE_MOVIECLIP;
seq->blend_mode = SEQ_TYPE_CROSS;
@@ -403,18 +403,18 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
seq->len = BKE_movieclip_get_duration(clip);
strip->us = 1;
-
+
BLI_strncpy(seq->name + 2, clip->id.name + 2, sizeof(seq->name) - 2);
BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
BKE_sequence_calc_disp(scene, seq);
BKE_sequencer_sort(scene);
-
+
sequencer_add_apply_replace_sel(C, op, seq);
sequencer_add_apply_overlap(C, op, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -669,7 +669,7 @@ static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, const w
sequencer_generic_invoke_xy__internal(C, op, SEQPROP_NOPATHS, SEQ_TYPE_MOVIE);
return sequencer_add_movie_strip_exec(C, op);
}
-
+
sequencer_generic_invoke_xy__internal(C, op, 0, SEQ_TYPE_MOVIE);
sequencer_add_init(C, op);
@@ -705,7 +705,7 @@ static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op)
void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Add Movie Strip";
ot->idname = "SEQUENCER_OT_movie_strip_add";
@@ -721,7 +721,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
WM_operator_properties_filesel(
ot, FILE_TYPE_FOLDER | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
@@ -746,7 +746,7 @@ static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, const w
sequencer_generic_invoke_xy__internal(C, op, SEQPROP_NOPATHS, SEQ_TYPE_SOUND_RAM);
return sequencer_add_sound_strip_exec(C, op);
}
-
+
sequencer_generic_invoke_xy__internal(C, op, 0, SEQ_TYPE_SOUND_RAM);
WM_event_add_fileselect(C, op);
@@ -758,7 +758,7 @@ static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, const w
void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Add Sound Strip";
ot->idname = "SEQUENCER_OT_sound_strip_add";
@@ -769,10 +769,10 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
ot->exec = sequencer_add_sound_strip_exec;
ot->poll = ED_operator_sequencer_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
WM_operator_properties_filesel(
ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
@@ -928,7 +928,7 @@ static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, const w
sequencer_generic_invoke_xy__internal(C, op, SEQPROP_ENDFRAME | SEQPROP_NOPATHS, SEQ_TYPE_IMAGE);
return sequencer_add_image_strip_exec(C, op);
}
-
+
sequencer_generic_invoke_xy__internal(C, op, SEQPROP_ENDFRAME, SEQ_TYPE_IMAGE);
sequencer_add_init(C, op);
@@ -944,7 +944,7 @@ static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, const w
void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Add Image Strip";
ot->idname = "SEQUENCER_OT_image_strip_add";
@@ -957,10 +957,10 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
ot->ui = sequencer_add_draw;
ot->poll = ED_operator_sequencer_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
WM_operator_properties_filesel(
ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
@@ -981,7 +981,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
struct SeqEffectHandle sh;
int start_frame, end_frame, channel, type; /* operator props */
-
+
Sequence *seq1, *seq2, *seq3;
const char *error_msg;
@@ -990,7 +990,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
channel = RNA_int_get(op->ptr, "channel");
type = RNA_enum_get(op->ptr, "type");
-
+
// XXX move to invoke
if (!seq_effect_find_selected(scene, NULL, type, &seq1, &seq2, &seq3, &error_msg)) {
BKE_report(op->reports, RPT_ERROR, error_msg);
@@ -1026,7 +1026,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
BKE_sequence_calc(scene, seq);
-
+
/* basic defaults */
seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
strip->us = 1;
@@ -1064,7 +1064,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
/* not sure if this is needed with update_changed_seq_and_deps.
* it was NOT called in blender 2.4x, but wont hurt */
- BKE_sequencer_sort(scene);
+ BKE_sequencer_sort(scene);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
@@ -1108,10 +1108,10 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot)
ot->exec = sequencer_add_effect_strip_exec;
ot->poll = ED_operator_sequencer_active_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME);
RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type");
RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color",
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index b33a26db728..72f78d4f466 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -65,7 +65,7 @@ void sequencer_buttons_register(ARegionType *UNUSED(art))
{
#if 0
PanelType *pt;
-
+
pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil");
strcpy(pt->idname, "SEQUENCER_PT_gpencil");
strcpy(pt->label, N_("Grease Pencil"));
@@ -83,7 +83,7 @@ static int sequencer_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = sequencer_has_buttons_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -95,10 +95,10 @@ void SEQUENCER_OT_properties(wmOperatorType *ot)
ot->name = "Properties";
ot->idname = "SEQUENCER_OT_properties";
ot->description = "Toggle the properties region visibility";
-
+
ot->exec = sequencer_properties_toggle_exec;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = 0;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 556888c63c2..ffcb4329726 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -125,12 +125,12 @@ void color3ubv_from_seq(Scene *curscene, Sequence *seq, unsigned char col[3])
case SEQ_TYPE_SCENE:
UI_GetThemeColor3ubv(TH_SEQ_SCENE, col);
-
+
if (seq->scene == curscene) {
UI_GetColorPtrShade3ubv(col, col, 20);
}
break;
-
+
/* transitions */
case SEQ_TYPE_CROSS:
case SEQ_TYPE_GAMCROSS:
@@ -216,7 +216,7 @@ static void drawseqwave(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *s
float startsample, endsample;
float value1, value2;
bSound *sound = seq->sound;
-
+
SoundWaveform *waveform;
if (length < 2) {
@@ -227,7 +227,7 @@ static void drawseqwave(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *s
sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
BLI_spin_init(sound->spinlock);
}
-
+
BLI_spin_lock(sound->spinlock);
if (!sound->waveform) {
if (!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) {
@@ -242,7 +242,7 @@ static void drawseqwave(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *s
return; /* nothing to draw */
}
BLI_spin_unlock(sound->spinlock);
-
+
waveform = sound->waveform;
if (waveform->length == 0) {
@@ -365,7 +365,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
}
immUniformColor4ubv(col);
-
+
/* clamp within parent sequence strip bounds */
if (x1_chan < x1) x1_chan = x1;
if (x2_chan > x2) x2_chan = x2;
@@ -399,10 +399,10 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
float v1[2], v2[2], v3[2], rx1 = 0, rx2 = 0; //for triangles and rect
float x1, x2, y1, y2;
unsigned int whichsel = 0;
-
+
x1 = seq->startdisp;
x2 = seq->enddisp;
-
+
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
y2 = seq->machine + SEQ_STRIP_OFSTOP;
@@ -410,32 +410,32 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
if (direction == SEQ_LEFTHANDLE) {
rx1 = x1;
rx2 = x1 + handsize_clamped * 0.75f;
-
+
v1[0] = x1 + handsize_clamped / 4; v1[1] = y1 + ( ((y1 + y2) / 2.0f - y1) / 2);
v2[0] = x1 + handsize_clamped / 4; v2[1] = y2 - ( ((y1 + y2) / 2.0f - y1) / 2);
v3[0] = v2[0] + handsize_clamped / 4; v3[1] = (y1 + y2) / 2.0f;
-
+
whichsel = SEQ_LEFTSEL;
}
else if (direction == SEQ_RIGHTHANDLE) {
rx1 = x2 - handsize_clamped * 0.75f;
rx2 = x2;
-
+
v1[0] = x2 - handsize_clamped / 4; v1[1] = y1 + ( ((y1 + y2) / 2.0f - y1) / 2);
v2[0] = x2 - handsize_clamped / 4; v2[1] = y2 - ( ((y1 + y2) / 2.0f - y1) / 2);
v3[0] = v2[0] - handsize_clamped / 4; v3[1] = (y1 + y2) / 2.0f;
-
+
whichsel = SEQ_RIGHTSEL;
}
-
+
/* draw! */
if (!(seq->type & SEQ_TYPE_EFFECT) ||
BKE_sequence_effect_get_num_inputs(seq->type) == 0)
{
glEnable(GL_BLEND);
-
+
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
+
if (seq->flag & whichsel) {
immUniformColor4ub(0, 0, 0, 80);
}
@@ -445,9 +445,9 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
else {
immUniformColor4ub(0, 0, 0, 22);
}
-
+
immRectf(pos, rx1, y1, rx2, y2);
-
+
if (seq->flag & whichsel) {
immUniformColor4ub(255, 255, 255, 200);
}
@@ -463,7 +463,7 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
glDisable(GL_BLEND);
}
-
+
if ((G.moving & G_TRANSFORM_SEQ) || (seq->flag & whichsel)) {
const char col[4] = {255, 255, 255, 255};
char numstr[32];
@@ -579,7 +579,7 @@ static void draw_seq_text(View2D *v2d, SpaceSeq *sseq, Sequence *seq, float x1,
str_len = BLI_snprintf(str, sizeof(str), "%s | %d",
name, seq->len);
}
-
+
if (seq->flag & SELECT) {
col[0] = col[1] = col[2] = 255;
}
@@ -604,23 +604,23 @@ static void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq, u
float x1, x2, y1, y2, pixely;
unsigned char col[4], blendcol[3];
View2D *v2d = &ar->v2d;
-
+
x1 = seq->startdisp;
x2 = seq->enddisp;
-
+
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
y2 = seq->machine + SEQ_STRIP_OFSTOP;
-
+
pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
-
+
if (pixely <= 0) return; /* can happen when the view is split/resized */
-
+
blendcol[0] = blendcol[1] = blendcol[2] = 120;
if (seq->startofs || seq->endofs) {
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
+
color3ubv_from_seq(scene, seq, col);
if (seq->flag & SELECT) {
@@ -710,7 +710,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
/* we need to know if this is a single image/color or not for drawing */
is_single_image = (char)BKE_sequence_single_check(seq);
-
+
/* body */
x1 = (seq->startstill) ? seq->start : seq->startdisp;
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
@@ -765,7 +765,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
x1 = seq->startdisp;
x2 = seq->enddisp;
-
+
/* draw sound wave */
if (seq->type == SEQ_TYPE_SOUND_RAM) {
if (!(sseq->flag & SEQ_NO_WAVEFORMS)) {
@@ -825,7 +825,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg
}
else
UI_GetColorPtrShade3ubv(col, col, outline_tint);
-
+
if ((seq->type == SEQ_TYPE_META) ||
((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS)))
{
@@ -978,7 +978,7 @@ static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scop
{
ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
ImBuf *scope;
-
+
IMB_colormanagement_imbuf_make_display_space(display_ibuf, &scene->view_settings,
&scene->display_settings);
@@ -1485,7 +1485,7 @@ void drawprefetchseqspace(Scene *scene, ARegion *UNUSED(ar), SpaceSeq *sseq)
{
int rectx, recty;
int render_size = sseq->render_size;
- int proxy_size = 100.0;
+ int proxy_size = 100.0;
if (render_size == 0) {
render_size = scene->r.size;
}
@@ -1558,12 +1558,12 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
Sequence *last_seq = BKE_sequencer_active_get(scene);
int sel = 0, j;
float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
-
+
/* loop through twice, first unselected, then selected */
for (j = 0; j < 2; j++) {
Sequence *seq;
int outline_tint = (j) ? 40 : -40; /* highlighting around strip edges indicating selection */
-
+
/* loop through strips, checking for those that are visible */
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
/* boundbox and selection tests for NOT drawing the strip... */
@@ -1573,15 +1573,15 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
else if (max_ii(seq->enddisp, seq->start + seq->len) < v2d->cur.xmin) continue;
else if (seq->machine + 1.0f < v2d->cur.ymin) continue;
else if (seq->machine > v2d->cur.ymax) continue;
-
+
/* strip passed all tests unscathed... so draw it now */
draw_seq_strip(C, sseq, scene, ar, seq, outline_tint, pixelx);
}
-
+
/* draw selected next time round */
sel = SELECT;
}
-
+
/* draw the last selected last (i.e. 'active' in other parts of Blender), removes some overlapping error */
if (last_seq)
draw_seq_strip(C, sseq, scene, ar, last_seq, 120, pixelx);
@@ -1614,7 +1614,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* draw darkened area outside of active timeline
+ /* draw darkened area outside of active timeline
* frame range used is preview range or scene range */
immUniformThemeColorShadeAlpha(TH_BACK, -25, -100);
@@ -1673,27 +1673,27 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
View2DScrollers *scrollers;
short unit = 0, cfra_flag = 0;
float col[3];
-
+
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
- if (ed && ed->metastack.first)
+ if (ed && ed->metastack.first)
glClearColor(col[0], col[1], col[2] - 0.1f, 0.0f);
- else
+ else
glClearColor(col[0], col[1], col[2], 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
UI_view2d_view_ortho(v2d);
-
-
- /* calculate extents of sequencer strips/data
+
+
+ /* calculate extents of sequencer strips/data
* NOTE: needed for the scrollers later
*/
boundbox_seq(scene, &v2d->tot);
-
-
+
+
/* draw backdrop */
draw_seq_backdrop(v2d);
-
+
/* regular grid-pattern over the rest of the view (i.e. 1-second grid lines) */
UI_view2d_constant_grid_draw(v2d, FPS);
@@ -1702,29 +1702,29 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, true);
UI_view2d_view_ortho(v2d);
}
-
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
-
+
seq_draw_sfra_efra(scene, v2d);
/* sequence strips (if there is data available to be drawn) */
if (ed) {
/* draw the data */
draw_seq_strips(C, ed, ar);
-
+
/* text draw cached (for sequence names), in pixelspace now */
UI_view2d_text_cache_draw(ar);
}
-
+
/* current frame */
UI_view2d_view_ortho(v2d);
if ((sseq->flag & SEQ_DRAWFRAMES) == 0) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
ANIM_draw_cfra(C, v2d, cfra_flag);
-
+
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ED_markers_draw(C, DRAW_MARKERS_LINES | DRAW_MARKERS_MARGIN);
-
+
/* preview range */
UI_view2d_view_ortho(v2d);
ANIM_draw_previewrange(C, v2d, 1);
@@ -1757,7 +1757,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_UNIT_VALUES, V2D_GRID_CLAMP);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-
+
/* draw current frame number-indicator on top of scrollers */
if ((sseq->flag & SEQ_NO_DRAW_CFRANUM) == 0) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index a4834caf709..b24817f2af8 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -130,7 +130,7 @@ typedef struct TransSeq {
typedef struct ProxyBuildJob {
struct Main *main;
struct Depsgraph *depsgraph;
- Scene *scene;
+ Scene *scene;
ListBase queue;
int stop;
} ProxyJob;
@@ -154,7 +154,7 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
struct SeqIndexBuildContext *context = link->data;
BKE_sequencer_proxy_rebuild(context, stop, do_update, progress);
-
+
if (*stop) {
pj->stop = 1;
fprintf(stderr, "Canceling proxy rebuild on users request...\n");
@@ -188,7 +188,7 @@ static void seq_proxy_build_job(const bContext *C)
ScrArea *sa = CTX_wm_area(C);
Sequence *seq;
GSet *file_list;
-
+
if (ed == NULL) {
return;
}
@@ -200,7 +200,7 @@ static void seq_proxy_build_job(const bContext *C)
if (!pj) {
pj = MEM_callocN(sizeof(ProxyJob), "proxy rebuild job");
-
+
pj->depsgraph = depsgraph;
pj->scene = scene;
pj->main = CTX_data_main(C);
@@ -220,7 +220,7 @@ static void seq_proxy_build_job(const bContext *C)
SEQ_END
BLI_gset_free(file_list, MEM_freeN);
-
+
if (!WM_jobs_is_running(wm_job)) {
G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
@@ -247,7 +247,7 @@ void boundbox_seq(Scene *scene, rctf *rect)
Editing *ed = BKE_sequencer_editing_get(scene, false);
float min[2], max[2];
-
+
if (ed == NULL) return;
min[0] = 0.0;
@@ -276,18 +276,18 @@ static int mouse_frame_side(View2D *v2d, short mouse_x, int frame)
{
int mval[2];
float mouseloc[2];
-
+
mval[0] = mouse_x;
mval[1] = 0;
-
+
/* choose the side based on which side of the playhead the mouse is on */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &mouseloc[0], &mouseloc[1]);
-
+
return mouseloc[0] > frame ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT;
}
-Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int sel)
+Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int sel)
{
/* sel - 0==unselected, 1==selected, -1==done care*/
Sequence *seq;
@@ -296,7 +296,7 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se
if (ed == NULL) return NULL;
if (sel > 0) sel = SELECT;
-
+
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq != test) &&
(test->machine == seq->machine) &&
@@ -319,16 +319,16 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se
return NULL;
}
-static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel)
+static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel)
{
/* sel - 0==unselected, 1==selected, -1==done care*/
Sequence *seq, *best_seq = NULL;
Editing *ed = BKE_sequencer_editing_get(scene, false);
-
+
int dist, best_dist;
best_dist = MAXFRAME * 2;
-
+
if (ed == NULL) return NULL;
seq = ed->seqbasep->first;
@@ -339,7 +339,7 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
((sel == -1) || (sel == (seq->flag & SELECT))))
{
dist = MAXFRAME * 2;
-
+
switch (lr) {
case SEQ_SIDE_LEFT:
if (seq->enddisp <= test->startdisp) {
@@ -352,7 +352,7 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
}
break;
}
-
+
if (dist == 0) {
best_seq = seq;
break;
@@ -378,15 +378,15 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[
float displen;
*hand = SEQ_SIDE_NONE;
-
+
if (ed == NULL) return NULL;
-
+
pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
-
+
seq = ed->seqbasep->first;
-
+
while (seq) {
if (seq->machine == (int)y) {
/* check for both normal strips, and strips that have been flipped horizontally */
@@ -394,23 +394,23 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[
((seq->startdisp > seq->enddisp) && (seq->startdisp >= x && seq->enddisp <= x)) )
{
if (BKE_sequence_tx_test(seq)) {
-
+
/* clamp handles to defined size in pixel space */
-
+
handsize = seq->handsize;
displen = (float)abs(seq->startdisp - seq->enddisp);
-
+
if (displen / pixelx > 16) { /* don't even try to grab the handles of small strips */
/* Set the max value to handle to 1/3 of the total len when its less than 28.
* This is important because otherwise selecting handles happens even when you click in the middle */
-
+
if ((displen / 3) < 30 * pixelx) {
handsize = displen / 3;
}
else {
CLAMP(handsize, 7 * pixelx, 30 * pixelx);
}
-
+
if (handsize + seq->startdisp >= x)
*hand = SEQ_SIDE_LEFT;
else if (-handsize + seq->enddisp <= x)
@@ -448,7 +448,7 @@ void ED_sequencer_deselect_all(Scene *scene)
Sequence *seq;
Editing *ed = BKE_sequencer_editing_get(scene, false);
-
+
if (ed == NULL) return;
SEQP_BEGIN (ed, seq)
@@ -456,7 +456,7 @@ void ED_sequencer_deselect_all(Scene *scene)
seq->flag &= ~SEQ_ALLSEL;
}
SEQ_END
-
+
}
void recurs_sel_seq(Sequence *seqm)
@@ -521,7 +521,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
{
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq;
-
+
*error_str = NULL;
if (!activeseq)
@@ -552,7 +552,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
seq2 = seq3;
seq3 = tmp;
}
-
+
switch (BKE_sequence_effect_get_num_inputs(type)) {
case 0:
@@ -574,12 +574,12 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
if (seq3 == NULL) seq3 = seq2;
break;
}
-
+
if (seq1 == NULL && seq2 == NULL && seq3 == NULL) {
*error_str = N_("TODO: in what cases does this happen?");
return 0;
}
-
+
*selseq1 = seq1;
*selseq2 = seq2;
*selseq3 = seq3;
@@ -691,7 +691,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
/* First Strip! */
/* strips with extended stillfames before */
-
+
/* Precaution, needed because the length saved on-disk may not match the length saved in the blend file,
* or our code may have minor differences reading file length between versions.
* This causes hard-cut to fail, see: T47862 */
@@ -733,7 +733,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
skip_dup = true;
}
}
-
+
BKE_sequence_reload_new_file(scene, seq, false);
BKE_sequence_calc(scene, seq);
@@ -741,7 +741,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
/* Duplicate AFTER the first change */
seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
}
-
+
if (seqn) {
seqn->flag |= SELECT;
@@ -843,14 +843,14 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
skip_dup = true;
}
}
-
+
BKE_sequence_calc(scene, seq);
if (!skip_dup) {
/* Duplicate AFTER the first change */
seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
}
-
+
if (seqn) {
seqn->flag |= SELECT;
@@ -904,14 +904,14 @@ static bool cut_seq_list(Scene *scene, ListBase *slist, int cutframe,
{
Sequence *seq, *seq_next_iter;
Sequence *seq_first_new = NULL;
-
+
seq = slist->first;
while (seq && seq != seq_first_new) {
seq_next_iter = seq->next; /* we need this because we may remove seq */
seq->tmp = NULL;
if (seq->flag & SELECT) {
- if (cutframe > seq->startdisp &&
+ if (cutframe > seq->startdisp &&
cutframe < seq->enddisp)
{
Sequence *seqn = cut_seq(scene, seq, cutframe);
@@ -949,7 +949,7 @@ static bool sequence_offset_after_frame(Scene *scene, const int delta, const int
TimeMarker *marker;
/* all strips >= cfra are shifted */
-
+
if (ed == NULL) return 0;
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -977,7 +977,7 @@ static void set_filter_seq(Scene *scene)
Sequence *seq;
Editing *ed = BKE_sequencer_editing_get(scene, false);
-
+
if (ed == NULL) return;
if (okee("Set Deinterlace") == 0) return;
@@ -1002,32 +1002,32 @@ static void UNUSED_FUNCTION(seq_remap_paths) (Scene *scene)
Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
Editing *ed = BKE_sequencer_editing_get(scene, false);
char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
-
-
+
+
if (last_seq == NULL)
return;
-
+
BLI_strncpy(from, last_seq->strip->dir, sizeof(from));
// XXX if (0 == sbutton(from, 0, sizeof(from) - 1, "From: "))
// return;
-
+
BLI_strncpy(to, from, sizeof(to));
// XXX if (0 == sbutton(to, 0, sizeof(to) - 1, "To: "))
// return;
-
+
if (STREQ(to, from))
return;
-
+
SEQP_BEGIN (ed, seq)
{
if (seq->flag & SELECT) {
if (STREQLEN(seq->strip->dir, from, strlen(from))) {
printf("found %s\n", seq->strip->dir);
-
+
/* strip off the beginning */
stripped[0] = 0;
BLI_strncpy(stripped, seq->strip->dir + strlen(from), FILE_MAX);
-
+
/* new path */
BLI_snprintf(seq->strip->dir, sizeof(seq->strip->dir), "%s%s", to, stripped);
printf("new %s\n", seq->strip->dir);
@@ -1035,7 +1035,7 @@ static void UNUSED_FUNCTION(seq_remap_paths) (Scene *scene)
}
}
SEQ_END
-
+
}
@@ -1051,7 +1051,7 @@ static int sequencer_gap_remove_exec(bContext *C, wmOperator *op)
boundbox_seq(scene, &rectf);
sfra = (int)rectf.xmin;
efra = (int)rectf.xmax;
-
+
/* first check if the current frame has a gap already */
for (cfra = CFRA; cfra >= sfra; cfra--) {
if (BKE_sequencer_evaluate_frame(scene, cfra)) {
@@ -1076,7 +1076,7 @@ static int sequencer_gap_remove_exec(bContext *C, wmOperator *op)
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -1088,15 +1088,15 @@ void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot)
ot->name = "Remove Gaps";
ot->idname = "SEQUENCER_OT_gap_remove";
ot->description = "Remove gap at current frame to first strip at the right, independent of selection or locked state of strips";
-
+
/* api callbacks */
// ot->invoke = sequencer_snap_invoke;
ot->exec = sequencer_gap_remove_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "all", 0, "All Gaps", "Do all gaps to right of current frame");
}
@@ -1104,13 +1104,13 @@ static int sequencer_gap_insert_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
int frames = RNA_int_get(op->ptr, "frames");
-
+
sequence_offset_after_frame(scene, frames, CFRA);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
-
+
}
void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot)
@@ -1119,15 +1119,15 @@ void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot)
ot->name = "Insert Gaps";
ot->idname = "SEQUENCER_OT_gap_insert";
ot->description = "Insert gap at current frame to first strips at the right, independent of selection or locked state of strips";
-
+
/* api callbacks */
// ot->invoke = sequencer_snap_invoke;
ot->exec = sequencer_gap_insert_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_int(ot->srna, "frames", 10, 0, INT_MAX, "Frames", "Frames to insert after current strip", 0, 1000);
}
@@ -1139,7 +1139,7 @@ static int seq_get_snaplimit(View2D *v2d)
* a bit lazy but its only done once pre transform */
float xmouse, ymouse, x;
int mval[2] = {24, 0}; /* 24 screen px snap */
-
+
UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
x = xmouse;
mval[0] = 0;
@@ -1192,7 +1192,7 @@ int sequencer_view_strips_poll(bContext *C)
static int sequencer_snap_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
-
+
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
int snap_frame;
@@ -1234,31 +1234,31 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
}
}
else if (seq->type & SEQ_TYPE_EFFECT) {
- if (seq->seq1 && (seq->seq1->flag & SELECT))
+ if (seq->seq1 && (seq->seq1->flag & SELECT))
BKE_sequence_calc(scene, seq);
- else if (seq->seq2 && (seq->seq2->flag & SELECT))
+ else if (seq->seq2 && (seq->seq2->flag & SELECT))
BKE_sequence_calc(scene, seq);
- else if (seq->seq3 && (seq->seq3->flag & SELECT))
+ else if (seq->seq3 && (seq->seq3->flag & SELECT))
BKE_sequence_calc(scene, seq);
}
}
/* as last: */
BKE_sequencer_sort(scene);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
}
static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
-
+
int snap_frame;
-
+
snap_frame = CFRA;
-
+
RNA_int_set(op->ptr, "frame", snap_frame);
return sequencer_snap_exec(C, op);
}
@@ -1269,15 +1269,15 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot)
ot->name = "Snap Strips to Frame";
ot->idname = "SEQUENCER_OT_snap";
ot->description = "Frame where selected strips will be snapped";
-
+
/* api callbacks */
ot->invoke = sequencer_snap_invoke;
ot->exec = sequencer_snap_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX);
}
@@ -1708,7 +1708,7 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op)
bool selected;
selected = !RNA_boolean_get(op->ptr, "unselected");
-
+
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq->flag & SEQ_LOCK) == 0) {
if (selected) { /* mute unselected */
@@ -1725,10 +1725,10 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op)
}
}
}
-
+
BKE_sequencer_update_muting(ed);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -1738,14 +1738,14 @@ void SEQUENCER_OT_mute(struct wmOperatorType *ot)
ot->name = "Mute Strips";
ot->idname = "SEQUENCER_OT_mute";
ot->description = "Mute (un)selected strips";
-
+
/* api callbacks */
ot->exec = sequencer_mute_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Mute unselected rather than selected strips");
}
@@ -1759,7 +1759,7 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op)
bool selected;
selected = !RNA_boolean_get(op->ptr, "unselected");
-
+
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq->flag & SEQ_LOCK) == 0) {
if (selected) { /* unmute unselected */
@@ -1776,10 +1776,10 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op)
}
}
}
-
+
BKE_sequencer_update_muting(ed);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -1789,14 +1789,14 @@ void SEQUENCER_OT_unmute(struct wmOperatorType *ot)
ot->name = "Un-Mute Strips";
ot->idname = "SEQUENCER_OT_unmute";
ot->description = "Unmute (un)selected strips";
-
+
/* api callbacks */
ot->exec = sequencer_unmute_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Unmute unselected rather than selected strips");
}
@@ -1825,11 +1825,11 @@ void SEQUENCER_OT_lock(struct wmOperatorType *ot)
ot->name = "Lock Strips";
ot->idname = "SEQUENCER_OT_lock";
ot->description = "Lock the active strip so that it can't be transformed";
-
+
/* api callbacks */
ot->exec = sequencer_lock_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1858,11 +1858,11 @@ void SEQUENCER_OT_unlock(struct wmOperatorType *ot)
ot->name = "UnLock Strips";
ot->idname = "SEQUENCER_OT_unlock";
ot->description = "Unlock the active strip so that it can't be transformed";
-
+
/* api callbacks */
ot->exec = sequencer_unlock_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -1900,11 +1900,11 @@ void SEQUENCER_OT_reload(struct wmOperatorType *ot)
ot->name = "Reload Strips";
ot->idname = "SEQUENCER_OT_reload";
ot->description = "Reload strips in the sequencer";
-
+
/* api callbacks */
ot->exec = sequencer_reload_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER; /* no undo, the data changed is stored outside 'main' */
@@ -1940,7 +1940,7 @@ void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot)
ot->name = "Refresh Sequencer";
ot->idname = "SEQUENCER_OT_refresh_all";
ot->description = "Refresh the sequencer editor";
-
+
/* api callbacks */
ot->exec = sequencer_refresh_all_exec;
ot->poll = sequencer_refresh_all_poll;
@@ -2061,14 +2061,14 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op)
cut_frame = RNA_int_get(op->ptr, "frame");
cut_hard = RNA_enum_get(op->ptr, "type");
cut_side = RNA_enum_get(op->ptr, "side");
-
+
if (cut_hard == SEQ_CUT_HARD) {
changed = cut_seq_list(scene, ed->seqbasep, cut_frame, cut_seq_hard);
}
else {
changed = cut_seq_list(scene, ed->seqbasep, cut_frame, cut_seq_soft);
}
-
+
if (changed) { /* got new strips ? */
Sequence *seq;
@@ -2121,7 +2121,7 @@ static int sequencer_cut_invoke(bContext *C, wmOperator *op, const wmEvent *even
if (ED_operator_sequencer_active(C) && v2d)
cut_side = mouse_frame_side(v2d, event->mval[0], cut_frame);
-
+
RNA_int_set(op->ptr, "frame", cut_frame);
RNA_enum_set(op->ptr, "side", cut_side);
/*RNA_enum_set(op->ptr, "type", cut_hard); */ /*This type is set from the key shortcut */
@@ -2136,15 +2136,15 @@ void SEQUENCER_OT_cut(struct wmOperatorType *ot)
ot->name = "Cut Strips";
ot->idname = "SEQUENCER_OT_cut";
ot->description = "Cut the selected strips";
-
+
/* api callbacks */
ot->invoke = sequencer_cut_invoke;
ot->exec = sequencer_cut_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be cut", INT_MIN, INT_MAX);
RNA_def_enum(ot->srna, "type", prop_cut_types, SEQ_CUT_SOFT, "Type", "The type of cut operation to perform on strips");
RNA_def_enum(ot->srna, "side", prop_side_types, SEQ_SIDE_BOTH, "Side", "The side that remains selected after cutting");
@@ -2196,14 +2196,14 @@ void SEQUENCER_OT_duplicate(wmOperatorType *ot)
ot->name = "Duplicate Strips";
ot->idname = "SEQUENCER_OT_duplicate";
ot->description = "Duplicate the selected strips";
-
+
/* api callbacks */
ot->exec = sequencer_add_duplicate_exec;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* to give to transform */
RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
}
@@ -2264,7 +2264,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -2290,12 +2290,12 @@ void SEQUENCER_OT_delete(wmOperatorType *ot)
ot->name = "Erase Strips";
ot->idname = "SEQUENCER_OT_delete";
ot->description = "Erase selected strips from the sequencer";
-
+
/* api callbacks */
ot->invoke = sequencer_delete_invoke;
ot->exec = sequencer_delete_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2358,7 +2358,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
-
+
Sequence *seq, *seq_new;
Strip *strip_new;
StripElem *se, *se_new;
@@ -2428,7 +2428,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
/* as last: */
BKE_sequencer_sort(scene);
-
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -2441,12 +2441,12 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot)
ot->name = "Separate Images";
ot->idname = "SEQUENCER_OT_images_separate";
ot->description = "On image sequence strips, it returns a strip for each image";
-
+
/* api callbacks */
ot->exec = sequencer_separate_images_exec;
ot->invoke = WM_operator_props_popup_confirm;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2532,11 +2532,11 @@ void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
ot->name = "Toggle Meta Strip";
ot->idname = "SEQUENCER_OT_meta_toggle";
ot->description = "Toggle a metastrip (to edit enclosed strips)";
-
+
/* api callbacks */
ot->exec = sequencer_meta_toggle_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2547,7 +2547,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
-
+
Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene);
int channel_max = 1;
@@ -2579,7 +2579,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
seqm->strip = MEM_callocN(sizeof(Strip), "metastrip");
seqm->strip->us = 1;
-
+
BKE_sequencer_active_set(scene, seqm);
if (BKE_sequence_test_overlap(ed->seqbasep, seqm) ) BKE_sequence_base_shuffle(ed->seqbasep, seqm, scene);
@@ -2599,11 +2599,11 @@ void SEQUENCER_OT_meta_make(wmOperatorType *ot)
ot->name = "Make Meta Strip";
ot->idname = "SEQUENCER_OT_meta_make";
ot->description = "Group selected strips into a metastrip";
-
+
/* api callbacks */
ot->exec = sequencer_meta_make_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2672,11 +2672,11 @@ void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
ot->name = "UnMeta Strip";
ot->idname = "SEQUENCER_OT_meta_separate";
ot->description = "Put the contents of a metastrip back in the sequencer";
-
+
/* api callbacks */
ot->exec = sequencer_meta_separate_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2698,11 +2698,11 @@ void SEQUENCER_OT_view_all(wmOperatorType *ot)
ot->name = "View All";
ot->idname = "SEQUENCER_OT_view_all";
ot->description = "View all the strips in the sequencer";
-
+
/* api callbacks */
ot->exec = sequencer_view_all_exec;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER;
}
@@ -2711,7 +2711,7 @@ static int sequencer_view_frame_exec(bContext *C, wmOperator *op)
{
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
ANIM_center_frame(C, smooth_viewtx);
-
+
return OPERATOR_FINISHED;
}
@@ -2721,11 +2721,11 @@ void SEQUENCER_OT_view_frame(wmOperatorType *ot)
ot->name = "View Frame";
ot->idname = "SEQUENCER_OT_view_frame";
ot->description = "Reset viewable area to show range around current frame";
-
+
/* api callbacks */
ot->exec = sequencer_view_frame_exec;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -2745,7 +2745,7 @@ static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op))
v2d->cur = v2d->tot;
UI_view2d_curRect_validate(v2d);
UI_view2d_sync(sc, area, v2d, V2D_LOCK_COPY);
-
+
#if 0
/* Like zooming on an image view */
float zoomX, zoomY;
@@ -2787,11 +2787,11 @@ void SEQUENCER_OT_view_all_preview(wmOperatorType *ot)
ot->name = "View All";
ot->idname = "SEQUENCER_OT_view_all_preview";
ot->description = "Zoom preview to fit in the area";
-
+
/* api callbacks */
ot->exec = sequencer_view_all_preview_exec;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER;
}
@@ -2862,11 +2862,11 @@ void SEQUENCER_OT_view_toggle(wmOperatorType *ot)
ot->name = "View Toggle";
ot->idname = "SEQUENCER_OT_view_toggle";
ot->description = "Toggle between sequencer views (sequence, preview, both)";
-
+
/* api callbacks */
ot->exec = sequencer_view_toggle_exec;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER;
}
@@ -2907,7 +2907,7 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
if (ymax != 0) {
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
+
xmax += xmargin;
xmin -= xmargin;
ymax += ymargin;
@@ -2936,7 +2936,7 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
else {
return OPERATOR_CANCELLED;
}
-
+
}
void SEQUENCER_OT_view_selected(wmOperatorType *ot)
@@ -2945,11 +2945,11 @@ void SEQUENCER_OT_view_selected(wmOperatorType *ot)
ot->name = "View Selected";
ot->idname = "SEQUENCER_OT_view_selected";
ot->description = "Zoom the sequencer on the selected strips";
-
+
/* api callbacks */
ot->exec = sequencer_view_selected_exec;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER;
}
@@ -2961,7 +2961,7 @@ static bool strip_jump_internal(Scene *scene,
bool changed = false;
int cfra = CFRA;
int nfra = BKE_sequencer_find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center, false);
-
+
if (nfra != cfra) {
CFRA = nfra;
changed = true;
@@ -2992,7 +2992,7 @@ static int sequencer_strip_jump_exec(bContext *C, wmOperator *op)
}
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -3009,7 +3009,7 @@ void SEQUENCER_OT_strip_jump(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "next", true, "Next Strip", "");
RNA_def_boolean(ot->srna, "center", true, "Use strip center", "");
@@ -3061,9 +3061,9 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op)
if (active_seq == NULL) return OPERATOR_CANCELLED;
seq = find_next_prev_sequence(scene, active_seq, side, -1);
-
+
if (seq) {
-
+
/* disallow effect strips */
if (BKE_sequence_effect_get_num_inputs(seq->type) >= 1 && (seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3))
return OPERATOR_CANCELLED;
@@ -3071,10 +3071,10 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
switch (side) {
- case SEQ_SIDE_LEFT:
+ case SEQ_SIDE_LEFT:
swap_sequence(scene, seq, active_seq);
break;
- case SEQ_SIDE_RIGHT:
+ case SEQ_SIDE_RIGHT:
swap_sequence(scene, active_seq, seq);
break;
}
@@ -3114,14 +3114,14 @@ void SEQUENCER_OT_swap(wmOperatorType *ot)
ot->name = "Swap Strip";
ot->idname = "SEQUENCER_OT_swap";
ot->description = "Swap active strip with strip to the right or left";
-
+
/* api callbacks */
ot->exec = sequencer_swap_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_enum(ot->srna, "side", prop_side_lr_types, SEQ_SIDE_RIGHT, "Side", "Side of the strip to swap");
}
@@ -3173,14 +3173,14 @@ void SEQUENCER_OT_rendersize(wmOperatorType *ot)
ot->name = "Set Render Size";
ot->idname = "SEQUENCER_OT_rendersize";
ot->description = "Set render size and aspect from active sequence";
-
+
/* api callbacks */
ot->exec = sequencer_rendersize_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
}
@@ -3464,13 +3464,13 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
GSet *file_list;
-
+
if (ed == NULL) {
return OPERATOR_CANCELLED;
}
file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list");
-
+
SEQP_BEGIN(ed, seq)
{
if ((seq->flag & SELECT)) {
@@ -3492,7 +3492,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
SEQ_END
BLI_gset_free(file_list, MEM_freeN);
-
+
return OPERATOR_FINISHED;
}
@@ -3502,11 +3502,11 @@ void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot)
ot->name = "Rebuild Proxy and Timecode Indices";
ot->idname = "SEQUENCER_OT_rebuild_proxy";
ot->description = "Rebuild all selected proxies and timecode indices using the job system";
-
+
/* api callbacks */
ot->invoke = sequencer_rebuild_proxy_invoke;
ot->exec = sequencer_rebuild_proxy_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER;
}
@@ -3543,27 +3543,27 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
if (proxy_25)
seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_25;
- else
+ else
seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_25;
-
+
if (proxy_50)
seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_50;
- else
+ else
seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_50;
-
+
if (proxy_75)
seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_75;
- else
+ else
seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_75;
-
+
if (proxy_100)
seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_100;
- else
+ else
seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_100;
-
+
if (!overwrite)
seq->strip->proxy->build_flags |= SEQ_PROXY_SKIP_EXISTING;
- else
+ else
seq->strip->proxy->build_flags &= ~SEQ_PROXY_SKIP_EXISTING;
}
}
@@ -3571,7 +3571,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
SEQ_END
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -3581,14 +3581,14 @@ void SEQUENCER_OT_enable_proxies(wmOperatorType *ot)
ot->name = "Set Selected Strip Proxies";
ot->idname = "SEQUENCER_OT_enable_proxies";
ot->description = "Enable selected proxies on all selected Movie strips";
-
+
/* api callbacks */
ot->invoke = sequencer_enable_proxies_invoke;
ot->exec = sequencer_enable_proxies_exec;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER;
-
+
RNA_def_boolean(ot->srna, "proxy_25", false, "25%", "");
RNA_def_boolean(ot->srna, "proxy_50", false, "50%", "");
RNA_def_boolean(ot->srna, "proxy_75", false, "75%", "");
@@ -3753,7 +3753,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
/* TODO, shouldn't this already be relative from the filesel?
* (as the 'filepath' is) for now just make relative here,
* but look into changing after 2.60 - campbell */
- BLI_path_rel(directory, bmain->name);
+ BLI_path_rel(directory, BKE_main_blendfile_path(bmain));
}
BLI_strncpy(seq->strip->dir, directory, sizeof(seq->strip->dir));
@@ -3869,10 +3869,10 @@ static int sequencer_export_subtitles_invoke(bContext *C, wmOperator *op, const
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
char filepath[FILE_MAX];
- if (bmain->name[0] == '\0')
+ if (BKE_main_blendfile_path(bmain)[0] == '\0')
BLI_strncpy(filepath, "untitled", sizeof(filepath));
else
- BLI_strncpy(filepath, bmain->name, sizeof(filepath));
+ BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
BLI_replace_extension(filepath, sizeof(filepath), ".srt");
RNA_string_set(op->ptr, "filepath", filepath);
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index f0480f3ce71..41fc98fbe4e 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -174,7 +174,7 @@ enum {
SEQ_SELECT_LR_NONE = 0,
SEQ_SELECT_LR_MOUSE,
SEQ_SELECT_LR_LEFT,
- SEQ_SELECT_LR_RIGHT
+ SEQ_SELECT_LR_RIGHT
};
/* defines used internally */
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index a3cfcae77b8..234989ef244 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -68,7 +68,7 @@ void sequencer_operatortypes(void)
WM_operatortype_append(SEQUENCER_OT_meta_toggle);
WM_operatortype_append(SEQUENCER_OT_meta_make);
WM_operatortype_append(SEQUENCER_OT_meta_separate);
-
+
WM_operatortype_append(SEQUENCER_OT_gap_remove);
WM_operatortype_append(SEQUENCER_OT_gap_insert);
WM_operatortype_append(SEQUENCER_OT_snap);
@@ -135,7 +135,7 @@ void sequencer_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
/* Common items ------------------------------------------------------------------ */
keymap = WM_keymap_find(keyconf, "SequencerCommon", SPACE_SEQ, 0);
@@ -228,7 +228,7 @@ void sequencer_keymap(wmKeyConfig *keyconf)
RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_gap_remove", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "all", false);
RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_gap_remove", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "all", true);
WM_keymap_add_item(keymap, "SEQUENCER_OT_gap_insert", EQUALKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "SEQUENCER_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_swap_inputs", SKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c
index 3f908dc7096..c58c05b67c0 100644
--- a/source/blender/editors/space_sequencer/sequencer_preview.c
+++ b/source/blender/editors/space_sequencer/sequencer_preview.c
@@ -80,11 +80,11 @@ static void preview_startjob(void *data, short *stop, short *do_update, float *p
BLI_mutex_lock(pj->mutex);
previewjb = pj->previews.first;
BLI_mutex_unlock(pj->mutex);
-
+
while (previewjb) {
PreviewJobAudio *preview_next;
bSound *sound = previewjb->sound;
-
+
BKE_sound_read_waveform(sound, stop);
if (*stop || G.is_break) {
@@ -98,12 +98,12 @@ static void preview_startjob(void *data, short *stop, short *do_update, float *p
BLI_spin_lock(sound->spinlock);
sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
BLI_spin_unlock(sound->spinlock);
-
+
BLI_mutex_lock(pj->mutex);
previewjb = previewjb->next;
BLI_mutex_unlock(pj->mutex);
}
-
+
BLI_mutex_lock(pj->mutex);
BLI_freelistN(&pj->previews);
pj->total = 0;
@@ -111,12 +111,12 @@ static void preview_startjob(void *data, short *stop, short *do_update, float *p
BLI_mutex_unlock(pj->mutex);
break;
}
-
+
BLI_mutex_lock(pj->mutex);
preview_next = previewjb->next;
BLI_freelinkN(&pj->previews, previewjb);
previewjb = preview_next;
- pj->processed++;
+ pj->processed++;
*progress = (pj->total > 0) ? (float)pj->processed / (float)pj->total : 1.0f;
*do_update = true;
BLI_mutex_unlock(pj->mutex);
@@ -145,19 +145,19 @@ void sequencer_preview_add_sound(const bContext *C, Sequence *seq)
if (!pj) {
pj = MEM_callocN(sizeof(PreviewJob), "preview rebuild job");
-
+
pj->mutex = BLI_mutex_alloc();
pj->scene = CTX_data_scene(C);
-
+
WM_jobs_customdata_set(wm_job, pj, free_preview_job);
WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_SEQUENCER, NC_SCENE | ND_SEQUENCER);
WM_jobs_callbacks(wm_job, preview_startjob, NULL, NULL, preview_endjob);
}
-
+
/* attempt to lock mutex of job here */
-
+
audiojob->sound = seq->sound;
-
+
BLI_mutex_lock(pj->mutex);
BLI_addtail(&pj->previews, audiojob);
pj->total++;
@@ -168,5 +168,5 @@ void sequencer_preview_add_sound(const bContext *C, Sequence *seq)
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
- ED_area_tag_redraw(sa);
+ ED_area_tag_redraw(sa);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index 8c57089f7ab..00811d68251 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -160,7 +160,7 @@ static ImBuf *make_waveform_view_from_ibuf_byte(ImBuf *ibuf)
wform_put_grid(tgt, w, h);
wform_put_border(tgt, w, h);
-
+
for (x = 0; x < 256; x++) {
wtable[x] = (unsigned char) (pow(((float) x + 1) / 256, waveform_gamma) * 255);
}
@@ -229,7 +229,7 @@ static ImBuf *make_waveform_view_from_ibuf_float(ImBuf *ibuf)
}
wform_put_border(tgt, w, h);
-
+
return rval;
}
@@ -285,7 +285,7 @@ static ImBuf *make_sep_waveform_view_from_ibuf_byte(ImBuf *ibuf)
}
wform_put_border(tgt, w, h);
-
+
return rval;
}
@@ -334,7 +334,7 @@ static ImBuf *make_sep_waveform_view_from_ibuf_float(ImBuf *ibuf)
}
wform_put_border(tgt, w, h);
-
+
return rval;
}
@@ -542,7 +542,7 @@ static ImBuf *make_histogram_view_from_ibuf_byte(ImBuf *ibuf)
}
wform_put_border((unsigned char *) rval->rect, rval->x, rval->y);
-
+
return rval;
}
@@ -610,7 +610,7 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf)
if (bins[2][x] > nb)
nb = bins[2][x];
}
-
+
for (x = 0; x < HIS_STEPS; x++) {
if (nr) {
draw_histogram_bar(rval, x + 1, ((float) bins[0][x]) / nr, 0);
@@ -622,11 +622,11 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf)
draw_histogram_bar(rval, x + 1, ((float) bins[2][x]) / nb, 2);
}
}
-
+
draw_histogram_marker(rval, get_bin_float(0.0));
draw_histogram_marker(rval, get_bin_float(1.0));
wform_put_border((unsigned char *) rval->rect, rval->x, rval->y);
-
+
return rval;
}
@@ -653,7 +653,7 @@ static void vectorscope_put_cross(unsigned char r, unsigned char g, unsigned ch
rgb[1] = (float)g / 255.0f;
rgb[2] = (float)b / 255.0f;
rgb_to_yuv_normalized(rgb, yuv);
-
+
p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) +
(int) ((yuv[1] * (w - 3) + 1)));
@@ -698,12 +698,12 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf)
for (x = 0; x < ibuf->x; x++) {
const char *src1 = src + 4 * (ibuf->x * y + x);
char *p;
-
+
rgb[0] = (float)src1[0] / 255.0f;
rgb[1] = (float)src1[1] / 255.0f;
rgb[2] = (float)src1[2] / 255.0f;
rgb_to_yuv_normalized(rgb, yuv);
-
+
p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) +
(int) ((yuv[1] * (w - 3) + 1)));
scope_put_pixel(wtable, (unsigned char *)p);
@@ -744,7 +744,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
for (x = 0; x < ibuf->x; x++) {
const float *src1 = src + 4 * (ibuf->x * y + x);
const char *p;
-
+
memcpy(rgb, src1, 3 * sizeof(float));
CLAMP(rgb[0], 0.0f, 1.0f);
@@ -752,7 +752,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
CLAMP(rgb[2], 0.0f, 1.0f);
rgb_to_yuv_normalized(rgb, yuv);
-
+
p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) +
(int) ((yuv[1] * (w - 3) + 1)));
scope_put_pixel(wtable, (unsigned char *)p);
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 90a369760ac..d7206a6da4e 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -59,11 +59,11 @@ static void *find_nearest_marker(int UNUSED(d1), int UNUSED(d2))
{
return NULL;
}
-
+
static void select_surrounding_handles(Scene *scene, Sequence *test) /* XXX BRING BACK */
{
Sequence *neighbor;
-
+
neighbor = find_neighboring_sequence(scene, test, SEQ_SIDE_LEFT, -1);
if (neighbor) {
/* Only select neighbor handle if matching handle from test seq is also selected, or if neighbor
@@ -152,10 +152,10 @@ static void select_linked_time(ListBase *seqbase, Sequence *seq_link)
void select_surround_from_last(Scene *scene)
{
Sequence *seq = get_last_seq(scene);
-
+
if (seq == NULL)
return;
-
+
select_surrounding_handles(scene, seq);
}
#endif
@@ -163,7 +163,7 @@ void select_surround_from_last(Scene *scene)
void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool deselect_all)
{
Editing *ed = BKE_sequencer_editing_get(scene, false);
-
+
if (deselect_all)
ED_sequencer_deselect_all(scene);
@@ -264,11 +264,11 @@ void SEQUENCER_OT_select_all(struct wmOperatorType *ot)
ot->name = "(De)select All";
ot->idname = "SEQUENCER_OT_select_all";
ot->description = "Select or deselect all strips";
-
+
/* api callbacks */
ot->exec = sequencer_de_select_all_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -294,7 +294,7 @@ static int sequencer_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -304,11 +304,11 @@ void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot)
ot->name = "Select Inverse";
ot->idname = "SEQUENCER_OT_select_inverse";
ot->description = "Select unselected strips";
-
+
/* api callbacks */
ot->exec = sequencer_select_inverse_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -322,16 +322,16 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
const bool linked_handle = RNA_boolean_get(op->ptr, "linked_handle");
const bool linked_time = RNA_boolean_get(op->ptr, "linked_time");
int left_right = RNA_enum_get(op->ptr, "left_right");
-
+
Sequence *seq, *neighbor, *act_orig;
int hand, sel_side;
TimeMarker *marker;
if (ed == NULL)
return OPERATOR_CANCELLED;
-
+
marker = find_nearest_marker(SCE_MARKERS, 1); //XXX - dummy function for now
-
+
seq = find_nearest_seq(scene, v2d, &hand, event->mval);
// XXX - not nice, Ctrl+RMB needs to do left_right only when not over a strip
@@ -353,13 +353,13 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
/* deselect_markers(0, 0); */ /* XXX, in 2.4x, seq selection used to deselect all, need to re-thnik this for 2.5 */
marker->flag |= SELECT;
}
-
+
}
else if (left_right != SEQ_SELECT_LR_NONE) {
/* use different logic for this */
float x;
ED_sequencer_deselect_all(scene);
-
+
switch (left_right) {
case SEQ_SELECT_LR_MOUSE:
x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
@@ -372,7 +372,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
x = CFRA;
break;
}
-
+
SEQP_BEGIN (ed, seq)
{
if (((x < CFRA) && (seq->enddisp <= CFRA)) ||
@@ -408,10 +408,10 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
if (extend == 0 && linked_handle == 0)
ED_sequencer_deselect_all(scene);
-
+
if (seq) {
BKE_sequencer_active_set(scene, seq);
-
+
if ((seq->type == SEQ_TYPE_IMAGE) || (seq->type == SEQ_TYPE_MOVIE)) {
if (seq->strip) {
BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR);
@@ -422,7 +422,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR);
}
}
-
+
/* On Alt selection, select the strip and bordering handles */
if (linked_handle) {
if (!ELEM(hand, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT)) {
@@ -521,7 +521,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
}
}
}
-
+
/* marker transform */
#if 0 // XXX probably need to redo this differently for 2.5
if (marker) {
@@ -529,7 +529,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
// getmouseco_areawin(mval);
xo = mval[0];
yo = mval[1];
-
+
while (get_mbut()) {
// getmouseco_areawin(mval);
if (abs(mval[0] - xo) + abs(mval[1] - yo) > 4) {
@@ -539,7 +539,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
}
}
#endif
-
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
/* allowing tweaks */
@@ -555,19 +555,19 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
{SEQ_SELECT_LR_RIGHT, "RIGHT", 0, "Right", "Select right"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Activate/Select";
ot->idname = "SEQUENCER_OT_select";
ot->description = "Select a strip (last selected becomes the \"active strip\")";
-
+
/* api callbacks */
ot->invoke = sequencer_select_invoke;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
RNA_def_boolean(ot->srna, "linked_handle", 0, "Linked Handle", "Select handles next to the active strip");
@@ -584,10 +584,10 @@ static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool li
Sequence *seq, *neighbor;
bool changed = false;
int isel;
-
+
if (ed == NULL)
return changed;
-
+
if (sel) {
sel = SELECT;
isel = 0;
@@ -596,14 +596,14 @@ static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool li
sel = 0;
isel = SELECT;
}
-
+
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;
}
}
-
+
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if ((seq->flag & SELECT) == sel) {
if (linked || (seq->tmp == NULL)) {
@@ -639,7 +639,7 @@ static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool li
}
}
}
-
+
return changed;
}
@@ -649,12 +649,12 @@ static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool li
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))
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -664,14 +664,14 @@ void SEQUENCER_OT_select_more(wmOperatorType *ot)
ot->name = "Select More";
ot->idname = "SEQUENCER_OT_select_more";
ot->description = "Select more strips adjacent to the current selection";
-
+
/* api callbacks */
ot->exec = sequencer_select_more_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
}
@@ -680,12 +680,12 @@ void SEQUENCER_OT_select_more(wmOperatorType *ot)
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))
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -695,14 +695,14 @@ void SEQUENCER_OT_select_less(wmOperatorType *ot)
ot->name = "Select Less";
ot->idname = "SEQUENCER_OT_select_less";
ot->description = "Shrink the current selection of adjacent selected strips";
-
+
/* api callbacks */
ot->exec = sequencer_select_less_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
}
@@ -712,9 +712,9 @@ static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, cons
{
Scene *scene = CTX_data_scene(C);
View2D *v2d = UI_view2d_fromcontext(C);
-
+
bool extend = RNA_boolean_get(op->ptr, "extend");
-
+
Sequence *mouse_seq;
int selected, hand;
@@ -722,20 +722,20 @@ static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, cons
mouse_seq = find_nearest_seq(scene, v2d, &hand, event->mval);
if (!mouse_seq)
return OPERATOR_FINISHED; /* user error as with mesh?? */
-
+
if (extend == 0)
ED_sequencer_deselect_all(scene);
-
+
mouse_seq->flag |= SELECT;
recurs_sel_seq(mouse_seq);
-
+
selected = 1;
while (selected) {
selected = select_more_less_seq__internal(scene, 1, 1);
}
-
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
-
+
return OPERATOR_FINISHED;
}
@@ -745,14 +745,14 @@ void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot)
ot->name = "Select Pick Linked";
ot->idname = "SEQUENCER_OT_select_linked_pick";
ot->description = "Select a chain of linked strips nearest to the mouse pointer";
-
+
/* api callbacks */
ot->invoke = sequencer_select_linked_pick_invoke;
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
}
@@ -780,14 +780,14 @@ void SEQUENCER_OT_select_linked(wmOperatorType *ot)
ot->name = "Select Linked";
ot->idname = "SEQUENCER_OT_select_linked";
ot->description = "Select all strips adjacent to the current selection";
-
+
/* api callbacks */
ot->exec = sequencer_select_linked_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
}
@@ -830,14 +830,14 @@ void SEQUENCER_OT_select_handles(wmOperatorType *ot)
ot->name = "Select Handles";
ot->idname = "SEQUENCER_OT_select_handles";
ot->description = "Select manipulator handles on the sides of the selected strip";
-
+
/* api callbacks */
ot->exec = sequencer_select_handles_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_enum(ot->srna, "side", prop_side_types, SEQ_SIDE_BOTH, "Side", "The side of the handle that is selected");
}
@@ -867,7 +867,7 @@ void SEQUENCER_OT_select_active_side(wmOperatorType *ot)
ot->name = "Select Active Side";
ot->idname = "SEQUENCER_OT_select_active_side";
ot->description = "Select strips on the nominated side of the active strip";
-
+
/* api callbacks */
ot->exec = sequencer_select_active_side_exec;
ot->poll = sequencer_edit_poll;
@@ -886,7 +886,7 @@ static int sequencer_borderselect_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
View2D *v2d = UI_view2d_fromcontext(C);
-
+
Sequence *seq;
rctf rectf, rq;
const bool select = !RNA_boolean_get(op->ptr, "deselect");
@@ -900,7 +900,7 @@ static int sequencer_borderselect_exec(bContext *C, wmOperator *op)
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
seq_rectf(seq, &rq);
-
+
if (BLI_rctf_isect(&rq, &rectf, NULL)) {
if (select) seq->flag |= SELECT;
else seq->flag &= ~SEQ_ALLSEL;
@@ -915,7 +915,7 @@ static int sequencer_borderselect_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
return OPERATOR_FINISHED;
-}
+}
/* ****** Border Select ****** */
@@ -925,18 +925,18 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->idname = "SEQUENCER_OT_select_border";
ot->description = "Select strips using border selection";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = sequencer_borderselect_exec;
ot->modal = WM_gesture_border_modal;
ot->cancel = WM_gesture_border_cancel;
-
+
ot->poll = ED_operator_sequencer_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
}
@@ -1267,15 +1267,15 @@ void SEQUENCER_OT_select_grouped(wmOperatorType *ot)
ot->name = "Select Grouped";
ot->description = "Select all strips grouped by various properties";
ot->idname = "SEQUENCER_OT_select_grouped";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = sequencer_select_grouped_exec;
ot->poll = sequencer_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", sequencer_prop_select_grouped_types, 0, "Type", "");
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index d3d847b1aa0..88dcc3a8821 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -98,7 +98,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
ImBuf *ibuf = sequencer_ibuf_get(bmain, depsgraph, scene, sseq, CFRA, 0, NULL);
ImageSampleInfo *info = op->customdata;
float fx, fy;
-
+
if (ibuf == NULL) {
IMB_freeImBuf(ibuf);
info->draw = 0;
@@ -122,7 +122,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
info->colp = NULL;
info->colfp = NULL;
-
+
if (ibuf->rect) {
cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index e1f48cfd048..75734963a0e 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -82,28 +82,28 @@ ARegion *sequencer_has_buttons_region(ScrArea *sa)
ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
if (ar) return ar;
-
+
/* add subdiv level; after header */
ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "buttons for sequencer");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_UI;
arnew->alignment = RGN_ALIGN_RIGHT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
-
+
return arnew;
}
static ARegion *sequencer_find_region(ScrArea *sa, short type)
{
ARegion *ar = NULL;
-
+
for (ar = sa->regionbase.first; ar; ar = ar->next)
if (ar->regiontype == type)
return ar;
@@ -117,7 +117,7 @@ static SpaceLink *sequencer_new(const ScrArea *UNUSED(sa), const Scene *scene)
{
ARegion *ar;
SpaceSeq *sseq;
-
+
sseq = MEM_callocN(sizeof(SpaceSeq), "initsequencer");
sseq->spacetype = SPACE_SEQ;
sseq->chanshown = 0;
@@ -127,19 +127,19 @@ static SpaceLink *sequencer_new(const ScrArea *UNUSED(sa), const Scene *scene)
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for sequencer");
-
+
BLI_addtail(&sseq->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
/* buttons/list view */
ar = MEM_callocN(sizeof(ARegion), "buttons for sequencer");
-
+
BLI_addtail(&sseq->regionbase, ar);
ar->regiontype = RGN_TYPE_UI;
ar->alignment = RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
-
+
/* preview region */
/* NOTE: if you change values here, also change them in sequencer_init_preview_region */
ar = MEM_callocN(sizeof(ARegion), "preview region for sequencer");
@@ -166,26 +166,26 @@ static SpaceLink *sequencer_new(const ScrArea *UNUSED(sa), const Scene *scene)
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for sequencer");
-
+
BLI_addtail(&sseq->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
-
+
+
/* seq space goes from (0,8) to (0, efra) */
-
+
ar->v2d.tot.xmin = 0.0f;
ar->v2d.tot.ymin = 0.0f;
ar->v2d.tot.xmax = scene->r.efra;
ar->v2d.tot.ymax = 8.0f;
-
+
ar->v2d.cur = ar->v2d.tot;
-
+
ar->v2d.min[0] = 10.0f;
ar->v2d.min[1] = 0.5f;
-
+
ar->v2d.max[0] = MAXFRAMEF;
ar->v2d.max[1] = MAXSEQ;
-
+
ar->v2d.minzoom = 0.01f;
ar->v2d.maxzoom = 100.0f;
@@ -200,7 +200,7 @@ static SpaceLink *sequencer_new(const ScrArea *UNUSED(sa), const Scene *scene)
/* not spacelink itself */
static void sequencer_free(SpaceLink *sl)
-{
+{
SpaceSeq *sseq = (SpaceSeq *) sl;
SequencerScopes *scopes = &sseq->scopes;
@@ -226,7 +226,7 @@ static void sequencer_free(SpaceLink *sl)
/* spacetype; init callback */
static void sequencer_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
{
-
+
}
static void sequencer_refresh(const bContext *C, ScrArea *sa)
@@ -330,7 +330,7 @@ static void sequencer_refresh(const bContext *C, ScrArea *sa)
static SpaceLink *sequencer_duplicate(SpaceLink *sl)
{
SpaceSeq *sseqn = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
// XXX sseq->gpd = gpencil_data_duplicate(sseq->gpd, false);
@@ -418,7 +418,7 @@ static void sequencer_drop_copy(wmDrag *drag, wmDropBox *drop)
char dir[FILE_MAX], file[FILE_MAX];
BLI_split_dirfile(drag->path, dir, file, sizeof(dir), sizeof(file));
-
+
RNA_string_set(drop->ptr, "directory", dir);
RNA_collection_clear(drop->ptr, "files");
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 3482e75bd71..5885312e255 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -66,17 +66,17 @@ static SpaceLink *text_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
{
ARegion *ar;
SpaceText *stext;
-
+
stext = MEM_callocN(sizeof(SpaceText), "inittext");
stext->spacetype = SPACE_TEXT;
stext->lheight = 12;
stext->tabnumber = 4;
stext->margin_column = 80;
-
+
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for text");
-
+
BLI_addtail(&stext->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
@@ -91,18 +91,18 @@ static SpaceLink *text_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for text");
-
+
BLI_addtail(&stext->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
return (SpaceLink *)stext;
}
/* not spacelink itself */
static void text_free(SpaceLink *sl)
-{
+{
SpaceText *stext = (SpaceText *) sl;
-
+
stext->text = NULL;
text_free_caches(stext);
}
@@ -205,7 +205,7 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_select_line);
WM_operatortype_append(TEXT_OT_select_all);
WM_operatortype_append(TEXT_OT_select_word);
-
+
WM_operatortype_append(TEXT_OT_move_lines);
WM_operatortype_append(TEXT_OT_jump);
@@ -231,7 +231,7 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_replace_set_selected);
WM_operatortype_append(TEXT_OT_start_find);
-
+
WM_operatortype_append(TEXT_OT_to_3d_object);
WM_operatortype_append(TEXT_OT_resolve_conflict);
@@ -243,7 +243,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
keymap = WM_keymap_find(keyconf, "Text Generic", SPACE_TEXT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_start_find", FKEY, KM_PRESS, KM_CTRL, 0);
#ifdef __APPLE__
@@ -255,7 +255,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_properties", TKEY, KM_PRESS, KM_CTRL, 0);
keymap = WM_keymap_find(keyconf, "Text", SPACE_TEXT, 0);
-
+
#ifdef __APPLE__
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_END);
@@ -263,30 +263,30 @@ static void text_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", NEXT_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", UPARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", FILE_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", DOWNARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", FILE_BOTTOM);
-
+
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", LINE_END);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", PREV_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", NEXT_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", UPARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", FILE_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", DOWNARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", FILE_BOTTOM);
-
+
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", DEL_PREV_WORD);
-
+
WM_keymap_add_item(keymap, "TEXT_OT_save", SKEY, KM_PRESS, KM_ALT | KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_OSKEY, 0);
- WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
+ WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_find_set_selected", EKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
#endif
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", false);
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", true);
@@ -294,7 +294,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", false);
-
+
kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
RNA_boolean_set(kmi->ptr, "reverse", true);
@@ -306,7 +306,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_run_script", PKEY, KM_PRESS, KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
@@ -314,7 +314,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "TEXT_OT_cut", DELKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_copy", INSERTKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_paste", INSERTKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "TEXT_OT_duplicate_line", DKEY, KM_PRESS, KM_CTRL, 0);
if (U.uiflag & USER_MMB_PASTE) { // XXX not dynamic
@@ -328,14 +328,14 @@ static void text_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_lines", UPARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "direction", TXT_MOVE_LINE_UP);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_lines", DOWNARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "direction", TXT_MOVE_LINE_DOWN);
-
+
WM_keymap_add_item(keymap, "TEXT_OT_indent", TABKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "TEXT_OT_unindent", TABKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_uncomment", DKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
-
+
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", LINE_END);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
@@ -367,7 +367,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", DEL_PREV_CHAR); /* same as above [#26623] */
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", DELKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD);
-
+
WM_keymap_add_item(keymap, "TEXT_OT_overwrite_toggle", INSERTKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", LEFTMOUSE, KM_PRESS, 0, 0);
@@ -388,7 +388,7 @@ static void text_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "TEXT_MT_toolbox", RIGHTMOUSE, KM_PRESS, KM_ANY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_autocomplete", SPACEKEY, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_item(keymap, "TEXT_OT_line_number", KM_TEXTINPUT, KM_ANY, KM_ANY, 0);
WM_keymap_add_item(keymap, "TEXT_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
}
@@ -418,18 +418,18 @@ static void text_main_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
ListBase *lb;
-
+
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
-
+
/* own keymap */
keymap = WM_keymap_find(wm->defaultconf, "Text Generic", SPACE_TEXT, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
keymap = WM_keymap_find(wm->defaultconf, "Text", SPACE_TEXT, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
-
+
/* add drop boxes */
lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
-
+
WM_event_add_dropbox_handler(&ar->handlers, lb);
}
@@ -438,19 +438,19 @@ static void text_main_region_draw(const bContext *C, ARegion *ar)
/* draw entirely, view changes should be handled here */
SpaceText *st = CTX_wm_space_text(C);
//View2D *v2d = &ar->v2d;
-
+
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
-
+
// UI_view2d_view_ortho(v2d);
-
+
/* data... */
draw_text_main(st, ar);
-
+
/* reset view matrix */
// UI_view2d_view_restore(C);
-
+
/* scrollers? */
}
@@ -510,7 +510,7 @@ static void text_drop_paste(wmDrag *drag, wmDropBox *drop)
static void text_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
-
+
WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy);
WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste);
}
@@ -550,9 +550,9 @@ static void text_properties_region_init(wmWindowManager *wm, ARegion *ar)
static void text_properties_region_draw(const bContext *C, ARegion *ar)
{
SpaceText *st = CTX_wm_space_text(C);
-
+
ED_region_panels(C, ar, NULL, -1, true);
-
+
/* this flag trick is make sure buttons have been added already */
if (st->flags & ST_FIND_ACTIVATE) {
if (UI_textbutton_activate_rna(C, ar, st, "find_text")) {
@@ -585,10 +585,10 @@ void ED_spacetype_text(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype text");
ARegionType *art;
-
+
st->spaceid = SPACE_TEXT;
strncpy(st->name, "Text", BKE_ST_MAXNAME);
-
+
st->new = text_new;
st->free = text_free;
st->init = text_init;
@@ -609,13 +609,13 @@ void ED_spacetype_text(void)
art->event_cursor = true;
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: properties */
art = MEM_callocN(sizeof(ARegionType), "spacetype text region");
art->regionid = RGN_TYPE_UI;
art->prefsizex = UI_COMPACT_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_UI;
-
+
art->init = text_properties_region_init;
art->draw = text_properties_region_draw;
BLI_addhead(&st->regiontypes, art);
@@ -625,7 +625,7 @@ void ED_spacetype_text(void)
art->regionid = RGN_TYPE_HEADER;
art->prefsizey = HEADERY;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
-
+
art->init = text_header_region_init;
art->draw = text_header_region_draw;
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 29ddee6e662..c1b49fbd32a 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -113,7 +113,7 @@ static int text_font_draw_character_utf8(const TextDrawContext *tdc, int x, int
#if 0
/* Formats every line of the current text */
-static void txt_format_text(SpaceText *st)
+static void txt_format_text(SpaceText *st)
{
TextLine *linep;
@@ -191,7 +191,7 @@ int wrap_width(const SpaceText *st, ARegion *ar)
{
int winx = ar->winx - TXT_SCROLL_WIDTH;
int x, max;
-
+
x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
max = st->cwidth ? (winx - x) / st->cwidth : 0;
return max > 8 ? max : 8;
@@ -358,7 +358,7 @@ void wrap_offset_in_line(const SpaceText *st, ARegion *ar, TextLine *linein, int
int text_get_char_pos(const SpaceText *st, const char *line, int cur)
{
int a = 0, i;
-
+
for (i = 0; i < cur && line[i]; i += BLI_str_utf8_size_safe(line + i)) {
if (line[i] == '\t')
a += st->tabnumber - a % st->tabnumber;
@@ -407,11 +407,11 @@ static int text_draw_wrapped(
if (max < 8) max = 8;
basex = x;
lines = 1;
-
+
fpos = fstart = 0; mstart = 0;
mend = txt_utf8_forward_columns(str, max, &padding) - str;
end = wrap = max - padding;
-
+
for (i = 0, mi = 0; str[mi]; i += columns, mi += BLI_str_utf8_size_safe(str + mi)) {
columns = BLI_str_utf8_char_width_safe(str + mi);
if (i + columns > end) {
@@ -659,7 +659,7 @@ void text_drawcache_tag_update(SpaceText *st, int full)
/* this happens if text editor ops are caled from python */
if (st == NULL)
return;
-
+
if (st->drawcache) {
DrawCache *drawcache = (DrawCache *)st->drawcache;
Text *txt = st->text;
@@ -808,17 +808,17 @@ static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll, rcti *back)
back->xmax = ar->winx;
back->ymin = 0;
back->ymax = ar->winy;
-
+
scroll->xmin = ar->winx - V2D_SCROLL_WIDTH;
scroll->xmax = ar->winx - 5;
scroll->ymin = 4;
scroll->ymax = 4 + pix_available;
-
+
/* when re-sizing a view-port with the bar at the bottom to a greater height more blank lines will be added */
if (ltexth + blank_lines < st->top + st->viewlines) {
blank_lines = st->top + st->viewlines - ltexth;
}
-
+
ltexth += blank_lines;
barheight = (ltexth > 0) ? (st->viewlines * pix_available) / ltexth : 0;
@@ -895,7 +895,7 @@ static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll, rcti *back)
if (hlend - hlstart < 2) {
hlend = hlstart + 2;
}
-
+
st->txtscroll = *scroll;
st->txtscroll.ymax = ar->winy - pix_top_margin - hlstart;
st->txtscroll.ymin = ar->winy - pix_top_margin - hlend;
@@ -937,10 +937,10 @@ static void draw_documentation(const SpaceText *st, ARegion *ar)
char *docs, buf[DOC_WIDTH + 1], *p;
int i, br, lines;
int boxw, boxh, l, x, y /* , top */ /* UNUSED */;
-
+
if (!st || !st->text) return;
if (!texttool_text_is_active(st->text)) return;
-
+
docs = texttool_docs_get();
if (!docs) return;
@@ -950,7 +950,7 @@ static void draw_documentation(const SpaceText *st, ARegion *ar)
/* Count the visible lines to the cursor */
for (tmp = st->text->curl, l = -st->top; tmp; tmp = tmp->prev, l++) ;
if (l < 0) return;
-
+
if (st->showlinenrs) {
x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET + TEXTXLOC - 4;
}
@@ -1031,7 +1031,7 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
int w, boxw = 0, boxh, i, x, y, *top;
const int lheight = st->lheight_dpi + TXT_LINE_SPACING;
const int margin_x = 2;
-
+
if (!st->text) return;
if (!texttool_text_is_active(st->text)) return;
@@ -1058,7 +1058,7 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
boxw = SUGG_LIST_WIDTH * st->cwidth + 20;
boxh = SUGG_LIST_SIZE * lheight + 8;
-
+
if (x + boxw > ar->winx)
x = MAX2(0, ar->winx - boxw);
@@ -1086,7 +1086,7 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc
BLI_strncpy(str, item->name, len + 1);
w = st->cwidth * text_get_char_pos(st, str, len);
-
+
if (item == sel) {
unsigned int posi = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1247,7 +1247,7 @@ static void draw_brackets(const SpaceText *st, const TextDrawContext *tdc, ARegi
Text *text = st->text;
int b, fc, find, stack, viewc, viewl, offl, offc, x, y;
int startc, endc, c;
-
+
char ch;
// showsyntax must be on or else the format string will be null
@@ -1266,7 +1266,7 @@ static void draw_brackets(const SpaceText *st, const TextDrawContext *tdc, ARegi
endc = -1;
find = -b;
stack = 0;
-
+
/* Don't highlight backets if syntax HL is off or bracket in string or comment. */
if (!linep->format || linep->format[fc] == FMT_TYPE_STRING || linep->format[fc] == FMT_TYPE_COMMENT)
return;
@@ -1391,7 +1391,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
const int clip_min_y = -(int)(st->lheight_dpi - 1);
st->viewlines = (st->lheight_dpi) ? (int)(ar->winy - clip_min_y) / (st->lheight_dpi + TXT_LINE_SPACING) : 0;
-
+
text_draw_context_init(st, &tdc);
text_update_drawcache(st, ar);
@@ -1399,7 +1399,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
/* make sure all the positional pointers exist */
if (!text->curl || !text->sell || !text->lines.first || !text->lines.last)
txt_clean_text(text);
-
+
/* update rects for scroll */
calc_text_rcts(st, ar, &scroll, &back); /* scroll will hold the entire bar size */
@@ -1454,7 +1454,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
}
y = ar->winy - st->lheight_dpi;
winx = ar->winx - TXT_SCROLL_WIDTH;
-
+
/* draw cursor, margin, selection and highlight */
draw_text_decoration(st, ar);
@@ -1493,13 +1493,13 @@ void draw_text_main(SpaceText *st, ARegion *ar)
text_draw(st, &tdc, tmp->line, st->left, ar->winx / st->cwidth, x, y, tmp->format);
y -= st->lheight_dpi + TXT_LINE_SPACING;
}
-
+
wrap_skip = 0;
}
-
+
if (st->flags & ST_SHOW_MARGIN) {
margin_column_x = x + st->cwidth * (st->margin_column - st->left);
-
+
if (margin_column_x >= x) {
const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
@@ -1527,7 +1527,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
draw_textscroll(st, &scroll, &back);
/* draw_documentation(st, ar); - No longer supported */
draw_suggestion_list(st, &tdc, ar);
-
+
text_font_end(&tdc);
}
@@ -1578,7 +1578,7 @@ void text_scroll_to_cursor(SpaceText *st, ARegion *ar, const bool center)
st->top = i;
}
}
-
+
if (st->wordwrap) {
st->left = 0;
}
diff --git a/source/blender/editors/space_text/text_format.c b/source/blender/editors/space_text/text_format.c
index 0133122c5a3..b64eefe969b 100644
--- a/source/blender/editors/space_text/text_format.c
+++ b/source/blender/editors/space_text/text_format.c
@@ -216,7 +216,7 @@ TextFormatType *ED_text_format_get(Text *text)
}
}
- /* If we make it here we never found an extension that worked - return
+ /* If we make it here we never found an extension that worked - return
* the "default" text format */
return tft_lb.first;
}
diff --git a/source/blender/editors/space_text/text_format_lua.c b/source/blender/editors/space_text/text_format_lua.c
index f7e1d433e51..8b6ec2d804b 100644
--- a/source/blender/editors/space_text/text_format_lua.c
+++ b/source/blender/editors/space_text/text_format_lua.c
@@ -34,7 +34,7 @@
/* *** Lua Keywords (for format_line) *** */
-/* Checks the specified source string for a Lua keyword (minus boolean & 'nil').
+/* Checks the specified source string for a Lua keyword (minus boolean & 'nil').
* This name must start at the beginning of the source string and must be
* followed by a non-identifier (see text_check_identifier(char)) or null char.
*
@@ -75,7 +75,7 @@ static int txtfmt_lua_find_keyword(const char *string)
return i;
}
-/* Checks the specified source string for a Lua special name/function. This
+/* Checks the specified source string for a Lua special name/function. This
* name must start at the beginning of the source string and must be followed
* by a non-identifier (see text_check_identifier(char)) or null character.
*
diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c
index 97dc1be3b9a..2daaaa348e6 100644
--- a/source/blender/editors/space_text/text_format_osl.c
+++ b/source/blender/editors/space_text/text_format_osl.c
@@ -132,7 +132,7 @@ static int txtfmt_osl_find_reserved(const char *string)
static int txtfmt_osl_find_specialvar(const char *string)
{
int i, len;
-
+
/* OSL shader types */
if (STR_LITERAL_STARTSWITH(string, "shader", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "surface", len)) i = len;
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index 1a6d3181349..50a8739c5b4 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -54,21 +54,21 @@ static ARegion *text_has_properties_region(ScrArea *sa)
ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
if (ar) return ar;
-
+
/* add subdiv level; after header */
ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "properties region");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_UI;
arnew->alignment = RGN_ALIGN_LEFT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
-
+
return arnew;
}
@@ -81,7 +81,7 @@ static int text_properties_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = text_has_properties_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -94,7 +94,7 @@ void TEXT_OT_properties(wmOperatorType *ot)
ot->name = "Properties";
ot->description = "Toggle the properties region visibility";
ot->idname = "TEXT_OT_properties";
-
+
/* api callbacks */
ot->exec = text_properties_exec;
ot->poll = text_properties_poll;
@@ -105,15 +105,15 @@ static int text_text_search_exec(bContext *C, wmOperator *UNUSED(op))
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = text_has_properties_region(sa);
SpaceText *st = CTX_wm_space_text(C);
-
+
if (ar) {
if (ar->flag & RGN_FLAG_HIDDEN)
ED_region_toggle_hidden(C, ar);
-
+
/* cannot send a button activate yet for case when region wasn't visible yet */
/* flag gets checked and cleared in main draw callback */
st->flags |= ST_FIND_ACTIVATE;
-
+
ED_region_tag_redraw(ar);
}
return OPERATOR_FINISHED;
@@ -126,7 +126,7 @@ void TEXT_OT_start_find(wmOperatorType *ot)
ot->name = "Find";
ot->description = "Start searching text";
ot->idname = "TEXT_OT_start_find";
-
+
/* api callbacks */
ot->exec = text_text_search_exec;
ot->poll = text_properties_poll;
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 01b404e321a..b3815d73c5c 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -124,7 +124,7 @@ static int text_region_edit_poll(bContext *C)
if (!st || !text)
return 0;
-
+
if (!ar || ar->regiontype != RGN_TYPE_WINDOW)
return 0;
@@ -198,11 +198,11 @@ void TEXT_OT_new(wmOperatorType *ot)
ot->name = "Create Text Block";
ot->idname = "TEXT_OT_new";
ot->description = "Create a new text data-block";
-
+
/* api callbacks */
ot->exec = text_new_exec;
ot->poll = text_new_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
}
@@ -234,7 +234,7 @@ static int text_open_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", str);
- text = BKE_text_load_ex(bmain, str, bmain->name, internal);
+ text = BKE_text_load_ex(bmain, str, BKE_main_blendfile_path(bmain), internal);
if (!text) {
if (op->customdata) MEM_freeN(op->customdata);
@@ -247,15 +247,15 @@ static int text_open_exec(bContext *C, wmOperator *op)
/* hook into UI */
pprop = op->customdata;
+ id_us_ensure_real(&text->id);
+
if (pprop->prop) {
- id_us_ensure_real(&text->id);
RNA_id_pointer_create(&text->id, &idptr);
RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
else if (st) {
st->text = text;
- id_us_ensure_real(&text->id);
st->left = 0;
st->top = 0;
st->scroll_accum[0] = 0.0f;
@@ -274,14 +274,14 @@ static int text_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e
{
Main *bmain = CTX_data_main(C);
Text *text = CTX_data_edit_text(C);
- const char *path = (text && text->name) ? text->name : bmain->name;
+ const char *path = (text && text->name) ? text->name : BKE_main_blendfile_path(bmain);
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return text_open_exec(C, op);
-
+
text_open_init(C, op);
RNA_string_set(op->ptr, "filepath", path);
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -301,7 +301,7 @@ void TEXT_OT_open(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_filesel(
ot, FILE_TYPE_FOLDER | FILE_TYPE_TEXT | FILE_TYPE_PYSCRIPT, FILE_SPECIAL, FILE_OPENFILE,
@@ -352,7 +352,7 @@ void TEXT_OT_reload(wmOperatorType *ot)
ot->name = "Reload";
ot->idname = "TEXT_OT_reload";
ot->description = "Reload active text data-block from its file";
-
+
/* api callbacks */
ot->exec = text_reload_exec;
ot->invoke = WM_operator_confirm;
@@ -401,12 +401,12 @@ void TEXT_OT_unlink(wmOperatorType *ot)
ot->name = "Unlink";
ot->idname = "TEXT_OT_unlink";
ot->description = "Unlink active text data-block";
-
+
/* api callbacks */
ot->exec = text_unlink_exec;
ot->invoke = WM_operator_confirm;
ot->poll = text_unlink_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
}
@@ -440,7 +440,7 @@ void TEXT_OT_make_internal(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_make_internal_exec;
ot->poll = text_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
}
@@ -453,7 +453,7 @@ static int text_save_poll(bContext *C)
if (!text_edit_poll(C))
return 0;
-
+
return (text->name != NULL && !(text->flags & TXT_ISMEM));
}
@@ -463,10 +463,10 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
TextLine *tmp;
BLI_stat_t st;
char filepath[FILE_MAX];
-
+
BLI_strncpy(filepath, text->name, FILE_MAX);
- BLI_path_abs(filepath, bmain->name);
-
+ BLI_path_abs(filepath, BKE_main_blendfile_path(bmain));
+
fp = BLI_fopen(filepath, "w");
if (fp == NULL) {
BKE_reportf(reports, RPT_ERROR, "Unable to save '%s': %s",
@@ -480,7 +480,7 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
fputc('\n', fp);
}
}
-
+
fclose(fp);
if (BLI_stat(filepath, &st) == 0) {
@@ -494,7 +494,7 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
BKE_reportf(reports, RPT_WARNING, "Unable to stat '%s': %s",
filepath, errno ? strerror(errno) : TIP_("unknown error stating file"));
}
-
+
text->flags &= ~TXT_ISDIRTY;
}
@@ -562,10 +562,10 @@ static int text_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
else if (text->flags & TXT_ISMEM)
str = text->id.name + 2;
else
- str = bmain->name;
-
+ str = BKE_main_blendfile_path(bmain);
+
RNA_string_set(op->ptr, "filepath", str);
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -576,7 +576,7 @@ void TEXT_OT_save_as(wmOperatorType *ot)
ot->name = "Save As";
ot->idname = "TEXT_OT_save_as";
ot->description = "Save active text file with options";
-
+
/* api callbacks */
ot->exec = text_save_as_exec;
ot->invoke = text_save_as_invoke;
@@ -653,7 +653,7 @@ void TEXT_OT_run_script(wmOperatorType *ot)
ot->name = "Run Script";
ot->idname = "TEXT_OT_run_script";
ot->description = "Run active script";
-
+
/* api callbacks */
ot->poll = text_run_script_poll;
ot->exec = text_run_script_exec;
@@ -672,7 +672,7 @@ static int text_refresh_pyconstraints_exec(bContext *UNUSED(C), wmOperator *UNUS
Object *ob;
bConstraint *con;
short update;
-
+
/* check all pyconstraints */
for (ob = CTX_data_main(C)->object.first; ob; ob = ob->id.next) {
update = 0;
@@ -684,7 +684,7 @@ static int text_refresh_pyconstraints_exec(bContext *UNUSED(C), wmOperator *UNUS
bPythonConstraint *data = con->data;
if (data->text == text) BPY_pyconstraint_update(ob, con);
update = 1;
-
+
}
}
}
@@ -696,7 +696,7 @@ static int text_refresh_pyconstraints_exec(bContext *UNUSED(C), wmOperator *UNUS
update = 1;
}
}
-
+
if (update) {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
@@ -713,7 +713,7 @@ void TEXT_OT_refresh_pyconstraints(wmOperatorType *ot)
ot->name = "Refresh PyConstraints";
ot->idname = "TEXT_OT_refresh_pyconstraints";
ot->description = "Refresh all pyconstraints";
-
+
/* api callbacks */
ot->exec = text_refresh_pyconstraints_exec;
ot->poll = text_edit_poll;
@@ -757,7 +757,7 @@ void TEXT_OT_paste(wmOperatorType *ot)
ot->name = "Paste";
ot->idname = "TEXT_OT_paste";
ot->description = "Paste text from clipboard";
-
+
/* api callbacks */
ot->exec = text_paste_exec;
ot->poll = text_edit_poll;
@@ -871,7 +871,7 @@ void TEXT_OT_cut(wmOperatorType *ot)
ot->name = "Cut";
ot->idname = "TEXT_OT_cut";
ot->description = "Cut selected text to clipboard";
-
+
/* api callbacks */
ot->exec = text_cut_exec;
ot->poll = text_edit_poll;
@@ -912,7 +912,7 @@ void TEXT_OT_indent(wmOperatorType *ot)
ot->name = "Indent";
ot->idname = "TEXT_OT_indent";
ot->description = "Indent selected text";
-
+
/* api callbacks */
ot->exec = text_indent_exec;
ot->poll = text_edit_poll;
@@ -948,7 +948,7 @@ void TEXT_OT_unindent(wmOperatorType *ot)
ot->name = "Unindent";
ot->idname = "TEXT_OT_unindent";
ot->description = "Unindent selected text";
-
+
/* api callbacks */
ot->exec = text_unindent_exec;
ot->poll = text_edit_poll;
@@ -1077,7 +1077,7 @@ void TEXT_OT_uncomment(wmOperatorType *ot)
ot->name = "Uncomment";
ot->idname = "TEXT_OT_uncomment";
ot->description = "Convert selected comment to text";
-
+
/* api callbacks */
ot->exec = text_uncomment_exec;
ot->poll = text_edit_poll;
@@ -1117,7 +1117,7 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
MEM_freeN(tmp->line);
if (tmp->format)
MEM_freeN(tmp->format);
-
+
/* Put new_line in the tmp->line spot still need to try and set the curc correctly. */
tmp->line = new_line;
tmp->len = strlen(new_line);
@@ -1126,7 +1126,7 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op)
max_len = tmp->len;
}
}
-
+
if (type == TO_TABS) {
char *tmp_line = MEM_mallocN(sizeof(*tmp_line) * (max_len + 1), __func__);
@@ -1212,7 +1212,7 @@ void TEXT_OT_convert_whitespace(wmOperatorType *ot)
ot->name = "Convert Whitespace";
ot->idname = "TEXT_OT_convert_whitespace";
ot->description = "Convert whitespaces by type";
-
+
/* api callbacks */
ot->exec = text_convert_whitespace_exec;
ot->poll = text_edit_poll;
@@ -1244,7 +1244,7 @@ void TEXT_OT_select_all(wmOperatorType *ot)
ot->name = "Select All";
ot->idname = "TEXT_OT_select_all";
ot->description = "Select all text";
-
+
/* api callbacks */
ot->exec = text_select_all_exec;
ot->poll = text_edit_poll;
@@ -1270,7 +1270,7 @@ void TEXT_OT_select_line(wmOperatorType *ot)
ot->name = "Select Line";
ot->idname = "TEXT_OT_select_line";
ot->description = "Select text by line";
-
+
/* api callbacks */
ot->exec = text_select_line_exec;
ot->poll = text_edit_poll;
@@ -1315,14 +1315,14 @@ static int move_lines_exec(bContext *C, wmOperator *op)
TextUndoBuf *utxt = ED_text_undo_push_init(C);
txt_move_lines(text, utxt, direction);
-
+
text_update_cursor_moved(C);
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
/* run the script while editing, evil but useful */
if (CTX_wm_space_text(C)->live_edit)
text_run_script(C, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -1338,7 +1338,7 @@ void TEXT_OT_move_lines(wmOperatorType *ot)
ot->name = "Move Lines";
ot->idname = "TEXT_OT_move_lines";
ot->description = "Move the currently selected line(s) up/down";
-
+
/* api callbacks */
ot->exec = move_lines_exec;
ot->poll = text_edit_poll;
@@ -1757,7 +1757,7 @@ static void cursor_skip(SpaceText *st, ARegion *ar, Text *text, int lines, const
{
TextLine **linep;
int *charp;
-
+
if (sel) { linep = &text->sell; charp = &text->selc; }
else { linep = &text->curl; charp = &text->curc; }
@@ -1802,7 +1802,7 @@ static int text_move_cursor(bContext *C, int type, bool select)
if (st && st->wordwrap && ar) txt_wrap_move_bol(st, ar, select);
else txt_move_bol(text, select);
break;
-
+
case LINE_END:
if (!select) {
txt_sel_clear(text);
@@ -1814,7 +1814,7 @@ static int text_move_cursor(bContext *C, int type, bool select)
case FILE_TOP:
txt_move_bof(text, select);
break;
-
+
case FILE_BOTTOM:
txt_move_eof(text, select);
break;
@@ -1857,7 +1857,7 @@ static int text_move_cursor(bContext *C, int type, bool select)
if (st && st->wordwrap && ar) txt_wrap_move_up(st, ar, select);
else txt_move_up(text, select);
break;
-
+
case NEXT_LINE:
if (st && st->wordwrap && ar) txt_wrap_move_down(st, ar, select);
else txt_move_down(text, select);
@@ -1893,7 +1893,7 @@ void TEXT_OT_move(wmOperatorType *ot)
ot->name = "Move Cursor";
ot->idname = "TEXT_OT_move";
ot->description = "Move cursor to position type";
-
+
/* api callbacks */
ot->exec = text_move_exec;
ot->poll = text_edit_poll;
@@ -1917,7 +1917,7 @@ void TEXT_OT_move_select(wmOperatorType *ot)
ot->name = "Move Select";
ot->idname = "TEXT_OT_move_select";
ot->description = "Move the cursor while selecting";
-
+
/* api callbacks */
ot->exec = text_move_select_exec;
ot->poll = text_space_edit_poll;
@@ -1961,7 +1961,7 @@ void TEXT_OT_jump(wmOperatorType *ot)
ot->name = "Jump";
ot->idname = "TEXT_OT_jump";
ot->description = "Jump cursor to line";
-
+
/* api callbacks */
ot->invoke = text_jump_invoke;
ot->exec = text_jump_exec;
@@ -2052,7 +2052,7 @@ static int text_delete_exec(bContext *C, wmOperator *op)
/* run the script while editing, evil but useful */
if (st->live_edit)
text_run_script(C, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2062,7 +2062,7 @@ void TEXT_OT_delete(wmOperatorType *ot)
ot->name = "Delete";
ot->idname = "TEXT_OT_delete";
ot->description = "Delete text by cursor position";
-
+
/* api callbacks */
ot->exec = text_delete_exec;
ot->poll = text_edit_poll;
@@ -2093,7 +2093,7 @@ void TEXT_OT_overwrite_toggle(wmOperatorType *ot)
ot->name = "Toggle Overwrite";
ot->idname = "TEXT_OT_overwrite_toggle";
ot->description = "Toggle overwrite while typing";
-
+
/* api callbacks */
ot->exec = text_toggle_overwrite_exec;
ot->poll = text_space_edit_poll;
@@ -2264,20 +2264,20 @@ static int text_scroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
TextScroll *tsc;
-
+
if (RNA_struct_property_is_set(op->ptr, "lines"))
return text_scroll_exec(C, op);
-
+
tsc = MEM_callocN(sizeof(TextScroll), "TextScroll");
tsc->first = 1;
tsc->zone = SCROLLHANDLE_BAR;
op->customdata = tsc;
-
+
st->flags |= ST_SCROLL_SELECT;
-
+
if (event->type == MOUSEPAN) {
text_update_character_width(st);
-
+
tsc->old[0] = event->x;
tsc->old[1] = event->y;
/* Sensitivity of scroll set to 4pix per line/char */
@@ -2291,7 +2291,7 @@ static int text_scroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
WM_event_add_modal_handler(C, op);
-
+
return OPERATOR_RUNNING_MODAL;
}
@@ -2300,11 +2300,11 @@ void TEXT_OT_scroll(wmOperatorType *ot)
/* identifiers */
ot->name = "Scroll";
/* don't really see the difference between this and
- * scroll_bar. Both do basically the same thing (aside
+ * scroll_bar. Both do basically the same thing (aside
* from keymaps).*/
ot->idname = "TEXT_OT_scroll";
ot->description = "";
-
+
/* api callbacks */
ot->exec = text_scroll_exec;
ot->invoke = text_scroll_invoke;
@@ -2330,10 +2330,10 @@ static int text_region_scroll_poll(bContext *C)
if (!st || !text)
return 0;
-
+
if (!ar || ar->regiontype != RGN_TYPE_WINDOW)
return 0;
-
+
return 1;
}
@@ -2347,7 +2347,7 @@ static int text_scroll_bar_invoke(bContext *C, wmOperator *op, const wmEvent *ev
if (RNA_struct_property_is_set(op->ptr, "lines"))
return text_scroll_exec(C, op);
-
+
/* verify we are in the right zone */
if (mval[0] > st->txtbar.xmin && mval[0] < st->txtbar.xmax) {
if (mval[1] >= st->txtbar.ymin && mval[1] <= st->txtbar.ymax) {
@@ -2392,11 +2392,11 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot)
/* identifiers */
ot->name = "Scrollbar";
/* don't really see the difference between this and
- * scroll. Both do basically the same thing (aside
+ * scroll. Both do basically the same thing (aside
* from keymaps).*/
ot->idname = "TEXT_OT_scroll_bar";
ot->description = "";
-
+
/* api callbacks */
ot->invoke = text_scroll_bar_invoke;
ot->modal = text_scroll_modal;
@@ -2431,7 +2431,7 @@ static int flatten_width(SpaceText *st, const char *str)
total += BLI_str_utf8_char_width_safe(str + i);
}
}
-
+
return total;
}
@@ -2444,14 +2444,14 @@ static int flatten_column_to_offset(SpaceText *st, const char *str, int index)
col = st->tabnumber - i % st->tabnumber;
else
col = BLI_str_utf8_char_width_safe(str + j);
-
+
if (i + col > index)
break;
-
+
i += col;
j += BLI_str_utf8_size_safe(str + j);
}
-
+
return j;
}
@@ -2482,7 +2482,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
int max = wrap_width(st, ar); /* column */
int charp = -1; /* mem */
bool found = false; /* flags */
-
+
/* Point to line matching given y position, if any. */
TextLine *linep = get_line_pos_wrapped(st, ar, &y);
@@ -2495,7 +2495,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
for (j = 0 ; !found && ((ch = linep->line[j]) != '\0'); j += BLI_str_utf8_size_safe(linep->line + j)) {
int chars;
int columns = BLI_str_utf8_char_width_safe(linep->line + j); /* = 1 for tab */
-
+
/* Mimic replacement of tabs */
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
@@ -2504,7 +2504,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
else {
chars = 1;
}
-
+
while (chars--) {
/* Gone too far, go back to last wrap point */
if (y < 0) {
@@ -2526,22 +2526,22 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
}
if (i + columns - start > max) {
end = MIN2(end, i);
-
+
if (found) {
/* exact cursor position was found, check if it's still on needed line (hasn't been wrapped) */
if (charp > endj && !chop && ch != '\0')
charp = endj;
break;
}
-
+
if (chop)
endj = j;
start = end;
end += max;
-
+
if (j < linep->len)
y--;
-
+
chop = true;
if (y == 0 && i + columns - start > x) {
charp = curs;
@@ -2553,7 +2553,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
if (found) {
break;
}
-
+
if (y == 0 && i + columns - start > x) {
charp = curs;
found = true;
@@ -2568,7 +2568,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
}
BLI_assert(y == 0);
-
+
if (!found) {
/* On correct line but didn't meet cursor, must be at end */
charp = linep->len;
@@ -2606,7 +2606,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, con
if (x < 0) x = 0;
x = text_pixel_x_to_column(st, x) + st->left;
-
+
if (st->wordwrap) {
text_cursor_set_to_pos_wrapped(st, ar, x, y, sel);
}
@@ -2614,12 +2614,12 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, con
TextLine **linep;
int *charp;
int w;
-
+
if (sel) { linep = &text->sell; charp = &text->selc; }
else { linep = &text->curl; charp = &text->curc; }
-
+
y -= txt_get_span(text->lines.first, *linep) - st->top;
-
+
if (y > 0) {
while (y-- != 0) {
if ((*linep)->next) *linep = (*linep)->next;
@@ -2631,7 +2631,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, con
}
}
-
+
w = flatten_width(st, (*linep)->line);
if (x < w) *charp = flatten_column_to_offset(st, (*linep)->line, x);
else *charp = (*linep)->len;
@@ -2679,7 +2679,7 @@ static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *ev
}
else if (!st->wordwrap && (event->mval[0] < 0 || event->mval[0] > ar->winx)) {
text_cursor_timer_ensure(C, ssel);
-
+
if (event->type == TIMER) {
text_cursor_set_to_pos(st, ar, CLAMPIS(event->mval[0], 0, ar->winx), event->mval[1], 1);
text_scroll_to_cursor(st, ar, false);
@@ -2876,7 +2876,7 @@ void TEXT_OT_line_number(wmOperatorType *ot)
ot->name = "Line Number";
ot->idname = "TEXT_OT_line_number";
ot->description = "The current line number";
-
+
/* api callbacks */
ot->invoke = text_line_number_invoke;
ot->poll = text_region_edit_poll;
@@ -2913,7 +2913,7 @@ static int text_insert_exec(bContext *C, wmOperator *op)
}
MEM_freeN(str);
-
+
if (!done)
return OPERATOR_CANCELLED;
@@ -2941,7 +2941,7 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else {
char str[BLI_UTF8_MAX + 1];
size_t len;
-
+
if (event->utf8_buf[0]) {
len = BLI_str_utf8_size_safe(event->utf8_buf);
memcpy(str, event->utf8_buf, len);
@@ -2956,7 +2956,7 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
ret = text_insert_exec(C, op);
-
+
/* run the script while editing, evil but useful */
if (ret == OPERATOR_FINISHED && CTX_wm_space_text(C)->live_edit)
text_run_script(C, NULL);
@@ -2972,7 +2972,7 @@ void TEXT_OT_insert(wmOperatorType *ot)
ot->name = "Insert";
ot->idname = "TEXT_OT_insert";
ot->description = "Insert text at cursor position";
-
+
/* api callbacks */
ot->exec = text_insert_exec;
ot->invoke = text_insert_invoke;
@@ -3064,7 +3064,7 @@ void TEXT_OT_find(wmOperatorType *ot)
ot->name = "Find Next";
ot->idname = "TEXT_OT_find";
ot->description = "Find specified text";
-
+
/* api callbacks */
ot->exec = text_find_exec;
ot->poll = text_space_edit_poll;
@@ -3116,7 +3116,7 @@ void TEXT_OT_find_set_selected(wmOperatorType *ot)
ot->name = "Find Set Selected";
ot->idname = "TEXT_OT_find_set_selected";
ot->description = "Find specified text and set as selected";
-
+
/* api callbacks */
ot->exec = text_find_set_selected_exec;
ot->poll = text_space_edit_poll;
@@ -3143,7 +3143,7 @@ void TEXT_OT_replace_set_selected(wmOperatorType *ot)
ot->name = "Replace Set Selected";
ot->idname = "TEXT_OT_replace_set_selected";
ot->description = "Replace text with specified text and set as selected";
-
+
/* api callbacks */
ot->exec = text_replace_set_selected_exec;
ot->poll = text_space_edit_poll;
@@ -3259,11 +3259,11 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot)
ot->name = "To 3D Object";
ot->idname = "TEXT_OT_to_3d_object";
ot->description = "Create 3D text object from active text data-block";
-
+
/* api callbacks */
ot->exec = text_to_3d_object_exec;
ot->poll = text_edit_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 95d0a246ccd..b3f45de518b 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -77,9 +77,9 @@ static SpaceLink *userpref_new(const ScrArea *UNUSED(area), const Scene *UNUSED(
/* not spacelink itself */
static void userpref_free(SpaceLink *UNUSED(sl))
-{
+{
// SpaceUserPref *spref = (SpaceUserPref *)sl;
-
+
}
@@ -105,7 +105,7 @@ static void userpref_main_region_init(wmWindowManager *wm, ARegion *ar)
{
/* do not use here, the properties changed in userprefs do a system-wide refresh, then scroller jumps back */
/* ar->v2d.flag &= ~V2D_IS_INITIALISED; */
-
+
ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
ED_region_panels_init(wm, ar);
@@ -122,7 +122,7 @@ static void userpref_operatortypes(void)
static void userpref_keymap(struct wmKeyConfig *UNUSED(keyconf))
{
-
+
}
/* add handlers, stuff you only do once or on area/region changes */
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index b87d6c0b85e..1224c284d5f 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -67,6 +67,7 @@
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
@@ -709,7 +710,7 @@ void ED_draw_object_facemap(
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
-
+
#if 0
DM_update_materials(dm, ob);
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index bfb2568df71..7b395153417 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -95,21 +95,21 @@ ARegion *view3d_has_buttons_region(ScrArea *sa)
ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
if (ar) return ar;
-
+
/* add subdiv level; after header */
ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
/* is error! */
if (ar == NULL) return NULL;
-
+
arnew = MEM_callocN(sizeof(ARegion), "buttons for view3d");
-
+
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype = RGN_TYPE_UI;
arnew->alignment = RGN_ALIGN_RIGHT;
-
+
arnew->flag = RGN_FLAG_HIDDEN;
-
+
return arnew;
}
@@ -132,12 +132,12 @@ ARegion *view3d_has_tools_region(ScrArea *sa)
for (arhead = sa->regionbase.first; arhead; arhead = arhead->next)
if (arhead->regiontype == RGN_TYPE_HEADER)
break;
-
+
/* is error! */
if (arhead == NULL) return NULL;
-
+
artool = MEM_callocN(sizeof(ARegion), "tools for view3d");
-
+
BLI_insertlinkafter(&sa->regionbase, arhead, artool);
artool->regiontype = RGN_TYPE_TOOLS;
artool->alignment = RGN_ALIGN_LEFT;
@@ -153,7 +153,7 @@ ARegion *view3d_has_tools_region(ScrArea *sa)
RegionView3D *ED_view3d_context_rv3d(bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
-
+
if (rv3d == NULL) {
ScrArea *sa = CTX_wm_area(C);
if (sa && sa->spacetype == SPACE_VIEW3D) {
@@ -309,10 +309,9 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
ARegion *ar;
View3D *v3d;
RegionView3D *rv3d;
-
+
v3d = MEM_callocN(sizeof(View3D), "initview3d");
v3d->spacetype = SPACE_VIEW3D;
- v3d->blockscale = 0.7f;
v3d->lay = v3d->layact = 1;
if (scene) {
v3d->lay = v3d->layact = scene->lay;
@@ -327,15 +326,19 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
v3d->shading.light = V3D_LIGHTING_STUDIO;
v3d->shading.shadow_intensity = 0.5f;
v3d->shading.xray_alpha = 0.5f;
+ v3d->shading.cavity_valley_factor = 1.0f;
+ v3d->shading.cavity_ridge_factor = 1.0f;
copy_v3_fl(v3d->shading.single_color, 0.8f);
v3d->overlay.flag = V3D_OVERLAY_LOOK_DEV;
+ v3d->overlay.wireframe_threshold = 0.5f;
+ v3d->overlay.bone_selection_alpha = 0.5f;
v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
-
+
v3d->flag = V3D_SELECT_OUTLINE;
v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL;
-
+
v3d->lens = 50.0f;
v3d->near = 0.01f;
v3d->far = 1000.0f;
@@ -353,14 +356,14 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for view3d");
-
+
BLI_addtail(&v3d->regionbase, ar);
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
-
+
/* tool shelf */
ar = MEM_callocN(sizeof(ARegion), "toolshelf for view3d");
-
+
BLI_addtail(&v3d->regionbase, ar);
ar->regiontype = RGN_TYPE_TOOLS;
ar->alignment = RGN_ALIGN_LEFT;
@@ -368,25 +371,25 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
/* buttons/list view */
ar = MEM_callocN(sizeof(ARegion), "buttons for view3d");
-
+
BLI_addtail(&v3d->regionbase, ar);
ar->regiontype = RGN_TYPE_UI;
ar->alignment = RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
-
+
/* main region */
ar = MEM_callocN(sizeof(ARegion), "main region for view3d");
-
+
BLI_addtail(&v3d->regionbase, ar);
ar->regiontype = RGN_TYPE_WINDOW;
-
+
ar->regiondata = MEM_callocN(sizeof(RegionView3D), "region view3d");
rv3d = ar->regiondata;
rv3d->viewquat[0] = 1.0f;
rv3d->persp = RV3D_PERSP;
rv3d->view = RV3D_VIEW_USER;
rv3d->dist = 10.0;
-
+
return (SpaceLink *)v3d;
}
@@ -396,9 +399,9 @@ static void view3d_free(SpaceLink *sl)
View3D *vd = (View3D *) sl;
if (vd->localvd) MEM_freeN(vd->localvd);
-
+
if (vd->properties_storage) MEM_freeN(vd->properties_storage);
-
+
if (vd->fx_settings.ssao)
MEM_freeN(vd->fx_settings.ssao);
if (vd->fx_settings.dof)
@@ -416,7 +419,7 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
{
View3D *v3do = (View3D *)sl;
View3D *v3dn = MEM_dupallocN(sl);
-
+
/* clear or remove stuff from old */
if (v3dn->localvd) {
@@ -427,7 +430,7 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
if (v3dn->drawtype == OB_RENDER)
v3dn->drawtype = OB_SOLID;
-
+
/* copy or clear inside new stuff */
v3dn->properties_storage = NULL;
@@ -453,19 +456,19 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
/* object ops. */
-
+
/* important to be before Pose keymap since they can both be enabled at once */
keymap = WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
-
-
+
+
keymap = WM_keymap_find(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
/* pose is not modal, operator poll checks for this */
keymap = WM_keymap_find(wm->defaultconf, "Pose", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -486,13 +489,13 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_find(wm->defaultconf, "Sculpt", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Mesh", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Curve", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Armature", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -501,7 +504,7 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_find(wm->defaultconf, "Metaball", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Lattice", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -524,12 +527,12 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_find(wm->defaultconf, "3D View", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
-
+
/* add drop boxes */
lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
-
+
WM_event_add_dropbox_handler(&ar->handlers, lb);
-
+
}
static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar)
@@ -632,7 +635,7 @@ static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = drag->poin;
-
+
drop->opcontext = WM_OP_EXEC_DEFAULT;
RNA_string_set(drop->ptr, "name", id->name + 2);
}
@@ -640,14 +643,14 @@ static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = drag->poin;
-
+
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = drag->poin;
-
+
if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
RNA_struct_property_unset(drop->ptr, "filepath");
@@ -663,7 +666,7 @@ static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
static void view3d_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
-
+
WM_dropbox_add(lb, "OBJECT_OT_add_named", view3d_ob_drop_poll, view3d_ob_drop_copy);
WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy);
WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_mesh_drop_poll, view3d_id_path_drop_copy);
@@ -701,14 +704,14 @@ static void view3d_widgets(void)
static void view3d_main_region_free(ARegion *ar)
{
RegionView3D *rv3d = ar->regiondata;
-
+
if (rv3d) {
if (rv3d->localvd) MEM_freeN(rv3d->localvd);
if (rv3d->clipbb) MEM_freeN(rv3d->clipbb);
if (rv3d->render_engine)
RE_engine_free(rv3d->render_engine);
-
+
if (rv3d->depths) {
if (rv3d->depths->depths) MEM_freeN(rv3d->depths->depths);
MEM_freeN(rv3d->depths);
@@ -730,19 +733,19 @@ static void *view3d_main_region_duplicate(void *poin)
{
if (poin) {
RegionView3D *rv3d = poin, *new;
-
+
new = MEM_dupallocN(rv3d);
if (rv3d->localvd)
new->localvd = MEM_dupallocN(rv3d->localvd);
if (rv3d->clipbb)
new->clipbb = MEM_dupallocN(rv3d->clipbb);
-
+
new->depths = NULL;
new->gpuoffscreen = NULL;
new->render_engine = NULL;
new->sms = NULL;
new->smooth_timer = NULL;
-
+
return new;
}
return NULL;
@@ -1143,7 +1146,7 @@ static void view3d_main_region_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
static void view3d_header_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
-
+
WM_event_add_keymap_handler(&ar->handlers, keymap);
ED_region_header_init(ar);
@@ -1222,7 +1225,7 @@ static void view3d_buttons_region_init(wmWindowManager *wm, ARegion *ar)
wmKeyMap *keymap;
ED_region_panels_init(wm, ar);
-
+
keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
@@ -1349,7 +1352,7 @@ static int view3d_tools_region_snap_size(const ARegion *ar, int size, int axis)
static void view3d_tools_region_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
-
+
ED_region_panels_init(wm, ar);
keymap = WM_keymap_find(wm->defaultconf, "3D View Generic", SPACE_VIEW3D, 0);
@@ -1419,7 +1422,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
}
}
-
+
return 1;
}
else if (CTX_data_equals(member, "active_object")) {
@@ -1431,7 +1434,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
CTX_data_id_pointer_set(result, &ob->id);
}
}
-
+
return 1;
}
else {
@@ -1490,10 +1493,10 @@ void ED_spacetype_view3d(void)
{
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype view3d");
ARegionType *art;
-
+
st->spaceid = SPACE_VIEW3D;
strncpy(st->name, "View3D", BKE_ST_MAXNAME);
-
+
st->new = view3d_new;
st->free = view3d_free;
st->init = view3d_init;
@@ -1520,7 +1523,7 @@ void ED_spacetype_view3d(void)
art->cursor = view3d_main_region_cursor;
art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */
BLI_addhead(&st->regiontypes, art);
-
+
/* regions: listview/buttons */
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d buttons region");
art->regionid = RGN_TYPE_UI;
@@ -1545,7 +1548,7 @@ void ED_spacetype_view3d(void)
art->init = view3d_tools_region_init;
art->draw = view3d_tools_region_draw;
BLI_addhead(&st->regiontypes, art);
-
+
#if 0
/* unfinished still */
view3d_toolshelf_register(art);
@@ -1561,6 +1564,6 @@ void ED_spacetype_view3d(void)
art->draw = view3d_header_region_draw;
art->message_subscribe = view3d_header_region_message_subscribe;
BLI_addhead(&st->regiontypes, art);
-
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 644a6956e54..69e8aa07d3f 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -835,7 +835,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
bcol = uiLayoutColumn(pa->layout, true);
row = uiLayoutRow(bcol, true); /* The filter button row */
-
+
RNA_pointer_create(NULL, &RNA_ToolSettings, ts, &tools_ptr);
uiItemR(row, &tools_ptr, "vertex_group_subset", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
@@ -864,7 +864,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
UI_but_flag_enable(but, UI_BUT_INACTIVE);
}
xco += x;
-
+
row = uiLayoutRow(split, true);
uiLayoutSetEnabled(row, !locked);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index d61e79c99f1..e199e84029e 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -441,14 +441,14 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View
return;
if (v3d->camera->type == OB_CAMERA)
ca = v3d->camera->data;
-
+
ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false);
/* the offsets */
x1 = viewborder.xmin;
y1 = viewborder.ymin;
x2 = viewborder.xmax;
y2 = viewborder.ymax;
-
+
glLineWidth(1.0f);
/* apply offsets so the real 3D camera shows through */
@@ -647,7 +647,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View
/* draw */
immUniformThemeColorShade(TH_VIEW_OVERLAY, 100);
-
+
/* TODO Was using UI_draw_roundbox_4fv(false, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color).
* We'll probably need a new imm_draw_line_roundbox_dashed dor that - though in practice the
* 2.0f round corner effect was nearly not visible anyway... */
@@ -885,7 +885,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d)
sub_v3_v3v3(end, o, scaled_axis);
immVertex3fv(pos, end);
immEnd();
-
+
/* -- draw ring around rotation center -- */
{
#define ROT_AXIS_DETAIL 13
@@ -1203,11 +1203,15 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
BLF_batch_draw_begin();
- if (U.uiflag & USER_SHOW_ROTVIEWICON) {
+ if (((U.uiflag & USER_SHOW_ROTVIEWICON) != 0) &&
+ (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)
+ {
draw_view_axis(rv3d, &rect);
}
- if ((v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) {
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0 &&
+ (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0)
+ {
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
ED_scene_draw_fps(scene, &rect);
}
@@ -1252,7 +1256,7 @@ static void view3d_draw_view(const bContext *C, ARegion *ar)
RenderEngineType *ED_view3d_engine_type(Scene *scene, int drawtype)
{
/*
- * Tempory viewport draw modes until we have a proper system.
+ * Tempory viewport draw modes until we have a proper system.
* all modes are done in the draw manager, except
* cycles material as it is an external render engine.
*/
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index e2ff809db36..cdf2106d8bf 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -131,6 +131,7 @@ static void view3d_operator_properties_common(wmOperatorType *ot, const enum eV3
typedef struct ViewOpsData {
/** Context pointers (assigned by #viewops_data_alloc). */
+ Main *bmain;
Scene *scene;
ScrArea *sa;
ARegion *ar;
@@ -221,6 +222,7 @@ static void viewops_data_alloc(bContext *C, wmOperator *op)
/* store data */
op->customdata = vod;
+ vod->bmain = CTX_data_main(C);
vod->depsgraph = CTX_data_depsgraph(C);
vod->scene = CTX_data_scene(C);
vod->sa = CTX_wm_area(C);
@@ -4592,6 +4594,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
@@ -4609,7 +4612,7 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
float ray_no[3];
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- scene, CTX_data_depsgraph(C), 0, ar, v3d);
+ bmain, scene, CTX_data_depsgraph(C), 0, ar, v3d);
float obmat[4][4];
Object *ob_dummy = NULL;
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 56e90c70511..d8cc9ab9828 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -151,7 +151,7 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE);
WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, FLY_MODAL_SPEED);
-
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE);
/* XXX - Bug in the event system, middle mouse release doesnt work */
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE);
@@ -550,12 +550,12 @@ static void flyEvent(bContext *C, wmOperator *op, FlyInfo *fly, const wmEvent *e
case FLY_MODAL_CONFIRM:
fly->state = FLY_CONFIRM;
break;
-
+
/* speed adjusting with mousepan (trackpad) */
case FLY_MODAL_SPEED:
{
float fac = 0.02f * (event->prevy - event->y);
-
+
/* allowing to brake immediate */
if (fac > 0.0f && fly->speed < 0.0f)
fly->speed = 0.0f;
@@ -563,7 +563,7 @@ static void flyEvent(bContext *C, wmOperator *op, FlyInfo *fly, const wmEvent *e
fly->speed = 0.0f;
else
fly->speed += fly->grid * fac;
-
+
break;
}
case FLY_MODAL_ACCELERATE:
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index dde86f8bafa..4f81fa7585c 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -117,7 +117,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
int nr = RNA_int_get(op->ptr, "nr");
const bool toggle = RNA_boolean_get(op->ptr, "toggle");
-
+
if (nr < 0)
return OPERATOR_CANCELLED;
@@ -165,13 +165,13 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
}
}
}
-
+
if (v3d->scenelock) handle_view3d_lock(C);
-
+
DEG_on_visible_update(CTX_data_main(C), false);
ED_area_tag_redraw(sa);
-
+
return OPERATOR_FINISHED;
}
@@ -181,18 +181,18 @@ static int view3d_layers_invoke(bContext *C, wmOperator *op, const wmEvent *even
{
if (event->ctrl || event->oskey)
return OPERATOR_PASS_THROUGH;
-
+
if (event->shift)
RNA_boolean_set(op->ptr, "extend", true);
else
RNA_boolean_set(op->ptr, "extend", false);
-
+
if (event->alt) {
const int nr = RNA_int_get(op->ptr, "nr") + 10;
RNA_int_set(op->ptr, "nr", nr);
}
view3d_layers_exec(C, op);
-
+
return OPERATOR_FINISHED;
}
@@ -207,15 +207,15 @@ void VIEW3D_OT_layers(wmOperatorType *ot)
ot->name = "Layers";
ot->description = "Toggle layer(s) visibility";
ot->idname = "VIEW3D_OT_layers";
-
+
/* api callbacks */
ot->invoke = view3d_layers_invoke;
ot->exec = view3d_layers_exec;
ot->poll = view3d_layers_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_int(ot->srna, "nr", 1, 0, 20, "Number", "The layer number to set, zero for all layers", 0, 20);
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Add this layer to the current view layers");
RNA_def_boolean(ot->srna, "toggle", 1, "Toggle", "Toggle the layer");
@@ -259,6 +259,33 @@ void VIEW3D_OT_toggle_xray_draw_option(wmOperatorType *ot)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Toggle Bone selection Overlay Operator
+ * \{ */
+
+static int toggle_matcap_flip(bContext *C, wmOperator *UNUSED(op))
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ v3d->shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
+ ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ return OPERATOR_FINISHED;
+}
+
+void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Flip MatCap";
+ ot->description = "Flip MatCap";
+ ot->idname = "VIEW3D_OT_toggle_matcap_flip";
+
+ /* api callbacks */
+ ot->exec = toggle_matcap_flip;
+ // ot->poll = toggle_show_xray_poll;
+}
+
+/** \} */
+
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
{
@@ -371,7 +398,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
ELEM(ob->mode,
OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT));
-
+
RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr);
RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr);
RNA_pointer_create(&scene->id, &RNA_Scene, scene, &sceneptr);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 6c9749e5eeb..017b31a0bf2 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -66,6 +66,7 @@ enum {
/* view3d_header.c */
void VIEW3D_OT_layers(struct wmOperatorType *ot);
void VIEW3D_OT_toggle_xray_draw_option(struct wmOperatorType *ot);
+void VIEW3D_OT_toggle_matcap_flip(struct wmOperatorType *ot);
/* view3d_ops.c */
void view3d_operatortypes(void);
@@ -134,7 +135,8 @@ void VIEW3D_OT_ruler(struct wmOperatorType *ot);
/* drawobject.c */
void draw_object_backbufsel(
- struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob,
+ struct Depsgraph *depsgraph, Scene *scene,
+ View3D *v3d, RegionView3D *rv3d, struct Object *ob,
short select_mode);
int view3d_effective_drawtype(const struct View3D *v3d);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 145f57174fd..eae0cf8e459 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -42,6 +42,7 @@
#include "BKE_displist.h"
#include "BKE_editmesh.h"
#include "BKE_context.h"
+#include "BKE_mesh_runtime.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_armature.c b/source/blender/editors/space_view3d/view3d_manipulator_armature.c
index 5d3d88ff2a2..abbd6c888b2 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_armature.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_armature.c
@@ -134,7 +134,10 @@ static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmManipulatorGro
const bArmature *arm = ob->data;
if (arm->drawtype == ARM_B_BONE) {
if (arm->act_bone && arm->act_bone->segments > 1) {
- return true;
+ View3D *v3d = CTX_wm_view3d(C);
+ if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
+ return true;
+ }
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_camera.c b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
index b680818dc14..49fa83e82fc 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_camera.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
@@ -63,6 +63,11 @@ struct CameraWidgetGroup {
static bool WIDGETGROUP_camera_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ return false;
+ }
+
Object *ob = CTX_data_active_object(C);
if (ob && ob->type == OB_CAMERA) {
Camera *camera = ob->data;
@@ -352,9 +357,13 @@ static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmManipulatorGroupTy
}
}
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ return false;
+ }
+
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
- View3D *v3d = CTX_wm_view3d(C);
if (rv3d->persp == RV3D_CAMOB) {
if (scene->r.mode & R_BORDER) {
/* TODO: support overrides. */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_empty.c b/source/blender/editors/space_view3d/view3d_manipulator_empty.c
index 1d56c5ee7f4..75e4a9e3314 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_empty.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_empty.c
@@ -106,6 +106,11 @@ static void manipulator_empty_image_prop_matrix_set(
static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ return false;
+ }
+
Object *ob = CTX_data_active_object(C);
if (ob && ob->type == OB_EMPTY) {
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
index e76be448be4..2a1fdee8e8a 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
@@ -54,6 +54,11 @@
static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ return false;
+ }
+
Object *ob = CTX_data_active_object(C);
return (ob && ob->pd && ob->pd->forcefield);
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
index 88c36fc2c0b..01c38cfd899 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
@@ -54,6 +54,11 @@
static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ return false;
+ }
+
Object *ob = CTX_data_active_object(C);
if (ob && ob->type == OB_LAMP) {
@@ -151,8 +156,12 @@ static void manipulator_area_lamp_prop_matrix_set(
static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
- Object *ob = CTX_data_active_object(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ return false;
+ }
+ Object *ob = CTX_data_active_object(C);
if (ob && ob->type == OB_LAMP) {
Lamp *la = ob->data;
return (la->type == LA_AREA);
@@ -226,6 +235,11 @@ void VIEW3D_WGT_lamp_area(wmManipulatorGroupType *wgt)
static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ return false;
+ }
+
Object *ob = CTX_data_active_object(C);
if (ob != NULL) {
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_navigate.c b/source/blender/editors/space_view3d/view3d_manipulator_navigate.c
index d86c6595bfa..c869e23d552 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_navigate.c
@@ -176,8 +176,13 @@ struct NavigateWidgetGroup {
int region_size[2];
};
-static bool WIDGETGROUP_navigate_poll(const bContext *UNUSED(C), wmManipulatorGroupType *UNUSED(wgt))
+static bool WIDGETGROUP_navigate_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
{
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->flag2 & V3D_RENDER_OVERRIDE) {
+ return false;
+ }
+
if (U.manipulator_flag & USER_MANIPULATOR_DRAW_NAVIGATE) {
return true;
}
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_ruler.c b/source/blender/editors/space_view3d/view3d_manipulator_ruler.c
index 9cde5ffc5e3..cd918695f60 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_ruler.c
@@ -31,8 +31,10 @@
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_object.h"
#include "BKE_gpencil.h"
+#include "BKE_main.h"
+
+#include "BKE_object.h"
#include "BKE_unit.h"
#include "DNA_object_types.h"
@@ -263,6 +265,7 @@ static bool view3d_ruler_pick(
*/
static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
{
+ Main *bmain = CTX_data_main(C);
if (state == ruler_info->state) {
return;
}
@@ -278,7 +281,7 @@ static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
}
else if (state == RULER_STATE_DRAG) {
ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_scene(C), CTX_data_depsgraph(C), 0,
+ bmain, CTX_data_scene(C), CTX_data_depsgraph(C), 0,
ruler_info->ar, CTX_wm_view3d(C));
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 4b2f254a2b6..b3211ed1108 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -71,9 +71,9 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
char str[FILE_MAX];
-
+
BKE_copybuffer_begin(bmain);
-
+
/* context, selection, could be generalized */
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
@@ -93,10 +93,10 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
}
}
}
-
+
BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
BKE_copybuffer_save(bmain, str, op->reports);
-
+
BKE_report(op->reports, RPT_INFO, "Copied selected objects to buffer");
return OPERATOR_FINISHED;
@@ -104,12 +104,12 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
static void VIEW3D_OT_copybuffer(wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Copy Selection to Buffer";
ot->idname = "VIEW3D_OT_copybuffer";
ot->description = "Selected objects are saved in a temp file";
-
+
/* api callbacks */
ot->exec = view3d_copybuffer_exec;
ot->poll = ED_operator_scene;
@@ -141,16 +141,16 @@ static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)
{
-
+
/* identifiers */
ot->name = "Paste Selection from Buffer";
ot->idname = "VIEW3D_OT_pastebuffer";
ot->description = "Contents of copy buffer gets pasted";
-
+
/* api callbacks */
ot->exec = view3d_pastebuffer_exec;
ot->poll = ED_operator_scene_editable;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -209,10 +209,10 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_layers);
WM_operatortype_append(VIEW3D_OT_copybuffer);
WM_operatortype_append(VIEW3D_OT_pastebuffer);
-
+
WM_operatortype_append(VIEW3D_OT_properties);
WM_operatortype_append(VIEW3D_OT_toolshelf);
-
+
WM_operatortype_append(VIEW3D_OT_snap_selected_to_grid);
WM_operatortype_append(VIEW3D_OT_snap_selected_to_cursor);
WM_operatortype_append(VIEW3D_OT_snap_selected_to_active);
@@ -223,6 +223,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_toggle_render);
WM_operatortype_append(VIEW3D_OT_toggle_xray_draw_option);
+ WM_operatortype_append(VIEW3D_OT_toggle_matcap_flip);
WM_operatortype_append(VIEW3D_OT_ruler_add);
@@ -233,17 +234,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
keymap = WM_keymap_find(keyconf, "3D View Generic", SPACE_VIEW3D, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_toolshelf", TKEY, KM_PRESS, 0, 0);
-
+
/* only for region 3D window */
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_CLICK, 0, 0);
-
+
WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
@@ -259,20 +260,20 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "VIEW3D_OT_navigate", FKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
-
+
WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEPAN, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEROTATE, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEZOOM, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0);
-
+
/*numpad +/-*/
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADMINUS, KM_PRESS, 0, 0)->ptr, "delta", -1);
/*ctrl +/-*/
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", EQUALKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MINUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
-
+
/*wheel mouse forward/back*/
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELINMOUSE, KM_PRESS, 0, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELOUTMOUSE, KM_PRESS, 0, 0)->ptr, "delta", -1);
@@ -301,6 +302,8 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "center", true);
+ WM_keymap_add_menu_pie(keymap, "VIEW3D_PIE_view", ACCENTGRAVEKEY, KM_CLICK_DRAG, 0, 0);
+
/* numpad view hotkeys*/
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
@@ -308,7 +311,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD3, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD4, KM_PRESS, 0, 0)->ptr, "type", V3D_VIEW_STEPLEFT);
WM_keymap_add_item(keymap, "VIEW3D_OT_view_persportho", PAD5, KM_PRESS, 0, 0);
-
+
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD6, KM_PRESS, 0, 0)->ptr, "type", V3D_VIEW_STEPRIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD8, KM_PRESS, 0, 0)->ptr, "type", V3D_VIEW_STEPUP);
@@ -334,7 +337,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL | KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELUPMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPUP);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPDOWN);
-
+
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", WHEELUPMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPLEFT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT);
@@ -357,7 +360,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", true);
-
+
#ifdef WITH_INPUT_NDOF
/* note: positioned here so keymaps show keyboard keys if assigned */
/* 3D mouse */
@@ -376,7 +379,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
-
+
/* 3D mouse align */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
@@ -467,7 +470,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0);
-
+
WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0);
@@ -477,19 +480,19 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "camera_only", false);
WM_keymap_add_item(keymap, "VIEW3D_OT_clear_render_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
-
+
WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0);
-
+
WM_keymap_add_menu(keymap, "VIEW3D_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
-
+
#ifdef __APPLE__
WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_OSKEY, 0);
#endif
WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* context ops */
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.transform_pivot_point");
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index fe14e82c152..30b91c1a8ee 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -57,13 +57,13 @@
void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4])
{
float vec4[4];
-
+
copy_v3_v3(vec4, co);
vec4[3] = 1.0;
/* r_co[0] = IS_CLIPPED; */ /* always overwritten */
-
+
mul_m4_v4(mat, vec4);
-
+
if (vec4[3] > FLT_EPSILON) {
r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
@@ -79,13 +79,13 @@ void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r
void ED_view3d_project_float_v3_m4(const ARegion *ar, const float vec[3], float r_co[3], float mat[4][4])
{
float vec4[4];
-
+
copy_v3_v3(vec4, vec);
vec4[3] = 1.0;
/* r_co[0] = IS_CLIPPED; */ /* always overwritten */
-
+
mul_m4_v4(mat, vec4);
-
+
if (vec4[3] > FLT_EPSILON) {
r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
@@ -551,10 +551,10 @@ void ED_view3d_win_to_delta(const ARegion *ar, const float mval[2], float out[3]
{
RegionView3D *rv3d = ar->regiondata;
float dx, dy;
-
+
dx = 2.0f * mval[0] * zfac / ar->winx;
dy = 2.0f * mval[1] * zfac / ar->winy;
-
+
out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index c0af3c7caaa..c30b72bfb95 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -38,8 +38,9 @@
#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_unit.h"
#include "BKE_gpencil.h"
+#include "BKE_main.h"
+#include "BKE_unit.h"
#include "BIF_gl.h"
@@ -267,6 +268,7 @@ static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2],
*/
static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
{
+ Main *bmain = CTX_data_main(C);
if (state == ruler_info->state) {
return;
}
@@ -282,7 +284,7 @@ static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
}
else if (state == RULER_STATE_DRAG) {
ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_scene(C), CTX_data_depsgraph(C), 0,
+ bmain, CTX_data_scene(C), CTX_data_depsgraph(C), 0,
ruler_info->ar, CTX_wm_view3d(C));
}
else {
@@ -326,7 +328,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
if (palcolor == NULL) {
palcolor = BKE_gpencil_palettecolor_addnew(palette, (char *)ruler_name, true);
}
-
+
gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
BKE_gpencil_free_strokes(gpf);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 745ebe66cf7..f4e39c7a563 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -116,6 +116,7 @@ void ED_view3d_viewcontext_init(bContext *C, ViewContext *vc)
{
memset(vc, 0, sizeof(ViewContext));
vc->ar = CTX_wm_region(C);
+ vc->bmain = CTX_data_main(C);
vc->depsgraph = CTX_data_depsgraph(C);
vc->scene = CTX_data_scene(C);
vc->view_layer = CTX_data_view_layer(C);
@@ -299,25 +300,25 @@ static bool edge_fully_inside_rect(const rctf *rect, const float v1[2], const fl
static bool edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
{
int d1, d2, d3, d4;
-
+
/* check points in rect */
if (edge_fully_inside_rect(rect, v1, v2)) return 1;
-
+
/* check points completely out rect */
if (v1[0] < rect->xmin && v2[0] < rect->xmin) return 0;
if (v1[0] > rect->xmax && v2[0] > rect->xmax) return 0;
if (v1[1] < rect->ymin && v2[1] < rect->ymin) return 0;
if (v1[1] > rect->ymax && v2[1] > rect->ymax) return 0;
-
+
/* simple check lines intersecting. */
d1 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymin);
d2 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymax);
d3 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymax);
d4 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymin);
-
+
if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0) return 0;
if (d1 > 0 && d2 > 0 && d3 > 0 && d4 > 0) return 0;
-
+
return 1;
}
@@ -373,7 +374,7 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[]
ViewContext vc_tmp;
LassoSelectUserData data;
rcti rect;
-
+
if ((ob->type != OB_ARMATURE) || (ob->pose == NULL)) {
return;
}
@@ -417,7 +418,7 @@ static void do_lasso_select_objects(
{
bool is_pose_mode = vc->obact ? (vc->obact->mode & OB_MODE_POSE) : false;
Base *base;
-
+
if (extend == false && select)
object_deselect_all_visible(vc->view_layer);
@@ -497,7 +498,7 @@ static void do_lasso_select_mesh(
ToolSettings *ts = vc->scene->toolsettings;
rcti rect;
int bbsel;
-
+
/* set editmesh */
vc->em = BKE_editmesh_from_object(vc->obedit);
@@ -513,7 +514,7 @@ static void do_lasso_select_mesh(
gpuLoadMatrix(vc->rv3d->viewmat);
bbsel = EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
-
+
if (ts->selectmode & SCE_SELECT_VERTEX) {
if (bbsel) {
edbm_backbuf_check_and_select_verts(vc->em, select);
@@ -532,7 +533,7 @@ static void do_lasso_select_mesh(
mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
-
+
if (ts->selectmode & SCE_SELECT_FACE) {
if (bbsel) {
edbm_backbuf_check_and_select_faces(vc->em, select);
@@ -541,7 +542,7 @@ static void do_lasso_select_mesh(
mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
-
+
EDBM_backbuf_free();
EDBM_selectmode_flush(vc->em);
}
@@ -793,7 +794,7 @@ static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], sh
BLI_lasso_boundbox(&rect, mcords, moves);
EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
-
+
edbm_backbuf_check_and_select_tfaces(me, select);
EDBM_backbuf_free();
@@ -805,19 +806,19 @@ static void do_lasso_select_paintface(ViewContext *vc, const int mcords[][2], sh
static void do_lasso_select_node(int mcords[][2], short moves, const bool select)
{
SpaceNode *snode = sa->spacedata.first;
-
+
bNode *node;
rcti rect;
int node_cent[2];
float node_centf[2];
-
+
BLI_lasso_boundbox(&rect, mcords, moves);
-
+
/* store selection in temp test flag */
for (node = snode->edittree->nodes.first; node; node = node->next) {
node_centf[0] = BLI_RCT_CENTER_X(&node->totr);
node_centf[1] = BLI_RCT_CENTER_Y(&node->totr);
-
+
ipoco_to_areaco_noclip(G.v2d, node_centf, node_cent);
if (BLI_rcti_isect_pt_v(&rect, node_cent) && BLI_lasso_is_point_inside(mcords, moves, node_cent[0], node_cent[1])) {
if (select) {
@@ -898,18 +899,18 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
ViewContext vc;
int mcords_tot;
const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
-
+
if (mcords) {
bool extend, select;
view3d_operator_needs_opengl(C);
-
+
/* setup view context for argument to callbacks */
ED_view3d_viewcontext_init(C, &vc);
-
+
extend = RNA_boolean_get(op->ptr, "extend");
select = !RNA_boolean_get(op->ptr, "deselect");
view3d_lasso_select(C, &vc, mcords, mcords_tot, extend, select);
-
+
MEM_freeN((void *)mcords);
return OPERATOR_FINISHED;
@@ -922,16 +923,16 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot)
ot->name = "Lasso Select";
ot->description = "Select items using lasso selection";
ot->idname = "VIEW3D_OT_select_lasso";
-
+
ot->invoke = WM_gesture_lasso_invoke;
ot->modal = WM_gesture_lasso_modal;
ot->exec = view3d_lasso_select_exec;
ot->poll = view3d_selectable_data;
ot->cancel = WM_gesture_lasso_cancel;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_gesture_lasso_select(ot);
}
@@ -1261,7 +1262,7 @@ finally:
for (uint i = 0; i < hits; i++) {
if (((buffer4[i].data[3] & 0xFFFF0000) != 0) == is_pose_mode) {
if (i != j) {
- buffer4[i] = buffer4[j];
+ buffer4[j] = buffer4[i];
}
j++;
}
@@ -1281,12 +1282,12 @@ static Base *mouse_select_eval_buffer(
ViewLayer *view_layer = vc->view_layer;
Base *base, *basact = NULL;
int a;
-
+
if (do_nearest) {
unsigned int min = 0xFFFFFFFF;
int selcol = 0, notcol = 0;
-
-
+
+
if (has_bones) {
/* we skip non-bone hits */
for (a = 0; a < hits; a++) {
@@ -1301,7 +1302,7 @@ static Base *mouse_select_eval_buffer(
if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) && hits > 1) {
notcol = BASACT(view_layer)->object->select_color;
}
-
+
for (a = 0; a < hits; a++) {
if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) {
min = buffer[4 * a + 1];
@@ -1309,7 +1310,7 @@ static Base *mouse_select_eval_buffer(
}
}
}
-
+
base = FIRSTBASE(view_layer);
while (base) {
if (BASE_SELECTABLE(base)) {
@@ -1320,7 +1321,7 @@ static Base *mouse_select_eval_buffer(
if (base) basact = base;
}
else {
-
+
base = startbase;
while (base) {
/* skip objects with select restriction, to prevent prematurely ending this loop
@@ -1330,7 +1331,7 @@ static Base *mouse_select_eval_buffer(
if (base == NULL) base = FIRSTBASE(view_layer);
if (base == startbase) break;
}
-
+
if (BASE_SELECTABLE(base)) {
for (a = 0; a < hits; a++) {
if (has_bones) {
@@ -1346,15 +1347,15 @@ static Base *mouse_select_eval_buffer(
}
}
}
-
+
if (basact) break;
-
+
base = base->next;
if (base == NULL) base = FIRSTBASE(view_layer);
if (base == startbase) break;
}
}
-
+
return basact;
}
@@ -1366,19 +1367,19 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
unsigned int buffer[MAXPICKBUF];
int hits;
bool do_nearest;
-
+
/* setup view context for argument to callbacks */
view3d_operator_needs_opengl(C);
ED_view3d_viewcontext_init(C, &vc);
-
+
hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, false, false, &do_nearest);
-
+
if (hits > 0) {
const bool has_bones = selectbuffer_has_bones(buffer, hits);
basact = mouse_select_eval_buffer(&vc, buffer, hits, vc.view_layer->object_bases.first, has_bones, do_nearest);
}
-
+
return basact;
}
@@ -1433,11 +1434,11 @@ static bool ed_object_select_pick(
/* always start list from basact in wire mode */
startbase = FIRSTBASE(view_layer);
if (BASACT(view_layer) && BASACT(view_layer)->next) startbase = BASACT(view_layer)->next;
-
+
/* This block uses the control key to make the object selected by its center point rather than its contents */
/* in editmode do not activate */
if (obcenter) {
-
+
/* note; shift+alt goes to group-flush-selecting */
if (enumerate) {
basact = object_mouse_select_menu(C, &vc, NULL, 0, mval, toggle);
@@ -1460,7 +1461,7 @@ static bool ed_object_select_pick(
}
}
base = base->next;
-
+
if (base == NULL) base = FIRSTBASE(view_layer);
if (base == startbase) break;
}
@@ -1579,16 +1580,16 @@ static bool ed_object_select_pick(
view_layer, basact, buffer, hits, extend, deselect, toggle, do_nearest))
{
/* then bone is found */
-
- /* we make the armature selected:
+
+ /* we make the armature selected:
* not-selected active object in posemode won't work well for tools */
basact->flag |= BASE_SELECTED;
BKE_scene_object_base_flag_sync_from_base(basact);
-
+
retval = true;
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object);
-
+
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
if (BASACT(view_layer) && (BASACT(view_layer)->object->mode & OB_MODE_WEIGHT_PAINT)) {
/* prevent activating */
@@ -1620,7 +1621,7 @@ static bool ed_object_select_pick(
/* so, do we have something selected? */
if (basact) {
retval = true;
-
+
if (vc.obedit) {
/* only do select */
deselectall_except(view_layer, basact);
@@ -1827,7 +1828,7 @@ static void do_nurbs_box_select__doSelect(
static int do_nurbs_box_select(ViewContext *vc, rcti *rect, bool select, bool extend)
{
BoxSelectUserData data;
-
+
view3d_userdata_boxselect_init(&data, vc, rect, select);
if (extend == false && select) {
@@ -1861,7 +1862,7 @@ static int do_lattice_box_select(ViewContext *vc, rcti *rect, bool select, bool
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
-
+
return OPERATOR_FINISHED;
}
@@ -1906,7 +1907,7 @@ static int do_mesh_box_select(
BoxSelectUserData data;
ToolSettings *ts = vc->scene->toolsettings;
int bbsel;
-
+
view3d_userdata_boxselect_init(&data, vc, rect, select);
if (extend == false && select)
@@ -1937,7 +1938,7 @@ static int do_mesh_box_select(
mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
-
+
if (ts->selectmode & SCE_SELECT_FACE) {
if (bbsel) {
edbm_backbuf_check_and_select_faces(vc->em, select);
@@ -1946,11 +1947,11 @@ static int do_mesh_box_select(
mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
-
+
EDBM_backbuf_free();
-
+
EDBM_selectmode_flush(vc->em);
-
+
return OPERATOR_FINISHED;
}
@@ -1969,7 +1970,7 @@ static int do_meta_box_select(
if (extend == false && select)
BKE_mball_deselect_all(mb);
-
+
for (ml = mb->editelems->first; ml; ml = ml->next) {
for (a = 0; a < hits; a++) {
if (ml->selcol1 == buffer[(4 * a) + 3]) {
@@ -2120,12 +2121,12 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
int bone_only;
int totobj = MAXPICKBUF; /* XXX solve later */
int hits;
-
+
if (vc->obact && (vc->obact->mode & OB_MODE_POSE))
bone_only = 1;
else
bone_only = 0;
-
+
if (extend == false && select) {
if (bone_only) {
FOREACH_OBJECT_IN_MODE_BEGIN (vc->view_layer, OB_MODE_POSE, ob_iter) {
@@ -2231,7 +2232,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
/* mask modifier ('armature' mode), etc. */
DEG_id_tag_update(&vc->obact->id, OB_RECALC_DATA);
}
-
+
/* copy on write tag is needed (for the armature), or else no refresh happens */
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
@@ -2260,7 +2261,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
/* setup view context for argument to callbacks */
ED_view3d_viewcontext_init(C, &vc);
-
+
select = !RNA_boolean_get(op->ptr, "deselect");
extend = RNA_boolean_get(op->ptr, "extend");
WM_operator_properties_border_to_rcti(op, &rect);
@@ -2336,7 +2337,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
}
return ret;
-}
+}
/* *****************Selection Operators******************* */
@@ -2348,17 +2349,17 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->description = "Select items using border selection";
ot->idname = "VIEW3D_OT_select_border";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = view3d_borderselect_exec;
ot->modal = WM_gesture_border_modal;
ot->poll = view3d_selectable_data;
ot->cancel = WM_gesture_border_cancel;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* rna */
WM_operator_properties_gesture_border_select(ot);
}
@@ -2458,7 +2459,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
retval = ED_mball_select_pick(C, location, extend, deselect, toggle);
else if (obedit->type == OB_FONT)
retval = ED_curve_editfont_select_pick(C, location, extend, deselect, toggle);
-
+
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT)
return PE_mouse_particles(C, location, extend, deselect, toggle);
@@ -2493,15 +2494,15 @@ void VIEW3D_OT_select(wmOperatorType *ot)
ot->name = "Activate/Select";
ot->description = "Activate/select item(s)";
ot->idname = "VIEW3D_OT_select";
-
+
/* api callbacks */
ot->invoke = view3d_select_invoke;
ot->exec = view3d_select_exec;
ot->poll = ED_operator_view3d_active;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
WM_operator_properties_mouse_select(ot);
@@ -2576,7 +2577,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva
ToolSettings *ts = vc->scene->toolsettings;
int bbsel;
CircleSelectUserData data;
-
+
bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
@@ -2601,7 +2602,7 @@ static void mesh_circle_select(ViewContext *vc, const bool select, const int mva
mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
-
+
if (ts->selectmode & SCE_SELECT_FACE) {
if (bbsel) {
edbm_backbuf_check_and_select_faces(vc->em, select);
@@ -2794,11 +2795,11 @@ static void do_circle_select_pose__doSelectBone(
static void pose_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad)
{
CircleSelectUserData data;
-
+
view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
-
+
pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
if (data.is_changed) {
@@ -2810,7 +2811,7 @@ static void pose_circle_select(ViewContext *vc, const bool select, const int mva
/* mask modifier ('armature' mode), etc. */
DEG_id_tag_update(&vc->obact->id, OB_RECALC_DATA);
}
-
+
/* copy on write tag is needed (for the armature), or else no refresh happens */
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
@@ -2824,13 +2825,13 @@ static bool armature_circle_doSelectJoint(void *userData, EditBone *ebone, const
if (head) {
if (data->select)
ebone->flag |= BONE_ROOTSEL;
- else
+ else
ebone->flag &= ~BONE_ROOTSEL;
}
else {
if (data->select)
ebone->flag |= BONE_TIPSEL;
- else
+ else
ebone->flag &= ~BONE_TIPSEL;
}
return 1;
@@ -3030,7 +3031,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc.scene);
}
}
-
+
return OPERATOR_FINISHED;
}
@@ -3039,13 +3040,13 @@ void VIEW3D_OT_select_circle(wmOperatorType *ot)
ot->name = "Circle Select";
ot->description = "Select items using circle selection";
ot->idname = "VIEW3D_OT_select_circle";
-
+
ot->invoke = WM_gesture_circle_invoke;
ot->modal = WM_gesture_circle_modal;
ot->exec = view3d_circle_select_exec;
ot->poll = view3d_selectable_data;
ot->cancel = WM_gesture_circle_cancel;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index ac967e3c97c..606c07cd1fa 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -140,15 +140,15 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
if (ob->mode & OB_MODE_POSE) {
bPoseChannel *pchan_eval;
bArmature *arm_eval = ob_eval->data;
-
+
invert_m4_m4(ob_eval->imat, ob_eval->obmat);
-
+
for (pchan_eval = ob_eval->pose->chanbase.first; pchan_eval; pchan_eval = pchan_eval->next) {
if (pchan_eval->bone->flag & BONE_SELECTED) {
if (pchan_eval->bone->layer & arm_eval->layer) {
if ((pchan_eval->bone->flag & BONE_CONNECTED) == 0) {
float nLoc[3];
-
+
/* get nearest grid point to snap to */
copy_v3_v3(nLoc, pchan_eval->pose_mat[3]);
/* We must operate in world space! */
@@ -158,10 +158,10 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
vec[2] = gridf * floorf(0.5f + nLoc[2] / gridf);
/* Back in object space... */
mul_m4_v3(ob_eval->imat, vec);
-
+
/* Get location of grid point in pose space. */
BKE_armature_loc_pose_to_bone(pchan_eval, vec, vec);
-
+
/* adjust location on the original pchan*/
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, pchan_eval->name);
if ((pchan->protectflag & OB_LOCK_LOCX) == 0)
@@ -181,18 +181,18 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
}
}
ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
-
+
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
else {
vec[0] = -ob_eval->obmat[3][0] + gridf * floorf(0.5f + ob_eval->obmat[3][0] / gridf);
vec[1] = -ob_eval->obmat[3][1] + gridf * floorf(0.5f + ob_eval->obmat[3][1] / gridf);
vec[2] = -ob_eval->obmat[3][2] + gridf * floorf(0.5f + ob_eval->obmat[3][2] / gridf);
-
+
if (ob->parent) {
float originmat[3][3];
BKE_object_where_is_calc_ex(depsgraph, scene, NULL, ob, originmat);
-
+
invert_m3_m3(imat, originmat);
mul_m3_v3(imat, vec);
}
@@ -202,7 +202,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
ob->loc[1] = ob_eval->loc[1] + vec[1];
if ((ob->protectflag & OB_LOCK_LOCZ) == 0)
ob->loc[2] = ob_eval->loc[2] + vec[2];
-
+
/* auto-keyframing */
ED_autokeyframe_object(C, scene, ob, ks);
@@ -213,7 +213,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
}
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -223,11 +223,11 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
ot->name = "Snap Selection to Grid";
ot->description = "Snap selected item(s) to nearest grid division";
ot->idname = "VIEW3D_OT_snap_selected_to_grid";
-
+
/* api callbacks */
ot->exec = snap_sel_to_grid_exec;
ot->poll = ED_operator_region_view3d_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -262,7 +262,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
if (obedit) {
float snap_target_local[3];
-
+
if (ED_transverts_check_obedit(obedit))
ED_transverts_create_from_obedit(&tvs, obedit, 0);
if (tvs.transverts_tot == 0)
@@ -270,7 +270,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
copy_m3_m4(bmat, obedit->obmat);
invert_m3_m3(imat, bmat);
-
+
/* get the cursor in object space */
sub_v3_v3v3(snap_target_local, snap_target_global, obedit->obmat[3]);
mul_m3_v3(imat, snap_target_local);
@@ -291,7 +291,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
copy_v3_v3(tv->loc, snap_target_local);
}
}
-
+
ED_transverts_update_obedit(&tvs, obedit);
ED_transverts_free(&tvs);
}
@@ -423,7 +423,7 @@ static int snap_selected_to_location(bContext *C, const float snap_target_global
}
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -445,11 +445,11 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
ot->name = "Snap Selection to Cursor";
ot->description = "Snap selected item(s) to cursor";
ot->idname = "VIEW3D_OT_snap_selected_to_cursor";
-
+
/* api callbacks */
ot->exec = snap_selected_to_cursor_exec;
ot->poll = ED_operator_view3d_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -500,7 +500,7 @@ static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
curs[0] = gridf * floorf(0.5f + curs[0] / gridf);
curs[1] = gridf * floorf(0.5f + curs[1] / gridf);
curs[2] = gridf * floorf(0.5f + curs[2] / gridf);
-
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); /* hrm */
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
@@ -513,11 +513,11 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
ot->name = "Snap Cursor to Grid";
ot->description = "Snap cursor to nearest grid division";
ot->idname = "VIEW3D_OT_snap_cursor_to_grid";
-
+
/* api callbacks */
ot->exec = snap_curs_to_grid_exec;
ot->poll = ED_operator_region_view3d_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -602,7 +602,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
copy_m3_m4(bmat, obedit_eval->obmat);
-
+
tv = tvs.transverts;
for (a = 0; a < tvs.transverts_tot; a++, tv++) {
copy_v3_v3(vec, tv->loc);
@@ -611,7 +611,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
add_v3_v3(centroid, vec);
minmax_v3v3_v3(min, max, vec);
}
-
+
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEAN) {
mul_v3_fl(centroid, 1.0f / (float)tvs.transverts_tot);
copy_v3_v3(cursor, centroid);
@@ -701,11 +701,11 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
ot->name = "Snap Cursor to Selected";
ot->description = "Snap cursor to center of selected item(s)";
ot->idname = "VIEW3D_OT_snap_cursor_to_selected";
-
+
/* api callbacks */
ot->exec = snap_curs_to_sel_exec;
ot->poll = ED_operator_view3d_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -761,7 +761,7 @@ static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
float *curs;
-
+
curs = ED_view3d_cursor3d_get(scene, v3d)->location;
if (snap_calc_active_center(C, false, curs)) {
@@ -781,11 +781,11 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
ot->name = "Snap Cursor to Active";
ot->description = "Snap cursor to active item";
ot->idname = "VIEW3D_OT_snap_cursor_to_active";
-
+
/* api callbacks */
ot->exec = snap_curs_to_active_exec;
ot->poll = ED_operator_view3d_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -800,7 +800,7 @@ static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op))
curs = ED_view3d_cursor3d_get(scene, v3d)->location;
zero_v3(curs);
-
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
@@ -813,11 +813,11 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
ot->name = "Snap Cursor to Center";
ot->description = "Snap cursor to the Center";
ot->idname = "VIEW3D_OT_snap_cursor_to_center";
-
+
/* api callbacks */
ot->exec = snap_curs_to_center_exec;
ot->poll = ED_operator_view3d_active;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -847,12 +847,12 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3])
if (ED_transverts_check_obedit(obedit))
ED_transverts_create_from_obedit(&tvs, obedit, TM_ALL_JOINTS);
-
+
if (tvs.transverts_tot == 0)
return false;
copy_m3_m4(bmat, obedit->obmat);
-
+
tv = tvs.transverts;
for (a = 0; a < tvs.transverts_tot; a++, tv++) {
copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc);
@@ -861,8 +861,8 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3])
add_v3_v3(centroid, vec);
minmax_v3v3_v3(min, max, vec);
}
-
+
ED_transverts_free(&tvs);
-
+
return true;
}
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index fa683f95988..8ea33927c4d 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -73,15 +73,15 @@ typedef struct CustomTool {
static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
{
wmOperatorType *ot = arg2;
-
+
if (ot) {
CustomTool *ct = MEM_callocN(sizeof(CustomTool), "CustomTool");
-
+
BLI_addtail(arg_listbase, ct);
BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
BLI_strncpy(ct->context, CTX_data_mode_string(C), OP_MAX_TYPENAME);
}
-
+
}
static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
@@ -93,7 +93,7 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons
if (BLI_strcasestr(ot->name, str)) {
if (WM_operator_poll((bContext *)C, ot)) {
-
+
if (false == UI_search_item_add(items, ot->name, ot, 0))
break;
}
@@ -110,30 +110,30 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
wmWindow *win = CTX_wm_window(C);
uiBlock *block;
uiBut *but;
-
+
/* clear initial search string, then all items show */
search[0] = 0;
-
+
block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
-
+
/* fake button, it holds space for search items */
uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
-
+
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, "");
UI_but_func_search_set(but, NULL, operator_search_cb, arg_listbase, operator_call_cb, NULL);
-
+
UI_block_bounds_set_normal(block, 6);
UI_block_direction_set(block, UI_DIR_DOWN);
UI_block_end(C, block);
-
+
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
event.customdatafree = false;
wm_event_add(win, &event);
-
+
return block;
}
@@ -144,13 +144,13 @@ static void view3d_panel_tool_shelf(const bContext *C, Panel *pa)
SpaceType *st = NULL;
uiLayout *col;
const char *context = CTX_data_mode_string(C);
-
+
if (sl)
st = BKE_spacetype_from_id(sl->spacetype);
-
+
if (st && st->toolshelf.first) {
CustomTool *ct;
-
+
for (ct = st->toolshelf.first; ct; ct = ct->next) {
if (STREQLEN(context, ct->context, OP_MAX_TYPENAME)) {
col = uiLayoutColumn(pa->layout, true);
@@ -181,7 +181,7 @@ static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = view3d_has_tools_region(sa);
-
+
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -193,10 +193,10 @@ void VIEW3D_OT_toolshelf(wmOperatorType *ot)
ot->name = "Tool Shelf";
ot->description = "Toggles tool shelf display";
ot->idname = "VIEW3D_OT_toolshelf";
-
+
ot->exec = view3d_toolshelf_toggle_exec;
ot->poll = ED_operator_view3d_active;
-
+
/* flags */
ot->flag = 0;
}
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 8b0b461d443..ca5375b6b54 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -46,6 +46,7 @@
#include "BKE_camera.h"
#include "BKE_context.h"
+#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_screen.h"
@@ -899,7 +900,7 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
* \param fallback_depth_pt: Use this points depth when no depth can be found.
*/
bool ED_view3d_autodist(
- struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d,
+ Depsgraph *depsgraph, ARegion *ar, View3D *v3d,
const int mval[2], float mouse_worldloc[3],
const bool alphaoverride, const float fallback_depth_pt[3])
{
@@ -936,7 +937,7 @@ bool ED_view3d_autodist(
}
}
-void ED_view3d_autodist_init(struct Depsgraph *depsgraph,
+void ED_view3d_autodist_init(Depsgraph *depsgraph,
ARegion *ar, View3D *v3d, int mode)
{
/* Get Z Depths, needed for perspective, nice for ortho */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index c52a1714802..73b9a67ac56 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -181,11 +181,11 @@ void ED_view3d_smooth_view_ex(
ED_view3d_from_object(ob_camera_eval, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
sms.to_camera = true; /* restore view3d values in end */
}
-
+
/* skip smooth viewing for render engine draw */
if (smooth_viewtx && v3d->drawtype != OB_RENDER) {
bool changed = false; /* zero means no difference */
-
+
if (sview->camera_old != sview->camera)
changed = true;
else if (sms.dst.dist != rv3d->dist)
@@ -196,7 +196,7 @@ void ED_view3d_smooth_view_ex(
changed = true;
else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat))
changed = true;
-
+
/* The new view is different from the old one
* so animate the view */
if (changed) {
@@ -214,10 +214,10 @@ void ED_view3d_smooth_view_ex(
}
sms.time_allowed = (double)smooth_viewtx / 1000.0;
-
+
/* if this is view rotation only
* we can decrease the time allowed by
- * the angle between quats
+ * the angle between quats
* this means small rotations wont lag */
if (sview->quat && !sview->ofs && !sview->dist) {
/* scale the time allowed by the rotation */
@@ -235,7 +235,7 @@ void ED_view3d_smooth_view_ex(
}
rv3d->rflag |= RV3D_NAVIGATING;
-
+
/* not essential but in some cases the caller will tag the area for redraw,
* and in that case we can get a flicker of the 'org' user view but we want to see 'src' */
view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);
@@ -254,7 +254,7 @@ void ED_view3d_smooth_view_ex(
ok = true;
}
}
-
+
/* if we get here nothing happens */
if (ok == false) {
if (sms.to_camera == false) {
@@ -298,15 +298,15 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *ar, bool
RegionView3D *rv3d = ar->regiondata;
struct SmoothView3DStore *sms = rv3d->sms;
float step, step_inv;
-
+
if (sms->time_allowed != 0.0)
step = (float)((rv3d->smooth_timer->duration) / sms->time_allowed);
else
step = 1.0f;
-
+
/* end timer */
if (step >= 1.0f) {
-
+
/* if we went to camera, store the original */
if (sms->to_camera) {
rv3d->persp = RV3D_CAMOB;
@@ -318,14 +318,14 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *ar, bool
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
-
+
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
rv3d->view = sms->org_view;
}
MEM_freeN(rv3d->sms);
rv3d->sms = NULL;
-
+
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
rv3d->smooth_timer = NULL;
rv3d->rflag &= ~RV3D_NAVIGATING;
@@ -344,7 +344,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *ar, bool
else {
interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step);
}
-
+
rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
@@ -356,7 +356,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *ar, bool
/* Event handling won't know if a UI item has been moved under the pointer. */
WM_event_add_mousemove(C);
}
-
+
if (sync_boxview && (rv3d->viewlock & RV3D_BOXVIEW)) {
view3d_boxview_copy(CTX_wm_area(C), ar);
}
@@ -456,9 +456,9 @@ static int view3d_camera_to_view_exec(bContext *C, wmOperator *UNUSED(op))
DEG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
rv3d->persp = RV3D_CAMOB;
-
+
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, v3d->camera);
-
+
return OPERATOR_FINISHED;
}
@@ -488,11 +488,11 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
ot->name = "Align Camera To View";
ot->description = "Set camera view to active view";
ot->idname = "VIEW3D_OT_camera_to_view";
-
+
/* api callbacks */
ot->exec = view3d_camera_to_view_exec;
ot->poll = view3d_camera_to_view_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -659,7 +659,7 @@ static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
}
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
}
-
+
return OPERATOR_FINISHED;
}
@@ -677,11 +677,11 @@ void VIEW3D_OT_object_as_camera(wmOperatorType *ot)
ot->name = "Set Active Object as Camera";
ot->description = "Set the active object as the active camera for this view or scene";
ot->idname = "VIEW3D_OT_object_as_camera";
-
+
/* api callbacks */
ot->exec = view3d_setobjectascamera_exec;
ot->poll = ED_operator_rv3d_user_region_poll;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@@ -701,7 +701,7 @@ void view3d_winmatrix_set(Depsgraph *depsgraph, ARegion *ar, const View3D *v3d,
rctf viewplane;
float clipsta, clipend;
bool is_ortho;
-
+
is_ortho = ED_view3d_viewplane_get(depsgraph, v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend, NULL);
rv3d->is_persp = !is_ortho;
@@ -778,13 +778,13 @@ void view3d_viewmatrix_set(
/* should be moved to better initialize later on XXX */
if (rv3d->viewlock & RV3D_LOCKED)
ED_view3d_lock(rv3d);
-
+
quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
if (rv3d->persp == RV3D_PERSP) rv3d->viewmat[3][2] -= rv3d->dist;
if (v3d->ob_centre) {
Object *ob_eval = DEG_get_evaluated_object(depsgraph, v3d->ob_centre);
float vec[3];
-
+
copy_v3_v3(vec, ob_eval->obmat[3]);
if (ob_eval->type == OB_ARMATURE && v3d->ob_centre_bone[0]) {
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_eval->pose, v3d->ob_centre_bone);
@@ -984,7 +984,7 @@ int view3d_opengl_select(
if (vc->rv3d->rflag & RV3D_CLIPPING)
ED_view3d_clipping_set(vc->rv3d);
-
+
#ifdef WITH_OPENGL_LEGACY
if (IS_VIEWPORT_LEGACY(vc->v3d)) {
@@ -1021,12 +1021,12 @@ int view3d_opengl_select(
G.f &= ~G_PICKSEL;
ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
-
+
if (v3d->drawtype > OB_WIRE) {
v3d->zbuf = 0;
glDisable(GL_DEPTH_TEST);
}
-
+
if (vc->rv3d->rflag & RV3D_CLIPPING)
ED_view3d_clipping_disable();
@@ -1052,28 +1052,28 @@ finally:
int ED_view3d_view_layer_set(int lay, const int *values, int *active)
{
int i, tot = 0;
-
+
/* ensure we always have some layer selected */
for (i = 0; i < 20; i++)
if (values[i])
tot++;
-
+
if (tot == 0)
return lay;
-
+
for (i = 0; i < 20; i++) {
-
+
if (active) {
/* if this value has just been switched on, make that layer active */
if (values[i] && (lay & (1 << i)) == 0) {
*active = (1 << i);
}
}
-
+
if (values[i]) lay |= (1 << i);
else lay &= ~(1 << i);
}
-
+
/* ensure always an active layer */
if (active && (lay & *active) == 0) {
for (i = 0; i < 20; i++) {
@@ -1083,7 +1083,7 @@ int ED_view3d_view_layer_set(int lay, const int *values, int *active)
}
}
}
-
+
return lay;
}
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index a7c97ba4d4a..352e85703bc 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -37,6 +37,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_main.h"
#include "BKE_report.h"
#include "BLT_translation.h"
@@ -507,6 +508,7 @@ static float userdef_speed = -1.f;
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
wmWindow *win = CTX_wm_window(C);
walk->rv3d = CTX_wm_region_view3d(C);
@@ -602,7 +604,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->rv3d->rflag |= RV3D_NAVIGATING;
walk->snap_context = ED_transform_snap_object_context_create_view3d(
- walk->scene, CTX_data_depsgraph(C), 0,
+ bmain, walk->scene, CTX_data_depsgraph(C), 0,
walk->ar, walk->v3d);
walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index a4d08b15a6d..b4f7e9256a3 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1520,7 +1520,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
/* confirm transform if launch key is released after mouse move */
if (t->flag & T_RELEASE_CONFIRM) {
/* XXX Keyrepeat bug in Xorg messes this up, will test when fixed */
- if (event->type == t->launch_event && (t->launch_event == LEFTMOUSE || t->launch_event == RIGHTMOUSE)) {
+ if ((event->type == t->launch_event) && ISMOUSE(t->launch_event)) {
t->state = TRANS_CONFIRM;
}
}
@@ -2140,14 +2140,8 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->mode = mode;
- t->launch_event = event ? event->type : -1;
-
- if (t->launch_event == EVT_TWEAK_R) {
- t->launch_event = RIGHTMOUSE;
- }
- else if (t->launch_event == EVT_TWEAK_L) {
- t->launch_event = LEFTMOUSE;
- }
+ /* Needed to translate tweak events to mouse buttons. */
+ t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1;
// XXX Remove this when wm_operator_call_internal doesn't use window->eventstate (which can have type = 0)
// For manipulator only, so assume LEFTMOUSE
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index b9f42a0d9fc..419f400df53 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -722,7 +722,7 @@ int special_transform_moving(TransInfo *t);
void transform_autoik_update(TransInfo *t, short mode);
bool transdata_check_local_islands(TransInfo *t, short around);
-int count_set_pose_transflags(int *out_mode, short around, struct Object *ob);
+int count_set_pose_transflags(struct Object *ob, const int mode, const short around, bool has_translate_rotate[2]);
/* auto-keying stuff used by special_aftertrans_update */
void autokeyframe_ob_cb_func(
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 8bfe14dc6ea..6c608a0b5e4 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -574,17 +574,14 @@ static short apply_targetless_ik(Object *ob)
return apply;
}
-static void add_pose_transdata(
- TransInfo *t, Object *ob, bPoseChannel *pchan,
- Object *ob_eval, bPoseChannel *pchan_eval,
- TransDataContainer *tc, TransData *td)
+static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td)
{
- Bone *bone = pchan_eval->bone;
+ Bone *bone = pchan->bone;
float pmat[3][3], omat[3][3];
float cmat[3][3], tmat[3][3];
float vec[3];
- copy_v3_v3(vec, pchan_eval->pose_mat[3]);
+ copy_v3_v3(vec, pchan->pose_mat[3]);
copy_v3_v3(td->center, vec);
td->ob = ob;
@@ -601,10 +598,10 @@ static void add_pose_transdata(
td->protectflag = pchan->protectflag;
td->loc = pchan->loc;
- copy_v3_v3(td->iloc, pchan_eval->loc);
+ copy_v3_v3(td->iloc, pchan->loc);
td->ext->size = pchan->size;
- copy_v3_v3(td->ext->isize, pchan_eval->size);
+ copy_v3_v3(td->ext->isize, pchan->size);
if (pchan->rotmode > 0) {
td->ext->rot = pchan->eul;
@@ -612,7 +609,7 @@ static void add_pose_transdata(
td->ext->rotAngle = NULL;
td->ext->quat = NULL;
- copy_v3_v3(td->ext->irot, pchan_eval->eul);
+ copy_v3_v3(td->ext->irot, pchan->eul);
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
td->ext->rot = NULL;
@@ -620,8 +617,8 @@ static void add_pose_transdata(
td->ext->rotAngle = &pchan->rotAngle;
td->ext->quat = NULL;
- td->ext->irotAngle = pchan_eval->rotAngle;
- copy_v3_v3(td->ext->irotAxis, pchan_eval->rotAxis);
+ td->ext->irotAngle = pchan->rotAngle;
+ copy_v3_v3(td->ext->irotAxis, pchan->rotAxis);
}
else {
td->ext->rot = NULL;
@@ -629,20 +626,20 @@ static void add_pose_transdata(
td->ext->rotAngle = NULL;
td->ext->quat = pchan->quat;
- copy_qt_qt(td->ext->iquat, pchan_eval->quat);
+ copy_qt_qt(td->ext->iquat, pchan->quat);
}
td->ext->rotOrder = pchan->rotmode;
/* proper way to get parent transform + own transform + constraints transform */
- copy_m3_m4(omat, ob_eval->obmat);
+ copy_m3_m4(omat, ob->obmat);
/* New code, using "generic" BKE_pchan_to_pose_mat(). */
{
float rotscale_mat[4][4], loc_mat[4][4];
float rpmat[3][3];
- BKE_pchan_to_pose_mat(pchan_eval, rotscale_mat, loc_mat);
+ BKE_pchan_to_pose_mat(pchan, rotscale_mat, loc_mat);
if (t->mode == TFM_TRANSLATION)
copy_m3_m4(pmat, loc_mat);
else
@@ -655,7 +652,7 @@ static void add_pose_transdata(
copy_m3_m4(rpmat, rotscale_mat);
if (constraints_list_needinv(t, &pchan->constraints)) {
- copy_m3_m4(tmat, pchan_eval->constinv);
+ copy_m3_m4(tmat, pchan->constinv);
invert_m3_m3(cmat, tmat);
mul_m3_series(td->mtx, cmat, omat, pmat);
mul_m3_series(td->ext->r_mtx, cmat, omat, rpmat);
@@ -675,7 +672,7 @@ static void add_pose_transdata(
if (pchan->parent) {
/* same as td->smtx but without pchan->bone->bone_mat */
td->flag |= TD_PBONE_LOCAL_MTX_C;
- mul_m3_m3m3(td->ext->l_smtx, pchan_eval->bone->bone_mat, td->smtx);
+ mul_m3_m3m3(td->ext->l_smtx, pchan->bone->bone_mat, td->smtx);
}
else {
td->flag |= TD_PBONE_LOCAL_MTX_P;
@@ -683,7 +680,7 @@ static void add_pose_transdata(
}
/* for axismat we use bone's own transform */
- copy_m3_m4(pmat, pchan_eval->pose_mat);
+ copy_m3_m4(pmat, pchan->pose_mat);
mul_m3_m3m3(td->axismtx, omat, pmat);
normalize_m3(td->axismtx);
@@ -708,10 +705,10 @@ static void add_pose_transdata(
bKinematicConstraint *data = has_targetless_ik(pchan);
if (data) {
if (data->flag & CONSTRAINT_IK_TIP) {
- copy_v3_v3(data->grabtarget, pchan_eval->pose_tail);
+ copy_v3_v3(data->grabtarget, pchan->pose_tail);
}
else {
- copy_v3_v3(data->grabtarget, pchan_eval->pose_head);
+ copy_v3_v3(data->grabtarget, pchan->pose_head);
}
td->loc = data->grabtarget;
copy_v3_v3(td->iloc, td->loc);
@@ -751,12 +748,11 @@ static void bone_children_clear_transflag(int mode, short around, ListBase *lb)
/* sets transform flags in the bones
* returns total number of bones with BONE_TRANSFORM */
-int count_set_pose_transflags(int *out_mode, short around, Object *ob)
+int count_set_pose_transflags(Object *ob, const int mode, short around, bool has_translate_rotate[2])
{
bArmature *arm = ob->data;
bPoseChannel *pchan;
Bone *bone;
- int mode = *out_mode;
int total = 0;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
@@ -784,43 +780,30 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob)
}
}
/* now count, and check if we have autoIK or have to switch from translate to rotate */
- bool has_translation = false, has_rotation = false;
-
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
if (bone->flag & BONE_TRANSFORM) {
total++;
- if (mode == TFM_TRANSLATION) {
+ if (has_translate_rotate != NULL) {
if (has_targetless_ik(pchan) == NULL) {
if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) {
- if (pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM)
- has_translation = true;
+ if (pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
+ has_translate_rotate[0] = true;
+ }
}
else {
- if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC)
- has_translation = true;
+ if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) {
+ has_translate_rotate[0] = true;
+ }
+ }
+ if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT) {
+ has_translate_rotate[1] = true;
}
- if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT)
- has_rotation = true;
}
- else
- has_translation = true;
- }
- }
- }
-
- /* only modify transform mode if there are bones here that do something...
- * otherwise we get problems when multiple objects are selected
- */
- if (total) {
- /* if there are no translatable bones, do rotation */
- if (mode == TFM_TRANSLATION && !has_translation) {
- if (has_rotation) {
- *out_mode = TFM_ROTATION;
- }
- else {
- *out_mode = TFM_RESIZE;
+ else {
+ has_translate_rotate[1] = true;
+ }
}
}
}
@@ -868,6 +851,8 @@ static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
/* change the chain-length of auto-ik */
void transform_autoik_update(TransInfo *t, short mode)
{
+ Main *bmain = CTX_data_main(t->context);
+
short *chainlen = &t->settings->autoik_chainlen;
bPoseChannel *pchan;
@@ -904,12 +889,12 @@ void transform_autoik_update(TransInfo *t, short mode)
if (changed) {
/* TODO(sergey): Consider doing partial update only. */
- DEG_relations_tag_update(G.main);
+ DEG_relations_tag_update(bmain);
}
}
/* frees temporal IKs */
-static void pose_grab_with_ik_clear(Object *ob)
+static void pose_grab_with_ik_clear(Main *bmain, Object *ob)
{
bKinematicConstraint *data;
bPoseChannel *pchan;
@@ -947,7 +932,7 @@ static void pose_grab_with_ik_clear(Object *ob)
if (relations_changed) {
/* TODO(sergey): Consider doing partial update only. */
- DEG_relations_tag_update(G.main);
+ DEG_relations_tag_update(bmain);
}
}
@@ -1055,7 +1040,7 @@ static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
}
/* main call which adds temporal IK chains */
-static short pose_grab_with_ik(Object *ob)
+static short pose_grab_with_ik(Main *bmain, Object *ob)
{
bArmature *arm;
bPoseChannel *pchan, *parent;
@@ -1101,8 +1086,8 @@ static short pose_grab_with_ik(Object *ob)
/* iTaSC needs clear for new IK constraints */
if (tot_ik) {
BIK_clear_data(ob->pose);
- /* TODO(sergey): Consuder doing partial update only. */
- DEG_relations_tag_update(G.main);
+ /* TODO(sergey): Consider doing partial update only. */
+ DEG_relations_tag_update(bmain);
}
return (tot_ik) ? 1 : 0;
@@ -1125,18 +1110,18 @@ static void createTransPose(TransInfo *t, Object **objects, uint objects_len)
tc->poseobj = objects[th_index];
}
}
+ Main *bmain = CTX_data_main(t->context);
t->data_len_all = 0;
+ bool has_translate_rotate_buf[2] = {false, false};
+ bool *has_translate_rotate = (t->mode == TFM_TRANSLATION) ? has_translate_rotate_buf : NULL;
+
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
Object *ob = tc->poseobj;
bArmature *arm;
- TransData *td;
- TransDataExtension *tdx;
short ik_on = 0;
- int i;
-
/* check validity of state */
arm = BKE_armature_from_object(tc->poseobj);
@@ -1153,16 +1138,34 @@ static void createTransPose(TransInfo *t, Object **objects, uint objects_len)
/* do we need to add temporal IK chains? */
if ((arm->flag & ARM_AUTO_IK) && t->mode == TFM_TRANSLATION) {
- ik_on = pose_grab_with_ik(ob);
+ ik_on = pose_grab_with_ik(bmain, ob);
if (ik_on) t->flag |= T_AUTOIK;
}
/* set flags and count total (warning, can change transform to rotate) */
- tc->data_len = count_set_pose_transflags(&t->mode, t->around, ob);
+ tc->data_len = count_set_pose_transflags(ob, t->mode, t->around, has_translate_rotate);
+ /* len may be zero, skip next iteration. */
+ }
+
+ /* if there are no translatable bones, do rotation */
+ if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) {
+ if (has_translate_rotate[1]) {
+ t->mode = TFM_ROTATION;
+ }
+ else {
+ t->mode = TFM_RESIZE;
+ }
+ }
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
if (tc->data_len == 0) {
continue;
}
+ Object *ob = tc->poseobj;
+ TransData *td;
+ TransDataExtension *tdx;
+ short ik_on = 0;
+ int i;
tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
@@ -1178,7 +1181,7 @@ static void createTransPose(TransInfo *t, Object **objects, uint objects_len)
td = tc->data;
for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->flag & BONE_TRANSFORM) {
- add_pose_transdata(t, ob, pchan, ob, pchan, tc, td);
+ add_pose_transdata(t, pchan, ob, tc, td);
td++;
}
}
@@ -5619,18 +5622,17 @@ static bool constraints_list_needinv(TransInfo *t, ListBase *list)
/* transcribe given object into TransData for Transforming */
static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
{
- Depsgraph *depsgraph = t->depsgraph;
Scene *scene = t->scene;
bool constinv;
bool skip_invert = false;
if (t->mode != TFM_DUMMY && ob->rigidbody_object) {
float rot[3][3], scale[3];
- float ctime = DEG_get_ctime(depsgraph);
+ float ctime = BKE_scene_frame_get(scene);
/* only use rigid body transform if simulation is running, avoids problems with initial setup of rigid bodies */
- // XXX: This needs fixing for COW. May need rigidbody_world from scene
if (BKE_rigidbody_check_sim_running(scene->rigidbody_world, ctime)) {
+
/* save original object transform */
copy_v3_v3(td->ext->oloc, ob->loc);
@@ -5665,26 +5667,21 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
constinv = constraints_list_needinv(t, &ob->constraints);
/* disable constraints inversion for dummy pass */
- // XXX: Should this use ob or ob_eval?! It's not clear!
if (t->mode == TFM_DUMMY)
skip_invert = true;
- Scene *scene_eval = DEG_get_evaluated_scene(t->depsgraph);
if (skip_invert == false && constinv == false) {
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- ob_eval->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc_time checks this */
- BKE_object_where_is_calc(t->depsgraph, scene_eval, ob_eval);
- ob_eval->transflag &= ~OB_NO_CONSTRAINTS;
- }
- else {
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- BKE_object_where_is_calc(t->depsgraph, scene_eval, ob_eval);
+ ob->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc_time checks this */
+ BKE_object_where_is_calc(t->depsgraph, t->scene, ob);
+ ob->transflag &= ~OB_NO_CONSTRAINTS;
}
+ else
+ BKE_object_where_is_calc(t->depsgraph, t->scene, ob);
td->ob = ob;
td->loc = ob->loc;
- copy_v3_v3(td->iloc, ob->loc);
+ copy_v3_v3(td->iloc, td->loc);
if (ob->rotmode > 0) {
td->ext->rot = ob->rot;
@@ -5782,8 +5779,7 @@ static void trans_object_base_deps_flag_finish(ViewLayer *view_layer)
/* it deselects Bases, so we have to call the clear function always after */
static void set_trans_object_base_flags(TransInfo *t)
{
- /* TODO(sergey): Get rid of global, use explicit main. */
- Main *bmain = G.main;
+ Main *bmain = CTX_data_main(t->context);
ViewLayer *view_layer = t->view_layer;
Scene *scene = t->scene;
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
@@ -5929,6 +5925,7 @@ static void clear_trans_object_base_flags(TransInfo *t)
// NOTE: context may not always be available, so must check before using it as it's a luxury for a few cases
void autokeyframe_ob_cb_func(bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, int tmode)
{
+ Main *bmain = CTX_data_main(C);
ID *id = &ob->id;
FCurve *fcu;
@@ -5961,7 +5958,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, ViewLayer *view_layer, O
if (adt && adt->action) {
for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) {
fcu->flag &= ~FCURVE_SELECTED;
- insert_keyframe(depsgraph, reports, id, adt->action,
+ insert_keyframe(bmain, depsgraph, reports, id, adt->action,
(fcu->grp ? fcu->grp->name : NULL),
fcu->rna_path, fcu->array_index, cfra,
ts->keyframe_type, flag);
@@ -6050,6 +6047,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, ViewLayer *view_layer, O
// NOTE: context may not always be available, so must check before using it as it's a luxury for a few cases
void autokeyframe_pose_cb_func(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
{
+ Main *bmain = CTX_data_main(C);
ID *id = &ob->id;
AnimData *adt = ob->adt;
bAction *act = (adt) ? adt->action : NULL;
@@ -6103,7 +6101,7 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, Object *ob, int tmode,
* NOTE: this will do constraints too, but those are ok to do here too?
*/
if (pchanName && STREQ(pchanName, pchan->name)) {
- insert_keyframe(depsgraph, reports, id, act,
+ insert_keyframe(bmain, depsgraph, reports, id, act,
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path, fcu->array_index, cfra,
ts->keyframe_type, flag);
@@ -6333,6 +6331,9 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
* */
void special_aftertrans_update(bContext *C, TransInfo *t)
{
+ Main *bmain = CTX_data_main(t->context);
+ BLI_assert(bmain == CTX_data_main(C));
+
Object *ob;
// short redrawipo=0, resetslowpar=1;
const bool canceled = (t->state == TRANS_CANCEL);
@@ -6428,7 +6429,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
if (canceled == 0) {
ED_node_post_apply_transform(C, snode->edittree);
- ED_node_link_insert(t->sa);
+ ED_node_link_insert(bmain, t->sa);
}
/* clear link line */
@@ -6521,7 +6522,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
// XXX: BAD! this get gpencil datablocks directly from main db...
// but that's how this currently works :/
- for (gpd = G.main->gpencil.first; gpd; gpd = gpd->id.next) {
+ for (gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
if (ID_REAL_USERS(gpd))
posttrans_gpd_clean(gpd);
}
@@ -6541,7 +6542,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
// XXX: BAD! this get gpencil datablocks directly from main db...
// but that's how this currently works :/
- for (mask = G.main->mask.first; mask; mask = mask->id.next) {
+ for (mask = bmain->mask.first; mask; mask = mask->id.next) {
if (ID_REAL_USERS(mask))
posttrans_mask_clean(mask);
}
@@ -6690,8 +6691,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
}
/* set BONE_TRANSFORM flags for autokey, manipulator draw might have changed them */
- if (!canceled && (t->mode != TFM_DUMMY))
- count_set_pose_transflags(&t->mode, t->around, ob);
+ if (!canceled && (t->mode != TFM_DUMMY)) {
+ count_set_pose_transflags(ob, t->mode, t->around, NULL);
+ }
/* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
if (!canceled && t->mode == TFM_TRANSLATION)
@@ -6705,7 +6707,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
}
if (t->mode == TFM_TRANSLATION)
- pose_grab_with_ik_clear(ob);
+ pose_grab_with_ik_clear(bmain, ob);
/* automatic inserting of keys and unkeyed tagging - only if transform wasn't canceled (or TFM_DUMMY) */
if (!canceled && (t->mode != TFM_DUMMY)) {
@@ -8451,6 +8453,7 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_ACTION) {
t->flag |= T_POINTS | T_2D_EDIT;
+ t->obedit_type = -1;
createTransActionData(C, t);
countAndCleanTransDataContainer(t);
@@ -8463,17 +8466,23 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_NLA) {
t->flag |= T_POINTS | T_2D_EDIT;
+ t->obedit_type = -1;
+
createTransNlaData(C, t);
countAndCleanTransDataContainer(t);
}
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 transformations */
createTransSeqData(C, t);
countAndCleanTransDataContainer(t);
}
else if (t->spacetype == SPACE_IPO) {
t->flag |= T_POINTS | T_2D_EDIT;
+ t->obedit_type = -1;
+
createTransGraphEditData(C, t);
countAndCleanTransDataContainer(t);
@@ -8485,6 +8494,7 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_NODE) {
t->flag |= T_POINTS | T_2D_EDIT;
+ t->obedit_type = -1;
createTransNodeData(C, t);
countAndCleanTransDataContainer(t);
@@ -8497,6 +8507,8 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_CLIP) {
t->flag |= T_POINTS | T_2D_EDIT;
+ t->obedit_type = -1;
+
if (t->options & CTX_MOVIECLIP) {
createTransTrackingData(C, t);
countAndCleanTransDataContainer(t);
@@ -8598,7 +8610,10 @@ void createTransData(bContext *C, TransInfo *t)
countAndCleanTransDataContainer(t);
}
}
-
+ }
+ /* Mark as initialized if above checks fail. */
+ if (t->data_len_all == -1) {
+ t->data_len_all = 0;
}
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, ob))) {
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 576bfddd28c..d3fcd5e5911 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -359,6 +359,7 @@ static void recalcData_actedit(TransInfo *t)
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
+ ac.bmain = CTX_data_main(t->context);
ac.scene = t->scene;
ac.view_layer = t->view_layer;
ac.obact = OBACT(view_layer);
@@ -386,7 +387,7 @@ static void recalcData_actedit(TransInfo *t)
if ((saction->flag & SACTION_NOREALTIMEUPDATES) == 0) {
for (ale = anim_data.first; ale; ale = ale->next) {
/* set refresh tags for objects using this animation */
- ANIM_list_elem_update(t->scene, ale);
+ ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale);
}
}
@@ -409,6 +410,7 @@ static void recalcData_graphedit(TransInfo *t)
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
+ ac.bmain = CTX_data_main(t->context);
ac.scene = t->scene;
ac.view_layer = t->view_layer;
ac.obact = OBACT(view_layer);
@@ -445,7 +447,7 @@ static void recalcData_graphedit(TransInfo *t)
* BUT only if realtime updates are enabled
*/
if ((sipo->flag & SIPO_NOREALTIMEUPDATES) == 0)
- ANIM_list_elem_update(t->scene, ale);
+ ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale);
}
/* do resort and other updates? */
diff --git a/source/blender/editors/transform/transform_manipulator_3d.c b/source/blender/editors/transform/transform_manipulator_3d.c
index b94ccf42325..b6782470f96 100644
--- a/source/blender/editors/transform/transform_manipulator_3d.c
+++ b/source/blender/editors/transform/transform_manipulator_3d.c
@@ -586,7 +586,6 @@ int ED_transform_calc_manipulator_stats(
const struct TransformCalcParams *params,
struct TransformBounds *tbounds)
{
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -596,8 +595,6 @@ int ED_transform_calc_manipulator_stats(
RegionView3D *rv3d = ar->regiondata;
Base *base;
Object *ob = OBACT(view_layer);
- Object *ob_eval = NULL;
- Object *obedit_eval = NULL;
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
int a, totsel = 0;
@@ -612,9 +609,6 @@ int ED_transform_calc_manipulator_stats(
rv3d->twdrawflag = 0xFFFF;
- ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
-
/* global, local or normal orientation?
* if we could check 'totsel' now, this should be skipped with no selection. */
if (ob && !is_gp_edit) {
@@ -629,7 +623,7 @@ int ED_transform_calc_manipulator_stats(
case V3D_MANIP_GIMBAL:
{
float mat[3][3];
- if (gimbal_axis(ob_eval, mat)) {
+ if (gimbal_axis(ob, mat)) {
copy_m4_m3(rv3d->twmat, mat);
break;
}
@@ -659,7 +653,7 @@ int ED_transform_calc_manipulator_stats(
copy_m4_m3(rv3d->twmat, mat);
break;
}
- copy_m4_m4(rv3d->twmat, ob_eval->obmat);
+ copy_m4_m4(rv3d->twmat, ob->obmat);
normalize_m4(rv3d->twmat);
break;
}
@@ -699,7 +693,7 @@ int ED_transform_calc_manipulator_stats(
copy_m3_m4(tbounds->axis, rv3d->twmat);
if (params->use_local_axis && (ob && ob->mode & OB_MODE_EDIT)) {
float diff_mat[3][3];
- copy_m3_m4(diff_mat, ob_eval->obmat);
+ copy_m3_m4(diff_mat, ob->obmat);
normalize_m3(diff_mat);
invert_m3(diff_mat);
mul_m3_m3m3(tbounds->axis, tbounds->axis, diff_mat);
@@ -762,7 +756,6 @@ int ED_transform_calc_manipulator_stats(
}
else if (obedit) {
ob = obedit;
- ob_eval = obedit_eval;
if (obedit->type == OB_MESH) {
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMEditSelection ese;
@@ -937,9 +930,9 @@ int ED_transform_calc_manipulator_stats(
/* selection center */
if (totsel) {
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
- mul_m4_v3(obedit_eval->obmat, tbounds->center);
- mul_m4_v3(obedit_eval->obmat, tbounds->min);
- mul_m4_v3(obedit_eval->obmat, tbounds->max);
+ mul_m4_v3(obedit->obmat, tbounds->center);
+ mul_m4_v3(obedit->obmat, tbounds->min);
+ mul_m4_v3(obedit->obmat, tbounds->max);
}
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
@@ -947,7 +940,7 @@ int ED_transform_calc_manipulator_stats(
int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed
bool ok = false;
- if ((pivot_point == V3D_AROUND_ACTIVE) && (pchan = BKE_pose_channel_active(ob_eval))) {
+ if ((pivot_point == V3D_AROUND_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) {
/* doesn't check selection or visibility intentionally */
Bone *bone = pchan->bone;
if (bone) {
@@ -958,11 +951,11 @@ int ED_transform_calc_manipulator_stats(
}
}
else {
- totsel = count_set_pose_transflags(&mode, 0, ob_eval);
+ totsel = count_set_pose_transflags(ob, mode, V3D_AROUND_CENTER_BOUNDS, NULL);
if (totsel) {
/* use channels to get stats */
- for (pchan = ob_eval->pose->chanbase.first; pchan; pchan = pchan->next) {
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
Bone *bone = pchan->bone;
if (bone && (bone->flag & BONE_TRANSFORM)) {
calc_tw_center(tbounds, pchan->pose_head);
@@ -975,9 +968,9 @@ int ED_transform_calc_manipulator_stats(
if (ok) {
mul_v3_fl(tbounds->center, 1.0f / (float)totsel); // centroid!
- mul_m4_v3(ob_eval->obmat, tbounds->center);
- mul_m4_v3(ob_eval->obmat, tbounds->min);
- mul_m4_v3(ob_eval->obmat, tbounds->max);
+ mul_m4_v3(ob->obmat, tbounds->center);
+ mul_m4_v3(ob->obmat, tbounds->min);
+ mul_m4_v3(ob->obmat, tbounds->max);
}
}
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
@@ -1018,18 +1011,16 @@ int ED_transform_calc_manipulator_stats(
if (!TESTBASELIB(base)) {
continue;
}
- Object *base_object_eval = DEG_get_evaluated_object(depsgraph, base->object);
if (ob == NULL) {
ob = base->object;
- ob_eval = base_object_eval;
}
- if (params->use_only_center || base_object_eval->bb == NULL) {
- calc_tw_center(tbounds, base_object_eval->obmat[3]);
+ if (params->use_only_center || base->object->bb == NULL) {
+ calc_tw_center(tbounds, base->object->obmat[3]);
}
else {
for (uint j = 0; j < 8; j++) {
float co[3];
- mul_v3_m4v3(co, base_object_eval->obmat, base_object_eval->bb->vec[j]);
+ mul_v3_m4v3(co, base->object->obmat, base->object->bb->vec[j]);
calc_tw_center(tbounds, co);
}
}
@@ -1547,12 +1538,6 @@ static void WIDGETGROUP_manipulator_draw_prepare(const bContext *C, wmManipulato
static bool WIDGETGROUP_manipulator_poll(const struct bContext *C, struct wmManipulatorGroupType *wgt)
{
/* it's a given we only use this in 3D view */
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = sa->spacedata.first;
- if (v3d && ((v3d->twflag & V3D_MANIPULATOR_DRAW)) == 0) {
- return false;
- }
-
bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
if ((tref_rt == NULL) ||
!STREQ(wgt->idname, tref_rt->manipulator_group))
@@ -1593,12 +1578,6 @@ struct XFormCageWidgetGroup {
static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmManipulatorGroupType *wgt)
{
- ScrArea *sa = CTX_wm_area(C);
- View3D *v3d = sa->spacedata.first;
- if (v3d && ((v3d->twflag & V3D_MANIPULATOR_DRAW)) == 0) {
- return false;
- }
-
bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C);
if (!STREQ(wgt->idname, tref_rt->manipulator_group)) {
WM_manipulator_group_type_unlink_delayed_ptr(wgt);
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 3065007ea6b..19df46455d7 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -56,8 +56,6 @@
#include "BKE_scene.h"
#include "BKE_workspace.h"
-#include "DEG_depsgraph_query.h"
-
#include "BLT_translation.h"
#include "ED_armature.h"
@@ -1016,14 +1014,12 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
}
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- const Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- bArmature *arm = ob_eval->data;
+ bArmature *arm = ob->data;
bPoseChannel *pchan;
float imat[3][3], mat[3][3];
bool ok = false;
- if (activeOnly && (pchan = BKE_pose_channel_active(ob_eval))) {
+ if (activeOnly && (pchan = BKE_pose_channel_active(ob))) {
add_v3_v3(normal, pchan->pose_mat[2]);
add_v3_v3(plane, pchan->pose_mat[1]);
ok = true;
@@ -1034,7 +1030,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
totsel = count_bone_select(arm, &arm->bonebase, true);
if (totsel) {
/* use channels to get stats */
- for (pchan = ob_eval->pose->chanbase.first; pchan; pchan = pchan->next) {
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
add_v3_v3(normal, pchan->pose_mat[2]);
add_v3_v3(plane, pchan->pose_mat[1]);
@@ -1047,7 +1043,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
/* use for both active & all */
if (ok) {
/* we need the transpose of the inverse for a normal... */
- copy_m3_m4(imat, ob_eval->obmat);
+ copy_m3_m4(imat, ob->obmat);
invert_m3_m3(mat, imat);
transpose_m3(mat);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 10de7f3ea36..704582deaca 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -406,6 +406,11 @@ void applyGridAbsolute(TransInfo *t)
void applySnapping(TransInfo *t, float *vec)
{
+ if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) {
+ /* Each Trans Data already makes the snap to face */
+ return;
+ }
+
if (t->tsnap.status & SNAP_FORCED) {
t->tsnap.targetSnap(t);
@@ -495,6 +500,7 @@ static bool bm_face_is_snap_target(BMFace *f, void *UNUSED(user_data))
static void initSnappingMode(TransInfo *t)
{
+ Main *bmain = CTX_data_main(t->context);
ToolSettings *ts = t->settings;
/* All obedit types will match. */
const int obedit_type = t->data_container->obedit ? t->data_container->obedit->type : -1;
@@ -582,7 +588,7 @@ static void initSnappingMode(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) {
if (t->tsnap.object_context == NULL) {
t->tsnap.object_context = ED_transform_snap_object_context_create_view3d(
- t->scene, t->depsgraph, 0, t->ar, t->view);
+ bmain, t->scene, t->depsgraph, 0, t->ar, t->view);
ED_transform_snap_object_context_set_editmesh_callbacks(
t->tsnap.object_context,
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 5932a35bf2b..e19320fa220 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -56,6 +56,7 @@
#include "BKE_tracking.h"
#include "BKE_context.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -113,6 +114,7 @@ typedef struct SnapObjectData_EditMesh {
} SnapObjectData_EditMesh;
struct SnapObjectContext {
+ Main *bmain;
Scene *scene;
Depsgraph *depsgraph;
@@ -2269,12 +2271,13 @@ static short snapObjectsRay(
* \{ */
SnapObjectContext *ED_transform_snap_object_context_create(
- Scene *scene, Depsgraph *depsgraph, int flag)
+ Main *bmain, Scene *scene, Depsgraph *depsgraph, int flag)
{
SnapObjectContext *sctx = MEM_callocN(sizeof(*sctx), __func__);
sctx->flag = flag;
+ sctx->bmain = bmain;
sctx->scene = scene;
sctx->depsgraph = depsgraph;
@@ -2285,11 +2288,11 @@ SnapObjectContext *ED_transform_snap_object_context_create(
}
SnapObjectContext *ED_transform_snap_object_context_create_view3d(
- Scene *scene, Depsgraph *depsgraph, int flag,
+ Main *bmain, Scene *scene, Depsgraph *depsgraph, int flag,
/* extra args for view3d */
const ARegion *ar, const View3D *v3d)
{
- SnapObjectContext *sctx = ED_transform_snap_object_context_create(scene, depsgraph, flag);
+ SnapObjectContext *sctx = ED_transform_snap_object_context_create(bmain, scene, depsgraph, flag);
sctx->use_v3d = true;
sctx->v3d_data.ar = ar;
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 3950b056e89..d2ac346df10 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -57,6 +57,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "WM_toolsystem.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -106,7 +107,6 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
CLOG_INFO(&LOG, 1, "name='%s', step=%d", undoname, step);
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
- // Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
/* undo during jobs are running can easily lead to freeing data using by jobs,
@@ -135,6 +135,9 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
WM_event_add_notifier(C, NC_WINDOW, NULL);
WM_event_add_notifier(C, NC_WM | ND_UNDO, NULL);
+ Main *bmain = CTX_data_main(C);
+ WM_toolsystem_refresh_screen_all(bmain);
+
if (win) {
win->addmousemove = true;
}
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 6390fde36fa..447cff065b7 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -227,7 +227,7 @@ void apply_keyb_grid(int shift, int ctrl, float *val, float fac1, float fac2, fl
/* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
if (invert)
ctrl = !ctrl;
-
+
if (ctrl && shift) {
if (fac3 != 0.0f) *val = fac3 * floorf(*val / fac3 + 0.5f);
}
@@ -263,7 +263,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
BLI_split_file_part(abs_name, fi, sizeof(fi));
BLI_snprintf(local_name, sizeof(local_name), "//%s/%s", folder, fi);
if (!STREQ(abs_name, local_name)) {
- switch (checkPackedFile(bmain->name, local_name, pf)) {
+ switch (checkPackedFile(BKE_main_blendfile_path(bmain), local_name, pf)) {
case PF_NOFILE:
BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), local_name);
uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
@@ -296,7 +296,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
}
}
- switch (checkPackedFile(bmain->name, abs_name, pf)) {
+ switch (checkPackedFile(BKE_main_blendfile_path(bmain), abs_name, pf)) {
case PF_NOFILE:
BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), abs_name);
//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index f037783bd5e..5e867afd58e 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -70,7 +70,7 @@ static int uvedit_center(Scene *scene, Object *obedit, BMEditMesh *em, Image *im
int tot = 0;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
-
+
zero_v2(center);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, obedit, ima, f))
@@ -101,7 +101,7 @@ static void uvedit_translate(Scene *scene, Object *obedit, BMEditMesh *em, Image
MLoopUV *luv;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
-
+
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, obedit, ima, f))
continue;
@@ -131,7 +131,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
float width = 8 * UI_UNIT_X;
ED_space_image_get_size(sima, &imx, &imy);
-
+
em = BKE_editmesh_from_object(obedit);
if (uvedit_center(scene, obedit, em, ima, center)) {
@@ -164,7 +164,7 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
step = 100;
digits = 2;
}
-
+
UI_block_align_begin(block);
uiDefButF(block, UI_BTYPE_NUM, B_UVEDIT_VERTEX, IFACE_("X:"), 0, 0, width, UI_UNIT_Y, &uvedit_old_center[0],
UNPACK2(range_xy[0]), step, digits, "");
@@ -217,12 +217,12 @@ static int image_panel_uv_poll(const bContext *C, PanelType *UNUSED(pt))
static void image_panel_uv(const bContext *C, Panel *pa)
{
uiBlock *block;
-
+
block = uiLayoutAbsoluteBlock(pa->layout);
UI_block_func_handle_set(block, do_uvedit_vertex, NULL);
uvedit_vertex_buttons(C, block);
-}
+}
void ED_uvedit_buttons_register(ARegionType *art)
{
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 6b8bc957b26..4473922841f 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -87,6 +87,8 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
x_fac = zoom[0];
y_fac = zoom[1];
+ glLineWidth(1.0f);
+
gpuTranslate2fv(cursor);
const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -194,12 +196,12 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
BLI_buffer_declare_static(vec2f, tf_uvorig_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
-
+
switch (sima->dt_uvstretch) {
case SI_UVDT_STRETCH_AREA:
{
float totarea = 0.0f, totuvarea = 0.0f, areadiff, uvarea, area;
-
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
const int efa_len = efa->len;
float (*tf_uv)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa_len);
@@ -214,7 +216,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
totarea += BM_face_calc_area(efa);
totuvarea += area_poly_v2(tf_uv, efa->len);
-
+
if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
@@ -266,17 +268,17 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
uvarea = area_poly_v2(tf_uv, efa->len) / totuvarea;
-
+
if (area < FLT_EPSILON || uvarea < FLT_EPSILON)
areadiff = 1.0f;
else if (area > uvarea)
areadiff = 1.0f - (uvarea / area);
else
areadiff = 1.0f - (area / uvarea);
-
+
weight_to_rgb(col, areadiff);
immUniformColor3fv(col);
-
+
/* TODO: use editmesh tessface */
immBegin(GWN_PRIM_TRI_FAN, efa->len);
@@ -455,7 +457,7 @@ static void draw_uvs_other_mesh(Object *ob, const Image *curimage,
for (a = 0; a < totcol; a++) {
Image *image;
-
+
/* if no materials, assume a default material with no image */
if (ob->totcol)
ED_object_get_active_image(ob, a + 1, &image, NULL, NULL, NULL);
@@ -602,7 +604,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
interpedges = (ts->selectmode & SCE_SELECT_VERTEX);
else
interpedges = (ts->uv_selectmode == UV_SELECT_VERTEX);
-
+
/* draw other uvs */
if (sima->flag & SI_DRAW_OTHER) {
Image *curimage;
@@ -618,7 +620,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
/* 1. draw shadow mesh */
-
+
if (sima->flag & SI_DRAWSHADOW) {
Object *ob_cage_eval = DEG_get_evaluated_object(depsgraph, obedit);
/* XXX TODO: Need to check if shadow mesh is different than original mesh. */
@@ -632,7 +634,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
/* 2. draw colored faces */
-
+
if (sima->flag & SI_DRAW_STRETCH) {
draw_uvs_stretch(sima, scene, obedit, em, efa_act);
}
@@ -899,7 +901,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
glPointSize(pointsize);
-
+
immBeginAtMost(GWN_PRIM_POINTS, bm->totface);
/* unselected faces */
@@ -950,7 +952,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
/* 6. draw uv vertices */
-
+
if (drawfaces != 2) { /* 2 means Mesh Face Mode */
pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -975,12 +977,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
immEnd();
-
+
/* pinned uvs */
/* give odd pointsizes odd pin pointsizes */
glPointSize(pointsize * 2 + (((int)pointsize % 2) ? (-1) : 0));
imm_cpack(0xFF);
-
+
immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
@@ -996,11 +998,11 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
immEnd();
-
+
/* selected uvs */
immUniformThemeColor(TH_VERTEX_SELECT);
glPointSize(pointsize);
-
+
immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
@@ -1033,10 +1035,10 @@ static void draw_uv_shadows_get(
if ((sima->mode == SI_MODE_PAINT) && obedit && obedit->type == OB_MESH) {
struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
-
+
*show_shadow = EDBM_uv_check(em);
}
-
+
*show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT);
}
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index fceb1532077..45a6ccfe28b 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -108,13 +108,13 @@ bool ED_uvedit_test(Object *obedit)
if (!obedit)
return 0;
-
+
if (obedit->type != OB_MESH)
return 0;
em = BKE_editmesh_from_object(obedit);
ret = EDBM_uv_check(em);
-
+
return ret;
}
@@ -167,7 +167,7 @@ bool ED_object_get_active_image(
if (r_ntree) *r_ntree = ntree;
return true;
}
-
+
if (r_ima) *r_ima = NULL;
if (r_iuser) *r_iuser = NULL;
if (r_node) *r_node = node;
@@ -364,7 +364,7 @@ bool uvedit_edge_select_test(
return BM_elem_flag_test(l->e, BM_ELEM_SELECT);
}
else {
- return BM_elem_flag_test(l->v, BM_ELEM_SELECT) &&
+ return BM_elem_flag_test(l->v, BM_ELEM_SELECT) &&
BM_elem_flag_test(l->next->v, BM_ELEM_SELECT);
}
}
@@ -417,7 +417,7 @@ void uvedit_edge_select_enable(
luv1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv2 = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
-
+
luv1->flag |= MLOOPUV_VERTSEL;
luv2->flag |= MLOOPUV_VERTSEL;
}
@@ -445,7 +445,7 @@ void uvedit_edge_select_disable(
luv1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv2 = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
-
+
luv1->flag &= ~MLOOPUV_VERTSEL;
luv2->flag &= ~MLOOPUV_VERTSEL;
}
@@ -667,7 +667,7 @@ static bool UNUSED_FUNCTION(ED_uvedit_median)(Scene *scene, Image *ima, Object *
bool ED_uvedit_center_multi(Scene *scene, Image *ima, Object **objects_edit, uint objects_len, float cent[2], char mode)
{
bool changed = false;
-
+
if (mode == V3D_AROUND_CENTER_BOUNDS) { /* bounding box */
float min[2], max[2];
if (ED_uvedit_minmax_multi(scene, ima, objects_edit, objects_len, min, max)) {
@@ -920,11 +920,11 @@ bool ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float
mindist = 1e10f;
copy_v2_v2(r_uv, co);
-
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
-
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
dist = len_manhattan_v2v2(co, luv->uv);
@@ -958,7 +958,7 @@ static void uv_select_edgeloop_vertex_loop_flag(UvMapVert *first)
count++;
}
-
+
if (count < 5)
first->flag = 1;
}
@@ -974,7 +974,7 @@ static UvMapVert *uv_select_edgeloop_vertex_map_get(UvVertMap *vmap, BMFace *efa
if (iterv->f == BM_elem_index_get(efa))
return first;
}
-
+
return NULL;
}
@@ -1113,7 +1113,7 @@ static int uv_select_edgeloop(
else {
select = true;
}
-
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l);
@@ -1724,7 +1724,7 @@ static void UV_OT_align(wmOperatorType *ot)
ot->description = "Align selected UV vertices to an axis";
ot->idname = "UV_OT_align";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_align_exec;
ot->poll = ED_operator_uvedit;
@@ -1919,7 +1919,7 @@ static void UV_OT_weld(wmOperatorType *ot)
ot->description = "Weld selected UV vertices together";
ot->idname = "UV_OT_weld";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_weld_exec;
ot->poll = ED_operator_uvedit;
@@ -2073,7 +2073,7 @@ static void UV_OT_select_all(wmOperatorType *ot)
ot->description = "Change selection of all UV vertices";
ot->idname = "UV_OT_select_all";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_select_all_exec;
ot->poll = ED_operator_uvedit;
@@ -2225,7 +2225,7 @@ static int uv_mouse_select_multi(
hituv[i] = luv->uv;
hitv[i] = BM_elem_index_get(l->v);
}
-
+
hitlen = hit.efa->len;
}
else if (selectmode == UV_SELECT_ISLAND) {
@@ -2330,7 +2330,7 @@ static int uv_mouse_select_multi(
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
-
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (sticky == SI_STICKY_DISABLE) continue;
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -2416,7 +2416,7 @@ static void UV_OT_select(wmOperatorType *ot)
ot->description = "Select UV vertices";
ot->idname = "UV_OT_select";
ot->flag = OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_select_exec;
ot->invoke = uv_select_invoke;
@@ -2465,7 +2465,7 @@ static void UV_OT_select_loop(wmOperatorType *ot)
ot->description = "Select a loop of connected UV vertices";
ot->idname = "UV_OT_select_loop";
ot->flag = OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_select_loop_exec;
ot->invoke = uv_select_loop_invoke;
@@ -2568,7 +2568,7 @@ static void UV_OT_select_linked(wmOperatorType *ot)
ot->description = "Select all UV vertices linked to the active UV map";
ot->idname = "UV_OT_select_linked";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_select_linked_exec;
ot->poll = ED_operator_uvedit; /* requires space image */
@@ -2775,19 +2775,19 @@ static void uv_select_flush_from_tag_sticky_loc_internal(
*/
static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object *obedit, const bool select)
{
- /* Selecting UV Faces with some modes requires us to change
+ /* Selecting UV Faces with some modes requires us to change
* the selection in other faces (depending on the sticky mode).
- *
+ *
* This only needs to be done when the Mesh is not used for
* selection (so for sticky modes, vertex or location based). */
-
+
ToolSettings *ts = scene->toolsettings;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
-
+
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_VERTEX) {
/* Tag all verts as untouched, then touch the ones that have a face center
* in the loop and select all MLoopUV's that use a touched vert. */
@@ -2816,19 +2816,19 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object
struct UvVertMap *vmap;
float limit[2];
unsigned int efa_index;
-
+
uvedit_pixel_to_float(sima, limit, 0.05);
-
+
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
vmap = BM_uv_vert_map_create(em->bm, limit, false, false);
if (vmap == NULL) {
return;
}
-
+
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, efa_index) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
/* tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); */ /* UNUSED */
-
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
uv_select_flush_from_tag_sticky_loc_internal(
scene, em, vmap, efa_index, l,
@@ -2837,7 +2837,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object
}
}
BM_uv_vert_map_free(vmap);
-
+
}
else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -3068,17 +3068,17 @@ static void UV_OT_select_border(wmOperatorType *ot)
ot->name = "Border Select";
ot->description = "Select UV vertices using border selection";
ot->idname = "UV_OT_select_border";
-
+
/* api callbacks */
ot->invoke = WM_gesture_border_invoke;
ot->exec = uv_border_select_exec;
ot->modal = WM_gesture_border_modal;
ot->poll = ED_operator_uvedit_space_image; /* requires space image */;
ot->cancel = WM_gesture_border_cancel;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "pinned", 0, "Pinned", "Border select pinned UVs only");
@@ -3137,7 +3137,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
ellipse[1] = height * zoomy / radius;
UI_view2d_region_to_view(&ar->v2d, x, y, &offset[0], &offset[1]);
-
+
/* do selection */
if (use_face_center) {
changed = false;
@@ -3193,14 +3193,14 @@ static void UV_OT_circle_select(wmOperatorType *ot)
ot->name = "Circle Select";
ot->description = "Select UV vertices using circle selection";
ot->idname = "UV_OT_circle_select";
-
+
/* api callbacks */
ot->invoke = WM_gesture_circle_invoke;
ot->modal = WM_gesture_circle_modal;
ot->exec = uv_circle_select_exec;
ot->poll = ED_operator_uvedit_space_image; /* requires space image */;
ot->cancel = WM_gesture_circle_cancel;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3416,7 +3416,7 @@ static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
if (!changed)
return OPERATOR_CANCELLED;
-
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, sima);
return OPERATOR_FINISHED;
@@ -3434,7 +3434,7 @@ static void UV_OT_snap_cursor(wmOperatorType *ot)
ot->description = "Snap cursor to target type";
ot->idname = "UV_OT_snap_cursor";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_snap_cursor_exec;
ot->poll = ED_operator_uvedit_space_image; /* requires space image */;
@@ -3513,7 +3513,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object
MLoopUV *luv;
bool changed = false;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
+
/* index every vert that has a selected UV using it, but only once so as to
* get unique indices and to count how much to malloc */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
@@ -3575,7 +3575,7 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
ED_space_image_get_size(sima, &width, &height);
w = (float)width;
h = (float)height;
-
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, obedit, ima, efa))
continue;
@@ -3647,7 +3647,7 @@ static void UV_OT_snap_selected(wmOperatorType *ot)
ot->description = "Snap selected UV vertices to target type";
ot->idname = "UV_OT_snap_selected";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_snap_selection_exec;
ot->poll = ED_operator_uvedit_space_image;
@@ -3673,7 +3673,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
BMIter iter, liter;
MLoopUV *luv;
const bool clear = RNA_boolean_get(op->ptr, "clear");
-
+
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -3682,7 +3682,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-
+
if (!clear) {
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
luv->flag |= MLOOPUV_PINNED;
@@ -3693,7 +3693,7 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
}
}
}
-
+
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
return OPERATOR_FINISHED;
@@ -3706,7 +3706,7 @@ static void UV_OT_pin(wmOperatorType *ot)
ot->description = "Set/clear selected UV vertices as anchored between multiple unwrap operations";
ot->idname = "UV_OT_pin";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_pin_exec;
ot->poll = ED_operator_uvedit;
@@ -3731,7 +3731,7 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
BMLoop *l;
BMIter iter, liter;
MLoopUV *luv;
-
+
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -3740,12 +3740,12 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-
+
if (luv->flag & MLOOPUV_PINNED)
uvedit_uv_select_enable(em, scene, l, false, cd_loop_uv_offset);
}
}
-
+
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
@@ -3758,7 +3758,7 @@ static void UV_OT_select_pinned(wmOperatorType *ot)
ot->description = "Select all pinned UV vertices";
ot->idname = "UV_OT_select_pinned";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_select_pinned_exec;
ot->poll = ED_operator_uvedit;
@@ -3878,7 +3878,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
/* flush vertex selection changes */
if (em->selectmode != SCE_SELECT_FACE)
EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX | SCE_SELECT_EDGE);
-
+
BM_select_history_validate(em->bm);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -3894,7 +3894,7 @@ static void UV_OT_hide(wmOperatorType *ot)
ot->description = "Hide (un)selected UV vertices";
ot->idname = "UV_OT_hide";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_hide_exec;
ot->poll = ED_operator_uvedit;
@@ -3961,7 +3961,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
totsel += BM_elem_flag_test(l->v, BM_ELEM_SELECT);
}
-
+
if (!totsel) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -4018,7 +4018,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
}
}
}
-
+
/* re-select tagged faces */
BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
@@ -4034,7 +4034,7 @@ static void UV_OT_reveal(wmOperatorType *ot)
ot->description = "Reveal all hidden UV vertices";
ot->idname = "UV_OT_reveal";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = uv_reveal_exec;
ot->poll = ED_operator_uvedit;
@@ -4063,9 +4063,9 @@ static int uv_set_2d_cursor_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
RNA_float_get_array(op->ptr, "location", sima->cursor);
-
+
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -4095,7 +4095,7 @@ static void UV_OT_cursor_set(wmOperatorType *ot)
ot->name = "Set 2D Cursor";
ot->description = "Set 2D cursor location";
ot->idname = "UV_OT_cursor_set";
-
+
/* api callbacks */
ot->exec = uv_set_2d_cursor_exec;
ot->invoke = uv_set_2d_cursor_invoke;
@@ -4381,7 +4381,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
wmKeyMapItem *kmi;
-
+
keymap = WM_keymap_find(keyconf, "UV Editor", 0, 0);
keymap->poll = ED_operator_uvedit_can_uv_sculpt;
@@ -4391,7 +4391,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
/* Mark edge seam */
WM_keymap_add_item(keymap, "UV_OT_mark_seam", EKEY, KM_PRESS, KM_CTRL, 0);
-
+
/* pick selection */
RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0)->ptr, "extend", false);
RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", true);
@@ -4437,7 +4437,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "UV_OT_select_pinned", PKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_weldalign", WKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_weldalign", WKEY, KM_PRESS, KM_SHIFT, 0);
/* uv operations */
WM_keymap_add_item(keymap, "UV_OT_stitch", VKEY, KM_PRESS, 0, 0);
@@ -4462,7 +4462,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
/* cursor */
WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
-
+
/* menus */
WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_menu(keymap, "IMAGE_MT_uvs_select_mode", TABKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index c510c12ae53..1d2583cf9d4 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -113,7 +113,7 @@ typedef struct PVert {
float uv[2];
unsigned char flag;
-} PVert;
+} PVert;
typedef struct PEdge {
struct PEdge *nextlink;
@@ -242,8 +242,8 @@ typedef struct PHandle {
*/
static int PHashSizes[] = {
- 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209,
- 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169,
+ 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209,
+ 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169,
4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459
};
@@ -294,7 +294,7 @@ static void phash_insert(PHash *ph, PHashLink *link)
link->next = lookup->next;
lookup->next = link;
}
-
+
ph->size++;
if (ph->size > (size * 3)) {
@@ -323,7 +323,7 @@ static PHashLink *phash_lookup(PHash *ph, PHashKey key)
return link;
else if (PHASH_hash(ph, link->key) != hash)
return NULL;
-
+
return link;
}
@@ -336,7 +336,7 @@ static PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link)
return link;
else if (PHASH_hash(ph, link->key) != hash)
return NULL;
-
+
return link;
}
@@ -562,7 +562,7 @@ static PEdge *p_wheel_edge_next(PEdge *e)
}
static PEdge *p_wheel_edge_prev(PEdge *e)
-{
+{
return (e->pair) ? e->pair->next : NULL;
}
@@ -619,7 +619,7 @@ static void p_chart_topological_sanity_check(PChart *chart)
for (v = chart->verts; v; v = v->nextlink)
param_test_equals_ptr("v->edge->vert", v, v->edge->vert);
-
+
for (e = chart->edges; e; e = e->nextlink) {
if (e->pair) {
param_test_equals_ptr("e->pair->pair", e, e->pair->pair);
@@ -867,7 +867,7 @@ static PBool p_edge_implicit_seam(PEdge *e, PEdge *ep)
ep->flag |= PEDGE_SEAM;
return P_TRUE;
}
-
+
return P_FALSE;
}
@@ -881,7 +881,7 @@ static PBool p_edge_has_pair(PHandle *handle, PEdge *e, PEdge **pair, PBool impl
if (e->flag & PEDGE_SEAM)
return P_FALSE;
-
+
key = PHASH_edge(key1, key2);
pe = (PEdge *)phash_lookup(handle->hash_edges, key);
*pair = NULL;
@@ -999,7 +999,7 @@ static void p_split_vert(PChart *chart, PEdge *e)
lastwe = e;
for (we = p_wheel_edge_prev(e); we && (we != e); we = p_wheel_edge_prev(we))
lastwe = we;
-
+
/* go over all edges in wheel */
for (we = lastwe; we; we = p_wheel_edge_next(we)) {
if (we->flag & PEDGE_VERTEX_SPLIT)
@@ -1202,7 +1202,7 @@ static PBool p_quad_split_direction(PHandle *handle, float **co, PHashKey *vkeys
/* Construction: boundary filling */
static void p_chart_boundaries(PChart *chart, int *nboundaries, PEdge **outer)
-{
+{
PEdge *e, *be;
float len, maxlen = -1.0;
@@ -1327,7 +1327,7 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
}
else {
ne2->vert->edge = ne2;
-
+
ne2->u.heaplink = BLI_heap_insert(heap, p_edge_boundary_angle(ne2), ne2);
e2->u.heaplink = BLI_heap_insert(heap, p_edge_boundary_angle(e2), e2);
}
@@ -1412,7 +1412,7 @@ static void p_polygon_kernel_clip(float (*oldpoints)[2], int noldpoints, float (
newpoints[*nnewpoints][1] = p2[1];
(*nnewpoints)++;
}
-
+
p1in = p2in;
p1 = p2;
}
@@ -1422,7 +1422,7 @@ static void p_polygon_kernel_center(float (*points)[2], int npoints, float *cent
{
int i, size, nnewpoints = npoints;
float (*oldpoints)[2], (*newpoints)[2], *p1, *p2;
-
+
size = npoints * 3;
oldpoints = MEM_mallocN(sizeof(float) * 2 * size, "PPolygonOldPoints");
newpoints = MEM_mallocN(sizeof(float) * 2 * size, "PPolygonNewPoints");
@@ -1486,7 +1486,7 @@ static void p_polygon_kernel_center(float (*points)[2], int npoints, float *cent
int NCOLLAPSE = 1;
int NCOLLAPSEX = 0;
-
+
static float p_vert_cotan(float *v1, float *v2, float *v3)
{
float a[3], b[3], c[3], clen;
@@ -1499,10 +1499,10 @@ static float p_vert_cotan(float *v1, float *v2, float *v3)
if (clen == 0.0f)
return 0.0f;
-
+
return dot_v3v3(a, b) / clen;
}
-
+
static PBool p_vert_flipped_wheel_triangle(PVert *v)
{
PEdge *e = v->edge;
@@ -1530,7 +1530,7 @@ static PBool p_vert_map_harmonic_weights(PVert *v)
do {
float t1, t2, weight;
PVert *v1, *v2;
-
+
v1 = e->next->vert;
v2 = e->next->next->vert;
t1 = p_vert_cotan(v2->co, e->vert->co, v1->co);
@@ -1563,7 +1563,7 @@ static PBool p_vert_map_harmonic_weights(PVert *v)
weightsum += t1 + t2;
positionsum[0] += (v2->uv[1] - v1->uv[1]) + (t1 * v2->uv[0] + t2 * v1->uv[0]);
positionsum[1] += (v1->uv[0] - v2->uv[0]) + (t1 * v2->uv[1] + t2 * v1->uv[1]);
-
+
e = p_wheel_edge_next(e);
} while (e && (e != v->edge));
}
@@ -1617,20 +1617,20 @@ static void p_vert_harmonic_insert(PVert *v)
do {
PEdge *nexte = p_wheel_edge_next(e);
- points[i][0] = e->next->vert->uv[0];
- points[i][1] = e->next->vert->uv[1];
+ points[i][0] = e->next->vert->uv[0];
+ points[i][1] = e->next->vert->uv[1];
if (nexte == NULL) {
i++;
- points[i][0] = e->next->next->vert->uv[0];
- points[i][1] = e->next->next->vert->uv[1];
+ points[i][0] = e->next->next->vert->uv[0];
+ points[i][1] = e->next->next->vert->uv[1];
break;
}
e = nexte;
i++;
} while (e != v->edge);
-
+
p_polygon_kernel_center(points, npoints, v->uv);
MEM_freeN(points);
@@ -1653,7 +1653,7 @@ static void p_vert_fix_edge_pointer(PVert *v)
/* set v->edge pointer to the edge with no pair, if there is one */
while (v->edge->pair) {
v->edge = p_wheel_edge_prev(v->edge);
-
+
if (v->edge == start)
break;
}
@@ -1699,7 +1699,7 @@ static void p_collapse_edge(PEdge *edge, PEdge *pair)
else
keepv->edge = pair->next->pair->next;
}
-
+
/* update pairs and v->edge pointers */
if (edge) {
PEdge *e1 = edge->next, *e2 = e1->next;
@@ -1821,7 +1821,7 @@ static PBool p_collapse_allowed_topologic(PEdge *edge, PEdge *pair)
* the chart) */
else if (!p_vert_interior(oldv) && !p_vert_interior(keepv))
return P_FALSE;
-
+
return P_TRUE;
}
@@ -1868,7 +1868,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
if (p_collapse_normal_flipped(v1->co, v2->co, oldv->co, keepv->co))
return P_FALSE;
-
+
a[0] = angle;
a[1] = p_vec_angle(v2->co, v1->co, oldv->co);
a[2] = M_PI - a[0] - a[1];
@@ -1903,7 +1903,7 @@ static PBool p_collapse_allowed_geometric(PEdge *edge, PEdge *pair)
/* abf++ criterion 2: avoid collapsing verts inwards */
if (p_vert_interior(keepv))
return P_FALSE;
-
+
/* don't collapse significant boundary changes */
angle = p_vec_angle(v1->co, oldv->co, v2->co);
if (angle < (M_PI * 160.0 / 180.0))
@@ -1921,7 +1921,7 @@ static PBool p_collapse_allowed(PEdge *edge, PEdge *pair)
if (oldv->flag & PVERT_PIN)
return P_FALSE;
-
+
return (p_collapse_allowed_topologic(edge, pair) &&
p_collapse_allowed_geometric(edge, pair));
}
@@ -2010,7 +2010,7 @@ static float p_collapse_cost(PEdge *edge, PEdge *pair)
return cost;
}
-
+
static void p_collapse_cost_vertex(PVert *vert, float *mincost, PEdge **mine)
{
PEdge *e, *enext, *pair;
@@ -2172,7 +2172,7 @@ static void p_chart_simplify_compute(PChart *chart)
for (v = chart->verts; v; v = v->nextlink) {
float cost;
PEdge *e = NULL;
-
+
p_collapse_cost_vertex(v, &cost, &e);
if (e)
@@ -2237,7 +2237,7 @@ static void p_chart_simplify_compute(PChart *chart)
BLI_heap_remove(heap, v->u.heaplink);
v->u.heaplink = NULL;
}
-
+
p_collapse_cost_vertex(v, &cost, &collapse);
if (collapse)
@@ -2331,7 +2331,7 @@ static void p_abf_setup_system(PAbfSystem *sys)
for (i = 0; i < sys->ninterior; i++)
sys->lambdaLength[i] = 1.0;
-
+
sys->minangle = 1.0 * M_PI / 180.0;
sys->maxangle = (float)M_PI - sys->minangle;
}
@@ -2649,7 +2649,7 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
dlambda1 = pre[0] + pre[1] + pre[2];
dlambda1 = sys->dstar[f->u.id] * (sys->bstar[f->u.id] - dlambda1);
-
+
sys->lambdaTriangle[f->u.id] += dlambda1;
dalpha = (sys->bAlpha[e1->u.id] - dlambda1);
@@ -2914,7 +2914,7 @@ static PBool p_chart_symmetry_pins(PChart *chart, PEdge *outer, PVert **pin1, PV
if (!maxe1 || !maxe2 || (maxlen < 0.5f * totlen))
return P_FALSE;
-
+
/* find pin1 in the split vertices */
be1 = maxe1;
be2 = maxe2;
@@ -3212,7 +3212,7 @@ static void p_chart_lscm_end(PChart *chart)
{
if (chart->u.lscm.context)
EIG_linear_solver_delete(chart->u.lscm.context);
-
+
if (chart->u.lscm.abf_alpha) {
MEM_freeN(chart->u.lscm.abf_alpha);
chart->u.lscm.abf_alpha = NULL;
@@ -3250,7 +3250,7 @@ static float p_face_stretch(PFace *f)
if (area <= 0.0f) /* flipped face -> infinite stretch */
return 1e10f;
-
+
w = 1.0f / (2.0f * area);
/* compute derivatives */
@@ -3682,7 +3682,7 @@ static SmoothNode *p_node_new(MemArena *arena, SmoothTriangle **tri, int ntri, f
if (ntri <= 10 || depth >= 15)
return node;
-
+
t1 = MEM_mallocN(sizeof(*t1) * ntri, "PNodeTri1");
t2 = MEM_mallocN(sizeof(*t2) * ntri, "PNodeTri1");
@@ -3707,7 +3707,7 @@ static SmoothNode *p_node_new(MemArena *arena, SmoothTriangle **tri, int ntri, f
MEM_freeN(t2);
return node;
}
-
+
node->tri = NULL;
node->ntri = 0;
MEM_freeN(tri);
@@ -3782,7 +3782,7 @@ static float p_smooth_median_edge_length(PChart *chart)
/* ok, so i'm lazy */
for (i = 0, e = chart->edges; e; e = e->nextlink, i++)
lengths[i] = p_edge_length(e);
-
+
qsort(lengths, i, sizeof(float), p_compare_float);
median = lengths[i / 2];
@@ -3876,7 +3876,7 @@ static void p_smooth(PChart *chart)
if ((gridx <= 2) || (gridy <= 2))
return;
-
+
edgesx = gridx - 1;
edgesy = gridy - 1;
nsize = gridx * gridy;
@@ -3936,7 +3936,7 @@ static void p_smooth(PChart *chart)
float p[2], b[3];
i = x + y * gridx;
-
+
p[0] = nodesx[i];
p[1] = nodesy[i];
@@ -3979,7 +3979,7 @@ static void p_smooth(PChart *chart)
for (it2 = 0; it2 < maxiter2; it2++) {
d = 0.0f;
totiter += 1;
-
+
memcpy(oldnodesx, nodesx, sizeof(float) * nsize);
memcpy(oldnodesy, nodesy, sizeof(float) * nsize);
@@ -4011,7 +4011,7 @@ static void p_smooth(PChart *chart)
sum1 += vedges[j] * oldnodesy[i + gridx];
nodesy[i] = sum1 / sum2;
-
+
p[0] = nodesx[i];
p[1] = nodesy[i];
@@ -4089,8 +4089,8 @@ static void p_smooth(PChart *chart)
t2->co3[0] = t->co3[0]; t2->co3[1] = t->co3[1];
t2->oco3[0] = t->oco3[0]; t2->oco3[1] = t->oco3[1];
- *trip = t; trip++; t++;
- *trip = t; trip++; t++;
+ *trip = t; trip++; t++;
+ *trip = t; trip++; t++;
}
}
@@ -4107,7 +4107,7 @@ static void p_smooth(PChart *chart)
p_node_delete(root);
BLI_memarena_free(arena);
-
+
MEM_freeN(triangles);
}
@@ -4149,7 +4149,7 @@ void param_delete(ParamHandle *handle)
for (i = 0; i < phandle->ncharts; i++)
p_chart_delete(phandle->charts[i]);
-
+
if (phandle->charts)
MEM_freeN(phandle->charts);
@@ -4496,24 +4496,24 @@ static void param_pack_rotate(ParamHandle *handle)
}
void param_pack(ParamHandle *handle, float margin, bool do_rotate)
-{
+{
/* box packing variables */
BoxPack *boxarray, *box;
float tot_width, tot_height, scale;
-
+
PChart *chart;
int i, unpacked = 0;
float trans[2];
double area = 0.0;
-
+
PHandle *phandle = (PHandle *)handle;
-
+
if (phandle->ncharts == 0)
return;
-
+
if (phandle->aspx != phandle->aspy)
param_scale(handle, 1.0f / phandle->aspx, 1.0f / phandle->aspy);
-
+
/* this could be its own function */
if (do_rotate) {
param_pack_rotate(handle);
@@ -4521,33 +4521,33 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate)
/* we may not use all these boxes */
boxarray = MEM_mallocN(phandle->ncharts * sizeof(BoxPack), "BoxPack box");
-
-
+
+
for (i = 0; i < phandle->ncharts; i++) {
chart = phandle->charts[i];
-
+
if (chart->flag & PCHART_NOPACK) {
unpacked++;
continue;
}
-
+
box = boxarray + (i - unpacked);
-
+
p_chart_uv_bbox(chart, trans, chart->u.pack.size);
-
+
trans[0] = -trans[0];
trans[1] = -trans[1];
-
+
p_chart_uv_translate(chart, trans);
-
+
box->w = chart->u.pack.size[0] + trans[0];
box->h = chart->u.pack.size[1] + trans[1];
box->index = i; /* warning this index skips PCHART_NOPACK boxes */
-
+
if (margin > 0.0f)
area += (double)sqrtf(box->w * box->h);
}
-
+
if (margin > 0.0f) {
/* multiply the margin by the area to give predictable results not dependent on UV scale,
* ...Without using the area running pack multiple times also gives a bad feedback loop.
@@ -4556,12 +4556,12 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate)
unpacked = 0;
for (i = 0; i < phandle->ncharts; i++) {
chart = phandle->charts[i];
-
+
if (chart->flag & PCHART_NOPACK) {
unpacked++;
continue;
}
-
+
box = boxarray + (i - unpacked);
trans[0] = margin;
trans[1] = margin;
@@ -4570,19 +4570,19 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate)
box->h += margin * 2;
}
}
-
+
BLI_box_pack_2d(boxarray, phandle->ncharts - unpacked, &tot_width, &tot_height);
-
+
if (tot_height > tot_width)
scale = 1.0f / tot_height;
else
scale = 1.0f / tot_width;
-
+
for (i = 0; i < phandle->ncharts - unpacked; i++) {
box = boxarray + i;
trans[0] = box->x;
trans[1] = box->y;
-
+
chart = phandle->charts[box->index];
p_chart_uv_translate(chart, trans);
p_chart_uv_scale(chart, scale);
@@ -4601,54 +4601,54 @@ void param_average(ParamHandle *handle)
float tot_fac, fac;
float minv[2], maxv[2], trans[2];
PHandle *phandle = (PHandle *)handle;
-
+
if (phandle->ncharts == 0)
return;
-
+
for (i = 0; i < phandle->ncharts; i++) {
PFace *f;
chart = phandle->charts[i];
if (chart->flag & PCHART_NOPACK)
continue;
-
+
chart->u.pack.area = 0.0f; /* 3d area */
chart->u.pack.rescale = 0.0f; /* UV area, abusing rescale for tmp storage, oh well :/ */
-
+
for (f = chart->faces; f; f = f->nextlink) {
chart->u.pack.area += p_face_area(f);
chart->u.pack.rescale += fabsf(p_face_uv_area_signed(f));
}
-
+
tot_facearea += chart->u.pack.area;
tot_uvarea += chart->u.pack.rescale;
}
-
+
if (tot_facearea == tot_uvarea || tot_facearea == 0.0f || tot_uvarea == 0.0f) {
/* nothing to do */
return;
}
-
+
tot_fac = tot_facearea / tot_uvarea;
-
+
for (i = 0; i < phandle->ncharts; i++) {
chart = phandle->charts[i];
if (chart->flag & PCHART_NOPACK)
continue;
-
+
if (chart->u.pack.area != 0.0f && chart->u.pack.rescale != 0.0f) {
fac = chart->u.pack.area / chart->u.pack.rescale;
-
+
/* Get the island center */
p_chart_uv_bbox(chart, minv, maxv);
trans[0] = (minv[0] + maxv[0]) / -2.0f;
trans[1] = (minv[1] + maxv[1]) / -2.0f;
-
+
/* Move center to 0,0 */
p_chart_uv_translate(chart, trans);
p_chart_uv_scale(chart, sqrtf(fac / tot_fac));
-
+
/* Move to original center */
trans[0] = -trans[0];
trans[1] = -trans[1];
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h
index 4322a3f7dfc..50b4ee66644 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.h
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.h
@@ -30,7 +30,7 @@
#ifdef __cplusplus
extern "C" {
#endif
-
+
#include "BLI_sys_types.h" // for intptr_t support
typedef void ParamHandle; /* handle to a set of charts */
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 4c205818329..f39498b08f3 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -2334,7 +2334,7 @@ void UV_OT_stitch(wmOperatorType *ot)
ot->description = "Stitch selected UV vertices by proximity";
ot->idname = "UV_OT_stitch";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->invoke = stitch_invoke;
ot->modal = stitch_modal;
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 521470d4e5f..78b412579e6 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -147,7 +147,7 @@ static bool ED_uvedit_ensure_uvs(bContext *C, Scene *UNUSED(scene), Object *obed
}
}
}
-
+
/* select new UV's (ignore UV_SYNC_SELECTION in this case) */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BMIter liter;
@@ -170,7 +170,7 @@ static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit)
BMLoop *l;
BMIter iter, liter;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
-
+
if (cd_loop_uv_offset == -1) {
return (em->bm->totfacesel != 0);
}
@@ -184,15 +184,15 @@ static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit)
}
else if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
-
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
break;
}
-
+
if (implicit && !l)
continue;
-
+
return true;
}
@@ -277,7 +277,7 @@ static ParamHandle *construct_param_handle(
BMEdge *eed;
BMIter iter, liter;
int i;
-
+
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
handle = param_construct_begin();
@@ -290,10 +290,10 @@ static ParamHandle *construct_param_handle(
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
}
-
+
/* we need the vert indices */
BM_mesh_elem_index_ensure(bm, BM_VERT);
-
+
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
@@ -494,7 +494,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
smd.levels = smd_real->levels;
smd.subdivType = smd_real->subdivType;
-
+
initialDerived = CDDM_from_editbmesh(em, false, false);
derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd,
NULL, SUBSURF_IN_EDIT_MODE);
@@ -563,7 +563,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
co[1] = subsurfedVerts[mloop[1].v].co;
co[2] = subsurfedVerts[mloop[2].v].co;
co[3] = subsurfedVerts[mloop[3].v].co;
-
+
/* This is where all the magic is done. If the vertex exists in the, we pass the original uv pointer to the solver, thus
* flushing the solution to the edit mesh. */
texface_from_original_index(origFace, origVertIndices[mloop[0].v], &uv[0], &pin[0], &select[0], scene, cd_loop_uv_offset);
@@ -791,7 +791,7 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
ot->idname = "UV_OT_minimize_stretch";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_CURSOR | OPTYPE_BLOCKING;
ot->description = "Reduce UV stretching by relaxing angles";
-
+
/* api callbacks */
ot->exec = minimize_stretch_exec;
ot->invoke = minimize_stretch_invoke;
@@ -869,7 +869,7 @@ void UV_OT_pack_islands(wmOperatorType *ot)
ot->description = "Transform all islands so that they fill up the UV space as much as possible";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = pack_islands_exec;
ot->poll = ED_operator_uvedit;
@@ -897,7 +897,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
param_average(handle);
param_flush(handle);
param_delete(handle);
-
+
DEG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
@@ -912,7 +912,7 @@ void UV_OT_average_islands_scale(wmOperatorType *ot)
ot->description = "Average the size of separate UV islands, based on their area in 3D space";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = average_islands_scale_exec;
ot->poll = ED_operator_uvedit;
@@ -950,7 +950,7 @@ void ED_uvedit_live_unwrap_re_solve(void)
param_flush(liveHandle);
}
}
-
+
void ED_uvedit_live_unwrap_end(short cancel)
{
if (liveHandle) {
@@ -1139,7 +1139,7 @@ static void uv_map_transform(bContext *C, wmOperator *op, float rotmat[4][4])
/* be compatible to the "old" sphere/cylinder mode */
if (direction == ALIGN_TO_OBJECT)
unit_m4(rotmat);
- else
+ else
uv_map_rotation_matrix(rotmat, rv3d, obedit, upangledeg, sideangledeg, radius);
}
@@ -1174,21 +1174,21 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
MLoopUV *luv;
BMFace *efa;
float scale, aspx, aspy;
-
+
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy);
-
+
if (aspx == aspy)
return;
-
+
if (aspx > aspy) {
scale = aspy / aspx;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
-
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[0] = ((luv->uv[0] - 0.5f) * scale) + 0.5f;
@@ -1201,7 +1201,7 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
-
+
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->uv[1] = ((luv->uv[1] - 0.5f) * scale) + 0.5f;
@@ -1436,7 +1436,7 @@ void UV_OT_unwrap(wmOperatorType *ot)
ot->description = "Unwrap the mesh of the object being edited";
ot->idname = "UV_OT_unwrap";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = unwrap_exec;
ot->poll = ED_operator_uvmap;
@@ -1596,7 +1596,7 @@ void UV_OT_project_from_view(wmOperatorType *ot)
ot->description = "Project the UV vertices of the mesh as seen in current 3D view";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->invoke = uv_from_view_invoke;
ot->exec = uv_from_view_exec;
@@ -1651,7 +1651,7 @@ void UV_OT_reset(wmOperatorType *ot)
ot->description = "Reset UV projection";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = reset_exec;
ot->poll = ED_operator_uvmap;
@@ -1670,7 +1670,7 @@ static void uv_sphere_project(float target[2], float source[3], float center[3],
/* split line is always zero */
if (target[0] >= 1.0f)
- target[0] -= 1.0f;
+ target[0] -= 1.0f;
}
static void uv_map_mirror(BMEditMesh *em, BMFace *efa)
@@ -1764,7 +1764,7 @@ void UV_OT_sphere_project(wmOperatorType *ot)
ot->description = "Project the UV vertices of the mesh over the curved surface of a sphere";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = sphere_project_exec;
ot->poll = ED_operator_uvmap;
@@ -1787,7 +1787,7 @@ static void uv_cylinder_project(float target[2], float source[3], float center[3
/* split line is always zero */
if (target[0] >= 1.0f)
- target[0] -= 1.0f;
+ target[0] -= 1.0f;
}
static int cylinder_project_exec(bContext *C, wmOperator *op)
@@ -1852,7 +1852,7 @@ void UV_OT_cylinder_project(wmOperatorType *ot)
ot->description = "Project the UV vertices of the mesh over the curved wall of a cylinder";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = cylinder_project_exec;
ot->poll = ED_operator_uvmap;
@@ -1969,7 +1969,7 @@ void UV_OT_cube_project(wmOperatorType *ot)
ot->description = "Project the UV vertices of the mesh over the six faces of a cube";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* api callbacks */
ot->exec = cube_project_exec;
ot->poll = ED_operator_uvmap;
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index 6cbdca756d5..f41a9b58085 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -95,7 +95,7 @@ NodeGroup *BlenderFileLoader::Load()
int id = 0;
DEG_OBJECT_ITER_BEGIN(
- depsgraph, ob, DEG_ITER_OBJECT_MODE_RENDER,
+ depsgraph, ob,
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
DEG_ITER_OBJECT_FLAG_VISIBLE |
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 95492016f25..0805cc25d04 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -238,7 +238,7 @@ GPUNodeLink *GPU_uniformbuffer_link_out(
void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
GPUBuiltin GPU_get_material_builtins(GPUMaterial *material);
-void GPU_material_sss_profile_create(GPUMaterial *material, float *radii, short *falloff_type, float *sharpness);
+void GPU_material_sss_profile_create(GPUMaterial *material, float radii[3], short *falloff_type, float *sharpness);
struct GPUUniformBuffer *GPU_material_sss_profile_get(
GPUMaterial *material, int sample_ct, struct GPUTexture **tex_profile);
@@ -246,22 +246,26 @@ struct GPUUniformBuffer *GPU_material_sss_profile_get(
GPUMaterial *GPU_material_from_nodetree_find(
struct ListBase *gpumaterials, const void *engine_type, int options);
GPUMaterial *GPU_material_from_nodetree(
- struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, const void *engine_type, int options);
-void GPU_material_generate_pass(
- GPUMaterial *mat, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines);
+ struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, const void *engine_type, int options,
+ const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines);
+void GPU_material_compile(GPUMaterial *mat);
void GPU_material_free(struct ListBase *gpumaterial);
void GPU_materials_free(void);
+void GPU_material_orphans_init(void);
+void GPU_material_orphans_exit(void);
+/* This has to be called from a thread with an ogl context bound. */
+void GPU_material_orphans_delete(void);
+
struct Scene *GPU_material_scene(GPUMaterial *material);
GPUMatType GPU_Material_get_type(GPUMaterial *material);
struct GPUPass *GPU_material_get_pass(GPUMaterial *material);
struct ListBase *GPU_material_get_inputs(GPUMaterial *material);
GPUMaterialStatus GPU_material_status(GPUMaterial *mat);
-struct GPUUniformBuffer *GPU_material_get_uniform_buffer(GPUMaterial *material);
-void GPU_material_create_uniform_buffer(GPUMaterial *material, struct ListBase *inputs);
-void GPU_material_uniform_buffer_tag_dirty(struct ListBase *gpumaterials);
+struct GPUUniformBuffer *GPU_material_uniform_buffer_get(GPUMaterial *material);
+void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs);
void GPU_material_vertex_attributes(GPUMaterial *material,
struct GPUVertexAttribs *attrib);
@@ -270,6 +274,7 @@ bool GPU_material_do_color_management(GPUMaterial *mat);
bool GPU_material_use_domain_surface(GPUMaterial *mat);
bool GPU_material_use_domain_volume(GPUMaterial *mat);
+void GPU_pass_cache_init(void);
void GPU_pass_cache_garbage_collect(void);
void GPU_pass_cache_free(void);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 737b4a542c8..09b351a544a 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -40,7 +40,7 @@ struct Image;
struct ImageUser;
struct PreviewImage;
struct Gwn_VertBuf;
-
+
struct GPUFrameBuffer;
typedef struct GPUTexture GPUTexture;
@@ -173,6 +173,11 @@ void GPU_invalid_tex_free(void);
void GPU_texture_free(GPUTexture *tex);
+void GPU_texture_orphans_init(void);
+void GPU_texture_orphans_exit(void);
+/* This has to be called from a thread with an ogl context bound. */
+void GPU_texture_orphans_delete(void);
+
void GPU_texture_ref(GPUTexture *tex);
void GPU_texture_bind(GPUTexture *tex, int number);
void GPU_texture_unbind(GPUTexture *tex);
diff --git a/source/blender/gpu/GPU_uniformbuffer.h b/source/blender/gpu/GPU_uniformbuffer.h
index c2480f8ba03..2f422fa1a92 100644
--- a/source/blender/gpu/GPU_uniformbuffer.h
+++ b/source/blender/gpu/GPU_uniformbuffer.h
@@ -35,7 +35,6 @@
struct ListBase;
typedef struct GPUUniformBuffer GPUUniformBuffer;
-typedef struct GPUUniformBufferDynamicItem GPUUniformBufferDynamicItem;
GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256]);
GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(struct ListBase *inputs, char err_out[256]);
@@ -52,7 +51,6 @@ int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo);
bool GPU_uniformbuffer_is_empty(GPUUniformBuffer *ubo);
bool GPU_uniformbuffer_is_dirty(GPUUniformBuffer *ubo);
-void GPU_uniformbuffer_tag_dirty(GPUUniformBuffer *ubo);
#define GPU_UBO_BLOCK_NAME "nodeTree"
diff --git a/source/blender/gpu/intern/gpu_basic_shader.c b/source/blender/gpu/intern/gpu_basic_shader.c
index 620a06ae606..b720bed2d0c 100644
--- a/source/blender/gpu/intern/gpu_basic_shader.c
+++ b/source/blender/gpu/intern/gpu_basic_shader.c
@@ -169,7 +169,7 @@ void GPU_basic_shaders_init(void)
void GPU_basic_shaders_exit(void)
{
int i;
-
+
for (i = 0; i < GPU_SHADER_OPTION_COMBINATIONS; i++)
if (GPU_MATERIAL_STATE.cached_shaders[i])
GPU_shader_free(GPU_MATERIAL_STATE.cached_shaders[i]);
@@ -238,7 +238,7 @@ static GPUShader *gpu_basic_shader(int options)
geom_glsl,
NULL,
defines);
-
+
if (shader) {
/* set texture map to first texture unit */
if (options & (GPU_SHADER_TEXTURE_2D | GPU_SHADER_TEXTURE_RECT)) {
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 9d2a0ceef4d..df8dbb03284 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -460,7 +460,7 @@ void GPU_pbvh_grid_buffers_update(
vbo_index += 1;
}
}
-
+
if (!buffers->smooth) {
for (j = 0; j < key->grid_size - 1; j++) {
for (k = 0; k < key->grid_size - 1; k++) {
@@ -865,7 +865,7 @@ void GPU_pbvh_bmesh_buffers_update(
fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
}
fmask /= 3.0f;
-
+
for (i = 0; i < 3; i++) {
gpu_bmesh_vert_to_buffer_copy__gwn(
v[i], buffers->vert_buf,
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index f182f08f4a9..0dd9d1f0908 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -40,10 +40,11 @@
#include "BLI_blenlib.h"
#include "BLI_hash_mm2a.h"
-#include "BLI_linklist.h"
+#include "BLI_link_utils.h"
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
+#include "BLI_threads.h"
#include "PIL_time.h"
@@ -75,39 +76,54 @@ static char *glsl_material_library = NULL;
* same for 2 different Materials. Unused GPUPasses are free by Garbage collection.
**/
-static LinkNode *pass_cache = NULL; /* GPUPass */
+/* Only use one linklist that contains the GPUPasses grouped by hash. */
+static GPUPass *pass_cache = NULL;
+static SpinLock pass_cache_spin;
-static uint32_t gpu_pass_hash(const char *vert, const char *geom, const char *frag, const char *defs)
+static uint32_t gpu_pass_hash(const char *frag_gen, const char *defs)
{
BLI_HashMurmur2A hm2a;
BLI_hash_mm2a_init(&hm2a, 0);
- BLI_hash_mm2a_add(&hm2a, (unsigned char *)frag, strlen(frag));
- BLI_hash_mm2a_add(&hm2a, (unsigned char *)vert, strlen(vert));
+ BLI_hash_mm2a_add(&hm2a, (unsigned char *)frag_gen, strlen(frag_gen));
if (defs)
BLI_hash_mm2a_add(&hm2a, (unsigned char *)defs, strlen(defs));
- if (geom)
- BLI_hash_mm2a_add(&hm2a, (unsigned char *)geom, strlen(geom));
return BLI_hash_mm2a_end(&hm2a);
}
-/* Search by hash then by exact string match. */
-static GPUPass *gpu_pass_cache_lookup(
- const char *vert, const char *geom, const char *frag, const char *defs, uint32_t hash)
+/* Search by hash only. Return first pass with the same hash.
+ * There is hash collision if (pass->next && pass->next->hash == hash) */
+static GPUPass *gpu_pass_cache_lookup(uint32_t hash)
{
- for (LinkNode *ln = pass_cache; ln; ln = ln->next) {
- GPUPass *pass = (GPUPass *)ln->link;
+ BLI_spin_lock(&pass_cache_spin);
+ /* Could be optimized with a Lookup table. */
+ for (GPUPass *pass = pass_cache; pass; pass = pass->next) {
if (pass->hash == hash) {
- /* Note: Could be made faster if that becomes a real bottleneck. */
- if ((defs != NULL) && (strcmp(pass->defines, defs) != 0)) { /* Pass */ }
- else if ((geom != NULL) && (strcmp(pass->geometrycode, geom) != 0)) { /* Pass */ }
- else if ((strcmp(pass->fragmentcode, frag) == 0) &&
- (strcmp(pass->vertexcode, vert) == 0))
- {
- return pass;
- }
+ BLI_spin_unlock(&pass_cache_spin);
+ return pass;
}
}
+ BLI_spin_unlock(&pass_cache_spin);
+ return NULL;
+}
+
+/* Check all possible passes with the same hash. */
+static GPUPass *gpu_pass_cache_resolve_collision(
+ GPUPass *pass, const char *vert, const char *geom, const char *frag, const char *defs, uint32_t hash)
+{
+ BLI_spin_lock(&pass_cache_spin);
+ /* Collision, need to strcmp the whole shader. */
+ for (; pass && (pass->hash == hash); pass = pass->next) {
+ if ((defs != NULL) && (strcmp(pass->defines, defs) != 0)) { /* Pass */ }
+ else if ((geom != NULL) && (strcmp(pass->geometrycode, geom) != 0)) { /* Pass */ }
+ else if ((strcmp(pass->fragmentcode, frag) == 0) &&
+ (strcmp(pass->vertexcode, vert) == 0))
+ {
+ BLI_spin_unlock(&pass_cache_spin);
+ return pass;
+ }
+ }
+ BLI_spin_unlock(&pass_cache_spin);
return NULL;
}
@@ -159,7 +175,7 @@ static int gpu_str_prefix(const char *str, const char *prefix)
str++;
prefix++;
}
-
+
return (*prefix == '\0');
}
@@ -278,7 +294,7 @@ static char *gpu_generate_function_prototyps(GHash *hash)
GPUFunction *function;
char *name, *prototypes;
int a;
-
+
/* automatically generate function prototypes to add to the top of the
* generated code, to avoid have to add the actual code & recompile all */
ghi = BLI_ghashIterator_new(hash);
@@ -656,7 +672,7 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds,
/* Handle the UBO block separately. */
if ((material != NULL) && !BLI_listbase_is_empty(&ubo_inputs)) {
- GPU_material_create_uniform_buffer(material, &ubo_inputs);
+ GPU_material_uniform_buffer_create(material, &ubo_inputs);
/* Inputs are sorted */
BLI_dynstr_appendf(ds, "\nlayout (std140) uniform %s {\n", GPU_UBO_BLOCK_NAME);
@@ -716,7 +732,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
for (node = nodes->first; node; node = node->next) {
BLI_dynstr_appendf(ds, "\t%s(", node->name);
-
+
for (input = node->inputs.first; input; input = input->next) {
if (input->source == GPU_SOURCE_TEX) {
BLI_dynstr_appendf(ds, "samp%d", input->texid);
@@ -1099,12 +1115,12 @@ void GPU_code_generate_glsl_lib(void)
/* GPU pass binding/unbinding */
-GPUShader *GPU_pass_shader(GPUPass *pass)
+GPUShader *GPU_pass_shader_get(GPUPass *pass)
{
return pass->shader;
}
-static void gpu_nodes_extract_dynamic_inputs(GPUShader *shader, ListBase *inputs, ListBase *nodes)
+void GPU_nodes_extract_dynamic_inputs(GPUShader *shader, ListBase *inputs, ListBase *nodes)
{
GPUNode *node;
GPUInput *next, *input;
@@ -1146,8 +1162,12 @@ static void gpu_nodes_extract_dynamic_inputs(GPUShader *shader, ListBase *inputs
if (input->bindtex)
extract = 1;
}
- else if (input->dynamicvec)
+ else if (input->dynamictype == GPU_DYNAMIC_UBO) {
+ /* Don't extract UBOs */
+ }
+ else if (input->dynamicvec) {
extract = 1;
+ }
if (extract)
input->shaderloc = GPU_shader_get_uniform(shader, input->shadername);
@@ -1230,7 +1250,7 @@ void GPU_pass_unbind(GPUPass *pass, ListBase *inputs)
if (input->ima || input->prv)
input->tex = NULL;
}
-
+
GPU_shader_unbind();
}
@@ -1251,7 +1271,7 @@ static void gpu_node_link_free(GPUNodeLink *link)
if (link->users < 0)
fprintf(stderr, "GPU_node_link_free: negative refcount\n");
-
+
if (link->users == 0) {
if (link->output)
link->output->link = NULL;
@@ -1292,7 +1312,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType
return;
}
}
-
+
input = MEM_callocN(sizeof(GPUInput), "GPUInput");
input->node = node;
@@ -1683,10 +1703,10 @@ GPUNodeLink *GPU_cube_map(Image *ima, ImageUser *iuser, bool is_data)
GPUNodeLink *GPU_image_preview(PreviewImage *prv)
{
GPUNodeLink *link = GPU_node_link_create();
-
+
link->image = GPU_NODE_LINK_IMAGE_PREVIEW;
link->ptr1 = prv;
-
+
return link;
}
@@ -1870,7 +1890,7 @@ static void gpu_nodes_tag(GPUNodeLink *link)
node = link->output->node;
if (node->tag)
return;
-
+
node->tag = true;
for (input = node->inputs.first; input; input = input->next)
if (input->link)
@@ -1896,16 +1916,25 @@ void GPU_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
}
}
+static bool gpu_pass_is_valid(GPUPass *pass)
+{
+ /* Shader is not null if compilation is successful,
+ * refcount is positive if compilation as not yet been done. */
+ return (pass->shader != NULL || pass->refcount > 0);
+}
+
GPUPass *GPU_generate_pass_new(
GPUMaterial *material,
- GPUNodeLink *frag_outlink, struct GPUVertexAttribs *attribs,
- ListBase *nodes, ListBase *inputs,
- const char *vert_code, const char *geom_code,
- const char *frag_lib, const char *defines)
+ GPUNodeLink *frag_outlink,
+ struct GPUVertexAttribs *attribs,
+ ListBase *nodes,
+ const char *vert_code,
+ const char *geom_code,
+ const char *frag_lib,
+ const char *defines)
{
char *vertexcode, *geometrycode, *fragmentcode;
- GPUShader *shader;
- GPUPass *pass;
+ GPUPass *pass = NULL, *pass_hash = NULL;
/* prune unused nodes */
GPU_nodes_prune(nodes, frag_outlink);
@@ -1914,6 +1943,24 @@ GPUPass *GPU_generate_pass_new(
/* generate code */
char *fragmentgen = code_generate_fragment(material, nodes, frag_outlink->output);
+
+ /* Cache lookup: Reuse shaders already compiled */
+ uint32_t hash = gpu_pass_hash(fragmentgen, defines);
+ pass_hash = gpu_pass_cache_lookup(hash);
+
+ if (pass_hash && (pass_hash->next == NULL || pass_hash->next->hash != hash)) {
+ /* No collision, just return the pass. */
+ MEM_freeN(fragmentgen);
+ if (!gpu_pass_is_valid(pass_hash)) {
+ /* Shader has already been created but failed to compile. */
+ return NULL;
+ }
+ pass_hash->refcount += 1;
+ return pass_hash;
+ }
+
+ /* Either the shader is not compiled or there is a hash collision...
+ * continue generating the shader strings. */
char *tmp = BLI_strdupcat(frag_lib, glsl_material_library);
vertexcode = code_generate_vertex(nodes, vert_code, (geom_code != NULL));
@@ -1923,51 +1970,62 @@ GPUPass *GPU_generate_pass_new(
MEM_freeN(fragmentgen);
MEM_freeN(tmp);
- /* Cache lookup: Reuse shaders already compiled */
- uint32_t hash = gpu_pass_hash(vertexcode, geometrycode, fragmentcode, defines);
- pass = gpu_pass_cache_lookup(vertexcode, geometrycode, fragmentcode, defines, hash);
+ if (pass_hash) {
+ /* Cache lookup: Reuse shaders already compiled */
+ pass = gpu_pass_cache_resolve_collision(pass_hash, vertexcode, geometrycode, fragmentcode, defines, hash);
+ }
+
if (pass) {
/* Cache hit. Reuse the same GPUPass and GPUShader. */
- shader = pass->shader;
- pass->refcount += 1;
+ if (!gpu_pass_is_valid(pass)) {
+ /* Shader has already been created but failed to compile. */
+ return NULL;
+ }
MEM_SAFE_FREE(vertexcode);
MEM_SAFE_FREE(fragmentcode);
MEM_SAFE_FREE(geometrycode);
+
+ pass->refcount += 1;
}
else {
- /* Cache miss. (Re)compile the shader. */
- shader = GPU_shader_create(vertexcode,
- fragmentcode,
- geometrycode,
- NULL,
- defines);
-
/* We still create a pass even if shader compilation
* fails to avoid trying to compile again and again. */
pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
- pass->shader = shader;
+ pass->shader = NULL;
pass->refcount = 1;
pass->hash = hash;
pass->vertexcode = vertexcode;
pass->fragmentcode = fragmentcode;
pass->geometrycode = geometrycode;
- pass->libcode = glsl_material_library;
pass->defines = (defines) ? BLI_strdup(defines) : NULL;
+ pass->compiled = false;
- BLI_linklist_prepend(&pass_cache, pass);
+ BLI_spin_lock(&pass_cache_spin);
+ if (pass_hash != NULL) {
+ /* Add after the first pass having the same hash. */
+ pass->next = pass_hash->next;
+ pass_hash->next = pass;
+ }
+ else {
+ /* No other pass have same hash, just prepend to the list. */
+ BLI_LINKS_PREPEND(pass_cache, pass);
+ }
+ BLI_spin_unlock(&pass_cache_spin);
}
- /* did compilation failed ? */
- if (!shader) {
- gpu_nodes_free(nodes);
- /* Pass will not be used. Don't increment refcount. */
- pass->refcount--;
- return NULL;
- }
- else {
- gpu_nodes_extract_dynamic_inputs(shader, inputs, nodes);
- return pass;
+ return pass;
+}
+
+void GPU_pass_compile(GPUPass *pass)
+{
+ if (!pass->compiled) {
+ pass->shader = GPU_shader_create(pass->vertexcode,
+ pass->fragmentcode,
+ pass->geometrycode,
+ NULL,
+ pass->defines);
+ pass->compiled = true;
}
}
@@ -2006,23 +2064,36 @@ void GPU_pass_cache_garbage_collect(void)
lasttime = ctime;
- LinkNode *next, **prev_ln = &pass_cache;
- for (LinkNode *ln = pass_cache; ln; ln = next) {
- GPUPass *pass = (GPUPass *)ln->link;
- next = ln->next;
+ BLI_spin_lock(&pass_cache_spin);
+ GPUPass *next, **prev_pass = &pass_cache;
+ for (GPUPass *pass = pass_cache; pass; pass = next) {
+ next = pass->next;
if (pass->refcount == 0) {
- gpu_pass_free(pass);
/* Remove from list */
- MEM_freeN(ln);
- *prev_ln = next;
+ *prev_pass = next;
+ gpu_pass_free(pass);
}
else {
- prev_ln = &ln->next;
+ prev_pass = &pass->next;
}
}
+ BLI_spin_unlock(&pass_cache_spin);
+}
+
+void GPU_pass_cache_init(void)
+{
+ BLI_spin_init(&pass_cache_spin);
}
void GPU_pass_cache_free(void)
{
- BLI_linklist_free(pass_cache, (LinkNodeFreeFP)gpu_pass_free);
+ BLI_spin_lock(&pass_cache_spin);
+ while (pass_cache) {
+ GPUPass *next = pass_cache->next;
+ gpu_pass_free(pass_cache);
+ pass_cache = next;
+ }
+ BLI_spin_unlock(&pass_cache_spin);
+
+ BLI_spin_end(&pass_cache_spin);
}
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 328da36c3de..04bee545a7e 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -157,33 +157,30 @@ typedef struct GPUInput {
} GPUInput;
struct GPUPass {
+ struct GPUPass *next;
+
struct GPUShader *shader;
char *fragmentcode;
char *geometrycode;
char *vertexcode;
char *defines;
- const char *libcode;
unsigned int refcount; /* Orphaned GPUPasses gets freed by the garbage collector. */
uint32_t hash; /* Identity hash generated from all GLSL code. */
+ bool compiled; /* Did we already tried to compile the attached GPUShader. */
};
-
typedef struct GPUPass GPUPass;
GPUPass *GPU_generate_pass_new(
GPUMaterial *material,
GPUNodeLink *frag_outlink, struct GPUVertexAttribs *attribs,
- ListBase *nodes, ListBase *inputs,
+ ListBase *nodes,
const char *vert_code, const char *geom_code,
const char *frag_lib, const char *defines);
-GPUPass *GPU_generate_pass(
- ListBase *nodes, ListBase *inputs, struct GPUNodeLink *outlink,
- struct GPUVertexAttribs *attribs, int *builtin,
- const GPUMatType type, const char *name,
- const bool use_opensubdiv);
-struct GPUShader *GPU_pass_shader(GPUPass *pass);
+struct GPUShader *GPU_pass_shader_get(GPUPass *pass);
+void GPU_nodes_extract_dynamic_inputs(struct GPUShader *shader, ListBase *inputs, ListBase *nodes);
void GPU_nodes_get_vertex_attributes(ListBase *nodes, struct GPUVertexAttribs *attribs);
void GPU_nodes_prune(ListBase *nodes, struct GPUNodeLink *outlink);
@@ -191,6 +188,7 @@ void GPU_pass_bind(GPUPass *pass, ListBase *inputs, double time, int mipmap);
void GPU_pass_update_uniforms(GPUPass *pass, ListBase *inputs);
void GPU_pass_unbind(GPUPass *pass, ListBase *inputs);
+void GPU_pass_compile(GPUPass *pass);
void GPU_pass_release(GPUPass *pass);
void GPU_pass_free_nodes(ListBase *nodes);
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 73e86c1b391..226711e230f 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -174,7 +174,7 @@ void gpu_extensions_init(void)
const char *renderer = (const char *)glGetString(GL_RENDERER);
const char *version = (const char *)glGetString(GL_VERSION);
- if (strstr(vendor, "ATI")) {
+ if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) {
GG.device = GPU_DEVICE_ATI;
GG.driver = GPU_DRIVER_OFFICIAL;
}
@@ -191,6 +191,7 @@ void gpu_extensions_init(void)
GG.driver = GPU_DRIVER_OFFICIAL;
}
else if ((strstr(renderer, "Mesa DRI R")) ||
+ (strstr(renderer, "Radeon") && strstr(vendor, "X.Org")) ||
(strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")) ||
(strstr(renderer, "Gallium ") && strstr(renderer, " on AMD ")))
{
@@ -214,6 +215,7 @@ void gpu_extensions_init(void)
GG.driver = GPU_DRIVER_SOFTWARE;
}
else {
+ printf("Warning: Could not find a matching GPU name. Things may not behave as expected.\n");
GG.device = GPU_DEVICE_ANY;
GG.driver = GPU_DRIVER_ANY;
}
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 75576c35f51..f86da2eb064 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -680,7 +680,7 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool dept
if (!GPU_framebuffer_check_valid(ofs->fb, err_out)) {
GPU_offscreen_free(ofs);
gpuPopAttrib();
- return NULL;
+ return NULL;
}
GPU_framebuffer_restore();
@@ -698,7 +698,7 @@ void GPU_offscreen_free(GPUOffScreen *ofs)
GPU_texture_free(ofs->color);
if (ofs->depth)
GPU_texture_free(ofs->depth);
-
+
MEM_freeN(ofs);
}
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index c2f14687ff5..92ad9d81b6c 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -34,6 +34,7 @@
#include "GPU_init_exit.h" /* interface */
#include "GPU_immediate.h"
#include "GPU_batch.h"
+#include "GPU_texture.h"
#include "BKE_global.h"
#include "intern/gpu_codegen.h"
@@ -56,6 +57,8 @@ void GPU_init(void)
gpu_extensions_init(); /* must come first */
+ GPU_texture_orphans_init();
+ GPU_material_orphans_init();
gpu_codegen_init();
if (G.debug & G_DEBUG_GPU)
@@ -80,6 +83,9 @@ void GPU_exit(void)
gpu_batch_exit();
+ GPU_texture_orphans_exit();
+ GPU_material_orphans_exit();
+
if (G.debug & G_DEBUG_GPU)
gpu_debug_exit();
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 1d3c1d13be3..302ddc62188 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -46,6 +46,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_rand.h"
+#include "BLI_threads.h"
#include "BKE_anim.h"
#include "BKE_colorband.h"
@@ -74,6 +75,9 @@
# include "BKE_DerivedMesh.h"
#endif
+static ListBase g_orphaned_mat = {NULL, NULL};
+static ThreadMutex g_orphan_lock;
+
/* Structs */
struct GPUMaterial {
@@ -87,7 +91,7 @@ struct GPUMaterial {
const void *engine_type; /* attached engine type */
int options; /* to identify shader variations (shadow, probe, world background...) */
-
+
/* for creating the material */
ListBase nodes;
GPUNodeLink *outlink;
@@ -127,10 +131,11 @@ struct GPUMaterial {
/* Eevee SSS */
GPUUniformBuffer *sss_profile; /* UBO containing SSS profile. */
GPUTexture *sss_tex_profile; /* Texture containing SSS profile. */
- float *sss_radii; /* UBO containing SSS profile. */
+ float sss_enabled;
+ float sss_radii[3];
int sss_samples;
- short int *sss_falloff;
- float *sss_sharpness;
+ short int sss_falloff;
+ float sss_sharpness;
bool sss_dirty;
};
@@ -142,36 +147,70 @@ enum {
/* Functions */
-void GPU_material_free(ListBase *gpumaterial)
+static void gpu_material_free_single(GPUMaterial *material)
{
- for (LinkData *link = gpumaterial->first; link; link = link->next) {
- GPUMaterial *material = link->data;
+ /* Cancel / wait any pending lazy compilation. */
+ DRW_deferred_shader_remove(material);
- /* Cancel / wait any pending lazy compilation. */
- DRW_deferred_shader_remove(material);
+ GPU_pass_free_nodes(&material->nodes);
+ GPU_inputs_free(&material->inputs);
- GPU_pass_free_nodes(&material->nodes);
- GPU_inputs_free(&material->inputs);
+ if (material->pass)
+ GPU_pass_release(material->pass);
- if (material->pass)
- GPU_pass_release(material->pass);
+ if (material->ubo != NULL) {
+ GPU_uniformbuffer_free(material->ubo);
+ }
- if (material->ubo != NULL) {
- GPU_uniformbuffer_free(material->ubo);
- }
+ if (material->sss_tex_profile != NULL) {
+ GPU_texture_free(material->sss_tex_profile);
+ }
- if (material->sss_tex_profile != NULL) {
- GPU_texture_free(material->sss_tex_profile);
- }
+ if (material->sss_profile != NULL) {
+ GPU_uniformbuffer_free(material->sss_profile);
+ }
+}
- if (material->sss_profile != NULL) {
- GPU_uniformbuffer_free(material->sss_profile);
+void GPU_material_free(ListBase *gpumaterial)
+{
+ for (LinkData *link = gpumaterial->first; link; link = link->next) {
+ GPUMaterial *material = link->data;
+
+ /* TODO(fclem): Check if the thread has an ogl context. */
+ if (BLI_thread_is_main()) {
+ gpu_material_free_single(material);
+ MEM_freeN(material);
+ }
+ else {
+ BLI_mutex_lock(&g_orphan_lock);
+ BLI_addtail(&g_orphaned_mat, BLI_genericNodeN(material));
+ BLI_mutex_unlock(&g_orphan_lock);
}
+ }
+ BLI_freelistN(gpumaterial);
+}
- MEM_freeN(material);
+void GPU_material_orphans_init(void)
+{
+ BLI_mutex_init(&g_orphan_lock);
+}
+
+void GPU_material_orphans_delete(void)
+{
+ BLI_mutex_lock(&g_orphan_lock);
+ LinkData *link;
+ while ((link = BLI_pophead(&g_orphaned_mat))) {
+ gpu_material_free_single((GPUMaterial *)link->data);
+ MEM_freeN(link->data);
+ MEM_freeN(link);
}
+ BLI_mutex_unlock(&g_orphan_lock);
+}
- BLI_freelistN(gpumaterial);
+void GPU_material_orphans_exit(void)
+{
+ GPU_material_orphans_delete();
+ BLI_mutex_end(&g_orphan_lock);
}
GPUBuiltin GPU_get_material_builtins(GPUMaterial *material)
@@ -199,7 +238,7 @@ ListBase *GPU_material_get_inputs(GPUMaterial *material)
return &material->inputs;
}
-GPUUniformBuffer *GPU_material_get_uniform_buffer(GPUMaterial *material)
+GPUUniformBuffer *GPU_material_uniform_buffer_get(GPUMaterial *material)
{
return material->ubo;
}
@@ -208,24 +247,11 @@ GPUUniformBuffer *GPU_material_get_uniform_buffer(GPUMaterial *material)
* Create dynamic UBO from parameters
* \param ListBase of BLI_genericNodeN(GPUInput)
*/
-void GPU_material_create_uniform_buffer(GPUMaterial *material, ListBase *inputs)
+void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs)
{
material->ubo = GPU_uniformbuffer_dynamic_create(inputs, NULL);
}
-void GPU_material_uniform_buffer_tag_dirty(ListBase *gpumaterials)
-{
- for (LinkData *link = gpumaterials->first; link; link = link->next) {
- GPUMaterial *material = link->data;
- if (material->ubo != NULL) {
- GPU_uniformbuffer_tag_dirty(material->ubo);
- }
- if (material->sss_profile != NULL) {
- material->sss_dirty = true;
- }
- }
-}
-
/* Eevee Subsurface scattering. */
/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
@@ -328,7 +354,7 @@ static float eval_integral(float x0, float x1, short falloff_type, float sharpne
#undef INTEGRAL_RESOLUTION
static void compute_sss_kernel(
- GPUSssKernelData *kd, float *radii, int sample_ct, int falloff_type, float sharpness)
+ GPUSssKernelData *kd, float radii[3], int sample_ct, int falloff_type, float sharpness)
{
float rad[3];
/* Minimum radius */
@@ -483,12 +509,13 @@ static void compute_sss_translucence_kernel(
}
#undef INTEGRAL_RESOLUTION
-void GPU_material_sss_profile_create(GPUMaterial *material, float *radii, short *falloff_type, float *sharpness)
+void GPU_material_sss_profile_create(GPUMaterial *material, float radii[3], short *falloff_type, float *sharpness)
{
- material->sss_radii = radii;
- material->sss_falloff = falloff_type;
- material->sss_sharpness = sharpness;
+ copy_v3_v3(material->sss_radii, radii);
+ material->sss_falloff = (falloff_type) ? *falloff_type : 0.0;
+ material->sss_sharpness = (sharpness) ? *sharpness : 0.0;
material->sss_dirty = true;
+ material->sss_enabled = true;
/* Update / Create UBO */
if (material->sss_profile == NULL) {
@@ -498,25 +525,25 @@ void GPU_material_sss_profile_create(GPUMaterial *material, float *radii, short
struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material, int sample_ct, GPUTexture **tex_profile)
{
- if (material->sss_radii == NULL)
+ if (!material->sss_enabled)
return NULL;
if (material->sss_dirty || (material->sss_samples != sample_ct)) {
GPUSssKernelData kd;
- float sharpness = (material->sss_sharpness != NULL) ? *material->sss_sharpness : 0.0f;
+ float sharpness = material->sss_sharpness;
/* XXX Black magic but it seems to fit. Maybe because we integrate -1..1 */
sharpness *= 0.5f;
- compute_sss_kernel(&kd, material->sss_radii, sample_ct, *material->sss_falloff, sharpness);
+ compute_sss_kernel(&kd, material->sss_radii, sample_ct, material->sss_falloff, sharpness);
/* Update / Create UBO */
GPU_uniformbuffer_update(material->sss_profile, &kd);
/* Update / Create Tex */
float *translucence_profile;
- compute_sss_translucence_kernel(&kd, 64, *material->sss_falloff, sharpness, &translucence_profile);
+ compute_sss_translucence_kernel(&kd, 64, material->sss_falloff, sharpness, &translucence_profile);
if (material->sss_tex_profile != NULL) {
GPU_texture_free(material->sss_tex_profile);
@@ -602,7 +629,8 @@ GPUMaterial *GPU_material_from_nodetree_find(
* so only do this when they are needed.
*/
GPUMaterial *GPU_material_from_nodetree(
- Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, const void *engine_type, int options)
+ Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, const void *engine_type, int options,
+ const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines)
{
LinkData *link;
bool has_volume_output, has_surface_output;
@@ -631,11 +659,38 @@ GPUMaterial *GPU_material_from_nodetree(
* generated VBOs are ready to accept the future shader. */
GPU_nodes_prune(&mat->nodes, mat->outlink);
GPU_nodes_get_vertex_attributes(&mat->nodes, &mat->attribs);
- mat->status = GPU_MAT_QUEUED;
+ /* Create source code and search pass cache for an already compiled version. */
+ mat->pass = GPU_generate_pass_new(mat,
+ mat->outlink,
+ &mat->attribs,
+ &mat->nodes,
+ vert_code,
+ geom_code,
+ frag_lib,
+ defines);
+
+ if (mat->pass == NULL) {
+ /* We had a cache hit and the shader has already failed to compile. */
+ mat->status = GPU_MAT_FAILED;
+ }
+ else {
+ GPUShader *sh = GPU_pass_shader_get(mat->pass);
+ if (sh != NULL) {
+ /* We had a cache hit and the shader is already compiled. */
+ mat->status = GPU_MAT_SUCCESS;
+ GPU_nodes_extract_dynamic_inputs(sh, &mat->inputs, &mat->nodes);
+ }
+ else {
+ mat->status = GPU_MAT_QUEUED;
+ }
+ }
+ }
+ else {
+ mat->status = GPU_MAT_FAILED;
}
/* note that even if building the shader fails in some way, we still keep
- * it to avoid trying to compile again and again, and simple do not use
+ * it to avoid trying to compile again and again, and simply do not use
* the actual shader on drawing */
link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
@@ -645,17 +700,26 @@ GPUMaterial *GPU_material_from_nodetree(
return mat;
}
-void GPU_material_generate_pass(
- GPUMaterial *mat, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines)
+void GPU_material_compile(GPUMaterial *mat)
{
- BLI_assert(mat->pass == NULL); /* Only run once! */
- if (mat->outlink) {
- mat->pass = GPU_generate_pass_new(
- mat, mat->outlink, &mat->attribs, &mat->nodes, &mat->inputs, vert_code, geom_code, frag_lib, defines);
- mat->status = (mat->pass) ? GPU_MAT_SUCCESS : GPU_MAT_FAILED;
+ /* Only run once! */
+ BLI_assert(mat->status == GPU_MAT_QUEUED);
+ BLI_assert(mat->pass);
+
+ /* NOTE: The shader may have already been compiled here since we are
+ * sharing GPUShader across GPUMaterials. In this case it's a no-op. */
+ GPU_pass_compile(mat->pass);
+ GPUShader *sh = GPU_pass_shader_get(mat->pass);
+
+ if (sh != NULL) {
+ mat->status = GPU_MAT_SUCCESS;
+ GPU_nodes_extract_dynamic_inputs(sh, &mat->inputs, &mat->nodes);
}
else {
mat->status = GPU_MAT_FAILED;
+ GPU_pass_free_nodes(&mat->nodes);
+ GPU_pass_release(mat->pass);
+ mat->pass = NULL;
}
}
@@ -670,6 +734,6 @@ void GPU_materials_free(void)
for (wo = G.main->world.first; wo; wo = wo->id.next)
GPU_material_free(&wo->gpumaterial);
-
+
GPU_material_free(&defmaterial.gpumaterial);
}
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 953f6daf805..fecac55087f 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -36,7 +36,7 @@
#include "GPU_select.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-
+
#include "MEM_guardedalloc.h"
#include "BLI_rect.h"
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index 919ccbea2e9..4520025ea7f 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -37,7 +37,7 @@
#include "GPU_select.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-
+
#include "MEM_guardedalloc.h"
#include "BLI_rect.h"
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 2068c5a6a75..8c978be81c1 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -189,11 +189,11 @@ static void shader_print_errors(const char *task, const char *log, const char **
c = pos + 1;
line++;
}
-
+
fprintf(stderr, "%s", c);
}
}
-
+
fprintf(stderr, "%s\n", log);
}
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 14d0b27bc28..aac75014b3e 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -32,6 +32,8 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math_base.h"
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
#include "BKE_global.h"
@@ -49,6 +51,9 @@ static struct GPUTextureGlobal {
GPUTexture *invalid_tex_3D;
} GG = {NULL, NULL, NULL};
+static ListBase g_orphaned_tex = {NULL, NULL};
+static ThreadMutex g_orphan_lock;
+
/* Maximum number of FBOs a texture can be attached to. */
#define GPU_TEX_MAX_FBO_ATTACHED 8
@@ -731,10 +736,10 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
{
GPUTexture *tex = prv->gputexture[0];
GLuint bindcode = 0;
-
+
if (tex)
bindcode = tex->bindcode;
-
+
/* this binds a texture, so that's why we restore it to 0 */
if (bindcode == 0) {
GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], GL_TEXTURE_2D, mipmap, 0, NULL);
@@ -753,9 +758,9 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
tex->target_base = GL_TEXTURE_2D;
tex->format = -1;
tex->components = -1;
-
+
prv->gputexture[0] = tex;
-
+
if (!glIsTexture(tex->bindcode)) {
GPU_print_error_debug("Blender Texture Not Loaded");
}
@@ -765,13 +770,13 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
glBindTexture(GL_TEXTURE_2D, tex->bindcode);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
-
+
tex->w = w;
tex->h = h;
}
-
+
glBindTexture(GL_TEXTURE_2D, 0);
-
+
return tex;
}
@@ -1083,13 +1088,23 @@ void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat)
glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_R, repeat);
}
+static void gpu_texture_delete(GPUTexture *tex)
+{
+ if (tex->bindcode && !tex->fromblender)
+ glDeleteTextures(1, &tex->bindcode);
+
+ gpu_texture_memory_footprint_remove(tex);
+
+ MEM_freeN(tex);
+}
+
void GPU_texture_free(GPUTexture *tex)
{
tex->refcount--;
if (tex->refcount < 0)
fprintf(stderr, "GPUTexture: negative refcount\n");
-
+
if (tex->refcount == 0) {
for (int i = 0; i < GPU_TEX_MAX_FBO_ATTACHED; ++i) {
if (tex->fb[i] != NULL) {
@@ -1097,13 +1112,38 @@ void GPU_texture_free(GPUTexture *tex)
}
}
- if (tex->bindcode && !tex->fromblender)
- glDeleteTextures(1, &tex->bindcode);
+ /* TODO(fclem): Check if the thread has an ogl context. */
+ if (BLI_thread_is_main()) {
+ gpu_texture_delete(tex);
+ }
+ else {
+ BLI_mutex_lock(&g_orphan_lock);
+ BLI_addtail(&g_orphaned_tex, BLI_genericNodeN(tex));
+ BLI_mutex_unlock(&g_orphan_lock);
+ }
+ }
+}
- gpu_texture_memory_footprint_remove(tex);
+void GPU_texture_orphans_init(void)
+{
+ BLI_mutex_init(&g_orphan_lock);
+}
- MEM_freeN(tex);
+void GPU_texture_orphans_delete(void)
+{
+ BLI_mutex_lock(&g_orphan_lock);
+ LinkData *link;
+ while ((link = BLI_pophead(&g_orphaned_tex))) {
+ gpu_texture_delete((GPUTexture *)link->data);
+ MEM_freeN(link);
}
+ BLI_mutex_unlock(&g_orphan_lock);
+}
+
+void GPU_texture_orphans_exit(void)
+{
+ GPU_texture_orphans_delete();
+ BLI_mutex_end(&g_orphan_lock);
}
void GPU_texture_ref(GPUTexture *tex)
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c
index afd43600d9b..1e39b2ea5b7 100644
--- a/source/blender/gpu/intern/gpu_uniformbuffer.c
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -62,26 +62,14 @@ struct GPUUniformBuffer {
typedef struct GPUUniformBufferDynamic {
GPUUniformBuffer buffer;
- ListBase items; /* GPUUniformBufferDynamicItem */
- void *data;
+ void *data; /* Continuous memory block to copy to GPU. */
char flag;
} GPUUniformBufferDynamic;
-struct GPUUniformBufferDynamicItem {
- struct GPUUniformBufferDynamicItem *next, *prev;
- GPUType gputype;
- float *data;
- int size;
-};
-
-
/* Prototypes */
static GPUType get_padded_gpu_type(struct LinkData *link);
static void gpu_uniformbuffer_inputs_sort(struct ListBase *inputs);
-static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
- GPUUniformBufferDynamic *ubo, const GPUType gputype, float *num);
-
/* Only support up to this type, if you want to extend it, make sure the
* padding logic is correct for the new types. */
#define MAX_UBO_GPU_TYPE GPU_VEC4
@@ -159,34 +147,47 @@ GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_ou
gpu_uniformbuffer_inputs_sort(inputs);
for (LinkData *link = inputs->first; link; link = link->next) {
- GPUInput *input = link->data;
- GPUType gputype = get_padded_gpu_type(link);
- gpu_uniformbuffer_populate(ubo, gputype, input->dynamicvec);
+ const GPUType gputype = get_padded_gpu_type(link);
+ ubo->buffer.size += gputype * sizeof(float);
}
+ /* Allocate the data. */
ubo->data = MEM_mallocN(ubo->buffer.size, __func__);
- /* Initialize buffer data. */
- GPU_uniformbuffer_dynamic_update(&ubo->buffer);
+ /* Now that we know the total ubo size we can start populating it. */
+ float *offset = ubo->data;
+ for (LinkData *link = inputs->first; link; link = link->next) {
+ GPUInput *input = link->data;
+ const GPUType gputype = get_padded_gpu_type(link);
+ memcpy(offset, input->dynamicvec, gputype * sizeof(float));
+ offset += gputype;
+ }
+
+ /* Note since we may create the UBOs in the CPU in a different thread than the main drawing one,
+ * we don't create the UBO in the GPU here. This will happen when we first bind the UBO.
+ */
+
return &ubo->buffer;
}
/**
- * Free the data, and clean the items list.
+ * Free the data
*/
-static void gpu_uniformbuffer_dynamic_reset(GPUUniformBufferDynamic *ubo)
+static void gpu_uniformbuffer_dynamic_free(GPUUniformBuffer *ubo_)
{
+ BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
+ GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
+
ubo->buffer.size = 0;
if (ubo->data) {
MEM_freeN(ubo->data);
}
- BLI_freelistN(&ubo->items);
}
void GPU_uniformbuffer_free(GPUUniformBuffer *ubo)
{
if (ubo->type == GPU_UBO_DYNAMIC) {
- gpu_uniformbuffer_dynamic_reset((GPUUniformBufferDynamic *)ubo);
+ gpu_uniformbuffer_dynamic_free(ubo);
}
glDeleteBuffers(1, &ubo->bindcode);
@@ -215,12 +216,6 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
- float *offset = ubo->data;
- for (GPUUniformBufferDynamicItem *item = ubo->items.first; item; item = item->next) {
- memcpy(offset, item->data, item->size);
- offset += item->gputype;
- }
-
if (ubo->flag & GPU_UBO_FLAG_INITIALIZED) {
gpu_uniformbuffer_update(ubo_, ubo->data);
}
@@ -316,27 +311,6 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
}
}
-/**
- * This may now happen from the main thread, so we can't update the UBO
- * We simply flag it as dirty
- */
-static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
- GPUUniformBufferDynamic *ubo, const GPUType gputype, float *num)
-{
- BLI_assert(gputype <= MAX_UBO_GPU_TYPE);
- GPUUniformBufferDynamicItem *item = MEM_callocN(sizeof(GPUUniformBufferDynamicItem), __func__);
-
- item->gputype = gputype;
- item->data = num;
- item->size = gputype * sizeof(float);
- ubo->buffer.size += item->size;
-
- ubo->flag |= GPU_UBO_FLAG_DIRTY;
- BLI_addtail(&ubo->items, item);
-
- return item;
-}
-
void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
{
if (number >= GPU_max_ubo_binds()) {
@@ -368,11 +342,4 @@ int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo)
return ubo->bindpoint;
}
-void GPU_uniformbuffer_tag_dirty(GPUUniformBuffer *ubo_)
-{
- BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
- GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
- ubo->flag |= GPU_UBO_FLAG_DIRTY;
-}
-
#undef MAX_UBO_GPU_TYPE
diff --git a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
index dbf6c267f14..bc940222f85 100644
--- a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
@@ -58,8 +58,8 @@ void main()
#elif !defined(GPU_ATI)
// Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA
// graphic cards, while on ATI it can cause a software fallback.
- gl_ClipVertex = co;
-#endif
+ gl_ClipVertex = co;
+#endif
#ifdef USE_COLOR
#ifdef DRAW_LINE
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
index 1dd5bf42b25..86b338e528e 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
@@ -59,4 +59,4 @@ void main()
#else
vert_dof_final();
#endif
-} \ No newline at end of file
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 795320df6b7..4c77dd038af 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2485,8 +2485,8 @@ void node_hair_info(out float is_strand, out float intercept, out float thicknes
is_strand = 1.0;
intercept = hairTime;
thickness = hairThickness;
- tangent = normalize(worldNormal); /* TODO fix naming */
- random = 0.0;
+ tangent = normalize(hairTangent);
+ random = wang_hash_noise(uint(hairStrandID)); /* TODO: could be precomputed per strand instead. */
#else
is_strand = 0.0;
intercept = 0.0;
@@ -2558,7 +2558,23 @@ void node_output_world(Closure surface, Closure volume, out Closure result)
/* EEVEE output */
void world_normals_get(out vec3 N)
{
+#ifdef HAIR_SHADER
+ vec3 B = normalize(cross(worldNormal, hairTangent));
+ float cos_theta;
+ if (hairThicknessRes == 1) {
+ vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ /* Random cosine normal distribution on the hair surface. */
+ cos_theta = rand.x * 2.0 - 1.0;
+ }
+ else {
+ /* Shade as a cylinder. */
+ cos_theta = hairThickTime / hairThickness;
+ }
+ float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));;
+ N = normalize(worldNormal * sin_theta + B * cos_theta);
+#else
N = gl_FrontFacing ? worldNormal : -worldNormal;
+#endif
}
void node_eevee_specular(
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
index 2a6c137e195..e297c242044 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
@@ -103,8 +103,8 @@ void main()
#elif !defined(GPU_ATI)
// Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA
// graphic cards, while on ATI it can cause a software fallback.
- gl_ClipVertex = co;
-#endif
+ gl_ClipVertex = co;
+#endif
#ifdef USE_OPENSUBDIV
outpt.v.position = co;
diff --git a/source/blender/ikplugin/CMakeLists.txt b/source/blender/ikplugin/CMakeLists.txt
index 8991e113410..eb34e50715e 100644
--- a/source/blender/ikplugin/CMakeLists.txt
+++ b/source/blender/ikplugin/CMakeLists.txt
@@ -25,7 +25,7 @@
remove_extra_strict_flags()
-set(INC
+set(INC
.
../blenkernel
../blenlib
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
index 216e60f5c5c..791b74e4bc9 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.c
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -105,7 +105,7 @@ void BIK_execute_tree(struct Depsgraph *depsgraph, struct Scene *scene, Object *
plugin->execute_tree_func(depsgraph, scene, ob, pchan, ctime);
}
-void BIK_release_tree(struct Scene *scene, Object *ob, float ctime)
+void BIK_release_tree(struct Scene *scene, Object *ob, float ctime)
{
IKPlugin *plugin = get_plugin(ob->pose);
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index af303556090..9ad98755be1 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -881,7 +881,7 @@ static int convert_channels(struct Depsgraph *depsgraph, IK_Scene *ikscene, Pose
ikchan->owner = ikscene->blArmature;
// the constraint and channels must be applied before we build the iTaSC scene,
- // this is because some of the pose data (e.g. pose head) don't have corresponding
+ // this is because some of the pose data (e.g. pose head) don't have corresponding
// joint angles and can't be applied to the iTaSC armature dynamically
if (!(pchan->flag & POSE_DONE))
BKE_pose_where_is_bone(depsgraph, ikscene->blscene, ikscene->blArmature, pchan, ctime, 1);
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 6853f5048f1..8043e01a147 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -229,7 +229,7 @@ typedef struct ID {
/* Only set for datablocks which are coming from copy-on-write, points to
* the original version of it.
*/
- void *orig_id;
+ struct ID *orig_id;
void *py_instance;
} ID;
@@ -381,7 +381,8 @@ typedef enum ID_Type {
#define ID_CHECK_UNDO(id) ((GS((id)->name) != ID_SCR) && (GS((id)->name) != ID_WM) && (GS((id)->name) != ID_WS))
-#define ID_BLEND_PATH(_bmain, _id) ((_id)->lib ? (_id)->lib->filepath : (_bmain)->name)
+#define ID_BLEND_PATH(_bmain, _id) ((_id)->lib ? (_id)->lib->filepath : BKE_main_blendfile_path((_bmain)))
+#define ID_BLEND_PATH_FROM_GLOBAL(_id) ((_id)->lib ? (_id)->lib->filepath : BKE_main_blendfile_path_from_global())
#define ID_MISSING(_id) (((_id)->tag & LIB_TAG_MISSING) != 0)
@@ -467,8 +468,8 @@ enum {
LIB_TAG_PRE_EXISTING = 1 << 11,
/* The datablock is a copy-on-write/localized version. */
- LIB_TAG_COPY_ON_WRITE = 1 << 12,
- LIB_TAG_COPY_ON_WRITE_EVAL = 1 << 13,
+ LIB_TAG_COPIED_ON_WRITE = 1 << 12,
+ LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT = 1 << 13,
LIB_TAG_LOCALIZED = 1 << 14,
/* RESET_NEVER tag datablock for freeing etc. behavior (usually set when copying real one into temp/runtime one). */
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 0568af454fc..2266390d348 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -677,10 +677,10 @@ typedef enum eDopeSheet_Flag {
typedef struct SpaceAction {
struct SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale;
-
- short blockhandler[8];
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
View2D v2d DNA_DEPRECATED; /* copied to region */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index daff6ab0baa..f37bccbfe4e 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -145,6 +145,11 @@ typedef struct ObjectDisplay {
/* Not saved in file! */
typedef struct Object_Runtime {
+ /* Original mesh pointer, before object->data was changed to point
+ * to mesh_eval.
+ * Is assigned by dependency graph's copy-on-write evaluation.
+ */
+ struct Mesh *mesh_orig;
/* Mesh structure created during object evaluation.
* It has all modifiers applied.
*/
@@ -337,26 +342,6 @@ typedef struct ObHook {
float force;
} ObHook;
-/* runtime only, but include here for rna access */
-typedef struct DupliObject {
- struct DupliObject *next, *prev;
- struct Object *ob;
- float mat[4][4];
- float orco[3], uv[2];
-
- short type; /* from Object.transflag */
- char no_draw, animated;
-
- /* persistent identifier for a dupli object, for inter-frame matching of
- * objects with motion blur, or inter-update matching for syncing */
- int persistent_id[16]; /* 2*MAX_DUPLI_RECUR */
-
- /* particle this dupli was generated from */
- struct ParticleSystem *particle_system;
- unsigned int random_id;
- unsigned int pad;
-} DupliObject;
-
/* **************** OBJECT ********************* */
/* used many places... should be specialized */
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 7849c05e48b..9213893ae66 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -121,7 +121,9 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */
char panelname[64], tabname[64]; /* defined as UI_MAX_NAME_STR */
char drawname[64]; /* panelname is identifier for restoring location */
- int ofsx, ofsy, sizex, sizey;
+ int ofsx, ofsy; /* offset within the region */
+ int sizex, sizey; /* panel size including children */
+ int blocksizex, blocksizey; /* panel size excluding children */
short labelofs, pad;
short flag, runtime_flag;
short control;
@@ -129,6 +131,7 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */
int sortorder; /* panels are aligned according to increasing sortorder */
struct Panel *paneltab; /* this panel is tabbed in *paneltab */
void *activedata; /* runtime for panel manipulation */
+ ListBase children; /* sub panels */
} Panel;
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index bbea3b168e3..18fd17c006e 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -84,11 +84,13 @@ struct BLI_mempool;
typedef struct SpaceLink {
struct SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED; /* XXX make deprecated */
- short blockhandler[8] DNA_DEPRECATED; /* XXX make deprecated */
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
} SpaceLink;
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Space Info
* \{ */
@@ -97,9 +99,10 @@ typedef struct SpaceLink {
typedef struct SpaceInfo {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
- short blockhandler[8] DNA_DEPRECATED; /* XXX make deprecated */
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
char rpt_mask;
char pad[7];
@@ -124,10 +127,10 @@ typedef enum eSpaceInfo_RptMask {
typedef struct SpaceButs {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
-
- short blockhandler[8] DNA_DEPRECATED;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */
@@ -193,6 +196,7 @@ typedef enum eSpaceButtons_Context {
BCONTEXT_CONSTRAINT = 11,
BCONTEXT_BONE_CONSTRAINT = 12,
BCONTEXT_VIEW_LAYER = 13,
+ BCONTEXT_TOOL = 14,
BCONTEXT_WORKSPACE = 15,
/* always as last... */
@@ -217,12 +221,6 @@ typedef enum eSpaceButtons_Align {
BUT_AUTO = 3,
} eSpaceButtons_Align;
-/* SpaceButs.flag */
-typedef enum eSpaceButtons_SubType {
- SB_SUBTYPE_DATA = 0,
- SB_SUBTYPE_TOOL = 1,
-} eSpaceButtons_SubType;
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -233,9 +231,10 @@ typedef enum eSpaceButtons_SubType {
typedef struct SpaceOops {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
- short blockhandler[8] DNA_DEPRECATED;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */
@@ -370,9 +369,10 @@ typedef enum eSpaceOutliner_Search_Flags {
typedef struct SpaceIpo {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
- short blockhandler[8] DNA_DEPRECATED;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */
@@ -446,9 +446,10 @@ typedef enum eGraphEdit_Mode {
typedef struct SpaceNla {
struct SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
- short blockhandler[8] DNA_DEPRECATED;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
short autosnap; /* this uses the same settings as autosnap for Action Editor */
short flag;
@@ -506,10 +507,10 @@ typedef enum eScreen_Redraws_Flag {
typedef struct SpaceSeq {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
-
- short blockhandler[8] DNA_DEPRECATED;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */
@@ -651,8 +652,12 @@ typedef struct FileSelectParams {
typedef struct SpaceFile {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
+ char _pad1[4];
int scroll_offset;
struct FileSelectParams *params; /* config and input for file select */
@@ -892,9 +897,10 @@ enum {
typedef struct SpaceImage {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
-
- int flag;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
struct Image *image;
struct ImageUser iuser;
@@ -921,7 +927,8 @@ typedef struct SpaceImage {
/* Filter settings when editor shows other object's UVs. */
int other_uv_filter;
- int pad2;
+
+ int flag;
MaskSpaceInfo mask_info;
} SpaceImage;
@@ -1017,9 +1024,10 @@ typedef enum eSpaceImage_OtherUVFilter {
typedef struct SpaceText {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
- short blockhandler[8] DNA_DEPRECATED;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
struct Text *text;
@@ -1100,8 +1108,11 @@ typedef struct Script {
typedef struct SpaceScript {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
+
struct Script *script;
short flags, menunr;
@@ -1130,9 +1141,10 @@ typedef struct bNodeTreePath {
typedef struct SpaceNode {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED;
- short blockhandler[8] DNA_DEPRECATED;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */
@@ -1242,9 +1254,10 @@ typedef enum eConsoleLine_Type {
typedef struct SpaceConsole {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale DNA_DEPRECATED; // XXX are these needed?
- short blockhandler[8] DNA_DEPRECATED; // XXX are these needed?
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
/* space vars */
int lheight, pad;
@@ -1267,9 +1280,12 @@ typedef struct SpaceConsole {
typedef struct SpaceUserPref {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
- char pad[3];
+ char _pad1[7];
char filter_type;
char filter[64]; /* search term for filtering in the UI */
} SpaceUserPref;
@@ -1284,7 +1300,12 @@ typedef struct SpaceUserPref {
typedef struct SpaceClip {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
+
+ char _pad1[4];
float xof, yof; /* user defined offset, image is centered */
float xlockof, ylockof; /* user defined offset from locked position */
@@ -1381,9 +1402,10 @@ typedef enum eSpaceClip_GPencil_Source {
typedef struct SpaceTopBar {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
-
- int pad;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
} SpaceTopBar;
/** \} */
@@ -1399,15 +1421,16 @@ typedef struct SpaceTopBar {
typedef struct SpaceStatusBar {
SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
-
- int pad;
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
} SpaceStatusBar;
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Space Type Definitions
+/** \name Space Defines (eSpace_Type)
* \{ */
/* space types, moved from DNA_screen_types.h */
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 9817d44c96b..17f520fdfa9 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -150,9 +150,9 @@ typedef struct uiWidgetStateColors {
typedef struct uiPanelColors {
char header[4];
char back[4];
+ char sub_back[4];
short show_header;
short show_back;
- int pad;
} uiPanelColors;
typedef struct uiGradientColors {
@@ -617,6 +617,7 @@ typedef enum eUserPref_Section {
USER_SECTION_THEME = 4,
USER_SECTION_INPUT = 5,
USER_SECTION_ADDONS = 6,
+ USER_SECTION_LIGHT = 7,
} eUserPref_Section;
/* UserDef.flag */
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 7bb2ce7af02..9794a1efbf5 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -140,6 +140,7 @@ typedef struct View3DShading {
short light;
char pad[2];
char studio_light[256]; /* FILE_MAXFILE */
+ char matcap[256]; /* FILE_MAXFILE */
float shadow_intensity;
float single_color[3];
@@ -149,6 +150,9 @@ typedef struct View3DShading {
float object_outline_color[3];
float xray_alpha;
+
+ float cavity_valley_factor;
+ float cavity_ridge_factor;
} View3DShading;
/* 3D Viewport Overlay setings */
@@ -165,15 +169,20 @@ typedef struct View3DOverlay {
/* Armature edit/pose mode settings */
int arm_flag;
+ float bone_selection_alpha;
+
+ /* Other settings */
+ float wireframe_threshold;
} View3DOverlay;
/* 3D ViewPort Struct */
typedef struct View3D {
struct SpaceLink *next, *prev;
ListBase regionbase; /* storage of regions for inactive spaces */
- int spacetype;
- float blockscale;
- short blockhandler[8];
+ char spacetype;
+ char link_flag;
+ char _pad0[6];
+ /* End 'SpaceLink' header. */
float viewquat[4] DNA_DEPRECATED;
float dist DNA_DEPRECATED;
@@ -199,7 +208,7 @@ typedef struct View3D {
int layact;
short ob_centre_cursor; /* optional bool for 3d cursor to define center */
- short scenelock, _pad0;
+ short scenelock, _pad1;
short flag, flag2, pad2;
float lens, grid;
@@ -332,7 +341,7 @@ typedef struct View3D {
enum {
V3D_LIGHTING_FLAT = 0,
V3D_LIGHTING_STUDIO = 1,
- V3D_LIGHTING_SCENE = 2
+ V3D_LIGHTING_MATCAP = 2,
};
/* View3DShading->flag */
@@ -342,6 +351,8 @@ enum {
V3D_SHADING_SHADOW = (1 << 2),
V3D_SHADING_SCENE_LIGHT = (1 << 3),
V3D_SHADING_SPECULAR_HIGHLIGHT = (1 << 4),
+ V3D_SHADING_CAVITY = (1 << 5),
+ V3D_SHADING_MATCAP_FLIP_X = (1 << 6),
};
/* View3DShading->single_color_type */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 4b88cace319..1c752d45228 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -806,6 +806,7 @@ PropertyType RNA_property_type(PropertyRNA *prop);
PropertySubType RNA_property_subtype(PropertyRNA *prop);
PropertyUnit RNA_property_unit(PropertyRNA *prop);
int RNA_property_flag(PropertyRNA *prop);
+int RNA_property_override_flag(PropertyRNA *prop);
int RNA_property_tags(PropertyRNA *prop);
bool RNA_property_builtin(PropertyRNA *prop);
void *RNA_property_py_data_get(PropertyRNA *prop);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 4e32651d356..d56ccbcfa01 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -149,6 +149,8 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname,
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag);
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag);
+void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag);
+void RNA_def_property_override_clear_flag(PropertyRNA *prop, PropertyOverrideFlag flag);
void RNA_def_property_tags(PropertyRNA *prop, int tags);
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype);
void RNA_def_property_array(PropertyRNA *prop, int length);
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 788b1372fc8..da2705d4660 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -57,7 +57,6 @@ extern const EnumPropertyItem rna_enum_mesh_select_mode_items[];
extern const EnumPropertyItem rna_enum_mesh_delimit_mode_items[];
extern const EnumPropertyItem rna_enum_space_type_items[];
extern const EnumPropertyItem rna_enum_space_image_mode_items[];
-extern const EnumPropertyItem rna_enum_space_button_mode_items[];
extern const EnumPropertyItem rna_enum_region_type_items[];
extern const EnumPropertyItem rna_enum_object_modifier_type_items[];
extern const EnumPropertyItem rna_enum_constraint_type_items[];
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 5d6f309ad65..9d304018990 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -158,7 +158,7 @@ typedef enum PropertySubType {
/* Make sure enums are updated with these */
/* HIGHEST FLAG IN USE: 1 << 31
- * FREE FLAGS: 11, 13, 14, 15, 30 */
+ * FREE FLAGS: 2, 9, 11, 13, 14, 15, 30 */
typedef enum PropertyFlag {
/* editable means the property is editable in the user
* interface, properties are editable by default except
@@ -176,15 +176,6 @@ typedef enum PropertyFlag {
* and collections */
PROP_ANIMATABLE = (1 << 1),
- /* Means the property can be overriden by a local 'proxy' of some linked datablock. */
- PROP_OVERRIDABLE_STATIC = (1 << 2),
- /* The property supports insertion (collections only). */
- PROP_OVERRIDABLE_STATIC_INSERTION = (1 << 9),
-
- /* Forbid usage of this property in comparison (& hence override) code.
- * Useful e.g. for collections of data like mesh's geometry, particles, etc. */
- PROP_NO_COMPARISON = (1 << 3),
-
/* This flag means when the property's widget is in 'textedit' mode, it will be updated
* after every typed char, instead of waiting final validation. Used e.g. for text searchbox.
* It will also cause UI_BUT_VALUE_CLEAR to be set for text buttons. We could add an own flag
@@ -253,6 +244,27 @@ typedef enum PropertyFlag {
PROP_ENUM_NO_TRANSLATE = (1 << 29), /* for enums not to be translated (e.g. viewlayers' names in nodes) */
} PropertyFlag;
+/* Flags related to comparing and overriding RNA properties. Make sure enums are updated with these */
+/* FREE FLAGS: 2, 3, 4, 5, 6, 7, 8, 9, 12 and above. */
+typedef enum PropertyOverrideFlag {
+ /* Means the property can be overriden by a local 'proxy' of some linked datablock. */
+ PROPOVERRIDE_OVERRIDABLE_STATIC = (1 << 0),
+
+ /* Forbid usage of this property in comparison (& hence override) code.
+ * Useful e.g. for collections of data like mesh's geometry, particles, etc. */
+ PROPOVERRIDE_NO_COMPARISON = (1 << 1),
+
+ /*** Collections-related ***/
+
+ /* The property supports insertion (collections only). */
+ PROPOVERRIDE_STATIC_INSERTION = (1 << 10),
+
+ /* Only use indices to compare items in the property, never names (collections only). */
+ /* Useful when nameprop of the items is generated from other data
+ * (e.g. name of material slots is actually name of assigned material). */
+ PROPOVERRIDE_NO_PROP_NAME = (1 << 11),
+} PropertyOverrideFlag;
+
/* Function parameters flags.
* WARNING: 16bits only. */
typedef enum ParameterFlag {
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 80d1897f604..fe063a8e335 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -290,7 +290,7 @@ static void rna_sortlist(ListBase *listbase, int (*cmp)(const void *, const void
Link *link;
void **array;
int a, size;
-
+
if (listbase->first == listbase->last)
return;
@@ -497,7 +497,7 @@ static int rna_enum_bitmask(PropertyRNA *prop)
if (eprop->item[a].identifier[0])
mask |= eprop->item[a].value;
}
-
+
return mask;
}
@@ -1416,7 +1416,7 @@ static void rna_set_raw_property(PropertyDefRNA *dp, PropertyRNA *prop)
return;
if (!dp->dnatype || !dp->dnaname || !dp->dnastructname)
return;
-
+
if (STREQ(dp->dnatype, "char")) {
prop->rawtype = PROP_RAW_CHAR;
prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
@@ -1677,7 +1677,7 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR
if (sprop->maxlength) {
fprintf(f, "#define %s_%s_MAX %d\n\n", srna->identifier, prop->identifier, sprop->maxlength);
}
-
+
fprintf(f, "void %sget(PointerRNA *ptr, char *value);\n", func);
fprintf(f, "int %slength(PointerRNA *ptr);\n", func);
fprintf(f, "void %sset(PointerRNA *ptr, const char *value);\n", func);
@@ -1733,7 +1733,7 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property
if (prop->flag & PROP_IDPROPERTY || prop->flag_internal & PROP_INTERN_BUILTIN) {
return;
}
-
+
/* disabled for now to avoid msvc compiler error due to large file size */
#if 0
if (prop->name && prop->description && prop->description[0] != '\0')
@@ -2259,7 +2259,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
fprintf(f, "\n{\n");
/* variable definitions */
-
+
if (func->flag & FUNC_USE_SELF_ID) {
fprintf(f, "\tstruct ID *_selfid;\n");
}
@@ -2301,7 +2301,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
/* for dynamic parameters we pass an additional int for the length of the parameter */
if (flag & PROP_DYNAMIC)
fprintf(f, "\tint %s%s_len;\n", pout ? "*" : "", dparm->prop->identifier);
-
+
fprintf(f, "\t%s%s %s%s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop),
ptrstr, dparm->prop->identifier);
}
@@ -2317,7 +2317,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if (func->flag & FUNC_USE_SELF_ID) {
fprintf(f, "\t_selfid = (struct ID *)_ptr->id.data;\n");
}
-
+
if ((func->flag & FUNC_NO_SELF) == 0) {
if (dsrna->dnafromprop) fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", dsrna->dnafromname);
else if (dsrna->dnaname) fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", dsrna->dnaname);
@@ -2886,7 +2886,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
{
char *strnest = (char *)"", *errnest = (char *)"";
int len, freenest = 0;
-
+
if (nest != NULL) {
len = strlen(nest);
@@ -3056,7 +3056,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
else fprintf(f, "NULL,\n");
fprintf(f, "\t%d, ", prop->magic);
rna_print_c_string(f, prop->identifier);
- fprintf(f, ", %d, %d, %d, %d, ", prop->flag, prop->flag_parameter, prop->flag_internal, prop->tags);
+ fprintf(f, ", %d, %d, %d, %d, %d, ", prop->flag, prop->flag_override, prop->flag_parameter, prop->flag_internal, prop->tags);
rna_print_c_string(f, prop->name); fprintf(f, ",\n\t");
rna_print_c_string(f, prop->description); fprintf(f, ",\n\t");
fprintf(f, "%d, ", prop->icon);
@@ -3441,7 +3441,7 @@ static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const
StructDefRNA *ds;
PropertyDefRNA *dp;
FunctionDefRNA *dfunc;
-
+
fprintf(f,
"\n"
"/* Automatically generated struct definitions for the Data API.\n"
@@ -3940,7 +3940,7 @@ static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f)
fprintf(f,
"/* Automatically generated classes for the Data API.\n"
" * Do not edit manually, changes will be overwritten. */\n\n");
-
+
fprintf(f, "#include \"RNA_blender.h\"\n");
fprintf(f, "#include \"RNA_types.h\"\n");
fprintf(f, "#include \"RNA_access.h\"\n");
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 603f4dbc44f..11e45bc688d 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -156,13 +156,13 @@ void rna_ID_name_set(PointerRNA *ptr, const char *value)
static int rna_ID_name_editable(PointerRNA *ptr, const char **UNUSED(r_info))
{
ID *id = (ID *)ptr->data;
-
+
if (GS(id->name) == ID_VF) {
VFont *vfont = (VFont *)id;
if (BKE_vfont_is_builtin(vfont))
return false;
}
-
+
return PROP_EDITABLE;
}
@@ -333,7 +333,7 @@ static ID *rna_ID_copy(ID *id, Main *bmain)
if (newid) id_us_min(newid);
return newid;
}
-
+
return NULL;
}
@@ -817,7 +817,7 @@ static void rna_def_ID_properties(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PropertyGroupItem", NULL);
RNA_def_struct_sdna(srna, "IDProperty");
RNA_def_struct_ui_text(srna, "ID Property", "Property that stores arbitrary, user defined properties");
-
+
/* IDP_STRING */
prop = RNA_def_property(srna, "string", PROP_STRING, PROP_NONE);
RNA_def_property_flag(prop, PROP_EXPORT | PROP_IDPROPERTY);
@@ -903,7 +903,7 @@ static void rna_def_ID_materials(BlenderRNA *brna)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
-
+
/* for mesh/mball/curve materials */
srna = RNA_def_struct(brna, "IDMaterials", NULL);
RNA_def_struct_sdna(srna, "ID");
@@ -1244,7 +1244,7 @@ static void rna_def_library(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "File Path", "Path to the library .blend file");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Library_filepath_set");
-
+
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Library");
RNA_def_property_ui_text(prop, "Parent", "");
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 5a0dec28324..0532aac1bc3 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -107,9 +107,9 @@ void RNA_init(void)
void RNA_exit(void)
{
StructRNA *srna;
-
+
RNA_property_update_cache_free();
-
+
for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
if (srna->cont.prophash) {
BLI_ghash_free(srna->cont.prophash, NULL, NULL);
@@ -137,7 +137,7 @@ void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
PointerRNA tmp = {{NULL}};
tmp.data = id;
idtype = rna_ID_refine(&tmp);
-
+
while (idtype->refine) {
type = idtype->refine(&tmp);
@@ -147,7 +147,7 @@ void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
idtype = type;
}
}
-
+
r_ptr->id.data = id;
r_ptr->type = idtype;
r_ptr->data = id;
@@ -289,7 +289,7 @@ IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create)
if (type && type->idproperties) {
return type->idproperties(ptr, create);
}
-
+
return NULL;
}
@@ -380,7 +380,7 @@ static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDPr
* description and otherwise removes it. this is to ensure that
* rna property access is type safe, e.g. if you defined the rna
* to have a certain array length you can count on that staying so */
-
+
switch (idprop->type) {
case IDP_IDPARRAY:
if (prop->type != PROP_COLLECTION)
@@ -693,7 +693,7 @@ bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
for (base = type; base; base = base->base)
if (base == srna)
return true;
-
+
return false;
}
@@ -718,7 +718,7 @@ PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
if (RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
return propptr.data;
}
-
+
return NULL;
}
@@ -1005,6 +1005,11 @@ int RNA_property_flag(PropertyRNA *prop)
return rna_ensure_property(prop)->flag;
}
+int RNA_property_override_flag(PropertyRNA *prop)
+{
+ return rna_ensure_property(prop)->flag_override;
+}
+
/**
* Get the tags set for \a prop as int bitfield.
* \note Doesn't perform any validity check on the set bits. #RNA_def_property_tags does this
@@ -1175,7 +1180,7 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin,
{
IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
int hardmin, hardmax;
-
+
if (prop->magic != RNA_MAGIC) {
/* attempt to get the local ID values */
IDProperty *idp_ui = rna_idproperty_ui(prop);
@@ -1688,7 +1693,7 @@ bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *pro
{
const EnumPropertyItem *item = NULL;
bool free;
-
+
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
if (item) {
bool result;
@@ -1705,7 +1710,7 @@ bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, con
{
const EnumPropertyItem *item = NULL;
bool free;
-
+
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
if (item) {
bool result;
@@ -1713,7 +1718,7 @@ bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, con
if (free) {
MEM_freeN((void *)item);
}
-
+
return result;
}
return false;
@@ -1927,7 +1932,7 @@ bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
/* check that base ID-block can support animation data */
if (!id_can_have_animdata(ptr->id.data))
return false;
-
+
prop = rna_ensure_property(prop);
if (!(prop->flag & PROP_ANIMATABLE))
@@ -1976,11 +1981,11 @@ bool RNA_property_overridable_get(PointerRNA *ptr, PropertyRNA *prop)
}
}
/* If this is a RNA-defined property (real or 'virtual' IDProp), we want to use RNA prop flag. */
- return !(prop->flag & PROP_NO_COMPARISON) && (prop->flag & PROP_OVERRIDABLE_STATIC);
+ return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON) && (prop->flag_override & PROPOVERRIDE_OVERRIDABLE_STATIC);
}
else {
/* If this is a real 'pure' IDProp (aka custom property), we want to use the IDProp flag. */
- return !(prop->flag & PROP_NO_COMPARISON) && (((IDProperty *)prop)->flag & IDP_FLAG_OVERRIDABLE_STATIC);
+ return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON) && (((IDProperty *)prop)->flag & IDP_FLAG_OVERRIDABLE_STATIC);
}
}
@@ -2016,7 +2021,7 @@ bool RNA_property_comparable(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
prop = rna_ensure_property(prop);
- return !(prop->flag & PROP_NO_COMPARISON);
+ return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON);
}
/* this function is to check if its possible to create a valid path from the ID
@@ -2142,7 +2147,7 @@ void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, Proper
/* cache element */
typedef struct tRnaUpdateCacheElem {
struct tRnaUpdateCacheElem *next, *prev;
-
+
PointerRNA ptr; /* L1 key - id as primary, data secondary/ignored? */
ListBase L2Funcs; /* L2 functions (LinkData<RnaUpdateFuncRef>) */
} tRnaUpdateCacheElem;
@@ -2158,18 +2163,18 @@ void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
tRnaUpdateCacheElem *uce = NULL;
UpdateFunc fn = NULL;
LinkData *ld;
-
+
/* sanity check */
if (NULL == ptr)
return;
-
+
prop = rna_ensure_property(prop);
-
+
/* we can only handle update calls with no context args for now (makes animsys updates easier) */
if ((is_rna == false) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
return;
fn = prop->update;
-
+
/* find cache element for which key matches... */
for (uce = rna_updates_cache.first; uce; uce = uce->next) {
/* just match by id only for now, since most update calls that we'll encounter only really care about this */
@@ -2182,11 +2187,11 @@ void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
/* create new instance */
uce = MEM_callocN(sizeof(tRnaUpdateCacheElem), "tRnaUpdateCacheElem");
BLI_addtail(&rna_updates_cache, uce);
-
+
/* copy pointer */
RNA_pointer_create(ptr->id.data, ptr->type, ptr->data, &uce->ptr);
}
-
+
/* check on the update func */
for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
/* stop on match - function already cached */
@@ -2200,13 +2205,13 @@ void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
{
tRnaUpdateCacheElem *uce;
-
+
/* TODO: should we check that bmain and scene are valid? The above stuff doesn't! */
-
+
/* execute the cached updates */
for (uce = rna_updates_cache.first; uce; uce = uce->next) {
LinkData *ld;
-
+
for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
UpdateFunc fn = (UpdateFunc)ld->data;
fn(bmain, scene, &uce->ptr);
@@ -2217,13 +2222,13 @@ void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
void RNA_property_update_cache_free(void)
{
tRnaUpdateCacheElem *uce, *ucn;
-
+
for (uce = rna_updates_cache.first; uce; uce = ucn) {
ucn = uce->next;
-
+
/* free L2 cache */
BLI_freelistN(&uce->L2Funcs);
-
+
/* remove self */
BLI_freelinkN(&rna_updates_cache, uce);
}
@@ -2424,7 +2429,7 @@ int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
{
BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop);
-
+
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
BLI_assert(RNA_property_array_check(prop) != false);
@@ -2679,7 +2684,7 @@ int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
{
IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
-
+
BLI_assert(RNA_property_type(prop) == PROP_INT);
BLI_assert(RNA_property_array_check(prop) != false);
@@ -2966,7 +2971,7 @@ float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, float *values)
{
FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
-
+
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
BLI_assert(RNA_property_array_check(prop) != false);
@@ -3402,7 +3407,7 @@ void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
if ((idprop = rna_idproperty_check(&prop, ptr))) {
group = RNA_struct_idprops(ptr, 0);
-
+
if (group) {
IDP_FreeFromGroup(group, idprop);
}
@@ -3683,7 +3688,7 @@ int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, Poi
{
CollectionPropertyIterator iter;
int index = 0;
-
+
BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
RNA_property_collection_begin(ptr, prop, &iter);
@@ -3692,7 +3697,7 @@ int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, Poi
break;
}
RNA_property_collection_end(&iter);
-
+
/* did we find it? */
if (iter.valid)
return index;
@@ -3885,7 +3890,7 @@ static int rna_property_array_length_all_dimensions(PointerRNA *ptr, PropertyRNA
for (size = 1, i = 0; i < dim; i++)
size *= len[i];
-
+
return size;
}
@@ -3938,7 +3943,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
out.len * arraylen, in.len);
return 0;
}
-
+
/* matching raw types */
if (out.type == in.type) {
void *inp = in.array;
@@ -4296,7 +4301,7 @@ void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int i
internal->itemsize = itemsize;
internal->skip = skip;
internal->length = length;
-
+
iter->valid = (internal->ptr != internal->endptr);
if (skip && iter->valid && skip(iter, internal->ptr))
@@ -4337,7 +4342,7 @@ void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
void rna_iterator_array_end(CollectionPropertyIterator *iter)
{
ArrayIterator *internal = &iter->internal.array;
-
+
if (internal->free_ptr) {
MEM_freeN(internal->free_ptr);
internal->free_ptr = NULL;
@@ -4392,7 +4397,7 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
len++;
p++;
}
-
+
/* skip the last quoted char to get the ']' */
len++;
p++;
@@ -4409,11 +4414,11 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
p++;
}
}
-
+
/* empty, return */
if (len == 0)
return NULL;
-
+
/* try to use fixed buffer if possible */
if (len + 1 < fixedlen)
buf = fixedbuf;
@@ -4459,22 +4464,22 @@ static bool rna_path_parse_collection_key(const char **path, PointerRNA *ptr, Pr
{
char fixedbuf[256];
int intkey;
-
+
*r_nextptr = *ptr;
/* end of path, ok */
if (!(**path))
return true;
-
+
if (**path == '[') {
char *token;
/* resolve the lookup with [] brackets */
token = rna_path_token(path, fixedbuf, sizeof(fixedbuf), 1);
-
+
if (!token)
return false;
-
+
/* check for "" to see if it is a string */
if (rna_token_strip_quotes(token)) {
if (RNA_property_collection_lookup_string(ptr, prop, token + 1, r_nextptr)) {
@@ -4497,7 +4502,7 @@ static bool rna_path_parse_collection_key(const char **path, PointerRNA *ptr, Pr
r_nextptr->data = NULL;
}
}
-
+
if (token != fixedbuf) {
MEM_freeN(token);
}
@@ -4511,7 +4516,7 @@ static bool rna_path_parse_collection_key(const char **path, PointerRNA *ptr, Pr
r_nextptr->data = NULL;
}
}
-
+
return true;
}
@@ -4522,21 +4527,21 @@ static bool rna_path_parse_array_index(const char **path, PointerRNA *ptr, Prope
int len[RNA_MAX_ARRAY_DIMENSION];
const int dim = RNA_property_array_dimension(ptr, prop, len);
int i;
-
+
*r_index = -1;
-
+
/* end of path, ok */
if (!(**path))
return true;
-
+
for (i = 0; i < dim; i++) {
int temp_index = -1;
char *token;
-
+
/* multi index resolve */
if (**path == '[') {
token = rna_path_token(path, fixedbuf, sizeof(fixedbuf), 1);
-
+
if (token == NULL) {
/* invalid syntax blah[] */
return false;
@@ -4548,12 +4553,12 @@ static bool rna_path_parse_array_index(const char **path, PointerRNA *ptr, Prope
else {
/* otherwise do int lookup */
temp_index = atoi(token);
-
+
if (temp_index == 0 && (token[0] != '0' || token[1] != '\0')) {
if (token != fixedbuf) {
MEM_freeN(token);
}
-
+
return false;
}
}
@@ -4571,33 +4576,33 @@ static bool rna_path_parse_array_index(const char **path, PointerRNA *ptr, Prope
/* just to avoid uninitialized pointer use */
token = fixedbuf;
}
-
+
if (token != fixedbuf) {
MEM_freeN(token);
}
-
+
/* out of range */
if (temp_index < 0 || temp_index >= len[i])
return false;
-
+
index_arr[i] = temp_index;
/* end multi index resolve */
}
-
+
/* arrays always contain numbers so further values are not valid */
if (**path)
return false;
-
+
/* flatten index over all dimensions */
{
int totdim = 1;
int flat_index = 0;
-
+
for (i = dim - 1; i >= 0; i--) {
flat_index += index_arr[i] * totdim;
totdim *= len[i];
}
-
+
*r_index = flat_index;
}
return true;
@@ -4673,7 +4678,7 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
*/
if (eval_pointer || *path) {
PointerRNA nextptr = RNA_property_pointer_get(&curptr, prop);
-
+
curptr = nextptr;
prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
index = -1;
@@ -4690,7 +4695,7 @@ static bool rna_path_parse(PointerRNA *ptr, const char *path,
PointerRNA nextptr;
if (!rna_path_parse_collection_key(&path, &curptr, prop, &nextptr))
return false;
-
+
curptr = nextptr;
prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
index = -1;
@@ -4807,7 +4812,7 @@ char *RNA_path_append(const char *path, PointerRNA *UNUSED(ptr), PropertyRNA *pr
DynStr *dynstr;
const char *s;
char appendstr[128], *result;
-
+
dynstr = BLI_dynstr_new();
/* add .identifier */
@@ -4882,7 +4887,7 @@ char *RNA_path_back(const char *path)
token = rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 1);
if (token && token != fixedbuf)
MEM_freeN(token);
-
+
if (!*current)
break;
@@ -5053,7 +5058,7 @@ char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
if (!ptr->id.data || !ptr->data)
return NULL;
-
+
if (!RNA_struct_is_ID(ptr->type)) {
if (ptr->type->path) {
/* if type has a path to some ID, use it */
@@ -5062,13 +5067,13 @@ char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
else if (ptr->type->nested && RNA_struct_is_ID(ptr->type->nested)) {
PointerRNA parentptr;
PropertyRNA *userprop;
-
+
/* find the property in the struct we're nested in that references this struct, and
* use its identifier as the first part of the path used...
*/
RNA_id_pointer_create(ptr->id.data, &parentptr);
userprop = RNA_struct_find_nested(&parentptr, ptr->type);
-
+
if (userprop)
ptrpath = BLI_strdup(RNA_property_identifier(userprop));
else
@@ -5081,7 +5086,7 @@ char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
else
return NULL;
}
-
+
return ptrpath;
}
@@ -5133,7 +5138,7 @@ char *RNA_path_from_ID_to_property_index(PointerRNA *ptr, PropertyRNA *prop, int
if (!ptr->id.data || !ptr->data)
return NULL;
-
+
/* path from ID to the struct holding this property */
ptrpath = RNA_path_from_ID_to_struct(ptr);
@@ -5863,23 +5868,23 @@ char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr)
{
DynStr *dynstr = BLI_dynstr_new();
char *cstring;
-
+
const char *propname;
int first_time = 1;
-
+
BLI_dynstr_append(dynstr, "{");
-
+
RNA_STRUCT_BEGIN (ptr, prop)
{
propname = RNA_property_identifier(prop);
-
+
if (STREQ(propname, "rna_type"))
continue;
-
+
if (first_time == 0)
BLI_dynstr_append(dynstr, ", ");
first_time = 0;
-
+
cstring = RNA_property_as_string(C, ptr, prop, -1, INT_MAX);
BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
MEM_freeN(cstring);
@@ -5887,8 +5892,8 @@ char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr)
RNA_STRUCT_END;
BLI_dynstr_append(dynstr, "}");
-
-
+
+
cstring = BLI_dynstr_get_cstring(dynstr);
BLI_dynstr_free(dynstr);
return cstring;
@@ -6041,7 +6046,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, in
DynStr *dynstr = BLI_dynstr_new();
char *cstring;
-
+
/* see if we can coerce into a python type - PropertyType */
switch (type) {
@@ -6212,7 +6217,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, in
BLI_dynstr_append(dynstr, cstring);
MEM_freeN(cstring);
}
-
+
RNA_property_collection_end(&collect_iter);
BLI_dynstr_append(dynstr, "]");
break;
@@ -6318,7 +6323,7 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *UNUSE
data_alloc->array_tot = 0;
data_alloc->array = NULL;
}
-
+
if (!(parm->flag_parameter & PARM_REQUIRED) && !(parm->flag & PROP_DYNAMIC)) {
switch (parm->type) {
case PROP_BOOLEAN:
@@ -6747,7 +6752,7 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop
*((PointerRNA *)dest) = *((PointerRNA *)src);
break;
}
-
+
if (ptype != srna && !RNA_struct_is_a(srna, ptype)) {
fprintf(stderr, "%s.%s: wrong type for parameter %s, "
"an object of type %s was expected, passed an object of type %s\n",
@@ -6774,7 +6779,7 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop
lb = (ListBase *)src;
clb = (ListBase *)dest;
ptype = RNA_property_pointer_type(ptr, prop);
-
+
if (ptype != srna && !RNA_struct_is_a(srna, ptype)) {
fprintf(stderr, "%s.%s: wrong type for parameter %s, "
"a collection of objects of type %s was expected, "
@@ -7020,17 +7025,17 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
/* get the length of the array to work with */
len = RNA_property_array_length(ptr, prop);
-
+
/* get and set the default values as appropriate for the various types */
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
if (len) {
if (index == -1) {
int *tmparray = MEM_callocN(sizeof(int) * len, "reset_defaults - boolean");
-
+
RNA_property_boolean_get_default_array(ptr, prop, tmparray);
RNA_property_boolean_set_array(ptr, prop, tmparray);
-
+
MEM_freeN(tmparray);
}
else {
@@ -7047,10 +7052,10 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
if (len) {
if (index == -1) {
int *tmparray = MEM_callocN(sizeof(int) * len, "reset_defaults - int");
-
+
RNA_property_int_get_default_array(ptr, prop, tmparray);
RNA_property_int_set_array(ptr, prop, tmparray);
-
+
MEM_freeN(tmparray);
}
else {
@@ -7067,10 +7072,10 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
if (len) {
if (index == -1) {
float *tmparray = MEM_callocN(sizeof(float) * len, "reset_defaults - float");
-
+
RNA_property_float_get_default_array(ptr, prop, tmparray);
RNA_property_float_set_array(ptr, prop, tmparray);
-
+
MEM_freeN(tmparray);
}
else {
@@ -7089,7 +7094,7 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
RNA_property_enum_set(ptr, prop, value);
return true;
}
-
+
case PROP_STRING:
{
char *value = RNA_property_string_get_default_alloc(ptr, prop, NULL, 0);
@@ -7097,14 +7102,14 @@ bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
MEM_freeN(value);
return true;
}
-
+
case PROP_POINTER:
{
PointerRNA value = RNA_property_pointer_get_default(ptr, prop);
RNA_property_pointer_set(ptr, prop, value);
return true;
}
-
+
default:
/* FIXME: are there still any cases that haven't been handled? comment out "default" block to check :) */
return false;
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index b06038a50e4..5b225b18a78 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -61,13 +61,13 @@ static void rna_ActionGroup_channels_next(CollectionPropertyIterator *iter)
ListBaseIterator *internal = &iter->internal.listbase;
FCurve *fcu = (FCurve *)internal->link;
bActionGroup *grp = fcu->grp;
-
+
/* only continue if the next F-Curve (if existent) belongs in the same group */
if ((fcu->next) && (fcu->next->grp == grp))
internal->link = (Link *)fcu->next;
else
internal->link = NULL;
-
+
iter->valid = (internal->link != NULL);
}
@@ -80,7 +80,7 @@ static void rna_Action_groups_remove(bAction *act, ReportList *reports, PointerR
{
bActionGroup *agrp = agrp_ptr->data;
FCurve *fcu, *fcn;
-
+
/* try to remove the F-Curve from the action */
if (BLI_remlink_safe(&act->groups, agrp) == false) {
BKE_reportf(reports, RPT_ERROR, "Action group '%s' not found in action '%s'", agrp->name, act->id.name + 2);
@@ -141,7 +141,7 @@ static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, PointerR
fcu->grp->name, act->id.name + 2);
return;
}
-
+
action_groups_remove_channel(act, fcu);
free_fcurve(fcu);
RNA_POINTER_INVALIDATE(fcu_ptr);
@@ -151,7 +151,7 @@ static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, PointerR
BKE_reportf(reports, RPT_ERROR, "F-Curve not found in action '%s'", act->id.name + 2);
return;
}
-
+
BLI_remlink(&act->curves, fcu);
free_fcurve(fcu);
RNA_POINTER_INVALIDATE(fcu_ptr);
@@ -227,7 +227,7 @@ int rna_Action_id_poll(PointerRNA *ptr, PointerRNA value)
{
ID *srcId = (ID *)ptr->id.data;
bAction *act = (bAction *)value.id.data;
-
+
if (act) {
/* there can still be actions that will have undefined id-root
* (i.e. floating "action-library" members) which we will not
@@ -238,7 +238,7 @@ int rna_Action_id_poll(PointerRNA *ptr, PointerRNA value)
else if (srcId)
return GS(srcId->name) == act->idroot;
}
-
+
return 0;
}
@@ -247,7 +247,7 @@ int rna_Action_actedit_assign_poll(PointerRNA *ptr, PointerRNA value)
{
SpaceAction *saction = (SpaceAction *)ptr->data;
bAction *act = (bAction *)value.id.data;
-
+
if (act) {
/* there can still be actions that will have undefined id-root
* (i.e. floating "action-library" members) which we will not
@@ -255,7 +255,7 @@ int rna_Action_actedit_assign_poll(PointerRNA *ptr, PointerRNA value)
*/
if (act->idroot == 0)
return 1;
-
+
if (saction) {
if (saction->mode == SACTCONT_ACTION) {
/* this is only Object-level for now... */
@@ -267,7 +267,7 @@ int rna_Action_actedit_assign_poll(PointerRNA *ptr, PointerRNA value)
}
}
}
-
+
return 0;
}
@@ -281,14 +281,14 @@ static void rna_def_dopesheet(BlenderRNA *brna)
srna = RNA_def_struct(brna, "DopeSheet", NULL);
RNA_def_struct_sdna(srna, "bDopeSheet");
RNA_def_struct_ui_text(srna, "Dope Sheet", "Settings for filtering the channels shown in animation editors");
-
+
/* Source of DopeSheet data */
/* XXX: make this obsolete? */
prop = RNA_def_property(srna, "source", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ID");
RNA_def_property_ui_text(prop, "Source",
"ID-Block representing source data, usually ID_SCE (i.e. Scene)");
-
+
/* Show data-block filters */
prop = RNA_def_property(srna, "show_datablock_filters", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ADS_FLAG_SHOW_DBFILTERS);
@@ -296,20 +296,20 @@ static void rna_def_dopesheet(BlenderRNA *brna)
"Show options for whether channels related to certain types of data are included");
RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN, NULL);
-
+
/* General Filtering Settings */
prop = RNA_def_property(srna, "show_only_selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLYSEL);
RNA_def_property_ui_text(prop, "Only Selected", "Only include channels relating to selected objects and data");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_hidden", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_INCL_HIDDEN);
RNA_def_property_ui_text(prop, "Display Hidden", "Include channels from objects/bone that are not visible");
RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "use_datablock_sort", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ADS_FLAG_NO_DB_SORT);
RNA_def_property_ui_text(prop, "Sort Data-Blocks",
@@ -317,14 +317,14 @@ static void rna_def_dopesheet(BlenderRNA *brna)
"(disable to increase viewport speed)");
RNA_def_property_ui_icon(prop, ICON_SORTALPHA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* Debug Filtering Settings */
prop = RNA_def_property(srna, "show_only_errors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLY_ERRORS);
RNA_def_property_ui_text(prop, "Show Errors", "Only include F-Curves and drivers that are disabled or have errors");
RNA_def_property_ui_icon(prop, ICON_HELP, 0); /* XXX: this doesn't quite fit */
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* Object Collection Filtering Settings */
prop = RNA_def_property(srna, "show_only_collection_objects", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLYOBGROUP);
@@ -332,13 +332,13 @@ static void rna_def_dopesheet(BlenderRNA *brna)
"Only include channels from objects in the specified collection");
RNA_def_property_ui_icon(prop, ICON_GROUP, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "filter_collection", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "filter_grp");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Filtering Collection", "Collection that included object should be a member of");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* FCurve Display Name Search Settings */
prop = RNA_def_property(srna, "show_only_matching_fcurves", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_BY_FCU_NAME);
@@ -346,13 +346,13 @@ static void rna_def_dopesheet(BlenderRNA *brna)
"Only include F-Curves with names containing search text");
RNA_def_property_ui_icon(prop, ICON_VIEWZOOM, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "filter_fcurve_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "searchstr");
RNA_def_property_ui_text(prop, "F-Curve Name Filter", "F-Curve live filtering string");
RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* NLA Name Search Settings (Shared with FCurve setting, but with different labels) */
prop = RNA_def_property(srna, "use_filter_text", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_BY_FCU_NAME);
@@ -360,13 +360,13 @@ static void rna_def_dopesheet(BlenderRNA *brna)
"Only include channels with names containing search text");
RNA_def_property_ui_icon(prop, ICON_VIEWZOOM, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "filter_text", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "searchstr");
RNA_def_property_ui_text(prop, "Name Filter", "Live filtering string");
RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* Multi-word fuzzy search option for name/text filters */
prop = RNA_def_property(srna, "use_multi_word_filter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ADS_FLAG_FUZZY_NAMES);
@@ -374,7 +374,7 @@ static void rna_def_dopesheet(BlenderRNA *brna)
"Perform fuzzy/multi-word matching (WARNING: May be slow)");
RNA_def_property_ui_icon(prop, ICON_SORTALPHA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* NLA Specific Settings */
prop = RNA_def_property(srna, "show_missing_nla", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NLA_NOACT);
@@ -382,21 +382,21 @@ static void rna_def_dopesheet(BlenderRNA *brna)
"Include animation data-blocks with no NLA data (NLA editor only)");
RNA_def_property_ui_icon(prop, ICON_ACTION, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* Summary Settings (DopeSheet editors only) */
prop = RNA_def_property(srna, "show_summary", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_SUMMARY);
RNA_def_property_ui_text(prop, "Display Summary", "Display an additional 'summary' line (Dope Sheet editors only)");
RNA_def_property_ui_icon(prop, ICON_BORDERMOVE, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_expanded_summary", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ADS_FLAG_SUMMARY_COLLAPSED);
RNA_def_property_ui_text(prop, "Collapse Summary",
"Collapse summary when shown, so all other channels get hidden (Dope Sheet editors only)");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
-
+
+
/* General DataType Filtering Settings */
prop = RNA_def_property(srna, "show_transforms", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOOBJ);
@@ -404,98 +404,98 @@ static void rna_def_dopesheet(BlenderRNA *brna)
"Include visualization of object-level animation data (mostly transforms)");
RNA_def_property_ui_icon(prop, ICON_MANIPUL, 0); /* XXX? */
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_shapekeys", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOSHAPEKEYS);
RNA_def_property_ui_text(prop, "Display Shapekeys", "Include visualization of shape key related animation data");
RNA_def_property_ui_icon(prop, ICON_SHAPEKEY_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_modifiers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOMODIFIERS);
RNA_def_property_ui_text(prop, "Display Modifier Data",
"Include visualization of animation data related to data-blocks linked to modifiers");
RNA_def_property_ui_icon(prop, ICON_MODIFIER, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_meshes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOMESH);
RNA_def_property_ui_text(prop, "Display Meshes", "Include visualization of mesh related animation data");
RNA_def_property_ui_icon(prop, ICON_MESH_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_lattices", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOLAT);
RNA_def_property_ui_text(prop, "Display Lattices", "Include visualization of lattice related animation data");
RNA_def_property_ui_icon(prop, ICON_LATTICE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_cameras", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOCAM);
RNA_def_property_ui_text(prop, "Display Camera", "Include visualization of camera related animation data");
RNA_def_property_ui_icon(prop, ICON_CAMERA_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_materials", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOMAT);
RNA_def_property_ui_text(prop, "Display Material", "Include visualization of material related animation data");
RNA_def_property_ui_icon(prop, ICON_MATERIAL_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_lamps", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOLAM);
RNA_def_property_ui_text(prop, "Display Lamp", "Include visualization of lamp related animation data");
RNA_def_property_ui_icon(prop, ICON_LAMP_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_linestyles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOLINESTYLE);
RNA_def_property_ui_text(prop, "Display Line Style", "Include visualization of Line Style related Animation data");
RNA_def_property_ui_icon(prop, ICON_LINE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_textures", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOTEX);
RNA_def_property_ui_text(prop, "Display Texture", "Include visualization of texture related animation data");
RNA_def_property_ui_icon(prop, ICON_TEXTURE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_curves", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOCUR);
RNA_def_property_ui_text(prop, "Display Curve", "Include visualization of curve related animation data");
RNA_def_property_ui_icon(prop, ICON_CURVE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_worlds", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOWOR);
RNA_def_property_ui_text(prop, "Display World", "Include visualization of world related animation data");
RNA_def_property_ui_icon(prop, ICON_WORLD_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_scenes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOSCE);
RNA_def_property_ui_text(prop, "Display Scene", "Include visualization of scene related animation data");
RNA_def_property_ui_icon(prop, ICON_SCENE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_particles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOPART);
RNA_def_property_ui_text(prop, "Display Particle", "Include visualization of particle related animation data");
RNA_def_property_ui_icon(prop, ICON_PARTICLE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_metaballs", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOMBA);
RNA_def_property_ui_text(prop, "Display Metaball", "Include visualization of metaball related animation data");
RNA_def_property_ui_icon(prop, ICON_META_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_armatures", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOARM);
RNA_def_property_ui_text(prop, "Display Armature", "Include visualization of armature related animation data");
RNA_def_property_ui_icon(prop, ICON_ARMATURE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NONTREE);
RNA_def_property_ui_text(prop, "Display Node", "Include visualization of node related animation data");
@@ -507,17 +507,17 @@ static void rna_def_dopesheet(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Display Speaker", "Include visualization of speaker related animation data");
RNA_def_property_ui_icon(prop, ICON_SPEAKER, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_gpencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOGPENCIL);
RNA_def_property_ui_text(prop, "Display Grease Pencil", "Include visualization of Grease Pencil related animation data and frames");
RNA_def_property_ui_icon(prop, ICON_GREASEPENCIL, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* GPencil Mode Settings */
prop = RNA_def_property(srna, "show_gpencil_3d_only", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_GP_3DONLY);
- RNA_def_property_ui_text(prop, "Active Scene Only",
+ RNA_def_property_ui_text(prop, "Active Scene Only",
"Only show Grease Pencil data-blocks used as part of the active scene");
RNA_def_property_ui_icon(prop, ICON_SCENE_DATA, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
@@ -527,16 +527,16 @@ static void rna_def_action_group(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ActionGroup", NULL);
RNA_def_struct_sdna(srna, "bActionGroup");
RNA_def_struct_ui_text(srna, "Action Group", "Groups of F-Curves");
-
+
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* WARNING: be very careful when working with this list, since the endpoint is not
* defined like a standard ListBase. Adding/removing channels from this list needs
* extreme care, otherwise the F-Curve list running through adjacent groups does
@@ -552,22 +552,22 @@ static void rna_def_action_group(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "FCurve");
RNA_def_property_collection_funcs(prop, NULL, "rna_ActionGroup_channels_next", NULL, NULL, NULL, NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Channels", "F-Curves in this group");
-
+
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_SELECTED);
RNA_def_property_ui_text(prop, "Select", "Action group is selected");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
+
prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_PROTECTED);
RNA_def_property_ui_text(prop, "Lock", "Action group is locked");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_EXPANDED);
RNA_def_property_ui_text(prop, "Expanded", "Action group is expanded");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
/* color set */
rna_def_actionbone_group_common(srna, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
@@ -672,14 +672,14 @@ static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_pointer(func, "marker", "TimelineMarker", "", "Timeline marker to remove");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
-
+
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "TimelineMarker");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_LIB_EXCEPTION);
RNA_def_property_pointer_funcs(prop, "rna_Action_active_pose_marker_get",
"rna_Action_active_pose_marker_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active Pose Marker", "Active pose marker for this action");
-
+
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "active_marker");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
@@ -692,25 +692,25 @@ static void rna_def_action(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "Action", "ID");
RNA_def_struct_sdna(srna, "bAction");
RNA_def_struct_ui_text(srna, "Action", "A collection of F-Curves for animation");
RNA_def_struct_ui_icon(srna, ICON_ACTION);
-
+
/* collections */
prop = RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "curves", NULL);
RNA_def_property_struct_type(prop, "FCurve");
RNA_def_property_ui_text(prop, "F-Curves", "The individual F-Curves that make up the action");
rna_def_action_fcurves(brna, prop);
-
+
prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "groups", NULL);
RNA_def_property_struct_type(prop, "ActionGroup");
RNA_def_property_ui_text(prop, "Groups", "Convenient groupings of F-Curves");
rna_def_action_groups(brna, prop);
-
+
prop = RNA_def_property(srna, "pose_markers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "markers", NULL);
RNA_def_property_struct_type(prop, "TimelineMarker");
@@ -718,13 +718,13 @@ static void rna_def_action(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
RNA_def_property_ui_text(prop, "Pose Markers", "Markers specific to this action, for labeling poses");
rna_def_action_pose_markers(brna, prop);
-
+
/* properties */
prop = RNA_def_float_vector(srna, "frame_range", 2, NULL, 0, 0, "Frame Range",
"The final frame range of all F-Curves within this action", 0, 0);
RNA_def_property_float_funcs(prop, "rna_Action_frame_range_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
/* special "type" limiter - should not really be edited in general,
* but is still available/editable in 'emergencies' */
prop = RNA_def_property(srna, "id_root", PROP_ENUM, PROP_NONE);
@@ -734,7 +734,7 @@ static void rna_def_action(BlenderRNA *brna)
"Type of ID block that action can be used on - "
"DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
-
+
/* API calls */
RNA_api_action(srna);
}
diff --git a/source/blender/makesrna/intern/rna_action_api.c b/source/blender/makesrna/intern/rna_action_api.c
index fe429d8698b..3d5252b8cdc 100644
--- a/source/blender/makesrna/intern/rna_action_api.c
+++ b/source/blender/makesrna/intern/rna_action_api.c
@@ -53,7 +53,7 @@
void RNA_api_action(StructRNA *UNUSED(srna))
{
-
+
}
#endif
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 84764187b62..d89e3e68492 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -85,9 +85,9 @@ const EnumPropertyItem rna_enum_keying_flag_items[] = {
static void rna_AnimData_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
-
- /* tag for refresh so that scheduled updates (e.g. action changed) will
- * get computed and reflected in the scene [#34869]
+
+ /* tag for refresh so that scheduled updates (e.g. action changed) will
+ * get computed and reflected in the scene [#34869]
*/
DEG_id_tag_update(id, OB_RECALC_OB | OB_RECALC_DATA);
}
@@ -95,7 +95,7 @@ static void rna_AnimData_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Point
static int rna_AnimData_action_editable(PointerRNA *ptr, const char **UNUSED(r_info))
{
AnimData *adt = (AnimData *)ptr->data;
-
+
/* active action is only editable when it is not a tweaking strip */
if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact))
return 0;
@@ -107,10 +107,10 @@ static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value)
{
ID *ownerId = (ID *)ptr->id.data;
AnimData *adt;
-
+
/* set action */
BKE_animdata_set_action(NULL, ownerId, value.data);
-
+
/* force action to get evaluated [#34869] */
adt = BKE_animdata_from_id(ownerId);
if (adt) {
@@ -157,16 +157,16 @@ static int RKS_POLL_rna_internal(KeyingSetInfo *ksi, bContext *C)
/* hook up arguments */
RNA_parameter_set_lookup(&list, "ksi", &ksi);
RNA_parameter_set_lookup(&list, "context", &C);
-
+
/* execute the function */
ksi->ext.call(C, &ptr, func, &list);
-
+
/* read the result */
RNA_parameter_get_lookup(&list, "ok", &ret);
ok = *(int *)ret;
}
RNA_parameter_list_free(&list);
-
+
return ok;
}
@@ -188,7 +188,7 @@ static void RKS_ITER_rna_internal(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks
RNA_parameter_set_lookup(&list, "ksi", &ksi);
RNA_parameter_set_lookup(&list, "context", &C);
RNA_parameter_set_lookup(&list, "ks", &ks);
-
+
/* execute the function */
ksi->ext.call(C, &ptr, func, &list);
}
@@ -214,7 +214,7 @@ static void RKS_GEN_rna_internal(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks,
RNA_parameter_set_lookup(&list, "context", &C);
RNA_parameter_set_lookup(&list, "ks", &ks);
RNA_parameter_set_lookup(&list, "data", data);
-
+
/* execute the function */
ksi->ext.call(C, &ptr, func, &list);
}
@@ -236,11 +236,11 @@ static void rna_KeyingSetInfo_unregister(Main *bmain, StructRNA *type)
if (ksi == NULL)
return;
-
+
/* free RNA data referencing this */
RNA_struct_free_extension(type, &ksi->ext);
RNA_struct_free(&BLENDER_RNA, type);
-
+
WM_main_add_notifier(NC_WINDOW, NULL);
/* unlink Blender-side data */
@@ -259,17 +259,17 @@ static StructRNA *rna_KeyingSetInfo_register(
/* setup dummy type info to store static properties in */
/* TODO: perhaps we want to get users to register as if they're using 'KeyingSet' directly instead? */
RNA_pointer_create(NULL, &RNA_KeyingSetInfo, &dummyksi, &dummyptr);
-
+
/* validate the python class */
if (validate(&dummyptr, data, have_function) != 0)
return NULL;
-
+
if (strlen(identifier) >= sizeof(dummyksi.idname)) {
BKE_reportf(reports, RPT_ERROR, "Registering keying set info class: '%s' is too long, maximum length is %d",
identifier, (int)sizeof(dummyksi.idname));
return NULL;
}
-
+
/* check if we have registered this info before, and remove it */
ksi = ANIM_keyingset_info_find_name(dummyksi.idname);
if (ksi && ksi->ext.srna) {
@@ -279,23 +279,23 @@ static StructRNA *rna_KeyingSetInfo_register(
/* create a new KeyingSetInfo type */
ksi = MEM_callocN(sizeof(KeyingSetInfo), "python keying set info");
memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo));
-
+
/* set RNA-extensions info */
ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo);
ksi->ext.data = data;
ksi->ext.call = call;
ksi->ext.free = free;
RNA_struct_blender_type_set(ksi->ext.srna, ksi);
-
+
/* set callbacks */
/* NOTE: we really should have all of these... */
ksi->poll = (have_function[0]) ? RKS_POLL_rna_internal : NULL;
ksi->iter = (have_function[1]) ? RKS_ITER_rna_internal : NULL;
ksi->generate = (have_function[2]) ? RKS_GEN_rna_internal : NULL;
-
+
/* add and register with other info as needed */
ANIM_keyingset_info_register(ksi);
-
+
WM_main_add_notifier(NC_WINDOW, NULL);
/* return the struct-rna added */
@@ -319,7 +319,7 @@ static int rna_ksPath_id_editable(PointerRNA *ptr, const char **UNUSED(r_info))
static void rna_ksPath_id_type_set(PointerRNA *ptr, int value)
{
KS_Path *data = (KS_Path *)(ptr->data);
-
+
/* set the driver type, then clear the id-block if the type is invalid */
data->idtype = value;
if ((data->id) && (GS(data->id->name) != data->idtype))
@@ -339,7 +339,7 @@ static void rna_ksPath_RnaPath_get(PointerRNA *ptr, char *value)
static int rna_ksPath_RnaPath_length(PointerRNA *ptr)
{
KS_Path *ksp = (KS_Path *)ptr->data;
-
+
if (ksp->rna_path)
return strlen(ksp->rna_path);
else
@@ -352,7 +352,7 @@ static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value)
if (ksp->rna_path)
MEM_freeN(ksp->rna_path);
-
+
if (value[0])
ksp->rna_path = BLI_strdup(value);
else
@@ -364,20 +364,20 @@ static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value)
static void rna_KeyingSet_name_set(PointerRNA *ptr, const char *value)
{
KeyingSet *ks = (KeyingSet *)ptr->data;
-
+
/* update names of corresponding groups if name changes */
if (!STREQ(ks->name, value)) {
KS_Path *ksp;
-
+
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
if ((ksp->groupmode == KSP_GROUP_KSNAME) && (ksp->id)) {
AnimData *adt = BKE_animdata_from_id(ksp->id);
-
+
/* TODO: NLA strips? */
if (adt && adt->action) {
bActionGroup *agrp;
-
- /* lazy check - should really find the F-Curve for the affected path and check its group
+
+ /* lazy check - should really find the F-Curve for the affected path and check its group
* but this way should be faster and work well for most cases, as long as there are no
* conflicts
*/
@@ -392,7 +392,7 @@ static void rna_KeyingSet_name_set(PointerRNA *ptr, const char *value)
}
}
}
-
+
/* finally, update name to new value */
BLI_strncpy(ks->name, value, sizeof(ks->name));
}
@@ -401,7 +401,7 @@ static void rna_KeyingSet_name_set(PointerRNA *ptr, const char *value)
static int rna_KeyingSet_active_ksPath_editable(PointerRNA *ptr, const char **UNUSED(r_info))
{
KeyingSet *ks = (KeyingSet *)ptr->data;
-
+
/* only editable if there are some paths to change to */
return (BLI_listbase_is_empty(&ks->paths) == false) ? PROP_EDITABLE : 0;
}
@@ -444,7 +444,7 @@ static PointerRNA rna_KeyingSet_typeinfo_get(PointerRNA *ptr)
{
KeyingSet *ks = (KeyingSet *)ptr->data;
KeyingSetInfo *ksi = NULL;
-
+
/* keying set info is only for builtin Keying Sets */
if ((ks->flag & KEYINGSET_ABSOLUTE) == 0)
ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
@@ -458,13 +458,13 @@ static KS_Path *rna_KeyingSet_paths_add(KeyingSet *keyingset, ReportList *report
{
KS_Path *ksp = NULL;
short flag = 0;
-
+
/* special case when index = -1, we key the whole array (as with other places where index is used) */
if (index == -1) {
flag |= KSP_FLAG_WHOLE_ARRAY;
index = 0;
}
-
+
/* if data is valid, call the API function for this */
if (keyingset) {
ksp = BKE_keyingset_add_path(keyingset, id, group_name, rna_path, index, flag, group_method);
@@ -473,7 +473,7 @@ static KS_Path *rna_KeyingSet_paths_add(KeyingSet *keyingset, ReportList *report
else {
BKE_report(reports, RPT_ERROR, "Keying set path could not be added");
}
-
+
/* return added path */
return ksp;
}
@@ -502,13 +502,13 @@ static void rna_KeyingSet_paths_clear(KeyingSet *keyingset, ReportList *reports)
/* if data is valid, call the API function for this */
if (keyingset) {
KS_Path *ksp, *kspn;
-
+
/* free each path as we go to avoid looping twice */
for (ksp = keyingset->paths.first; ksp; ksp = kspn) {
kspn = ksp->next;
BKE_keyingset_free_path(keyingset, ksp);
}
-
+
/* reset the active path, since there aren't any left */
keyingset->active_path = 0;
}
@@ -567,7 +567,7 @@ static FCurve *rna_Driver_from_existing(AnimData *adt, bContext *C, FCurve *src_
else {
/* just make a copy of the existing one and add to self */
FCurve *new_fcu = copy_fcurve(src_driver);
-
+
/* XXX: if we impose any ordering on these someday, this will be problematic */
BLI_addtail(&adt->drivers, new_fcu);
return new_fcu;
@@ -619,39 +619,39 @@ bool rna_AnimaData_override_apply(
static void rna_def_common_keying_flags(StructRNA *srna, short reg)
{
PropertyRNA *prop;
-
+
/* override scene/userpref defaults? */
prop = RNA_def_property(srna, "use_insertkey_override_needed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "keyingoverride", INSERTKEY_NEEDED);
- RNA_def_property_ui_text(prop, "Override Insert Keyframes Default- Only Needed",
+ RNA_def_property_ui_text(prop, "Override Insert Keyframes Default- Only Needed",
"Override default setting to only insert keyframes where they're needed in the relevant F-Curves");
if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
-
+
prop = RNA_def_property(srna, "use_insertkey_override_visual", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "keyingoverride", INSERTKEY_MATRIX);
- RNA_def_property_ui_text(prop, "Override Insert Keyframes Default - Visual",
+ RNA_def_property_ui_text(prop, "Override Insert Keyframes Default - Visual",
"Override default setting to insert keyframes based on 'visual transforms'");
if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
-
+
prop = RNA_def_property(srna, "use_insertkey_override_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "keyingoverride", INSERTKEY_XYZ2RGB);
RNA_def_property_ui_text(prop, "Override F-Curve Colors - XYZ to RGB",
"Override default setting to set color for newly added transformation F-Curves "
"(Location, Rotation, Scale) to be based on the transform axis");
if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
-
-
+
+
/* value to override defaults with */
prop = RNA_def_property(srna, "use_insertkey_needed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_NEEDED);
RNA_def_property_ui_text(prop, "Insert Keyframes - Only Needed", "Only insert keyframes where they're needed in the relevant F-Curves");
if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
-
+
prop = RNA_def_property(srna, "use_insertkey_visual", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_MATRIX);
RNA_def_property_ui_text(prop, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'");
if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
-
+
prop = RNA_def_property(srna, "use_insertkey_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_XYZ2RGB);
RNA_def_property_ui_text(prop, "F-Curve Colors - XYZ to RGB", "Color for newly added transformation F-Curves (Location, Rotation, Scale) is based on the transform axis");
@@ -674,36 +674,36 @@ static void rna_def_keyingset_info(BlenderRNA *brna)
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
-
+
srna = RNA_def_struct(brna, "KeyingSetInfo", NULL);
RNA_def_struct_sdna(srna, "KeyingSetInfo");
RNA_def_struct_ui_text(srna, "Keying Set Info", "Callback function defines for builtin Keying Sets");
RNA_def_struct_refine_func(srna, "rna_KeyingSetInfo_refine");
RNA_def_struct_register_funcs(srna, "rna_KeyingSetInfo_register", "rna_KeyingSetInfo_unregister", NULL);
-
+
/* Properties --------------------- */
-
+
RNA_define_verify_sdna(0); /* not in sdna */
-
+
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "idname");
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "ID Name", KEYINGSET_IDNAME_DOC);
-
+
prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "UI Name", "");
RNA_def_struct_name_property(srna, prop);
RNA_def_property_flag(prop, PROP_REGISTER);
-
+
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
RNA_def_property_ui_text(prop, "Description", "A short description of the keying set");
-
+
/* Regarding why we don't use rna_def_common_keying_flags() here:
- * - Using it would keep this case in sync with the other places
+ * - Using it would keep this case in sync with the other places
* where these options are exposed (which are optimized for being
* used in the UI).
* - Unlike all the other places, this case is used for defining
@@ -716,9 +716,9 @@ static void rna_def_keyingset_info(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_keying_flag_items);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
RNA_def_property_ui_text(prop, "Options", "Keying Set options to use when inserting keyframes");
-
+
RNA_define_verify_sdna(1);
-
+
/* Function Callbacks ------------- */
/* poll */
func = RNA_def_function(srna, "poll", NULL);
@@ -727,7 +727,7 @@ static void rna_def_keyingset_info(BlenderRNA *brna)
RNA_def_function_return(func, RNA_def_boolean(func, "ok", 1, "", ""));
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
-
+
/* iterator */
func = RNA_def_function(srna, "iterator", NULL);
RNA_def_function_ui_description(func, "Call generate() on the structs which have properties to be keyframed");
@@ -736,7 +736,7 @@ static void rna_def_keyingset_info(BlenderRNA *brna)
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func, "ks", "KeyingSet", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
-
+
/* generate */
func = RNA_def_function(srna, "generate", NULL);
RNA_def_function_ui_description(func, "Add Paths to the Keying Set to keyframe the properties of the given data");
@@ -753,11 +753,11 @@ static void rna_def_keyingset_path(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "KeyingSetPath", NULL);
RNA_def_struct_sdna(srna, "KS_Path");
RNA_def_struct_ui_text(srna, "Keying Set Path", "Path to a setting for use in a Keying Set");
-
+
/* ID */
prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ID");
@@ -768,7 +768,7 @@ static void rna_def_keyingset_path(BlenderRNA *brna)
"ID-Block that keyframes for Keying Set should be added to "
"(for Absolute Keying Sets only)");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, NULL); /* XXX: maybe a bit too noisy */
-
+
prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "idtype");
RNA_def_property_enum_items(prop, rna_enum_id_type_items);
@@ -777,19 +777,19 @@ static void rna_def_keyingset_path(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, NULL); /* XXX: maybe a bit too noisy */
-
+
/* Group */
prop = RNA_def_property(srna, "group", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Group Name", "Name of Action Group to assign setting(s) for this path to");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, NULL); /* XXX: maybe a bit too noisy */
-
+
/* Grouping */
prop = RNA_def_property(srna, "group_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "groupmode");
RNA_def_property_enum_items(prop, rna_enum_keyingset_path_grouping_items);
RNA_def_property_ui_text(prop, "Grouping Method", "Method used to define which Group-name to use");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, NULL); /* XXX: maybe a bit too noisy */
-
+
/* Path + Array Index */
prop = RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_ksPath_RnaPath_get", "rna_ksPath_RnaPath_length",
@@ -802,7 +802,7 @@ static void rna_def_keyingset_path(BlenderRNA *brna)
prop = RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific setting if applicable");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, NULL); /* XXX: maybe a bit too noisy */
-
+
/* Flags */
prop = RNA_def_property(srna, "use_entire_array", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", KSP_FLAG_WHOLE_ARRAY);
@@ -810,7 +810,7 @@ static void rna_def_keyingset_path(BlenderRNA *brna)
"When an 'array/vector' type is chosen (Location, Rotation, Color, etc.), "
"entire array is to be used");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, NULL); /* XXX: maybe a bit too noisy */
-
+
/* Keyframing Settings */
rna_def_common_keying_flags(srna, 0);
}
@@ -823,7 +823,7 @@ static void rna_def_keyingset_paths(BlenderRNA *brna, PropertyRNA *cprop)
FunctionRNA *func;
PropertyRNA *parm;
-
+
PropertyRNA *prop;
RNA_def_property_srna(cprop, "KeyingSetPaths");
@@ -831,7 +831,7 @@ static void rna_def_keyingset_paths(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_sdna(srna, "KeyingSet");
RNA_def_struct_ui_text(srna, "Keying set paths", "Collection of keying set paths");
-
+
/* Add Path */
func = RNA_def_function(srna, "add", "rna_KeyingSet_paths_add");
RNA_def_function_ui_description(func, "Add a new path for the Keying Set");
@@ -871,7 +871,7 @@ static void rna_def_keyingset_paths(BlenderRNA *brna, PropertyRNA *cprop)
func = RNA_def_function(srna, "clear", "rna_KeyingSet_paths_clear");
RNA_def_function_ui_description(func, "Remove all the paths from the Keying Set");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
-
+
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "KeyingSetPath");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -891,17 +891,17 @@ static void rna_def_keyingset(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "KeyingSet", NULL);
RNA_def_struct_ui_text(srna, "Keying Set", "Settings that should be keyframed together");
-
+
/* Id/Label */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "idname");
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "ID Name", KEYINGSET_IDNAME_DOC);
/* RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_RENAME, NULL); */ /* NOTE: disabled, as ID name shouldn't be editable */
-
+
prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_KeyingSet_name_set");
@@ -909,19 +909,19 @@ static void rna_def_keyingset(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_KEYINGSET);
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_RENAME, NULL);
-
+
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
RNA_def_property_ui_text(prop, "Description", "A short description of the keying set");
-
+
/* KeyingSetInfo (Type Info) for Builtin Sets only */
prop = RNA_def_property(srna, "type_info", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "KeyingSetInfo");
RNA_def_property_pointer_funcs(prop, "rna_KeyingSet_typeinfo_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Type Info", "Callback function defines for built-in Keying Sets");
-
+
/* Paths */
prop = RNA_def_property(srna, "paths", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "paths", NULL);
@@ -936,11 +936,11 @@ static void rna_def_keyingset(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Absolute",
"Keying Set defines specific paths/settings to be keyframed "
"(i.e. is not reliant on context info)");
-
+
/* Keyframing Flags */
rna_def_common_keying_flags(srna, 0);
-
-
+
+
/* Keying Set API */
RNA_api_keyingset(srna);
}
@@ -955,12 +955,12 @@ static void rna_api_animdata_nla_tracks(BlenderRNA *brna, PropertyRNA *cprop)
FunctionRNA *func;
PropertyRNA *prop;
-
+
RNA_def_property_srna(cprop, "NlaTracks");
srna = RNA_def_struct(brna, "NlaTracks", NULL);
RNA_def_struct_sdna(srna, "AnimData");
RNA_def_struct_ui_text(srna, "NLA Tracks", "Collection of NLA Tracks");
-
+
func = RNA_def_function(srna, "new", "rna_NlaTrack_new");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Add a new NLA Track");
@@ -968,7 +968,7 @@ static void rna_api_animdata_nla_tracks(BlenderRNA *brna, PropertyRNA *cprop)
/* return type */
parm = RNA_def_pointer(func, "track", "NlaTrack", "", "New NLA Track");
RNA_def_function_return(func, parm);
-
+
func = RNA_def_function(srna, "remove", "rna_NlaTrack_remove");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Remove a NLA Track");
@@ -992,12 +992,12 @@ static void rna_api_animdata_drivers(BlenderRNA *brna, PropertyRNA *cprop)
FunctionRNA *func;
/* PropertyRNA *prop; */
-
+
RNA_def_property_srna(cprop, "AnimDataDrivers");
srna = RNA_def_struct(brna, "AnimDataDrivers", NULL);
RNA_def_struct_sdna(srna, "AnimData");
RNA_def_struct_ui_text(srna, "Drivers", "Collection of Driver F-Curves");
-
+
/* AnimData.drivers.from_existing(...) */
func = RNA_def_function(srna, "from_existing", "rna_Driver_from_existing");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@@ -1006,7 +1006,7 @@ static void rna_api_animdata_drivers(BlenderRNA *brna, PropertyRNA *cprop)
/* return type */
parm = RNA_def_pointer(func, "driver", "FCurve", "", "New Driver F-Curve");
RNA_def_function_return(func, parm);
-
+
/* AnimData.drivers.find(...) */
func = RNA_def_function(srna, "find", "rna_Driver_find");
RNA_def_function_ui_description(func, "Find a driver F-Curve. Note that this function performs a linear scan "
@@ -1023,11 +1023,11 @@ static void rna_api_animdata_drivers(BlenderRNA *brna, PropertyRNA *cprop)
void rna_def_animdata_common(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "animation_data", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "adt");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_override_funcs(prop, NULL, NULL, "rna_AnimaData_override_apply");
RNA_def_property_ui_text(prop, "Animation Data", "Animation data for this data-block");
}
@@ -1036,11 +1036,11 @@ static void rna_def_animdata(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "AnimData", NULL);
RNA_def_struct_ui_text(srna, "Animation Data", "Animation data for data-block");
RNA_def_struct_ui_icon(srna, ICON_ANIM_DATA);
-
+
/* NLA */
prop = RNA_def_property(srna, "nla_tracks", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "nla_tracks", NULL);
@@ -1048,11 +1048,12 @@ static void rna_def_animdata(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "NLA Tracks", "NLA Tracks (i.e. Animation Layers)");
rna_api_animdata_nla_tracks(brna, prop);
-
+
/* Active Action */
prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
/* this flag as well as the dynamic test must be defined for this to be editable... */
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_pointer_funcs(prop, NULL, "rna_AnimData_action_set", NULL, "rna_Action_id_poll");
RNA_def_property_editable_func(prop, "rna_AnimData_action_editable");
RNA_def_property_ui_text(prop, "Action", "Active Action for this data-block");
@@ -1065,31 +1066,31 @@ static void rna_def_animdata(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Action Extrapolation",
"Action to take for gaps past the Active Action's range (when evaluating with NLA)");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL);
-
+
prop = RNA_def_property(srna, "action_blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "act_blendmode");
RNA_def_property_enum_items(prop, rna_enum_nla_mode_blend_items);
RNA_def_property_ui_text(prop, "Action Blending",
"Method used for combining Active Action's result with result of NLA stack");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-
- prop = RNA_def_property(srna, "action_influence", PROP_FLOAT, PROP_NONE);
+
+ prop = RNA_def_property(srna, "action_influence", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "act_influence");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Action Influence",
"Amount the Active Action contributes to the result of the NLA stack");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-
+
/* Drivers */
prop = RNA_def_property(srna, "drivers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "drivers", NULL);
RNA_def_property_struct_type(prop, "FCurve");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Drivers", "The Drivers/Expressions for this data-block");
-
+
rna_api_animdata_drivers(brna, prop);
-
+
/* General Settings */
prop = RNA_def_property(srna, "use_nla", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ADT_NLA_EVAL_OFF);
@@ -1108,7 +1109,7 @@ static void rna_def_animdata(BlenderRNA *brna)
void RNA_def_animation(BlenderRNA *brna)
{
rna_def_animdata(brna);
-
+
rna_def_keyingset(brna);
rna_def_keyingset_path(brna);
rna_def_keyingset_info(brna);
diff --git a/source/blender/makesrna/intern/rna_animation_api.c b/source/blender/makesrna/intern/rna_animation_api.c
index 492659fdc2e..0b8f1acbd74 100644
--- a/source/blender/makesrna/intern/rna_animation_api.c
+++ b/source/blender/makesrna/intern/rna_animation_api.c
@@ -52,13 +52,13 @@ static void rna_KeyingSet_context_refresh(KeyingSet *ks, bContext *C, ReportList
{
/* TODO: enable access to providing a list of overrides (dsources)? */
int success = ANIM_validate_keyingset(C, NULL, ks);
-
+
if (success != 0) {
switch (success) {
case MODIFYKEY_INVALID_CONTEXT:
BKE_report(reports, RPT_ERROR, "Invalid context for keying set");
break;
-
+
case MODIFYKEY_MISSING_TYPEINFO:
BKE_report(reports, RPT_ERROR, "Incomplete built-in keying set, appears to be missing type info");
break;
@@ -72,7 +72,7 @@ void RNA_api_keyingset(StructRNA *srna)
{
FunctionRNA *func;
/*PropertyRNA *parm; */
-
+
/* validate relative Keying Set (used to ensure paths are ok for context) */
func = RNA_def_function(srna, "refresh", "rna_KeyingSet_context_refresh");
RNA_def_function_ui_description(func,
diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c
index 2ba067629a9..94b4d60ca25 100644
--- a/source/blender/makesrna/intern/rna_animviz.c
+++ b/source/blender/makesrna/intern/rna_animviz.c
@@ -65,7 +65,7 @@ static PointerRNA rna_AnimViz_motion_paths_get(PointerRNA *ptr)
static void rna_AnimViz_ghost_start_frame_set(PointerRNA *ptr, int value)
{
bAnimVizSettings *data = (bAnimVizSettings *)ptr->data;
-
+
data->ghost_sf = value;
CLAMP(data->ghost_ef, data->ghost_sf, MAXFRAME / 2);
}
@@ -73,7 +73,7 @@ static void rna_AnimViz_ghost_start_frame_set(PointerRNA *ptr, int value)
static void rna_AnimViz_ghost_end_frame_set(PointerRNA *ptr, int value)
{
bAnimVizSettings *data = (bAnimVizSettings *)ptr->data;
-
+
data->ghost_ef = value;
CLAMP(data->ghost_sf, 1, data->ghost_ef);
}
@@ -81,7 +81,7 @@ static void rna_AnimViz_ghost_end_frame_set(PointerRNA *ptr, int value)
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... */
data->path_sf = value;
CLAMP(data->path_ef, data->path_sf + 1, MAXFRAME / 2);
@@ -90,7 +90,7 @@ static void rna_AnimViz_path_start_frame_set(PointerRNA *ptr, int value)
static void rna_AnimViz_path_end_frame_set(PointerRNA *ptr, int value)
{
bAnimVizSettings *data = (bAnimVizSettings *)ptr->data;
-
+
data->path_ef = value;
CLAMP(data->path_sf, 1, data->path_ef - 1);
}
@@ -100,7 +100,7 @@ static void rna_AnimViz_path_end_frame_set(PointerRNA *ptr, int value)
void rna_def_motionpath_common(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "motion_path", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mpath");
RNA_def_property_ui_text(prop, "Motion Path", "Motion Path for this element");
@@ -110,15 +110,15 @@ static void rna_def_animviz_motionpath_vert(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "MotionPathVert", NULL);
RNA_def_struct_sdna(srna, "bMotionPathVert");
RNA_def_struct_ui_text(srna, "Motion Path Cache Point", "Cached location on path");
-
+
prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Coordinates", "");
-
+
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOTIONPATH_VERT_SEL);
RNA_def_property_ui_text(prop, "Select", "Path point is selected for editing");
@@ -128,28 +128,28 @@ static void rna_def_animviz_motion_path(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "MotionPath", NULL);
RNA_def_struct_sdna(srna, "bMotionPath");
RNA_def_struct_ui_text(srna, "Motion Path", "Cache of the worldspace positions of an element over a frame range");
-
+
/* Collections */
prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "points", "length");
RNA_def_property_struct_type(prop, "MotionPathVert");
RNA_def_property_ui_text(prop, "Motion Path Points", "Cached positions per frame");
-
+
/* Playback Ranges */
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "start_frame");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Start Frame", "Starting frame of the stored range");
-
+
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "end_frame");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "End Frame", "End frame of the stored range");
-
+
prop = RNA_def_property(srna, "length", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Length", "Number of frames cached");
@@ -173,7 +173,7 @@ static void rna_def_animviz_motion_path(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* xxx */
RNA_def_property_ui_text(prop, "Use Bone Heads",
"For PoseBone paths, use the bone head location when calculating this path");
-
+
/* FIXME: Motion Paths are not currently editable... */
prop = RNA_def_property(srna, "is_modified", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOTIONPATH_FLAG_EDIT);
@@ -199,7 +199,7 @@ static void rna_def_animviz_ghosts(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_type_items[] = {
{GHOST_TYPE_NONE, "NONE", 0, "No Ghosts", "Do not show any ghosts"},
{GHOST_TYPE_ACFRA, "CURRENT_FRAME", 0, "Around Current Frame", "Show ghosts from around the current frame"},
@@ -207,8 +207,8 @@ static void rna_def_animviz_ghosts(BlenderRNA *brna)
{GHOST_TYPE_KEYS, "KEYS", 0, "On Keyframes", "Show ghosts on keyframes"},
{0, NULL, 0, NULL, NULL}
};
-
-
+
+
srna = RNA_def_struct(brna, "AnimVizOnionSkinning", NULL);
RNA_def_struct_sdna(srna, "bAnimVizSettings");
RNA_def_struct_nested(brna, srna, "AnimViz");
@@ -220,21 +220,21 @@ static void rna_def_animviz_ghosts(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Type", "Method used for determining what ghosts get drawn");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
/* Settings */
prop = RNA_def_property(srna, "show_only_selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ghost_flag", GHOST_FLAG_ONLYSEL);
RNA_def_property_ui_text(prop, "On Selected Bones Only",
"For Pose-Mode drawing, only draw ghosts for selected bones");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "frame_step", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ghost_step");
RNA_def_property_range(prop, 1, 20);
RNA_def_property_ui_text(prop, "Frame Step",
"Number of frames between ghosts shown (not for 'On Keyframes' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
/* Playback Ranges */
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "ghost_sf");
@@ -243,7 +243,7 @@ static void rna_def_animviz_ghosts(BlenderRNA *brna)
"Starting frame of range of Ghosts to display "
"(not for 'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "ghost_ef");
RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_ghost_end_frame_set", NULL);
@@ -251,7 +251,7 @@ static void rna_def_animviz_ghosts(BlenderRNA *brna)
"End frame of range of Ghosts to display "
"(not for 'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
/* Around Current Ranges */
prop = RNA_def_property(srna, "frame_before", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "ghost_bc");
@@ -260,7 +260,7 @@ static void rna_def_animviz_ghosts(BlenderRNA *brna)
"Number of frames to show before the current frame "
"(only for 'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "frame_after", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "ghost_ac");
RNA_def_property_range(prop, 0, 30);
@@ -274,63 +274,63 @@ static void rna_def_animviz_paths(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_type_items[] = {
{MOTIONPATH_TYPE_ACFRA, "CURRENT_FRAME", 0, "Around Frame",
"Display Paths of poses within a fixed number of frames around the current frame"},
{MOTIONPATH_TYPE_RANGE, "RANGE", 0, "In Range", "Display Paths of poses within specified range"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "AnimVizMotionPaths", NULL);
RNA_def_struct_sdna(srna, "bAnimVizSettings");
RNA_def_struct_nested(brna, srna, "AnimViz");
RNA_def_struct_ui_text(srna, "Motion Path Settings", "Motion Path settings for animation visualization");
-
+
/* Enums */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "path_type");
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Paths Type", "Type of range to show for Motion Paths");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "bake_location", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "path_bakeflag");
RNA_def_property_enum_items(prop, rna_enum_motionpath_bake_location_items);
RNA_def_property_ui_text(prop, "Bake Location", "When calculating Bone Paths, use Head or Tips");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
/* Settings */
prop = RNA_def_property(srna, "show_frame_numbers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_FNUMS);
RNA_def_property_ui_text(prop, "Show Frame Numbers", "Show frame numbers on Motion Paths");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "show_keyframe_highlight", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_KFRAS);
RNA_def_property_ui_text(prop, "Highlight Keyframes", "Emphasize position of keyframes on Motion Paths");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "show_keyframe_numbers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_KFNOS);
RNA_def_property_ui_text(prop, "Show Keyframe Numbers", "Show frame numbers of Keyframes on Motion Paths");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "show_keyframe_action_all", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "path_viewflag", MOTIONPATH_VIEW_KFACT);
RNA_def_property_ui_text(prop, "All Action Keyframes",
"For bone motion paths, search whole Action for keyframes instead of in group"
" with matching name only (is slower)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "frame_step", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "path_step");
RNA_def_property_range(prop, 1, 100);
RNA_def_property_ui_text(prop, "Frame Step",
"Number of frames between paths shown (not for 'On Keyframes' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
-
+
+
/* Playback Ranges */
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "path_sf");
@@ -339,7 +339,7 @@ static void rna_def_animviz_paths(BlenderRNA *brna)
"Starting frame of range of paths to display/calculate "
"(not for 'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "path_ef");
RNA_def_property_int_funcs(prop, NULL, "rna_AnimViz_path_end_frame_set", NULL);
@@ -347,7 +347,7 @@ static void rna_def_animviz_paths(BlenderRNA *brna)
"End frame of range of paths to display/calculate "
"(not for 'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
/* Around Current Ranges */
prop = RNA_def_property(srna, "frame_before", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "path_bc");
@@ -356,7 +356,7 @@ static void rna_def_animviz_paths(BlenderRNA *brna)
"Number of frames to show before the current frame "
"(only for 'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
prop = RNA_def_property(srna, "frame_after", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "path_ac");
RNA_def_property_range(prop, 1, MAXFRAMEF / 2);
@@ -365,7 +365,7 @@ static void rna_def_animviz_paths(BlenderRNA *brna)
"(only for 'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* XXX since this is only for 3d-view drawing */
-
+
/* Readonly Property - Do any motion paths exist/need updating? (Mainly for bone paths) */
prop = RNA_def_property(srna, "has_motion_paths", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "path_bakeflag", MOTIONPATH_BAKE_HAS_PATHS);
@@ -378,7 +378,7 @@ static void rna_def_animviz_paths(BlenderRNA *brna)
void rna_def_animviz_common(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "animation_visualization", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "avs");
@@ -389,18 +389,18 @@ static void rna_def_animviz(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "AnimViz", NULL);
RNA_def_struct_sdna(srna, "bAnimVizSettings");
RNA_def_struct_ui_text(srna, "Animation Visualization", "Settings for the visualization of motion");
-
+
/* onion-skinning settings (nested struct) */
prop = RNA_def_property(srna, "onion_skin_frames", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "AnimVizOnionSkinning");
RNA_def_property_pointer_funcs(prop, "rna_AnimViz_onion_skinning_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Onion Skinning", "Onion Skinning (ghosting) settings for visualization");
-
+
/* motion path settings (nested struct) */
prop = RNA_def_property(srna, "motion_path", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -416,7 +416,7 @@ void RNA_def_animviz(BlenderRNA *brna)
rna_def_animviz(brna);
rna_def_animviz_ghosts(brna);
rna_def_animviz_paths(brna);
-
+
rna_def_animviz_motion_path(brna);
rna_def_animviz_motionpath_vert(brna);
}
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 30c643388af..44a21e797f1 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -44,6 +44,7 @@
#ifdef RNA_RUNTIME
#include "BKE_context.h"
+#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_main.h"
@@ -72,13 +73,13 @@ static void rna_Armature_act_bone_set(PointerRNA *ptr, PointerRNA value)
else {
if (value.id.data != arm) {
Object *ob = (Object *)value.id.data;
-
+
if (GS(ob->id.name) != ID_OB || (ob->data != arm)) {
printf("ERROR: armature set active bone - new active doesn't come from this armature\n");
return;
}
}
-
+
arm->act_bone = value.data;
arm->act_bone->flag |= BONE_SELECTED;
}
@@ -147,7 +148,7 @@ static void rna_Armature_update_layers(Main *bmain, Scene *UNUSED(scene), Pointe
static void rna_Armature_redraw_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
-
+
DEG_id_tag_update(id, DEG_TAG_COPY_ON_WRITE);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
}
@@ -156,10 +157,10 @@ static void rna_Armature_redraw_data(Main *UNUSED(bmain), Scene *UNUSED(scene),
static void rna_Bone_update_renamed(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
-
+
/* redraw view */
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
-
+
/* update animation channels */
WM_main_add_notifier(NC_ANIMATION | ND_ANIMCHAN, id);
}
@@ -167,7 +168,7 @@ static void rna_Bone_update_renamed(Main *UNUSED(bmain), Scene *UNUSED(scene), P
static void rna_Bone_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
-
+
/* 1) special updates for cases where rigs try to hook into armature drawing stuff
* e.g. Mask Modifier - 'Armature' option
* 2) tag armature for copy-on-write, so that selection status (set by addons)
@@ -176,25 +177,25 @@ static void rna_Bone_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
if (id) {
if (GS(id->name) == ID_AR) {
bArmature *arm = (bArmature *)id;
-
+
if (arm->flag & ARM_HAS_VIZ_DEPS) {
DEG_id_tag_update(id, OB_RECALC_DATA);
}
-
+
DEG_id_tag_update(id, DEG_TAG_COPY_ON_WRITE);
}
else if (GS(id->name) == ID_OB) {
Object *ob = (Object *)id;
bArmature *arm = (bArmature *)ob->data;
-
+
if (arm->flag & ARM_HAS_VIZ_DEPS) {
DEG_id_tag_update(id, OB_RECALC_DATA);
}
-
+
DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
}
-
+
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
/* spaces that show animation data of the selected bone need updating */
@@ -206,7 +207,7 @@ static char *rna_Bone_path(PointerRNA *ptr)
ID *id = ptr->id.data;
Bone *bone = (Bone *)ptr->data;
char name_esc[sizeof(bone->name) * 2];
-
+
BLI_strescape(name_esc, bone->name, sizeof(name_esc));
/* special exception for trying to get the path where ID-block is Object
@@ -217,7 +218,7 @@ static char *rna_Bone_path(PointerRNA *ptr)
return BLI_sprintfN("pose.bones[\"%s\"].bone", name_esc);
}
}
-
+
/* from armature... */
return BLI_sprintfN("bones[\"%s\"]", name_esc);
}
@@ -266,7 +267,7 @@ static void rna_bone_layer_set(int *layer, const int *values)
for (i = 0; i < 32; i++)
if (values[i])
tot++;
-
+
if (tot == 0)
return;
@@ -280,9 +281,9 @@ static void rna_Bone_layer_set(PointerRNA *ptr, const int *values)
{
bArmature *arm = (bArmature *)ptr->id.data;
Bone *bone = (Bone *)ptr->data;
-
+
rna_bone_layer_set(&bone->layer, values);
-
+
arm->layer_used = 0;
rna_Armature_layer_used_refresh(arm, &arm->bonebase);
}
@@ -296,7 +297,7 @@ static void rna_Armature_layer_set(PointerRNA *ptr, const int *values)
for (i = 0; i < 32; i++)
if (values[i])
tot++;
-
+
if (tot == 0)
return;
@@ -335,12 +336,12 @@ static void rna_EditBone_name_set(PointerRNA *ptr, const char *value)
bArmature *arm = (bArmature *)ptr->id.data;
EditBone *ebone = (EditBone *)ptr->data;
char oldname[sizeof(ebone->name)], newname[sizeof(ebone->name)];
-
+
/* need to be on the stack */
BLI_strncpy_utf8(newname, value, sizeof(ebone->name));
BLI_strncpy(oldname, ebone->name, sizeof(ebone->name));
-
- ED_armature_bone_rename(arm, oldname, newname);
+
+ ED_armature_bone_rename(G.main, arm, oldname, newname);
}
static void rna_Bone_name_set(PointerRNA *ptr, const char *value)
@@ -348,12 +349,12 @@ static void rna_Bone_name_set(PointerRNA *ptr, const char *value)
bArmature *arm = (bArmature *)ptr->id.data;
Bone *bone = (Bone *)ptr->data;
char oldname[sizeof(bone->name)], newname[sizeof(bone->name)];
-
+
/* need to be on the stack */
BLI_strncpy_utf8(newname, value, sizeof(bone->name));
BLI_strncpy(oldname, bone->name, sizeof(bone->name));
- ED_armature_bone_rename(arm, oldname, newname);
+ ED_armature_bone_rename(G.main, arm, oldname, newname);
}
static void rna_EditBone_layer_set(PointerRNA *ptr, const int values[])
@@ -414,7 +415,7 @@ static void rna_EditBone_parent_set(PointerRNA *ptr, PointerRNA value)
/* make sure this is a valid child */
if (parbone == ebone)
return;
-
+
for (pbone = parbone->parent; pbone; pbone = pbone->parent)
if (pbone == ebone)
return;
@@ -441,7 +442,7 @@ static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, Po
bArmature *arm = (bArmature *)ptr->id.data;
EditBone *ebone = (EditBone *)ptr->data;
EditBone *child, *eboflip;
-
+
/* update our parent */
if (ebone->parent && ebone->flag & BONE_CONNECTED)
copy_v3_v3(ebone->parent->tail, ebone->head);
@@ -459,11 +460,11 @@ static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, Po
eboflip->head[0] = -ebone->head[0];
eboflip->tail[0] = -ebone->tail[0];
-
+
/* update our parent */
if (eboflip->parent && eboflip->flag & BONE_CONNECTED)
copy_v3_v3(eboflip->parent->tail, eboflip->head);
-
+
/* update our children if necessary */
for (child = arm->edbo->first; child; child = child->next)
if (child->parent == eboflip && (child->flag & BONE_CONNECTED))
@@ -504,9 +505,9 @@ static int rna_Armature_is_editmode_get(PointerRNA *ptr)
return (arm->edbo != NULL);
}
-static void rna_Armature_transform(struct bArmature *arm, float *mat)
+static void rna_Armature_transform(struct bArmature *arm, Main *bmain, float *mat)
{
- ED_armature_transform(arm, (float (*)[4])mat, true);
+ ED_armature_transform(bmain, arm, (float (*)[4])mat, true);
}
#else
@@ -521,48 +522,48 @@ void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone)
else \
RNA_def_property_update(prop, 0, "rna_Armature_update_data"); \
} (void)0;
-
+
PropertyRNA *prop;
-
+
/* Roll In/Out */
prop = RNA_def_property(srna, "bbone_rollin", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "roll1");
RNA_def_property_range(prop, -M_PI * 2.0, M_PI * 2.0);
RNA_def_property_ui_text(prop, "Roll In", "Roll offset for the start of the B-Bone, adjusts twist");
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
-
+
prop = RNA_def_property(srna, "bbone_rollout", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "roll2");
RNA_def_property_range(prop, -M_PI * 2.0, M_PI * 2.0);
RNA_def_property_ui_text(prop, "Roll Out", "Roll offset for the end of the B-Bone, adjusts twist");
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
-
+
if (is_posebone == false) {
prop = RNA_def_property(srna, "use_endroll_as_inroll", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Inherit End Roll", "Use Roll Out of parent bone as Roll In of its children");
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ADD_PARENT_END_ROLL);
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
}
-
+
/* Curve X/Y Offsets */
prop = RNA_def_property(srna, "bbone_curveinx", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "curveInX");
RNA_def_property_range(prop, -5.0f, 5.0f);
RNA_def_property_ui_text(prop, "In X", "X-axis handle offset for start of the B-Bone's curve, adjusts curvature");
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
-
+
prop = RNA_def_property(srna, "bbone_curveiny", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "curveInY");
RNA_def_property_range(prop, -5.0f, 5.0f);
RNA_def_property_ui_text(prop, "In Y", "Y-axis handle offset for start of the B-Bone's curve, adjusts curvature");
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
-
+
prop = RNA_def_property(srna, "bbone_curveoutx", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "curveOutX");
RNA_def_property_range(prop, -5.0f, 5.0f);
RNA_def_property_ui_text(prop, "Out X", "X-axis handle offset for end of the B-Bone's curve, adjusts curvature");
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
-
+
prop = RNA_def_property(srna, "bbone_curveouty", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "curveOutY");
RNA_def_property_range(prop, -5.0f, 5.0f);
@@ -576,7 +577,7 @@ void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone)
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Ease In", "Length of first Bezier Handle (for B-Bones only)");
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
-
+
prop = RNA_def_property(srna, "bbone_easeout", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ease2");
RNA_def_property_range(prop, -5.0f, 5.0f);
@@ -591,14 +592,14 @@ void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone)
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Scale In", "Scale factor for start of the B-Bone, adjusts thickness (for tapering effects)");
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
-
+
prop = RNA_def_property(srna, "bbone_scaleout", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "scaleOut");
RNA_def_property_range(prop, 0.0f, 5.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Scale Out", "Scale factor for end of the B-Bone, adjusts thickness (for tapering effects)");
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone);
-
+
#undef RNA_DEF_CURVEBONE_UPDATE
}
@@ -630,23 +631,23 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Connected", "When bone has a parent, bone's head is stuck to the parent's tail");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "use_inherit_rotation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_HINGE);
RNA_def_property_ui_text(prop, "Inherit Rotation", "Bone inherits rotation or scale from parent bone");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "use_envelope_multiply", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_MULT_VG_ENV);
RNA_def_property_ui_text(prop, "Multiply Vertex Group with Envelope",
"When deforming bone, multiply effects of Vertex Group weights with Envelope influence");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "use_deform", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_DEFORM);
RNA_def_property_ui_text(prop, "Deform", "Enable Bone to deform geometry");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "use_inherit_scale", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Inherit Scale", "Bone inherits scaling from parent bone");
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_SCALE);
@@ -656,19 +657,19 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
RNA_def_property_ui_text(prop, "Local Location", "Bone location is set in local space");
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_LOCAL_LOCATION);
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "use_relative_parent", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Relative Parenting", "Object children will use relative transform, like deform");
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_RELATIVE_PARENTING);
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE);
RNA_def_property_ui_text(prop, "Draw Wire",
"Bone is always drawn as Wireframe regardless of viewport draw mode "
"(useful for non-obstructive custom bone shapes)");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
+
/* XXX: use_cyclic_offset is deprecated in 2.5. May/may not return */
prop = RNA_def_property(srna, "use_cyclic_offset", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_CYCLICOFFSET);
@@ -676,7 +677,7 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
"When bone doesn't have a parent, it receives cyclic offset effects (Deprecated)");
// "When bone doesn't have a parent, it receives cyclic offset effects");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_UNSELECTABLE);
RNA_def_property_ui_text(prop, "Selectable", "Bone is able to be selected");
@@ -689,13 +690,13 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Envelope Deform Distance", "Bone deformation distance (for Envelope deform only)");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "envelope_weight", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "weight");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Envelope Deform Weight", "Bone deformation weight (for Envelope deform only)");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "head_radius", PROP_FLOAT, PROP_UNSIGNED);
if (editbone) RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
else RNA_def_property_update(prop, 0, "rna_Armature_update_data");
@@ -704,7 +705,7 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
/*RNA_def_property_range(prop, 0, 1000); */
RNA_def_property_ui_range(prop, 0.01, 100, 0.1, 3);
RNA_def_property_ui_text(prop, "Envelope Head Radius", "Radius of head of bone (for Envelope deform only)");
-
+
prop = RNA_def_property(srna, "tail_radius", PROP_FLOAT, PROP_UNSIGNED);
if (editbone) RNA_def_property_update(prop, 0, "rna_Armature_editbone_transform_update");
else RNA_def_property_update(prop, 0, "rna_Armature_update_data");
@@ -713,20 +714,20 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
/*RNA_def_property_range(prop, 0, 1000); */
RNA_def_property_ui_range(prop, 0.01, 100, 0.1, 3);
RNA_def_property_ui_text(prop, "Envelope Tail Radius", "Radius of tail of bone (for Envelope deform only)");
-
+
/* b-bones deform settings */
prop = RNA_def_property(srna, "bbone_segments", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "segments");
RNA_def_property_range(prop, 1, 32);
RNA_def_property_ui_text(prop, "B-Bone Segments", "Number of subdivisions of bone (for B-Bones only)");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "bbone_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xwidth");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "B-Bone Display X Width", "B-Bone X size");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "bbone_z", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "zwidth");
RNA_def_property_range(prop, 0.0f, 1000.0f);
@@ -739,13 +740,13 @@ static void rna_def_bone(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "Bone", NULL);
RNA_def_struct_ui_text(srna, "Bone", "Bone in an Armature data-block");
RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
RNA_def_struct_path_func(srna, "rna_Bone_path");
RNA_def_struct_idprops_func(srna, "rna_Bone_idprops");
-
+
/* pointers/collections */
/* parent (pointer) */
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
@@ -754,7 +755,7 @@ static void rna_def_bone(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
RNA_def_property_ui_text(prop, "Parent", "Parent bone (in same Armature)");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
+
/* children (collection) */
prop = RNA_def_property(srna, "children", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "childbase", NULL);
@@ -778,13 +779,13 @@ static void rna_def_bone(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Select", "");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* XXX: review whether this could be used for interesting effects... */
RNA_def_property_update(prop, 0, "rna_Bone_select_update");
-
+
prop = RNA_def_property(srna, "select_head", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ROOTSEL);
RNA_def_property_ui_text(prop, "Select Head", "");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
+
prop = RNA_def_property(srna, "select_tail", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_TIPSEL);
RNA_def_property_ui_text(prop, "Select Tail", "");
@@ -839,13 +840,13 @@ static void rna_def_edit_bone(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "EditBone", NULL);
RNA_def_struct_sdna(srna, "EditBone");
RNA_def_struct_idprops_func(srna, "rna_EditBone_idprops");
RNA_def_struct_ui_text(srna, "Edit Bone", "Editmode bone in an Armature data-block");
RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
-
+
RNA_define_verify_sdna(0); /* not in sdna */
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
@@ -854,7 +855,7 @@ static void rna_def_edit_bone(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Parent", "Parent edit bone (in same Armature)");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
+
prop = RNA_def_property(srna, "roll", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "roll");
RNA_def_property_ui_range(prop, -M_PI * 2, M_PI * 2, 10, 2);
@@ -902,7 +903,7 @@ static void rna_def_edit_bone(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Head Select", "");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
+
prop = RNA_def_property(srna, "select_tail", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_TIPSEL);
RNA_def_property_ui_text(prop, "Tail Select", "");
@@ -1026,7 +1027,7 @@ static void rna_def_armature(BlenderRNA *brna)
{ARM_RESTPOS, "REST", 0, "Rest Position", "Show Armature in binding pose state (no posing possible)"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "Armature", "ID");
RNA_def_struct_ui_text(srna, "Armature",
"Armature data-block containing a hierarchy of bones, usually used for rigging characters");
@@ -1034,13 +1035,14 @@ static void rna_def_armature(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "bArmature");
func = RNA_def_function(srna, "transform", "rna_Armature_transform");
+ RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Transform armature bones by a matrix");
parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
/* Animation Data */
rna_def_animdata_common(srna);
-
+
/* Collections */
prop = RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
@@ -1062,7 +1064,7 @@ static void rna_def_armature(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pose Position", "Show armature in binding pose or final posed state");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
prop = RNA_def_property(srna, "draw_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "drawtype");
RNA_def_property_enum_items(prop, prop_drawtype_items);
@@ -1088,7 +1090,7 @@ static void rna_def_armature(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, NULL, "rna_Armature_layer_set");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Armature_update_layers");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
/* layer protection */
prop = RNA_def_property(srna, "layers_protected", PROP_BOOLEAN, PROP_LAYER);
RNA_def_property_boolean_sdna(prop, NULL, "layer_protected", 1);
@@ -1097,47 +1099,47 @@ static void rna_def_armature(BlenderRNA *brna)
"Protected layers in Proxy Instances are restored to Proxy settings "
"on file reload and undo");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
+
/* flag */
prop = RNA_def_property(srna, "show_axes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_DRAWAXES);
RNA_def_property_ui_text(prop, "Draw Axes", "Draw bone axes");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
prop = RNA_def_property(srna, "show_names", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_DRAWNAMES);
RNA_def_property_ui_text(prop, "Draw Names", "Draw bone names");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
prop = RNA_def_property(srna, "use_deform_delay", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_DELAYDEFORM);
RNA_def_property_ui_text(prop, "Delay Deform", "Don't deform children when manipulating bones in Pose Mode");
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
-
+
prop = RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_MIRROR_EDIT);
RNA_def_property_ui_text(prop, "X-Axis Mirror", "Apply changes to matching bone on opposite side of X-Axis");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
prop = RNA_def_property(srna, "use_auto_ik", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_AUTO_IK);
RNA_def_property_ui_text(prop, "Auto IK", "Add temporary IK constraints while grabbing bones in Pose Mode");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
prop = RNA_def_property(srna, "show_bone_custom_shapes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ARM_NO_CUSTOM);
RNA_def_property_ui_text(prop, "Draw Custom Bone Shapes", "Draw bones with their custom shapes");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
+
prop = RNA_def_property(srna, "show_group_colors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_COL_CUSTOM);
RNA_def_property_ui_text(prop, "Draw Bone Group Colors", "Draw bone group colors");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-
+
/* XXX deprecated ....... old animviz for armatures only */
prop = RNA_def_property(srna, "show_only_ghost_selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_GHOST_ONLYSEL);
@@ -1157,7 +1159,7 @@ static void rna_def_armature(BlenderRNA *brna)
"(only for 'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
prop = RNA_def_property(srna, "ghost_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "ghostsize");
RNA_def_property_range(prop, 1, 20);
@@ -1165,7 +1167,7 @@ static void rna_def_armature(BlenderRNA *brna)
"Frame step for Ghosts (not for 'On Keyframes' Onion-skinning method)");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
prop = RNA_def_property(srna, "ghost_frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "ghostsf");
RNA_def_property_int_funcs(prop, NULL, "rna_Armature_ghost_start_frame_set", NULL);
@@ -1174,7 +1176,7 @@ static void rna_def_armature(BlenderRNA *brna)
"'Around Current Frame' Onion-skinning method)");
RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
-
+
prop = RNA_def_property(srna, "ghost_frame_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "ghostef");
RNA_def_property_int_funcs(prop, NULL, "rna_Armature_ghost_end_frame_set", NULL);
diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c
index 98ca58e0edd..413cb10422a 100644
--- a/source/blender/makesrna/intern/rna_boid.c
+++ b/source/blender/makesrna/intern/rna_boid.c
@@ -96,7 +96,7 @@ static void rna_Boids_reset(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRN
{
if (ptr->type == &RNA_ParticleSystem) {
ParticleSystem *psys = (ParticleSystem *)ptr->data;
-
+
psys->recalc = PSYS_RECALC_RESET;
DEG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
@@ -110,7 +110,7 @@ static void rna_Boids_reset_deps(Main *bmain, Scene *UNUSED(scene), PointerRNA *
{
if (ptr->type == &RNA_ParticleSystem) {
ParticleSystem *psys = (ParticleSystem *)ptr->data;
-
+
psys->recalc = PSYS_RECALC_RESET;
DEG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
@@ -211,10 +211,10 @@ static int particle_id_check(PointerRNA *ptr)
static char *rna_BoidSettings_path(PointerRNA *ptr)
{
BoidSettings *boids = (BoidSettings *)ptr->data;
-
+
if (particle_id_check(ptr)) {
ParticleSettings *part = (ParticleSettings *)ptr->id.data;
-
+
if (part->boids == boids)
return BLI_sprintfN("boids");
}
@@ -418,36 +418,36 @@ static void rna_def_boidrule(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
/* data */
srna = RNA_def_struct(brna, "BoidRule", NULL);
RNA_def_struct_ui_text(srna, "Boid Rule", "");
RNA_def_struct_refine_func(srna, "rna_BoidRule_refine");
RNA_def_struct_path_func(srna, "rna_BoidRule_path");
-
+
/* strings */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Boid rule name");
RNA_def_struct_name_property(srna, prop);
-
+
/* enums */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, rna_enum_boidrule_type_items);
RNA_def_property_ui_text(prop, "Type", "");
-
+
/* flags */
prop = RNA_def_property(srna, "use_in_air", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BOIDRULE_IN_AIR);
RNA_def_property_ui_text(prop, "In Air", "Use rule when boid is flying");
RNA_def_property_update(prop, 0, "rna_Boids_reset");
-
+
prop = RNA_def_property(srna, "use_on_land", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BOIDRULE_ON_LAND);
RNA_def_property_ui_text(prop, "On Land", "Use rule when boid is on land");
RNA_def_property_update(prop, 0, "rna_Boids_reset");
-
+
/*prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); */
/*RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Expanded); */
/*RNA_def_property_ui_text(prop, "Expanded", "Set modifier expanded in the user interface"); */
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index d227d7a3dbe..75d05115006 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -111,7 +111,7 @@ const EnumPropertyItem rna_enum_brush_vertex_tool_items[] = {
{0, NULL, 0, NULL, NULL}
};
-
+
const EnumPropertyItem rna_enum_brush_image_tool_items[] = {
{PAINT_TOOL_DRAW, "DRAW", ICON_BRUSH_TEXDRAW, "Draw", ""},
{PAINT_TOOL_SOFTEN, "SOFTEN", ICON_BRUSH_SOFTEN, "Soften", ""},
@@ -403,14 +403,14 @@ static void rna_Brush_sculpt_tool_update(Main *bmain, Scene *scene, PointerRNA *
rna_Brush_reset_icon(br, "sculpt");
rna_Brush_update(bmain, scene, ptr);
}
-
+
static void rna_Brush_vertex_tool_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
rna_Brush_reset_icon(br, "vertex_paint");
rna_Brush_update(bmain, scene, ptr);
}
-
+
static void rna_Brush_imagepaint_tool_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
@@ -656,8 +656,8 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_TextureCapabilities_" \
#prop_name_ "_get", NULL); \
RNA_def_property_ui_text(prop, ui_name_, NULL)
-
-
+
+
srna = RNA_def_struct(brna, "BrushTextureSlot", "TextureSlot");
RNA_def_struct_sdna(srna, "MTex");
RNA_def_struct_ui_text(srna, "Brush Texture Slot", "Texture slot for textures in a Brush data-block");
@@ -707,10 +707,10 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Random Angle", "Brush texture random angle");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
-
+
TEXTURE_CAPABILITY(has_texture_angle_source, "Has Texture Angle Source");
TEXTURE_CAPABILITY(has_random_texture_angle, "Has Random Texture Angle");
- TEXTURE_CAPABILITY(has_texture_angle, "Has Texture Angle Source");
+ TEXTURE_CAPABILITY(has_texture_angle, "Has Texture Angle Source");
}
static void rna_def_sculpt_capabilities(BlenderRNA *brna)
@@ -813,7 +813,7 @@ static void rna_def_brush(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_blend_items[] = {
{IMB_BLEND_MIX, "MIX", 0, "Mix", "Use mix blending mode while painting"},
{IMB_BLEND_ADD, "ADD", 0, "Add", "Use add blending mode while painting"},
@@ -841,7 +841,7 @@ static void rna_def_brush(BlenderRNA *brna)
{IMB_BLEND_COLOR, "COLOR", 0, "Color", "Use color blending mode while painting"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem brush_sculpt_plane_items[] = {
{SCULPT_DISP_DIR_AREA, "AREA", 0, "Area Plane", ""},
{SCULPT_DISP_DIR_VIEW, "VIEW", 0, "View Plane", ""},
@@ -903,7 +903,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_brush_vertex_tool_items);
RNA_def_property_ui_text(prop, "Blending mode", "Brush blending mode");
RNA_def_property_update(prop, 0, "rna_Brush_vertex_tool_update");
-
+
prop = RNA_def_property(srna, "image_tool", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "imagepaint_tool");
RNA_def_property_enum_items(prop, rna_enum_brush_image_tool_items);
@@ -933,7 +933,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_enum_items(prop, brush_mask_tool_items);
RNA_def_property_ui_text(prop, "Mask Tool", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
+
/* number values */
prop = RNA_def_property(srna, "size", PROP_INT, PROP_PIXEL);
RNA_def_property_int_funcs(prop, NULL, "rna_Brush_set_size", NULL);
@@ -941,7 +941,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, -1);
RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels");
RNA_def_property_update(prop, 0, "rna_Brush_size_update");
-
+
prop = RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_funcs(prop, NULL, "rna_Brush_set_unprojected_radius", NULL);
RNA_def_property_range(prop, 0.001, FLT_MAX);
@@ -985,14 +985,14 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_range(prop, 0.5, 0.99);
RNA_def_property_ui_text(prop, "Smooth Stroke Factor", "Higher values give a smoother stroke");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
+
prop = RNA_def_property(srna, "rate", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rate");
RNA_def_property_range(prop, 0.0001f, 10000.0f);
RNA_def_property_ui_range(prop, 0.01f, 1.0f, 1, 3);
RNA_def_property_ui_text(prop, "Rate", "Interval between paints for Airbrush");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
+
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "rgb");
@@ -1149,20 +1149,20 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_AIRBRUSH);
RNA_def_property_ui_text(prop, "Airbrush", "Keep applying paint effect while holding mouse (spray)");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
+
prop = RNA_def_property(srna, "use_original_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ORIGINAL_NORMAL);
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true);
RNA_def_property_ui_text(prop, "Original Normal",
"When locked keep using normal of surface where stroke was initiated");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
+
prop = RNA_def_property(srna, "use_pressure_strength", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ALPHA_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
+
prop = RNA_def_property(srna, "use_offset_pressure", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_OFFSET_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
@@ -1204,7 +1204,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(prop, "Inverse Smooth Pressure", "Lighter pressure causes more smoothing to be applied");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
+
prop = RNA_def_property(srna, "use_relative_jitter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_ABSOLUTE_JITTER);
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true);
@@ -1260,7 +1260,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ACCUMULATE);
RNA_def_property_ui_text(prop, "Accumulate", "Accumulate stroke daubs on top of each other");
RNA_def_property_update(prop, 0, "rna_Brush_update");
-
+
prop = RNA_def_property(srna, "use_space_attenuation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACE_ATTEN);
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true);
@@ -1379,7 +1379,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "mtex");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Texture Slot", "");
-
+
prop = RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mtex.tex");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
@@ -1444,7 +1444,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Clone Image", "Image for clone tool");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_Brush_update");
-
+
prop = RNA_def_property(srna, "clone_alpha", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clone.alpha");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -1524,7 +1524,7 @@ static void rna_def_operator_stroke_element(BlenderRNA *brna)
prop = RNA_def_property(srna, "time", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_flag(prop, PROP_IDPROPERTY);
RNA_def_property_ui_text(prop, "Time", "");
-
+
/* used for Grease Pencil sketching sessions */
prop = RNA_def_property(srna, "is_start", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_flag(prop, PROP_IDPROPERTY);
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 3d1a1458102..0958011a7f0 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -89,11 +89,11 @@ static void rna_ClothSettings_bending_set(struct PointerRNA *ptr, float value)
static void rna_ClothSettings_max_bend_set(struct PointerRNA *ptr, float value)
{
ClothSimSettings *settings = (ClothSimSettings *)ptr->data;
-
+
/* check for clipping */
if (value < settings->bending)
value = settings->bending;
-
+
settings->max_bend = value;
}
@@ -111,11 +111,11 @@ static void rna_ClothSettings_structural_set(struct PointerRNA *ptr, float value
static void rna_ClothSettings_max_struct_set(struct PointerRNA *ptr, float value)
{
ClothSimSettings *settings = (ClothSimSettings *)ptr->data;
-
+
/* check for clipping */
if (value < settings->structural)
value = settings->structural;
-
+
settings->max_struct = value;
}
@@ -291,7 +291,7 @@ static void rna_def_cloth_solver_result(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem status_items[] = {
{BPH_SOLVER_SUCCESS, "SUCCESS", 0, "Success", "Computation was successful"},
{BPH_SOLVER_NUMERICAL_ISSUE, "NUMERICAL_ISSUE", 0, "Numerical Issue", "The provided data did not satisfy the prerequisites"},
@@ -299,49 +299,49 @@ static void rna_def_cloth_solver_result(BlenderRNA *brna)
{BPH_SOLVER_INVALID_INPUT, "INVALID_INPUT", 0, "Invalid Input", "The inputs are invalid, or the algorithm has been improperly called"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "ClothSolverResult", NULL);
RNA_def_struct_ui_text(srna, "Solver Result", "Result of cloth solver iteration");
-
+
RNA_define_verify_sdna(0);
-
+
prop = RNA_def_property(srna, "status", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, status_items);
RNA_def_property_enum_sdna(prop, NULL, "status");
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Status", "Status of the solver iteration");
-
+
prop = RNA_def_property(srna, "max_error", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "max_error");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Maximum Error", "Maximum error during substeps");
-
+
prop = RNA_def_property(srna, "min_error", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "min_error");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Minimum Error", "Minimum error during substeps");
-
+
prop = RNA_def_property(srna, "avg_error", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "avg_error");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Average Error", "Average error during substeps");
-
+
prop = RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "max_iterations");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Maximum Iterations", "Maximum iterations during substeps");
-
+
prop = RNA_def_property(srna, "min_iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "min_iterations");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Minimum Iterations", "Minimum iterations during substeps");
-
+
prop = RNA_def_property(srna, "avg_iterations", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "avg_iterations");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Average Iterations", "Average iterations during substeps");
-
+
RNA_define_verify_sdna(1);
}
@@ -349,14 +349,14 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ClothSettings", NULL);
RNA_def_struct_ui_text(srna, "Cloth Settings", "Cloth simulation settings for an object");
RNA_def_struct_sdna(srna, "ClothSimSettings");
RNA_def_struct_path_func(srna, "rna_ClothSettings_path");
-
+
/* goal */
-
+
prop = RNA_def_property(srna, "goal_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mingoal");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -377,13 +377,13 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Goal Default",
"Default Goal (vertex target position) value, when no Vertex Group used");
RNA_def_property_update(prop, 0, "rna_cloth_update");
-
+
prop = RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "goalspring");
RNA_def_property_range(prop, 0.0f, 0.999f);
RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness");
RNA_def_property_update(prop, 0, "rna_cloth_update");
-
+
prop = RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "goalfrict");
RNA_def_property_range(prop, 0.0f, 50.0f);
@@ -426,7 +426,7 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
"rna_ClothSettings_mass_vgroup_set");
RNA_def_property_ui_text(prop, "Mass Vertex Group", "Vertex Group for pinning of vertices");
RNA_def_property_update(prop, 0, "rna_cloth_pinning_changed");
-
+
prop = RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, -100.0, 100.0);
@@ -510,14 +510,14 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
"If enabled, stiffness can be scaled along a weight painted vertex group");
RNA_def_property_update(prop, 0, "rna_cloth_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
-
+
prop = RNA_def_property(srna, "spring_damping", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "Cdis");
RNA_def_property_range(prop, 0.0f, 50.0f);
RNA_def_property_ui_text(prop, "Spring Damping",
"Damping of cloth velocity (higher = more smooth, less jiggling)");
RNA_def_property_update(prop, 0, "rna_cloth_update");
-
+
prop = RNA_def_property(srna, "structural_stiffness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "structural");
RNA_def_property_range(prop, 0.0f, 10000.0f);
@@ -650,7 +650,7 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ClothCollisionSettings", NULL);
RNA_def_struct_ui_text(srna, "Cloth Collision Settings",
"Cloth simulation settings for self collision and collision with other objects");
@@ -678,7 +678,7 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Repulsion Distance",
"Maximum distance to apply repulsion force, must be greater than minimum distance");
RNA_def_property_update(prop, 0, "rna_cloth_update");
-
+
prop = RNA_def_property(srna, "distance_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "epsilon");
RNA_def_property_range(prop, 0.001f, 1.0f);
@@ -712,13 +712,13 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_SELF);
RNA_def_property_ui_text(prop, "Enable Self Collision", "Enable self collisions");
RNA_def_property_update(prop, 0, "rna_cloth_update");
-
+
prop = RNA_def_property(srna, "self_distance_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "selfepsilon");
RNA_def_property_range(prop, 0.5f, 1.0f);
RNA_def_property_ui_text(prop, "Self Minimum Distance", "0.5 means no distance at all, 1.0 is maximum distance");
RNA_def_property_update(prop, 0, "rna_cloth_update");
-
+
prop = RNA_def_property(srna, "self_friction", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 80.0f);
RNA_def_property_ui_text(prop, "Self Friction", "Friction/damping with self contact");
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index f895cfbbf0c..67fb58b6208 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -75,7 +75,7 @@ static int rna_CurveMapping_curves_length(PointerRNA *ptr)
for (len = 0; len < CM_TOT; len++)
if (!cumap->cm[len].curve)
break;
-
+
return len;
}
@@ -154,11 +154,11 @@ static void rna_CurveMapping_clipmaxy_range(PointerRNA *ptr, float *min, float *
static char *rna_ColorRamp_path(PointerRNA *ptr)
{
char *path = NULL;
-
+
/* handle the cases where a single data-block may have 2 ramp types */
if (ptr->id.data) {
ID *id = ptr->id.data;
-
+
switch (GS(id->name)) {
case ID_NT:
{
@@ -166,7 +166,7 @@ static char *rna_ColorRamp_path(PointerRNA *ptr)
bNode *node;
PointerRNA node_ptr;
char *node_path;
-
+
for (node = ntree->nodes.first; node; node = node->next) {
if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
if (node->storage == ptr->data) {
@@ -182,14 +182,14 @@ static char *rna_ColorRamp_path(PointerRNA *ptr)
}
break;
}
-
+
case ID_LS:
{
/* may be NULL */
path = BKE_linestyle_path_to_color_ramp((FreestyleLineStyle *)id, (ColorBand *)ptr->data);
break;
}
-
+
default:
/* everything else just uses 'color_ramp' */
path = BLI_strdup("color_ramp");
@@ -200,7 +200,7 @@ static char *rna_ColorRamp_path(PointerRNA *ptr)
/* everything else just uses 'color_ramp' */
path = BLI_strdup("color_ramp");
}
-
+
return path;
}
@@ -210,7 +210,7 @@ static char *rna_ColorRampElement_path(PointerRNA *ptr)
PropertyRNA *prop;
char *path = NULL;
int index;
-
+
/* helper macro for use here to try and get the path
* - this calls the standard code for getting a path to a texture...
*/
@@ -232,13 +232,13 @@ static char *rna_ColorRampElement_path(PointerRNA *ptr)
/* FIXME: this is a very slow way to do it, but it will have to suffice... */
if (ptr->id.data) {
ID *id = ptr->id.data;
-
+
switch (GS(id->name)) {
case ID_NT:
{
bNodeTree *ntree = (bNodeTree *)id;
bNode *node;
-
+
for (node = ntree->nodes.first; node; node = node->next) {
if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
RNA_pointer_create(id, &RNA_ColorRamp, node->storage, &ramp_ptr);
@@ -272,10 +272,10 @@ static char *rna_ColorRampElement_path(PointerRNA *ptr)
}
}
}
-
+
/* cleanup the macro we defined */
#undef COLRAMP_GETPATH
-
+
return path;
}
@@ -283,12 +283,12 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
{
if (ptr->id.data) {
ID *id = ptr->id.data;
-
+
switch (GS(id->name)) {
case ID_MA:
{
Material *ma = ptr->id.data;
-
+
DEG_id_tag_update(&ma->id, 0);
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma);
break;
@@ -323,7 +323,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
case ID_PA:
{
ParticleSettings *part = ptr->id.data;
-
+
DEG_id_tag_update(&part->id, OB_RECALC_DATA | PSYS_RECALC_REDO);
WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, part);
}
@@ -548,7 +548,7 @@ static const EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_ite
return items;
}
-static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
ID *id = ptr->id.data;
@@ -565,7 +565,7 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain)
else if (GS(id->name) == ID_MC) {
MovieClip *clip = (MovieClip *) id;
- BKE_movieclip_reload(clip);
+ BKE_movieclip_reload(bmain, clip);
/* all sequencers for now, we don't know which scenes are using this clip as a strip */
BKE_sequencer_cache_cleanup();
@@ -761,7 +761,7 @@ static void rna_def_curvemapping(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "CurveMapping",
"Curve mapping to map color, vector and scalar values to other values using "
"a user defined curve");
-
+
prop = RNA_def_property(srna, "use_clip", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CUMA_DO_CLIP);
RNA_def_property_ui_text(prop, "Clip", "Force the curve view to fit a defined boundary");
@@ -828,7 +828,7 @@ static void rna_def_color_ramp_element(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "CBData");
RNA_def_struct_path_func(srna, "rna_ColorRampElement_path");
RNA_def_struct_ui_text(srna, "Color Ramp Element", "Element defining a color at a position in the color ramp");
-
+
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "r");
RNA_def_property_array(prop, 4);
@@ -893,7 +893,7 @@ static void rna_def_color_ramp(BlenderRNA *brna)
{COLBAND_INTERP_CONSTANT, "CONSTANT", 0, "Constant", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem prop_mode_items[] = {
{COLBAND_BLEND_RGB, "RGB", 0, "RGB", ""},
{COLBAND_BLEND_HSV, "HSV", 0, "HSV", ""},
@@ -913,7 +913,7 @@ static void rna_def_color_ramp(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "ColorBand");
RNA_def_struct_path_func(srna, "rna_ColorRamp_path");
RNA_def_struct_ui_text(srna, "Color Ramp", "Color ramp mapping a scalar value to a color");
-
+
prop = RNA_def_property(srna, "elements", PROP_COLLECTION, PROP_COLOR);
RNA_def_property_collection_sdna(prop, NULL, "data", "tot");
RNA_def_property_struct_type(prop, "ColorRampElement");
@@ -948,7 +948,7 @@ static void rna_def_color_ramp(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Total", "Total number of elements");
RNA_def_property_update(prop, 0, "rna_ColorRamp_update");
#endif
-
+
func = RNA_def_function(srna, "evaluate", "rna_ColorRamp_eval");
RNA_def_function_ui_description(func, "Evaluate ColorRamp");
parm = RNA_def_float(func, "position", 1.0f, 0.0f, 1.0f, "Position", "Evaluate ColorRamp at position", 0.0f, 1.0f);
@@ -964,7 +964,7 @@ static void rna_def_histogram(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_mode_items[] = {
{HISTO_MODE_LUMA, "LUMA", 0, "Luma", "Luma"},
{HISTO_MODE_RGB, "RGB", 0, "RGB", "Red Green Blue"},
@@ -977,7 +977,7 @@ static void rna_def_histogram(BlenderRNA *brna)
srna = RNA_def_struct(brna, "Histogram", NULL);
RNA_def_struct_ui_text(srna, "Histogram", "Statistical view of the levels of color in an image");
-
+
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, prop_mode_items);
@@ -1006,12 +1006,12 @@ static void rna_def_scopes(BlenderRNA *brna)
srna = RNA_def_struct(brna, "Scopes", NULL);
RNA_def_struct_ui_text(srna, "Scopes", "Scopes for statistical view of an image");
-
+
prop = RNA_def_property(srna, "use_full_resolution", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, "Scopes", "sample_full", 1);
RNA_def_property_ui_text(prop, "Full Sample", "Sample every pixel of the image");
RNA_def_property_update(prop, 0, "rna_Scopes_update");
-
+
prop = RNA_def_property(srna, "accuracy", PROP_FLOAT, PROP_PERCENTAGE);
RNA_def_property_float_sdna(prop, "Scopes", "accuracy");
RNA_def_property_range(prop, 0.0, 100.0);
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 7c53a3b54c0..a01f2afa26e 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -52,59 +52,59 @@ const EnumPropertyItem rna_enum_constraint_type_items[] = {
{CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""},
{CONSTRAINT_TYPE_OBJECTSOLVER, "OBJECT_SOLVER", ICON_CONSTRAINT_DATA, "Object Solver", ""},
{0, "", 0, N_("Transform"), ""},
- {CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location",
+ {CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location",
"Copy the location of a target (with an optional offset), so that they move together"},
- {CONSTRAINT_TYPE_ROTLIKE, "COPY_ROTATION", ICON_CONSTRAINT_DATA, "Copy Rotation",
+ {CONSTRAINT_TYPE_ROTLIKE, "COPY_ROTATION", ICON_CONSTRAINT_DATA, "Copy Rotation",
"Copy the rotation of a target (with an optional offset), so that they rotate together"},
- {CONSTRAINT_TYPE_SIZELIKE, "COPY_SCALE", ICON_CONSTRAINT_DATA, "Copy Scale",
+ {CONSTRAINT_TYPE_SIZELIKE, "COPY_SCALE", ICON_CONSTRAINT_DATA, "Copy Scale",
"Copy the scale factors of a target (with an optional offset), so that they are scaled by the same amount"},
- {CONSTRAINT_TYPE_TRANSLIKE, "COPY_TRANSFORMS", ICON_CONSTRAINT_DATA, "Copy Transforms",
+ {CONSTRAINT_TYPE_TRANSLIKE, "COPY_TRANSFORMS", ICON_CONSTRAINT_DATA, "Copy Transforms",
"Copy all the transformations of a target, so that they move together"},
- {CONSTRAINT_TYPE_DISTLIMIT, "LIMIT_DISTANCE", ICON_CONSTRAINT_DATA, "Limit Distance",
+ {CONSTRAINT_TYPE_DISTLIMIT, "LIMIT_DISTANCE", ICON_CONSTRAINT_DATA, "Limit Distance",
"Restrict movements to within a certain distance of a target (at the time of constraint evaluation only)"},
- {CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location",
+ {CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location",
"Restrict movement along each axis within given ranges"},
- {CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation",
+ {CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation",
"Restrict rotation along each axis within given ranges"},
- {CONSTRAINT_TYPE_SIZELIMIT, "LIMIT_SCALE", ICON_CONSTRAINT_DATA, "Limit Scale",
+ {CONSTRAINT_TYPE_SIZELIMIT, "LIMIT_SCALE", ICON_CONSTRAINT_DATA, "Limit Scale",
"Restrict scaling along each axis with given ranges"},
- {CONSTRAINT_TYPE_SAMEVOL, "MAINTAIN_VOLUME", ICON_CONSTRAINT_DATA, "Maintain Volume",
+ {CONSTRAINT_TYPE_SAMEVOL, "MAINTAIN_VOLUME", ICON_CONSTRAINT_DATA, "Maintain Volume",
"Compensate for scaling one axis by applying suitable scaling to the other two axes"},
- {CONSTRAINT_TYPE_TRANSFORM, "TRANSFORM", ICON_CONSTRAINT_DATA, "Transformation",
+ {CONSTRAINT_TYPE_TRANSFORM, "TRANSFORM", ICON_CONSTRAINT_DATA, "Transformation",
"Use one transform property from target to control another (or same) property on owner"},
{CONSTRAINT_TYPE_TRANSFORM_CACHE, "TRANSFORM_CACHE", ICON_CONSTRAINT_DATA, "Transform Cache",
"Look up the transformation matrix from an external file"},
{0, "", 0, N_("Tracking"), ""},
- {CONSTRAINT_TYPE_CLAMPTO, "CLAMP_TO", ICON_CONSTRAINT_DATA, "Clamp To",
+ {CONSTRAINT_TYPE_CLAMPTO, "CLAMP_TO", ICON_CONSTRAINT_DATA, "Clamp To",
"Restrict movements to lie along a curve by remapping location along curve's longest axis"},
{CONSTRAINT_TYPE_DAMPTRACK, "DAMPED_TRACK", ICON_CONSTRAINT_DATA, "Damped Track",
"Point towards a target by performing the smallest rotation necessary"},
- {CONSTRAINT_TYPE_KINEMATIC, "IK", ICON_CONSTRAINT_DATA, "Inverse Kinematics",
+ {CONSTRAINT_TYPE_KINEMATIC, "IK", ICON_CONSTRAINT_DATA, "Inverse Kinematics",
"Control a chain of bones by specifying the endpoint target (Bones only)"},
{CONSTRAINT_TYPE_LOCKTRACK, "LOCKED_TRACK", ICON_CONSTRAINT_DATA, "Locked Track",
"Rotate around the specified ('locked') axis to point towards a target"},
- {CONSTRAINT_TYPE_SPLINEIK, "SPLINE_IK", ICON_CONSTRAINT_DATA, "Spline IK",
+ {CONSTRAINT_TYPE_SPLINEIK, "SPLINE_IK", ICON_CONSTRAINT_DATA, "Spline IK",
"Align chain of bones along a curve (Bones only)"},
- {CONSTRAINT_TYPE_STRETCHTO, "STRETCH_TO", ICON_CONSTRAINT_DATA, "Stretch To",
+ {CONSTRAINT_TYPE_STRETCHTO, "STRETCH_TO", ICON_CONSTRAINT_DATA, "Stretch To",
"Stretch along Y-Axis to point towards a target"},
{CONSTRAINT_TYPE_TRACKTO, "TRACK_TO", ICON_CONSTRAINT_DATA, "Track To",
"Legacy tracking constraint prone to twisting artifacts"},
{0, "", 0, N_("Relationship"), ""},
- {CONSTRAINT_TYPE_ACTION, "ACTION", ICON_CONSTRAINT_DATA, "Action",
+ {CONSTRAINT_TYPE_ACTION, "ACTION", ICON_CONSTRAINT_DATA, "Action",
"Use transform property of target to look up pose for owner from an Action"},
- {CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of",
+ {CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of",
"Make target the 'detachable' parent of owner"},
- {CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor",
+ {CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor",
"Use position (and optionally rotation) of target to define a 'wall' or 'floor' that the owner can not cross"},
- {CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path",
+ {CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path",
"Use to animate an object/bone following a path"},
- {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot",
+ {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot",
"Change pivot point for transforms (buggy)"},
/* {CONSTRAINT_TYPE_RIGIDBODYJOINT, "RIGID_BODY_JOINT", ICON_CONSTRAINT_DATA, "Rigid Body Joint",
"Use to define a Rigid Body Constraint (for Game Engine use only)"}, */
- /* {CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script",
+ /* {CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script",
"Custom constraint(s) written in Python (Not yet implemented)"}, */
- {CONSTRAINT_TYPE_SHRINKWRAP, "SHRINKWRAP", ICON_CONSTRAINT_DATA, "Shrinkwrap",
+ {CONSTRAINT_TYPE_SHRINKWRAP, "SHRINKWRAP", ICON_CONSTRAINT_DATA, "Shrinkwrap",
"Restrict movements to surface of target mesh"},
{0, NULL, 0, NULL, NULL}
};
@@ -229,23 +229,23 @@ static void rna_Constraint_name_set(PointerRNA *ptr, const char *value)
{
bConstraint *con = ptr->data;
char oldname[sizeof(con->name)];
-
+
/* make a copy of the old name first */
BLI_strncpy(oldname, con->name, sizeof(con->name));
-
+
/* copy the new name into the name slot */
BLI_strncpy_utf8(con->name, value, sizeof(con->name));
-
+
/* make sure name is unique */
if (ptr->id.data) {
Object *ob = ptr->id.data;
ListBase *list = get_constraint_lb(ob, con, NULL);
-
+
/* if we have the list, check for unique name, otherwise give up */
if (list)
BKE_constraint_unique_name(con, list);
}
-
+
/* fix all the animation data which may link to this */
BKE_animdata_fix_paths_rename_all(NULL, "constraints", oldname, con->name);
}
@@ -291,7 +291,7 @@ static void rna_Constraint_influence_update(Main *bmain, Scene *scene, PointerRN
if (ob->pose)
ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
-
+
rna_Constraint_update(bmain, scene, ptr);
}
@@ -318,7 +318,7 @@ static const EnumPropertyItem *rna_Constraint_owner_space_itemf(bContext *UNUSED
{
Object *ob = (Object *)ptr->id.data;
bConstraint *con = (bConstraint *)ptr->data;
-
+
if (BLI_findindex(&ob->constraints, con) == -1)
return owner_space_pchan_items;
else /* object */
@@ -332,14 +332,14 @@ static const EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *UNUSE
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
-
+
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
-
+
for (ct = targets.first; ct; ct = ct->next)
if (ct->tar && ct->tar->type == OB_ARMATURE)
break;
-
+
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 1);
@@ -384,7 +384,7 @@ static void rna_SplineIKConstraint_joint_bindings_get(PointerRNA *ptr, float *va
{
bConstraint *con = (bConstraint *)ptr->data;
bSplineIKConstraint *ikData = (bSplineIKConstraint *)con->data;
-
+
memcpy(values, ikData->points, ikData->numpoints * sizeof(float));
}
@@ -392,7 +392,7 @@ static void rna_SplineIKConstraint_joint_bindings_set(PointerRNA *ptr, const flo
{
bConstraint *con = (bConstraint *)ptr->data;
bSplineIKConstraint *ikData = (bSplineIKConstraint *)con->data;
-
+
memcpy(ikData->points, values, ikData->numpoints * sizeof(float));
}
@@ -508,12 +508,12 @@ static const EnumPropertyItem constraint_distance_items[] = {
static void rna_def_constraint_headtail_common(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "head_tail", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, "bConstraint", "headtail");
RNA_def_property_ui_text(prop, "Head/Tail", "Target along length of bone: Head=0, Tail=1");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "use_bbone_shape", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, "bConstraint", "flag", CONSTRAINT_BBONE_SHAPE);
RNA_def_property_ui_text(prop, "Follow B-Bone", "Follow shape of B-Bone segments when calculating Head/Tail position");
@@ -604,13 +604,13 @@ static void rna_def_constraint_childof(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", CHILDOF_SIZEZ);
RNA_def_property_ui_text(prop, "Scale Z", "Use Z Scale of Parent");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "inverse_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "invmat");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Inverse Matrix", "Transformation matrix to apply before");
-
+
}
static void rna_def_constraint_python(BlenderRNA *brna)
@@ -1001,7 +1001,7 @@ static void rna_def_constraint_transform_like(BlenderRNA *brna)
srna = RNA_def_struct(brna, "CopyTransformsConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Copy Transforms Constraint", "Copy all the transforms of the target");
-
+
rna_def_constraint_headtail_common(srna);
RNA_def_struct_sdna_from(srna, "bTransLikeConstraint", "data");
@@ -1149,9 +1149,9 @@ static void rna_def_constraint_locked_track(BlenderRNA *brna)
srna = RNA_def_struct(brna, "LockedTrackConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Locked Track Constraint",
"Point toward the target along the track axis, while locking the other axis");
-
+
rna_def_constraint_headtail_common(srna);
-
+
RNA_def_struct_sdna_from(srna, "bLockTrackConstraint", "data");
rna_def_constraint_target_common(srna);
@@ -1206,7 +1206,7 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna)
RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Offset", "Offset from the position corresponding to the time frame");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "offset_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "offset_fac");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -1229,7 +1229,7 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_FOLLOW);
RNA_def_property_ui_text(prop, "Follow Curve", "Object will follow the heading and banking of the curve");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "use_fixed_location", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_STATIC);
RNA_def_property_ui_text(prop, "Fixed Position",
@@ -1866,9 +1866,9 @@ static void rna_def_constraint_distance_limit(BlenderRNA *brna)
srna = RNA_def_struct(brna, "LimitDistanceConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Limit Distance Constraint", "Limit the distance from target object");
-
+
rna_def_constraint_headtail_common(srna);
-
+
RNA_def_struct_sdna_from(srna, "bDistLimitConstraint", "data");
rna_def_constraint_target_common(srna);
@@ -1884,7 +1884,7 @@ static void rna_def_constraint_distance_limit(BlenderRNA *brna)
RNA_def_property_enum_items(prop, constraint_distance_items);
RNA_def_property_ui_text(prop, "Limit Mode", "Distances in relation to sphere of influence to allow");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LIMITDIST_TRANSFORM);
RNA_def_property_ui_text(prop, "For Transform", "Transforms are affected by this constraint as well");
@@ -1895,7 +1895,7 @@ static void rna_def_constraint_shrinkwrap(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem type_items[] = {
{MOD_SHRINKWRAP_NEAREST_SURFACE, "NEAREST_SURFACE", 0, "Nearest Surface Point",
"Shrink the location to the nearest target surface"},
@@ -1905,24 +1905,24 @@ static void rna_def_constraint_shrinkwrap(BlenderRNA *brna)
"Shrink the location to the nearest target vertex"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "ShrinkwrapConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Shrinkwrap Constraint", "Create constraint-based shrinkwrap relationship");
RNA_def_struct_sdna_from(srna, "bShrinkwrapConstraint", "data");
-
+
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "target"); /* TODO, mesh type */
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Mesh_object_poll");
RNA_def_property_ui_text(prop, "Target", "Target Mesh object");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
+
prop = RNA_def_property(srna, "shrinkwrap_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shrinkType");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Shrinkwrap Type", "Select type of shrinkwrap algorithm for target position");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "dist");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
@@ -1968,9 +1968,9 @@ static void rna_def_constraint_damped_track(BlenderRNA *brna)
srna = RNA_def_struct(brna, "DampedTrackConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Damped Track Constraint",
"Point toward target by taking the shortest rotation path");
-
+
rna_def_constraint_headtail_common(srna);
-
+
RNA_def_struct_sdna_from(srna, "bDampTrackConstraint", "data");
rna_def_constraint_target_common(srna);
@@ -1986,7 +1986,7 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem splineik_xz_scale_mode[] = {
{CONSTRAINT_SPLINEIK_XZS_NONE, "NONE", 0, "None", "Don't scale the X and Z axes (Default)"},
{CONSTRAINT_SPLINEIK_XZS_ORIGINAL, "BONE_ORIGINAL", 0, "Bone Original",
@@ -2001,7 +2001,7 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
srna = RNA_def_struct(brna, "SplineIKConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Spline IK Constraint", "Align 'n' bones along a curve");
RNA_def_struct_sdna_from(srna, "bSplineIKConstraint", "data");
-
+
/* target chain */
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tar");
@@ -2009,7 +2009,7 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Target", "Curve that controls this relationship");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
+
prop = RNA_def_property(srna, "chain_count", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "chainlen");
/* TODO: this should really check the max length of the chain the constraint is attached to */
@@ -2017,7 +2017,7 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Chain Length", "How many bones are included in the chain");
/* XXX: this update goes wrong... needs extra flush? */
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
+
/* direct access to bindings */
/* NOTE: only to be used by experienced users */
prop = RNA_def_property(srna, "joint_bindings", PROP_FLOAT, PROP_FACTOR);
@@ -2030,31 +2030,31 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
"(EXPERIENCED USERS ONLY) The relative positions of the joints along the chain, "
"as percentages");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
/* settings */
prop = RNA_def_property(srna, "use_chain_offset", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_NO_ROOT);
RNA_def_property_ui_text(prop, "Chain Offset", "Offset the entire chain relative to the root joint");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "use_even_divisions", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_EVENSPLITS);
RNA_def_property_ui_text(prop, "Even Divisions",
"Ignore the relative lengths of the bones when fitting to the curve");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "use_y_stretch", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_SCALE_LIMITED);
RNA_def_property_ui_text(prop, "Y Stretch", "Stretch the Y axis of the bones to fit the curve");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "use_curve_radius", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_NO_CURVERAD);
RNA_def_property_ui_text(prop, "Use Curve Radius",
"Average radius of the endpoints is used to tweak the X and Z Scaling of the bones, "
"on top of XZ Scale mode");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
/* xz scaling mode */
prop = RNA_def_property(srna, "xz_scale_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "xzScaleMode");
@@ -2062,33 +2062,33 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "XZ Scale Mode",
"Method used for determining the scaling of the X and Z axes of the bones");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
/* volume presevation for "volumetric" scale mode */
prop = RNA_def_property(srna, "bulge", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 100.f);
RNA_def_property_ui_text(prop, "Volume Variation", "Factor between volume variation and stretching");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "use_bulge_min", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_USE_BULGE_MIN);
RNA_def_property_ui_text(prop, "Use Volume Variation Minimum", "Use lower limit for volume variation");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "use_bulge_max", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_USE_BULGE_MAX);
RNA_def_property_ui_text(prop, "Use Volume Variation Maximum", "Use upper limit for volume variation");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "bulge_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 1.0f);
RNA_def_property_ui_text(prop, "Volume Variation Minimum", "Minimum volume stretching factor");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "bulge_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 1.0, 100.0f);
RNA_def_property_ui_text(prop, "Volume Variation Maximum", "Maximum volume stretching factor");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "bulge_smooth", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0.0, 1.0f);
RNA_def_property_ui_text(prop, "Volume Variation Smoothness", "Strength of volume stretching clamping");
@@ -2116,37 +2116,37 @@ static void rna_def_constraint_pivot(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PivotConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Pivot Constraint", "Rotate around a different point");
-
+
rna_def_constraint_headtail_common(srna);
-
+
RNA_def_struct_sdna_from(srna, "bPivotConstraint", "data");
-
+
/* target-defined pivot */
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tar");
RNA_def_property_ui_text(prop, "Target", "Target Object, defining the position of the pivot when defined");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
+
prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "subtarget");
RNA_def_property_ui_text(prop, "Sub-Target", "");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
+
/* pivot offset */
prop = RNA_def_property(srna, "use_relative_location", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", PIVOTCON_FLAG_OFFSET_ABS);
RNA_def_property_ui_text(prop, "Use Relative Offset",
"Offset will be an absolute point in space instead of relative to the target");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "offset");
RNA_def_property_ui_text(prop, "Offset",
"Offset of pivot from target (when set), or from owner's location "
"(when Fixed Position is off), or the absolute pivot point");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
-
+
/* rotation-based activation */
prop = RNA_def_property(srna, "rotation_range", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rotAxis");
@@ -2324,21 +2324,21 @@ void RNA_def_constraint(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
/* data */
srna = RNA_def_struct(brna, "Constraint", NULL);
RNA_def_struct_ui_text(srna, "Constraint", "Constraint modifying the transformation of objects and bones");
RNA_def_struct_refine_func(srna, "rna_ConstraintType_refine");
RNA_def_struct_path_func(srna, "rna_Constraint_path");
RNA_def_struct_sdna(srna, "bConstraint");
-
+
/* strings */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Constraint_name_set");
RNA_def_property_ui_text(prop, "Name", "Constraint name");
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT | NA_RENAME, NULL);
-
+
/* enums */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -2361,12 +2361,12 @@ void RNA_def_constraint(BlenderRNA *brna)
/* flags */
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_OFF);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Disable", "Enable/Disable Constraint");
-
+
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_EXPAND);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Expanded", "Constraint's panel is expanded in UI");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
@@ -2375,17 +2375,17 @@ void RNA_def_constraint(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CONSTRAINT_DISABLE);
RNA_def_property_ui_text(prop, "Valid", "Constraint has valid settings and can be evaluated");
-
+
/* TODO: setting this to true must ensure that all others in stack are turned off too... */
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_ACTIVE);
RNA_def_property_ui_text(prop, "Active", "Constraint is the one being edited ");
-
+
prop = RNA_def_property(srna, "is_proxy_local", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_PROXY_LOCAL);
RNA_def_property_ui_text(prop, "Proxy Local",
"Constraint was added in this proxy instance (i.e. did not belong to source Armature)");
-
+
/* values */
prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "enforce");
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 894af338c12..0681a449aa2 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -55,7 +55,7 @@ static const EnumPropertyItem beztriple_handle_type_items[] = {
{0, NULL, 0, NULL, NULL}
};
#endif
-
+
const EnumPropertyItem rna_enum_keyframe_handle_type_items[] = {
{HD_FREE, "FREE", 0, "Free", ""},
{HD_VECT, "VECTOR", 0, "Vector", ""},
@@ -71,7 +71,7 @@ const EnumPropertyItem rna_enum_beztriple_interpolation_mode_items[] = {
{BEZT_IPO_CONST, "CONSTANT", ICON_IPO_CONSTANT, "Constant", "No interpolation, value of A gets held until B is encountered"},
{BEZT_IPO_LIN, "LINEAR", ICON_IPO_LINEAR, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"},
{BEZT_IPO_BEZ, "BEZIER", ICON_IPO_BEZIER, "Bezier", "Smooth interpolation between A and B, with some control over curve shape"},
-
+
/* easing */
{0, "", 0, N_("Easing (by strength)"), "Predefined inertial transitions, useful for motion graphics (from least to most ''dramatic'')"},
{BEZT_IPO_SINE, "SINE", ICON_IPO_SINE, "Sinusoidal", "Sinusoidal easing (weakest, almost linear but with a slight curvature)"},
@@ -81,12 +81,12 @@ const EnumPropertyItem rna_enum_beztriple_interpolation_mode_items[] = {
{BEZT_IPO_QUINT, "QUINT", ICON_IPO_QUINT, "Quintic", "Quintic easing"},
{BEZT_IPO_EXPO, "EXPO", ICON_IPO_EXPO, "Exponential", "Exponential easing (dramatic)"},
{BEZT_IPO_CIRC, "CIRC", ICON_IPO_CIRC, "Circular", "Circular easing (strongest and most dynamic)"},
-
+
{0, "", 0, N_("Dynamic Effects"), "Simple physics-inspired easing effects"},
{BEZT_IPO_BACK, "BACK", ICON_IPO_BACK, "Back", "Cubic easing with overshoot and settle"},
{BEZT_IPO_BOUNCE, "BOUNCE", ICON_IPO_BOUNCE, "Bounce", "Exponentially decaying parabolic bounce, like when objects collide"},
{BEZT_IPO_ELASTIC, "ELASTIC", ICON_IPO_ELASTIC, "Elastic", "Exponentially decaying sine wave, like an elastic band"},
-
+
{0, NULL, 0, NULL, NULL}
};
@@ -159,7 +159,7 @@ static Nurb *curve_nurb_from_point(Curve *cu, const void *point, int *nu_index,
if (nu_index) {
*nu_index = i;
}
-
+
if (pt_index) {
if (nu->type == CU_BEZIER) *pt_index = (int)((BezTriple *)point - nu->bezt);
else *pt_index = (int)((BPoint *)point - nu->bp);
@@ -173,7 +173,7 @@ static StructRNA *rna_Curve_refine(PointerRNA *ptr)
{
Curve *cu = (Curve *)ptr->data;
short obtype = BKE_curve_type_get(cu);
-
+
if (obtype == OB_FONT) return &RNA_TextCurve;
else if (obtype == OB_SURF) return &RNA_SurfaceCurve;
else return &RNA_Curve;
@@ -218,7 +218,7 @@ static void rna_BezTriple_ctrlpoint_set(PointerRNA *ptr, const float *values)
static void rna_Curve_texspace_set(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Curve *cu = (Curve *)ptr->data;
-
+
if (cu->texflag & CU_AUTOSPACE)
BKE_curve_texspace_calc(cu);
}
@@ -232,34 +232,34 @@ static int rna_Curve_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_in
static void rna_Curve_texspace_loc_get(PointerRNA *ptr, float *values)
{
Curve *cu = (Curve *)ptr->data;
-
+
if (!cu->bb)
BKE_curve_texspace_calc(cu);
-
+
copy_v3_v3(values, cu->loc);
}
static void rna_Curve_texspace_loc_set(PointerRNA *ptr, const float *values)
{
Curve *cu = (Curve *)ptr->data;
-
+
copy_v3_v3(cu->loc, values);
}
static void rna_Curve_texspace_size_get(PointerRNA *ptr, float *values)
{
Curve *cu = (Curve *)ptr->data;
-
+
if (!cu->bb)
BKE_curve_texspace_calc(cu);
-
+
copy_v3_v3(values, cu->size);
}
static void rna_Curve_texspace_size_set(PointerRNA *ptr, const float *values)
{
Curve *cu = (Curve *)ptr->data;
-
+
copy_v3_v3(cu->size, values);
}
@@ -448,7 +448,7 @@ static void rna_Curve_resolution_u_update_data(Main *bmain, Scene *scene, Pointe
nu->resolu = cu->resolu;
nu = nu->next;
}
-
+
rna_Curve_update_data(bmain, scene, ptr);
}
@@ -900,7 +900,7 @@ static void rna_def_beztriple(BlenderRNA *brna)
static void rna_def_path(BlenderRNA *UNUSED(brna), StructRNA *srna)
{
PropertyRNA *prop;
-
+
/* number values */
prop = RNA_def_property(srna, "path_duration", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pathlen");
@@ -909,18 +909,18 @@ static void rna_def_path(BlenderRNA *UNUSED(brna), StructRNA *srna)
"The number of frames that are needed to traverse the path, "
"defining the maximum value for the 'Evaluation Time' setting");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
/* flags */
prop = RNA_def_property(srna, "use_path", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_PATH);
RNA_def_property_ui_text(prop, "Path", "Enable the curve to become a translation path");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "use_path_follow", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_FOLLOW);
RNA_def_property_ui_text(prop, "Follow", "Make curve path children to rotate along the path");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "use_stretch", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_STRETCH);
RNA_def_property_ui_text(prop, "Stretch", "Option for curve-deform: "
@@ -943,7 +943,7 @@ static void rna_def_path(BlenderRNA *UNUSED(brna), StructRNA *srna)
static void rna_def_nurbs(BlenderRNA *UNUSED(brna), StructRNA *srna)
{
PropertyRNA *prop;
-
+
/* flags */
prop = RNA_def_property(srna, "use_uv_as_generated", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_UV_ORCO);
@@ -992,7 +992,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_ui_range(prop, 0.01, 10, 1, 3);
RNA_def_property_ui_text(prop, "Font size", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "small_caps_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "smallcaps_scale");
RNA_def_property_ui_range(prop, 0, 1.0, 1, 2);
@@ -1004,51 +1004,51 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Distance between lines of text", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "space_word", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "wordspace");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Spacing between words", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "space_character", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spacing");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Global spacing between characters", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "shear", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shear");
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_ui_text(prop, "Shear", "Italic angle of the characters");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xof");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, -50.0f, 50.0f, 10, 3);
RNA_def_property_ui_text(prop, "X Offset", "Horizontal offset from the object origin");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "yof");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, -50.0f, 50.0f, 10, 3);
RNA_def_property_ui_text(prop, "Y Offset", "Vertical offset from the object origin");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "underline_position", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ulpos");
RNA_def_property_range(prop, -0.2f, 0.8f);
RNA_def_property_ui_text(prop, "Underline Position", "Vertical position of underline");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "underline_height", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ulheight");
RNA_def_property_range(prop, 0.0f, 0.8f);
RNA_def_property_ui_text(prop, "Underline Thickness", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "text_boxes", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "tb", "totbox");
RNA_def_property_struct_type(prop, "TextBox");
@@ -1058,7 +1058,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_int_sdna(prop, NULL, "actbox");
RNA_def_property_ui_text(prop, "The active text box", "");
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_Curve_active_textbox_index_range");
-
+
/* strings */
prop = RNA_def_property(srna, "family", PROP_STRING, PROP_NONE);
RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2);
@@ -1067,7 +1067,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
"followed by the character they represent, eg. 'family-a', 'family-b', etc, "
"set this setting to 'family-', and turn on Vertex Duplication)");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "str");
RNA_def_property_ui_text(prop, "Body Text", "Content of this text object");
@@ -1079,7 +1079,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len_wchar");
RNA_def_property_struct_type(prop, "TextCharacterFormat");
RNA_def_property_ui_text(prop, "Character Info", "Stores the style of each character");
-
+
/* pointers */
prop = RNA_def_property(srna, "follow_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "textoncurve");
@@ -1087,7 +1087,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Text on Curve", "Curve deforming text object");
RNA_def_property_update(prop, 0, "rna_Curve_update_deps");
-
+
prop = RNA_def_property(srna, "font", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "vfont");
RNA_def_property_ui_text(prop, "Font", "");
@@ -1128,10 +1128,10 @@ static void rna_def_textbox(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "TextBox", NULL);
RNA_def_struct_ui_text(srna, "Text Box", "Text bounding box for layout");
-
+
/* number values */
prop = RNA_def_property(srna, "x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "x");
@@ -1139,7 +1139,7 @@ static void rna_def_textbox(BlenderRNA *brna)
RNA_def_property_ui_range(prop, -50.0f, 50.0f, 10, 3);
RNA_def_property_ui_text(prop, "Textbox X Offset", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "y");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
@@ -1160,7 +1160,7 @@ static void rna_def_textbox(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0f, 50.0f, 10, 3);
RNA_def_property_ui_text(prop, "Textbox Height", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
RNA_def_struct_path_func(srna, "rna_TextBox_path");
}
@@ -1168,27 +1168,27 @@ static void rna_def_charinfo(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "TextCharacterFormat", NULL);
RNA_def_struct_sdna(srna, "CharInfo");
RNA_def_struct_ui_text(srna, "Text Character Format", "Text character formatting settings");
-
+
/* flags */
prop = RNA_def_property(srna, "use_bold", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_CHINFO_BOLD);
RNA_def_property_ui_text(prop, "Bold", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "use_italic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_CHINFO_ITALIC);
RNA_def_property_ui_text(prop, "Italic", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "use_underline", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_CHINFO_UNDERLINE);
RNA_def_property_ui_text(prop, "Underline", "");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
/* probably there is no reason to expose this */
#if 0
prop = RNA_def_property(srna, "wrap", PROP_BOOLEAN, PROP_NONE);
@@ -1212,7 +1212,7 @@ static void rna_def_charinfo(BlenderRNA *brna)
static void rna_def_surface(BlenderRNA *brna)
{
StructRNA *srna;
-
+
srna = RNA_def_struct(brna, "SurfaceCurve", "Curve");
RNA_def_struct_sdna(srna, "Curve");
RNA_def_struct_ui_text(srna, "Surface Curve", "Curve data-block used for storing surfaces");
@@ -1224,7 +1224,7 @@ static void rna_def_surface(BlenderRNA *brna)
static void rna_def_text(BlenderRNA *brna)
{
StructRNA *srna;
-
+
srna = RNA_def_struct(brna, "TextCurve", "Curve");
RNA_def_struct_sdna(srna, "Curve");
RNA_def_struct_ui_text(srna, "Text Curve", "Curve data-block used for storing text");
@@ -1335,7 +1335,7 @@ static void rna_def_curve(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem curve_twist_mode_items[] = {
{CU_TWIST_Z_UP, "Z_UP", 0, "Z-Up", "Use Z-Up axis to calculate the curve twist at each point"},
{CU_TWIST_MINIMUM, "MINIMUM", 0, "Minimum", "Use the least twist over the entire curve"},
@@ -1392,7 +1392,7 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_update(prop, NC_GEOM | ND_DATA, NULL);
rna_def_path(brna, srna);
-
+
/* Number values */
prop = RNA_def_property(srna, "bevel_resolution", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "bevresol");
@@ -1401,63 +1401,63 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bevel Resolution",
"Bevel resolution when depth is non-zero and no specific bevel object has been defined");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE | PROP_UNIT_LENGTH);
RNA_def_property_float_sdna(prop, NULL, "width");
RNA_def_property_ui_range(prop, -1.0, 1.0, 0.1, 3);
RNA_def_property_float_funcs(prop, "rna_Curve_offset_get", "rna_Curve_offset_set", NULL);
RNA_def_property_ui_text(prop, "Offset", "Offset the curve to adjust the width of a text");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "extrude", PROP_FLOAT, PROP_NONE | PROP_UNIT_LENGTH);
RNA_def_property_float_sdna(prop, NULL, "ext1");
RNA_def_property_ui_range(prop, 0, 100.0, 0.1, 3);
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_text(prop, "Extrude", "Amount of curve extrusion when not using a bevel object");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "bevel_depth", PROP_FLOAT, PROP_NONE | PROP_UNIT_LENGTH);
RNA_def_property_float_sdna(prop, NULL, "ext2");
RNA_def_property_ui_range(prop, 0, 100.0, 0.1, 3);
RNA_def_property_ui_text(prop, "Bevel Depth", "Bevel depth when not using a bevel object");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "resolution_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolu");
RNA_def_property_range(prop, 1, 1024);
RNA_def_property_ui_range(prop, 1, 64, 1, -1);
RNA_def_property_ui_text(prop, "Resolution U", "Surface resolution in U direction");
RNA_def_property_update(prop, 0, "rna_Curve_resolution_u_update_data");
-
+
prop = RNA_def_property(srna, "resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv");
RNA_def_property_ui_range(prop, 1, 64, 1, -1);
RNA_def_property_range(prop, 1, 1024);
RNA_def_property_ui_text(prop, "Resolution V", "Surface resolution in V direction");
RNA_def_property_update(prop, 0, "rna_Curve_resolution_v_update_data");
-
+
prop = RNA_def_property(srna, "render_resolution_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolu_ren");
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_range(prop, 0, 64, 1, -1);
RNA_def_property_ui_text(prop, "Render Resolution U",
"Surface resolution in U direction used while rendering (zero uses preview resolution)");
-
+
prop = RNA_def_property(srna, "render_resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv_ren");
RNA_def_property_ui_range(prop, 0, 64, 1, -1);
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_text(prop, "Render Resolution V",
"Surface resolution in V direction used while rendering (zero uses preview resolution)");
-
-
+
+
prop = RNA_def_property(srna, "eval_time", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ctime");
RNA_def_property_ui_text(prop, "Evaluation Time",
"Parametric position along the length of the curve that Objects 'following' it should be "
"at (position is evaluated by dividing by the 'Path Length' value)");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
/* pointers */
prop = RNA_def_property(srna, "bevel_object", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Object");
@@ -1485,7 +1485,7 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_enum_funcs(prop, NULL, "rna_Curve_dimension_set", NULL);
RNA_def_property_ui_text(prop, "Dimensions", "Select 2D or 3D curve type");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "fill_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, curve3d_fill_mode_items);
@@ -1547,7 +1547,7 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_editable_func(prop, "rna_Curve_texspace_editable");
RNA_def_property_float_funcs(prop, "rna_Curve_texspace_loc_get", "rna_Curve_texspace_loc_set", NULL);
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "texspace_size", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 3);
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
@@ -1555,7 +1555,7 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_editable_func(prop, "rna_Curve_texspace_editable");
RNA_def_property_float_funcs(prop, "rna_Curve_texspace_size_get", "rna_Curve_texspace_size_set", NULL);
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
/* not supported yet */
#if 0
prop = RNA_def_property(srna, "texspace_rot", PROP_FLOAT, PROP_EULER);
@@ -1564,12 +1564,12 @@ static void rna_def_curve(BlenderRNA *brna)
RNA_def_property_editable_func(prop, texspace_editable);
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
#endif
-
+
prop = RNA_def_property(srna, "use_uv_as_generated", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_UV_ORCO);
RNA_def_property_ui_text(prop, "Use UV for mapping", "Uses the UV values as Generated textured coordinates");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
/* materials */
prop = RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol");
@@ -1633,7 +1633,7 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bezier Points", "Collection of points for Bezier curves only");
rna_def_curve_spline_bezpoints(brna, prop);
-
+
prop = RNA_def_property(srna, "tilt_interpolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "tilt_interp");
RNA_def_property_enum_items(prop, spline_interpolation_items);
@@ -1752,7 +1752,7 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Material Index", "");
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_Curve_material_index_range");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-
+
prop = RNA_def_property(srna, "character_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "charidx");
RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* editing this needs knot recalc*/
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 03e58f8f78e..5b91a3e43d2 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -128,12 +128,12 @@ void rna_freelinkN(ListBase *listbase, void *vlink)
void rna_freelistN(ListBase *listbase)
{
Link *link, *next;
-
+
for (link = listbase->first; link; link = next) {
next = link->next;
MEM_freeN(link);
}
-
+
listbase->first = listbase->last = NULL;
}
@@ -335,13 +335,13 @@ typedef struct DNAStructMember {
static int rna_member_cmp(const char *name, const char *oname)
{
int a = 0;
-
+
/* compare without pointer or array part */
while (name[0] == '*')
name++;
while (oname[0] == '*')
oname++;
-
+
while (1) {
if (name[a] == '[' && oname[a] == 0) return 1;
if (name[a] == '[' && oname[a] == '[') return 1;
@@ -419,7 +419,7 @@ static int rna_find_sdna_member(SDNA *sdna, const char *structname, const char *
static int rna_validate_identifier(const char *identifier, char *error, bool property)
{
int a = 0;
-
+
/* list is from...
* ", ".join(['"%s"' % kw for kw in __import__("keyword").kwlist if kw not in {"False", "None", "True"}])
*/
@@ -431,13 +431,13 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro
"is", "lambda", "nonlocal", "not", "or", "pass", "raise",
"return", "try", "while", "with", "yield", NULL
};
-
-
+
+
if (!isalpha(identifier[0])) {
strcpy(error, "first character failed isalpha() check");
return 0;
}
-
+
for (a = 0; identifier[a]; a++) {
if (DefRNA.preprocess && property) {
if (isalpha(identifier[a]) && isupper(identifier[a])) {
@@ -445,7 +445,7 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro
return 0;
}
}
-
+
if (identifier[a] == '_') {
continue;
}
@@ -460,7 +460,7 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro
return 0;
}
}
-
+
for (a = 0; kwlist[a]; a++) {
if (STREQ(identifier, kwlist[a])) {
strcpy(error, "this keyword is reserved by python");
@@ -482,14 +482,14 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro
}
}
}
-
+
return 1;
}
void RNA_identifier_sanitize(char *identifier, int property)
{
int a = 0;
-
+
/* list from http://docs.python.org/py3k/reference/lexical_analysis.html#keywords */
static const char *kwlist[] = {
/* "False", "None", "True", */
@@ -499,13 +499,13 @@ void RNA_identifier_sanitize(char *identifier, int property)
"is", "lambda", "nonlocal", "not", "or", "pass", "raise",
"return", "try", "while", "with", "yield", NULL
};
-
-
+
+
if (!isalpha(identifier[0])) {
/* first character failed isalpha() check */
identifier[0] = '_';
}
-
+
for (a = 0; identifier[a]; a++) {
if (DefRNA.preprocess && property) {
if (isalpha(identifier[a]) && isupper(identifier[a])) {
@@ -513,7 +513,7 @@ void RNA_identifier_sanitize(char *identifier, int property)
identifier[a] = tolower(identifier[a]);
}
}
-
+
if (identifier[a] == '_') {
continue;
}
@@ -528,7 +528,7 @@ void RNA_identifier_sanitize(char *identifier, int property)
identifier[a] = '_';
}
}
-
+
for (a = 0; kwlist[a]; a++) {
if (STREQ(identifier, kwlist[a])) {
/* this keyword is reserved by python.
@@ -703,7 +703,7 @@ void RNA_free(BlenderRNA *brna)
}
rna_freelistN(&brna->structs);
-
+
MEM_freeN(brna);
}
else {
@@ -1078,13 +1078,13 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
if (DefRNA.preprocess) {
char error[512];
-
+
if (rna_validate_identifier(identifier, error, true) == 0) {
fprintf(stderr, "%s: property identifier \"%s.%s\" - %s\n", __func__,
CONTAINER_RNA_ID(cont), identifier, error);
DefRNA.error = 1;
}
-
+
dcont = rna_find_container_def(cont);
/* XXX - toto, detect supertype collisions */
@@ -1198,7 +1198,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
if (type != PROP_COLLECTION && type != PROP_POINTER) {
prop->flag = PROP_EDITABLE;
-
+
if (type != PROP_STRING) {
#ifdef RNA_RUNTIME
prop->flag |= PROP_ANIMATABLE;
@@ -1293,6 +1293,16 @@ void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
prop->flag &= ~flag;
}
+void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
+{
+ prop->flag_override |= flag;
+}
+
+void RNA_def_property_override_clear_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
+{
+ prop->flag_override &= ~flag;
+}
+
/**
* Add the property-tags passed as \a tags to \a prop (if valid).
*
@@ -1372,7 +1382,7 @@ void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int le
{
StructRNA *srna = DefRNA.laststruct;
int i;
-
+
if (dimension < 1 || dimension > RNA_MAX_ARRAY_DIMENSION) {
fprintf(stderr, "%s: \"%s.%s\", array dimension must be between 1 and %d.\n",
__func__, srna->identifier, prop->identifier, RNA_MAX_ARRAY_DIMENSION);
@@ -1884,7 +1894,7 @@ static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *stru
prop->arraydimension = 0;
prop->totarraylength = 0;
}
-
+
dp->dnastructname = structname;
dp->dnastructfromname = ds->dnafromname;
dp->dnastructfromprop = ds->dnafromprop;
@@ -1900,7 +1910,7 @@ void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, co
{
PropertyDefRNA *dp;
StructRNA *srna = DefRNA.laststruct;
-
+
if (!DefRNA.preprocess) {
fprintf(stderr, "%s: only during preprocessing.\n", __func__);
return;
@@ -1946,7 +1956,7 @@ void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const
PropertyDefRNA *dp;
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
StructRNA *srna = DefRNA.laststruct;
-
+
if (!DefRNA.preprocess) {
fprintf(stderr, "%s: only during preprocessing.\n", __func__);
return;
@@ -2036,7 +2046,7 @@ void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const
{
/* PropertyDefRNA *dp; */
StructRNA *srna = DefRNA.laststruct;
-
+
if (!DefRNA.preprocess) {
fprintf(stderr, "%s: only during preprocessing.\n", __func__);
return;
@@ -2104,7 +2114,7 @@ void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, co
{
/* PropertyDefRNA *dp; */
StructRNA *srna = DefRNA.laststruct;
-
+
if (!DefRNA.preprocess) {
fprintf(stderr, "%s: only during preprocessing.\n", __func__);
return;
@@ -2660,7 +2670,7 @@ PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier,
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_default(prop, default_value);
RNA_def_property_ui_text(prop, ui_name, ui_description);
@@ -2673,7 +2683,7 @@ PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_, const char *ident
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
if (len != 0) RNA_def_property_array(prop, len);
if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
@@ -2687,7 +2697,7 @@ PropertyRNA *RNA_def_boolean_layer(StructOrFunctionRNA *cont_, const char *ident
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER);
if (len != 0) RNA_def_property_array(prop, len);
if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
@@ -2701,7 +2711,7 @@ PropertyRNA *RNA_def_boolean_layer_member(StructOrFunctionRNA *cont_, const char
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER_MEMBER);
if (len != 0) RNA_def_property_array(prop, len);
if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
@@ -2715,7 +2725,7 @@ PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *iden
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_XYZ); /* XXX */
if (len != 0) RNA_def_property_array(prop, len);
if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
@@ -2730,7 +2740,7 @@ PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
@@ -2748,7 +2758,7 @@ PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifi
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */
@@ -2767,7 +2777,7 @@ PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifie
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
@@ -2854,7 +2864,7 @@ PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, co
printf("%s: items not allowed to be NULL.\n", __func__);
return NULL;
}
-
+
prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
if (items) RNA_def_property_enum_items(prop, items);
RNA_def_property_enum_default(prop, default_value);
@@ -2896,7 +2906,7 @@ PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, f
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
@@ -2914,7 +2924,7 @@ PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identi
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ);
@@ -2932,7 +2942,7 @@ PropertyRNA *RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_, const char *id
const char *ui_description, float softmin, float softmax)
{
PropertyRNA *prop;
-
+
prop = RNA_def_float_vector(cont_, identifier, len, default_value, hardmin, hardmax, ui_name, ui_description,
softmin, softmax);
prop->subtype = PROP_XYZ_LENGTH;
@@ -2946,7 +2956,7 @@ PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identif
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR);
@@ -3023,7 +3033,7 @@ PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identif
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
@@ -3042,7 +3052,7 @@ PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *id
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE);
@@ -3060,7 +3070,7 @@ PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identi
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
ASSERT_SOFT_HARD_LIMITS;
prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR);
@@ -3077,7 +3087,7 @@ PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier,
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, type);
RNA_def_property_ui_text(prop, ui_name, ui_description);
@@ -3090,7 +3100,7 @@ PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *ide
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
RNA_def_property_struct_runtime(prop, type);
if ((type->flag & STRUCT_ID) != 0) {
@@ -3106,7 +3116,7 @@ PropertyRNA *RNA_def_collection(StructOrFunctionRNA *cont_, const char *identifi
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, type);
RNA_def_property_ui_text(prop, ui_name, ui_description);
@@ -3119,7 +3129,7 @@ PropertyRNA *RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, type);
RNA_def_property_ui_text(prop, ui_name, ui_description);
@@ -3576,7 +3586,7 @@ void RNA_def_property_free_pointers(PropertyRNA *prop)
static void rna_def_property_free(StructOrFunctionRNA *cont_, PropertyRNA *prop)
{
ContainerRNA *cont = cont_;
-
+
if (prop->flag_internal & PROP_INTERN_RUNTIME) {
if (cont->prophash)
BLI_ghash_remove(cont->prophash, prop->identifier, NULL, NULL);
@@ -3594,7 +3604,7 @@ int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *ide
{
ContainerRNA *cont = cont_;
PropertyRNA *prop;
-
+
for (prop = cont->properties.first; prop; prop = prop->next) {
if (STREQ(prop->identifier, identifier)) {
if (prop->flag_internal & PROP_INTERN_RUNTIME) {
diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index 8bfa8b7d551..f904d4c06b1 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -44,6 +44,8 @@
#include "BLI_iterator.h"
+#include "BKE_anim.h"
+
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_debug.h"
#include "DEG_depsgraph_query.h"
@@ -126,6 +128,14 @@ static int rna_DepsgraphObjectInstance_is_instance_get(PointerRNA *ptr)
return (deg_iter->dupli_object_current != NULL);
}
+/* ******************** Sorted ***************** */
+
+static int rna_Depsgraph_mode_get(PointerRNA *ptr)
+{
+ Depsgraph *depsgraph = ptr->data;
+ return DEG_get_mode(depsgraph);
+}
+
/* ******************** Updates ***************** */
static PointerRNA rna_DepsgraphUpdate_id_get(PointerRNA *ptr)
@@ -206,7 +216,6 @@ static void rna_Depsgraph_objects_begin(CollectionPropertyIterator *iter, Pointe
data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
- data->mode = DEG_ITER_OBJECT_MODE_RENDER;
((BLI_Iterator *)iter->internal.custom)->valid = true;
DEG_iterator_objects_begin(iter->internal.custom, data);
@@ -247,7 +256,6 @@ static void rna_Depsgraph_object_instances_begin(CollectionPropertyIterator *ite
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_DUPLI;
- data->mode = DEG_ITER_OBJECT_MODE_RENDER;
((BLI_Iterator *)iter->internal.custom)->valid = true;
DEG_iterator_objects_begin(iter->internal.custom, data);
@@ -464,9 +472,20 @@ static void rna_def_depsgraph(BlenderRNA *brna)
PropertyRNA *parm;
PropertyRNA *prop;
+ static EnumPropertyItem enum_depsgraph_mode_items[] = {
+ {DAG_EVAL_VIEWPORT, "VIEWPORT", 0, "Viewport", "Viewport non-rendered mode"},
+ {DAG_EVAL_PREVIEW, "PREVIEW", 0, "Preview", "Viewport rendered draw mode"},
+ {DAG_EVAL_RENDER, "RENDER", 0, "Render", "Render"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "Depsgraph", NULL);
RNA_def_struct_ui_text(srna, "Dependency Graph", "");
+ prop = RNA_def_enum(srna, "mode", enum_depsgraph_mode_items, 0, "Mode", "Evaluation mode");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_enum_funcs(prop, "rna_Depsgraph_mode_get", NULL, NULL);
+
/* Debug helpers. */
func = RNA_def_function(srna, "debug_relations_graphviz", "rna_Depsgraph_debug_relations_graphviz");
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index 0358efff266..509265c04df 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -438,7 +438,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_dissolve", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_DISSOLVE);
RNA_def_property_ui_text(prop, "Dissolve", "Enable to make surface changes disappear over time");
-
+
prop = RNA_def_property(srna, "dissolve_speed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "diss_speed");
RNA_def_property_range(prop, 1.0, 10000.0);
@@ -448,12 +448,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_drying", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_USE_DRYING);
RNA_def_property_ui_text(prop, "Dry", "Enable to make surface wetness dry over time");
-
+
prop = RNA_def_property(srna, "dry_speed", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 1.0, 10000.0);
RNA_def_property_ui_range(prop, 1.0, 10000.0, 5, -1);
RNA_def_property_ui_text(prop, "Dry Speed", "Approximately in how many frames should drying happen");
-
+
/*
* Simulation settings
*/
@@ -462,12 +462,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_range(prop, 16.0, 4096.0);
RNA_def_property_ui_range(prop, 16.0, 4096.0, 1, -1);
RNA_def_property_ui_text(prop, "Resolution", "Output image resolution");
-
+
prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
RNA_def_property_ui_text(prop, "UV Map", "UV map name");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DynamicPaint_uvlayer_set");
-
+
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "start_frame");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -475,7 +475,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1.0, 9999, 1, -1);
RNA_def_property_ui_text(prop, "Start Frame", "Simulation start frame");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaintSurfaces_updateFrames");
-
+
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "end_frame");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -483,13 +483,13 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1.0, 9999.0, 1, -1);
RNA_def_property_ui_text(prop, "End Frame", "Simulation end frame");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaintSurfaces_updateFrames");
-
+
prop = RNA_def_property(srna, "frame_substeps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "substeps");
RNA_def_property_range(prop, 0.0, 20.0);
RNA_def_property_ui_range(prop, 0.0, 10, 1, -1);
RNA_def_property_ui_text(prop, "Sub-Steps", "Do extra frames between scene frames to ensure smooth motion");
-
+
prop = RNA_def_property(srna, "use_antialiasing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_ANTIALIAS);
@@ -542,7 +542,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_items(prop, prop_dynamicpaint_effecttype);
RNA_def_property_ui_text(prop, "Effect Type", "");
-
+
prop = RNA_def_property(srna, "use_dry_log", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_DRY_LOG);
RNA_def_property_ui_text(prop, "Slow", "Use logarithmic drying (makes high values to dry faster than low values)");
@@ -551,13 +551,13 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_DISSOLVE_LOG);
RNA_def_property_ui_text(prop, "Slow",
"Use logarithmic dissolve (makes high values to fade faster than low values)");
-
+
prop = RNA_def_property(srna, "use_spread", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "effect", MOD_DPAINT_EFFECT_DO_SPREAD);
RNA_def_property_ui_text(prop, "Use Spread", "Process spread effect (spread wet paint around surface)");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaintSurface_reset");
-
+
prop = RNA_def_property(srna, "spread_speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "spread_speed");
RNA_def_property_range(prop, 0.001, 10.0);
@@ -575,19 +575,19 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0, 2.0);
RNA_def_property_ui_range(prop, 0.0, 2.0, 1, 2);
RNA_def_property_ui_text(prop, "Color Spread", "How fast colors get mixed within wet paint");
-
+
prop = RNA_def_property(srna, "use_drip", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "effect", MOD_DPAINT_EFFECT_DO_DRIP);
RNA_def_property_ui_text(prop, "Use Drip", "Process drip effect (drip wet paint to gravity direction)");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaintSurface_reset");
-
+
prop = RNA_def_property(srna, "use_shrink", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "effect", MOD_DPAINT_EFFECT_DO_SHRINK);
RNA_def_property_ui_text(prop, "Use Shrink", "Process shrink effect (shrink paint areas)");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaintSurface_reset");
-
+
prop = RNA_def_property(srna, "shrink_speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shrink_speed");
RNA_def_property_range(prop, 0.001, 10.0);
@@ -618,7 +618,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_MULALPHA);
RNA_def_property_ui_text(prop, "Premultiply alpha", "Multiply color by alpha (recommended for Blender input)");
-
+
prop = RNA_def_property(srna, "image_output_path", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_sdna(prop, NULL, "image_output_path");
RNA_def_property_ui_text(prop, "Output Path", "Directory to save the textures");
@@ -658,7 +658,7 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
/* return type */
parm = RNA_def_boolean(func, "exists", 0, "", "");
RNA_def_function_return(func, parm);
-
+
prop = RNA_def_property(srna, "depth_clamp", PROP_FLOAT, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.00, 50.0);
@@ -674,12 +674,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_ui_range(prop, -5.0, 5.0, 1, 2);
RNA_def_property_ui_text(prop, "Displace Factor", "Strength of displace when applied to the mesh");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
prop = RNA_def_property(srna, "image_fileformat", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_items(prop, prop_dynamicpaint_image_fileformat);
RNA_def_property_ui_text(prop, "File Format", "");
-
+
prop = RNA_def_property(srna, "displace_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "disp_type");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -824,12 +824,12 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0, 1.0, 5, 2);
RNA_def_property_ui_text(prop, "Paint Alpha", "Paint alpha");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
prop = RNA_def_property(srna, "use_absolute_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_ABS_ALPHA);
RNA_def_property_ui_text(prop, "Absolute Alpha",
"Only increase alpha value if paint alpha is higher than existing");
-
+
prop = RNA_def_property(srna, "paint_wetness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "wetness");
RNA_def_property_range(prop, 0.0, 1.0);
@@ -837,7 +837,7 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Paint Wetness",
"Paint wetness, visible in wetmap (some effects only affect wet paint)");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
prop = RNA_def_property(srna, "use_paint_erase", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_ERASE);
RNA_def_property_ui_text(prop, "Erase Paint", "Erase / remove paint instead of adding it");
@@ -890,7 +890,7 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_VELOCITY_COLOR);
RNA_def_property_ui_text(prop, "Replace Color", "Replace brush color by velocity color ramp");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
/*
* Paint Area / Collision
*/
@@ -900,7 +900,7 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_dynamicpaint_collisiontype);
RNA_def_property_ui_text(prop, "Paint Source", "");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
prop = RNA_def_property(srna, "paint_distance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "paint_distance");
RNA_def_property_range(prop, 0.0, 500.0);
@@ -908,19 +908,19 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Proximity Distance",
"Maximum distance from brush to mesh surface to affect paint");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
prop = RNA_def_property(srna, "use_proximity_ramp_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_RAMP_ALPHA);
RNA_def_property_ui_text(prop, "Only Use Alpha", "Only read color ramp alpha");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
prop = RNA_def_property(srna, "proximity_falloff", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_sdna(prop, NULL, "proximity_falloff");
RNA_def_property_enum_items(prop, prop_dynamicpaint_prox_falloff);
RNA_def_property_ui_text(prop, "Falloff", "Proximity falloff type");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
prop = RNA_def_property(srna, "use_proximity_project", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_PROX_PROJECT);
RNA_def_property_ui_text(prop, "Project",
@@ -944,7 +944,7 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_NEGATE_VOLUME);
RNA_def_property_ui_text(prop, "Negate Volume", "Negate influence inside the volume");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
/*
* Particle
@@ -956,12 +956,12 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Particle Systems", "The particle system to paint with");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_reset_dependency");
-
+
prop = RNA_def_property(srna, "use_particle_radius", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_PART_RAD);
RNA_def_property_ui_text(prop, "Use Particle Radius", "Use radius from particle settings");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
prop = RNA_def_property(srna, "solid_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "particle_radius");
RNA_def_property_range(prop, 0.01, 10.0);
@@ -975,7 +975,7 @@ static void rna_def_dynamic_paint_brush_settings(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0, 1.0, 5, -1);
RNA_def_property_ui_text(prop, "Smooth Radius", "Smooth falloff added after solid radius");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_DynamicPaint_redoModifier");
-
+
/*
* Color ramps
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 61fcc0e6654..64d6960d0ff 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -85,7 +85,7 @@ const EnumPropertyItem rna_enum_beztriple_interpolation_easing_items[] = {
{BEZT_IPO_EASE_AUTO, "AUTO", ICON_IPO_EASE_IN_OUT, "Automatic Easing",
"Easing type is chosen automatically based on what the type of interpolation used "
"(e.g. 'Ease In' for transitional types, and 'Ease Out' for dynamic effects)"},
-
+
{BEZT_IPO_EASE_IN, "EASE_IN", ICON_IPO_EASE_IN, "Ease In", "Only on the end closest to the next keyframe"},
{BEZT_IPO_EASE_OUT, "EASE_OUT", ICON_IPO_EASE_OUT, "Ease Out", "Only on the end closest to the first keyframe"},
{BEZT_IPO_EASE_IN_OUT, "EASE_IN_OUT", ICON_IPO_EASE_IN_OUT, "Ease In and Out", "Segment between both keyframes"},
@@ -138,21 +138,21 @@ static void rna_ChannelDriver_update_data(Main *bmain, Scene *scene, PointerRNA
ChannelDriver *driver = ptr->data;
driver->flag &= ~DRIVER_FLAG_INVALID;
-
+
/* TODO: this really needs an update guard... */
DEG_relations_tag_update(bmain);
DEG_id_tag_update(id, OB_RECALC_OB | OB_RECALC_DATA);
-
+
WM_main_add_notifier(NC_SCENE | ND_FRAME, scene);
}
static void rna_ChannelDriver_update_expr(Main *bmain, Scene *scene, PointerRNA *ptr)
{
ChannelDriver *driver = ptr->data;
-
+
/* tag driver as needing to be recompiled */
driver->flag |= DRIVER_FLAG_RECOMPILE;
-
+
/* update_data() clears invalid flag and schedules for updates */
rna_ChannelDriver_update_data(bmain, scene, ptr);
}
@@ -168,7 +168,7 @@ static void rna_DriverTarget_update_data(Main *bmain, Scene *scene, PointerRNA *
for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
driver = fcu->driver;
fcu->flag &= ~FCURVE_DISABLED;
-
+
if (driver) {
/* FIXME: need to be able to search targets for required one... */
/*BLI_findindex(&driver->targets, ptr->data) != -1) */
@@ -212,7 +212,7 @@ static int rna_DriverTarget_id_editable(PointerRNA *ptr, const char **UNUSED(r_i
static int rna_DriverTarget_id_type_editable(PointerRNA *ptr, const char **UNUSED(r_info))
{
DriverTarget *dtar = (DriverTarget *)ptr->data;
-
+
/* when the id-type can only be object, don't allow editing
* otherwise, there may be strange crashes
*/
@@ -222,7 +222,7 @@ static int rna_DriverTarget_id_type_editable(PointerRNA *ptr, const char **UNUSE
static void rna_DriverTarget_id_type_set(PointerRNA *ptr, int value)
{
DriverTarget *data = (DriverTarget *)(ptr->data);
-
+
/* check if ID-type is settable */
if ((data->flag & DTAR_FLAG_ID_OB_ONLY) == 0) {
/* change ID-type to the new type */
@@ -232,7 +232,7 @@ static void rna_DriverTarget_id_type_set(PointerRNA *ptr, int value)
/* make sure ID-type is Object */
data->idtype = ID_OB;
}
-
+
/* clear the id-block if the type is invalid */
if ((data->id) && (GS(data->id->name) != data->idtype))
data->id = NULL;
@@ -251,7 +251,7 @@ static void rna_DriverTarget_RnaPath_get(PointerRNA *ptr, char *value)
static int rna_DriverTarget_RnaPath_length(PointerRNA *ptr)
{
DriverTarget *dtar = (DriverTarget *)ptr->data;
-
+
if (dtar->rna_path)
return strlen(dtar->rna_path);
else
@@ -261,11 +261,11 @@ static int rna_DriverTarget_RnaPath_length(PointerRNA *ptr)
static void rna_DriverTarget_RnaPath_set(PointerRNA *ptr, const char *value)
{
DriverTarget *dtar = (DriverTarget *)ptr->data;
-
+
/* XXX in this case we need to be very careful, as this will require some new dependencies to be added! */
if (dtar->rna_path)
MEM_freeN(dtar->rna_path);
-
+
if (value[0])
dtar->rna_path = BLI_strdup(value);
else
@@ -275,7 +275,7 @@ static void rna_DriverTarget_RnaPath_set(PointerRNA *ptr, const char *value)
static void rna_DriverVariable_type_set(PointerRNA *ptr, int value)
{
DriverVar *dvar = (DriverVar *)ptr->data;
-
+
/* call the API function for this */
driver_change_variable_type(dvar, value);
}
@@ -283,7 +283,7 @@ static void rna_DriverVariable_type_set(PointerRNA *ptr, int value)
void rna_DriverVariable_name_set(PointerRNA *ptr, const char *value)
{
DriverVar *data = (DriverVar *)(ptr->data);
-
+
BLI_strncpy_utf8(data->name, value, 64);
driver_variable_name_validate(data);
}
@@ -314,7 +314,7 @@ static void rna_Driver_remove_variable(ChannelDriver *driver, ReportList *report
static void rna_FKeyframe_handle1_get(PointerRNA *ptr, float *values)
{
BezTriple *bezt = (BezTriple *)ptr->data;
-
+
values[0] = bezt->vec[0][0];
values[1] = bezt->vec[0][1];
}
@@ -322,7 +322,7 @@ static void rna_FKeyframe_handle1_get(PointerRNA *ptr, float *values)
static void rna_FKeyframe_handle1_set(PointerRNA *ptr, const float *values)
{
BezTriple *bezt = (BezTriple *)ptr->data;
-
+
bezt->vec[0][0] = values[0];
bezt->vec[0][1] = values[1];
}
@@ -330,7 +330,7 @@ static void rna_FKeyframe_handle1_set(PointerRNA *ptr, const float *values)
static void rna_FKeyframe_handle2_get(PointerRNA *ptr, float *values)
{
BezTriple *bezt = (BezTriple *)ptr->data;
-
+
values[0] = bezt->vec[2][0];
values[1] = bezt->vec[2][1];
}
@@ -338,7 +338,7 @@ static void rna_FKeyframe_handle2_get(PointerRNA *ptr, float *values)
static void rna_FKeyframe_handle2_set(PointerRNA *ptr, const float *values)
{
BezTriple *bezt = (BezTriple *)ptr->data;
-
+
bezt->vec[2][0] = values[0];
bezt->vec[2][1] = values[1];
}
@@ -346,7 +346,7 @@ static void rna_FKeyframe_handle2_set(PointerRNA *ptr, const float *values)
static void rna_FKeyframe_ctrlpoint_get(PointerRNA *ptr, float *values)
{
BezTriple *bezt = (BezTriple *)ptr->data;
-
+
values[0] = bezt->vec[1][0];
values[1] = bezt->vec[1][1];
}
@@ -354,7 +354,7 @@ static void rna_FKeyframe_ctrlpoint_get(PointerRNA *ptr, float *values)
static void rna_FKeyframe_ctrlpoint_set(PointerRNA *ptr, const float *values)
{
BezTriple *bezt = (BezTriple *)ptr->data;
-
+
bezt->vec[1][0] = values[0];
bezt->vec[1][1] = values[1];
}
@@ -374,7 +374,7 @@ static void rna_FCurve_RnaPath_get(PointerRNA *ptr, char *value)
static int rna_FCurve_RnaPath_length(PointerRNA *ptr)
{
FCurve *fcu = (FCurve *)ptr->data;
-
+
if (fcu->rna_path)
return strlen(fcu->rna_path);
else
@@ -387,7 +387,7 @@ static void rna_FCurve_RnaPath_set(PointerRNA *ptr, const char *value)
if (fcu->rna_path)
MEM_freeN(fcu->rna_path);
-
+
if (value[0]) {
fcu->rna_path = BLI_strdup(value);
fcu->flag &= ~FCURVE_DISABLED;
@@ -402,7 +402,7 @@ static void rna_FCurve_group_set(PointerRNA *ptr, PointerRNA value)
ID *vid = (ID *)value.id.data;
FCurve *fcu = ptr->data;
bAction *act = NULL;
-
+
/* get action */
if (ELEM(NULL, pid, vid)) {
printf("ERROR: one of the ID's for the groups to assign to is invalid (ptr=%p, val=%p)\n", pid, vid);
@@ -413,7 +413,7 @@ static void rna_FCurve_group_set(PointerRNA *ptr, PointerRNA value)
printf("ERROR: ID's differ - ptr=%p vs value=%p\n", pid, vid);
return;
}
-
+
if (GS(pid->name) == ID_AC && GS(vid->name) == ID_AC) {
/* the ID given is the action already - usually when F-Curve is obtained from an action's pointer */
act = (bAction *)pid;
@@ -423,14 +423,14 @@ static void rna_FCurve_group_set(PointerRNA *ptr, PointerRNA value)
AnimData *adt = BKE_animdata_from_id(ptr->id.data);
act = (adt) ? adt->action : NULL;
}
-
+
/* already belongs to group? */
if (fcu->grp == value.data) {
/* nothing to do */
printf("ERROR: F-Curve already belongs to this group\n");
return;
}
-
+
/* can only change group if we have info about the action the F-Curve is in
* (i.e. for drivers or random F-Curves, this cannot be done)
*/
@@ -444,10 +444,10 @@ static void rna_FCurve_group_set(PointerRNA *ptr, PointerRNA value)
printf("ERROR: F-Curve (%p) doesn't exist in action '%s'\n", fcu, act->id.name);
return;
}
-
+
/* try to remove F-Curve from action (including from any existing groups) */
action_groups_remove_channel(act, fcu);
-
+
/* add the F-Curve back to the action now in the right place */
/* TODO: make the api function handle the case where there isn't any group to assign to */
if (value.data) {
@@ -535,10 +535,10 @@ static void rna_FModifier_active_set(PointerRNA *ptr, int UNUSED(value))
static void rna_FModifier_start_frame_set(PointerRNA *ptr, float value)
{
FModifier *fcm = (FModifier *)ptr->data;
-
+
CLAMP(value, MINAFRAMEF, MAXFRAMEF);
fcm->sfra = value;
-
+
/* XXX: maintain old offset? */
if (fcm->sfra >= fcm->efra) {
fcm->efra = fcm->sfra;
@@ -548,10 +548,10 @@ static void rna_FModifier_start_frame_set(PointerRNA *ptr, float value)
static void rna_FModifer_end_frame_set(PointerRNA *ptr, float value)
{
FModifier *fcm = (FModifier *)ptr->data;
-
+
CLAMP(value, MINAFRAMEF, MAXFRAMEF);
fcm->efra = value;
-
+
/* XXX: maintain old offset? */
if (fcm->efra <= fcm->sfra) {
fcm->sfra = fcm->efra;
@@ -562,11 +562,11 @@ static void rna_FModifier_start_frame_range(PointerRNA *UNUSED(ptr), float *min,
float *UNUSED(softmin), float *UNUSED(softmax))
{
// FModifier *fcm = (FModifier *)ptr->data;
-
- /* Technically, "sfra <= efra" must hold; however, we can't strictly enforce that,
- * or else it becomes tricky to adjust the range... [#36844]
- *
- * NOTE: we do not set soft-limits on lower bounds, as it's too confusing when you
+
+ /* Technically, "sfra <= efra" must hold; however, we can't strictly enforce that,
+ * or else it becomes tricky to adjust the range... [#36844]
+ *
+ * NOTE: we do not set soft-limits on lower bounds, as it's too confusing when you
* can't easily use the slider to set things here
*/
*min = MINAFRAMEF;
@@ -577,13 +577,13 @@ static void rna_FModifier_end_frame_range(PointerRNA *ptr, float *min, float *ma
float *softmin, float *softmax)
{
FModifier *fcm = (FModifier *)ptr->data;
-
- /* Technically, "sfra <= efra" must hold; however, we can't strictly enforce that,
- * or else it becomes tricky to adjust the range... [#36844]
+
+ /* Technically, "sfra <= efra" must hold; however, we can't strictly enforce that,
+ * or else it becomes tricky to adjust the range... [#36844]
*/
*min = MINAFRAMEF;
*softmin = (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) ? fcm->sfra : MINAFRAMEF;
-
+
*softmax = MAXFRAMEF;
*max = MAXFRAMEF;
}
@@ -602,22 +602,22 @@ static void rna_FModifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Poin
ID *id = ptr->id.data;
FModifier *fcm = (FModifier *)ptr->data;
AnimData *adt = BKE_animdata_from_id(id);
-
+
DEG_id_tag_update(id, (GS(id->name) == ID_OB) ? OB_RECALC_OB : OB_RECALC_DATA);
-
+
/* tag datablock for time update so that animation is recalculated,
* as FModifiers affect how animation plays...
*/
DEG_id_tag_update(id, DEG_TAG_TIME);
if (adt != NULL) {
adt->recalc |= ADT_RECALC_ANIM;
-
+
if (adt->action != NULL) {
/* action is separate datablock, needs separate tag */
DEG_id_tag_update(&adt->action->id, DEG_TAG_COPY_ON_WRITE);
}
}
-
+
if (fcm->curve && fcm->type == FMODIFIER_TYPE_CYCLES) {
calchandles_fcurve(fcm->curve);
}
@@ -682,9 +682,9 @@ static void rna_FModifierLimits_minx_set(PointerRNA *ptr, float value)
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
-
+
data->rect.xmin = value;
-
+
if (data->rect.xmin >= data->rect.xmax) {
data->rect.xmax = data->rect.xmin;
}
@@ -694,9 +694,9 @@ static void rna_FModifierLimits_maxx_set(PointerRNA *ptr, float value)
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
-
+
data->rect.xmax = value;
-
+
if (data->rect.xmax <= data->rect.xmin) {
data->rect.xmin = data->rect.xmax;
}
@@ -706,9 +706,9 @@ static void rna_FModifierLimits_miny_set(PointerRNA *ptr, float value)
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
-
+
data->rect.ymin = value;
-
+
if (data->rect.ymin >= data->rect.ymax) {
data->rect.ymax = data->rect.ymin;
}
@@ -718,9 +718,9 @@ static void rna_FModifierLimits_maxy_set(PointerRNA *ptr, float value)
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
-
+
data->rect.ymax = value;
-
+
if (data->rect.ymax <= data->rect.ymin) {
data->rect.ymin = data->rect.ymax;
}
@@ -731,7 +731,7 @@ static void rna_FModifierLimits_minx_range(PointerRNA *UNUSED(ptr), float *min,
{
// FModifier *fcm = (FModifier *)ptr->data;
// FMod_Limits *data = fcm->data;
-
+
/* no soft-limits on lower bound - it's too confusing when you can't easily use the slider to set things here */
*min = MINAFRAMEF;
*max = MAXFRAMEF;
@@ -742,10 +742,10 @@ static void rna_FModifierLimits_maxx_range(PointerRNA *ptr, float *min, float *m
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
-
+
*min = MINAFRAMEF;
*softmin = (data->flag & FCM_LIMIT_XMIN) ? data->rect.xmin : MINAFRAMEF;
-
+
*softmax = MAXFRAMEF;
*max = MAXFRAMEF;
}
@@ -755,7 +755,7 @@ static void rna_FModifierLimits_miny_range(PointerRNA *UNUSED(ptr), float *min,
{
// FModifier *fcm = (FModifier *)ptr->data;
// FMod_Limits *data = fcm->data;
-
+
/* no soft-limits on lower bound - it's too confusing when you can't easily use the slider to set things here */
*min = -FLT_MAX;
*max = FLT_MAX;
@@ -766,12 +766,12 @@ static void rna_FModifierLimits_maxy_range(PointerRNA *ptr, float *min, float *m
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Limits *data = fcm->data;
-
+
*min = -FLT_MAX;
*softmin = (data->flag & FCM_LIMIT_YMIN) ? data->rect.ymin : -FLT_MAX;
-
+
*softmax = FLT_MAX;
- *max = FLT_MAX;
+ *max = FLT_MAX;
}
@@ -780,7 +780,7 @@ static void rna_FModifierStepped_start_frame_range(PointerRNA *ptr, float *min,
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Stepped *data = fcm->data;
-
+
*min = MINAFRAMEF;
*max = (data->flag & FCM_STEPPED_NO_AFTER) ? data->end_frame : MAXFRAMEF;
}
@@ -799,12 +799,12 @@ static void rna_FModifierStepped_frame_start_set(PointerRNA *ptr, float value)
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Stepped *data = fcm->data;
-
+
float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max;
rna_FModifierStepped_start_frame_range(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);
value = CLAMPIS(value, prop_clamp_min, prop_clamp_max);
-
- /* Need to set both step-data's start/end and the start/end on the base-data,
+
+ /* Need to set both step-data's start/end and the start/end on the base-data,
* or else Restrict-Range doesn't work due to RNA-property shadowing (T52009)
*/
data->start_frame = value;
@@ -815,12 +815,12 @@ static void rna_FModifierStepped_frame_end_set(PointerRNA *ptr, float value)
{
FModifier *fcm = (FModifier *)ptr->data;
FMod_Stepped *data = fcm->data;
-
+
float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max;
rna_FModifierStepped_end_frame_range(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);
value = CLAMPIS(value, prop_clamp_min, prop_clamp_max);
-
- /* Need to set both step-data's start/end and the start/end on the base-data,
+
+ /* Need to set both step-data's start/end and the start/end on the base-data,
* or else Restrict-Range doesn't work due to RNA-property shadowing (T52009)
*/
data->end_frame = value;
@@ -839,10 +839,10 @@ static void rna_FKeyframe_points_add(FCurve *fcu, int tot)
BezTriple *bezt;
fcu->bezt = MEM_recallocN(fcu->bezt, sizeof(BezTriple) * (fcu->totvert + tot));
-
+
bezt = fcu->bezt + fcu->totvert;
fcu->totvert += tot;
-
+
while (tot--) {
/* defaults, no userprefs gives predictable results for API */
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
@@ -946,17 +946,17 @@ static void rna_def_fmodifier_generator(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem generator_mode_items[] = {
{FCM_GENERATOR_POLYNOMIAL, "POLYNOMIAL", 0, "Expanded Polynomial", ""},
{FCM_GENERATOR_POLYNOMIAL_FACTORISED, "POLYNOMIAL_FACTORISED", 0, "Factorized Polynomial", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "FModifierGenerator", "FModifier");
RNA_def_struct_ui_text(srna, "Generator F-Modifier", "Deterministically generate values for the modified F-Curve");
RNA_def_struct_sdna_from(srna, "FMod_Generator", "data");
-
+
/* define common props */
prop = RNA_def_property(srna, "use_additive", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_GENERATOR_ADDITIVE);
@@ -964,19 +964,19 @@ static void rna_def_fmodifier_generator(BlenderRNA *brna)
"Values generated by this modifier are applied on top of "
"the existing values instead of overwriting them");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, generator_mode_items);
RNA_def_property_ui_text(prop, "Mode", "Type of generator to use");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_verify_data_update");
-
+
/* order of the polynomial */
prop = RNA_def_property(srna, "poly_order", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop, "Polynomial Order",
"The highest power of 'x' for this polynomial (number of coefficients - 1)");
RNA_def_property_range(prop, 1, 100);
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_verify_data_update");
-
+
/* coefficients array */
prop = RNA_def_property(srna, "coefficients", PROP_FLOAT, PROP_NONE);
RNA_def_property_array(prop, 32);
@@ -993,7 +993,7 @@ static void rna_def_fmodifier_function_generator(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_type_items[] = {
{0, "SIN", 0, "Sine", ""},
{1, "COS", 0, "Cosine", ""},
@@ -1003,28 +1003,28 @@ static void rna_def_fmodifier_function_generator(BlenderRNA *brna)
{5, "SINC", 0, "Normalized Sine", "sin(x) / x"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "FModifierFunctionGenerator", "FModifier");
RNA_def_struct_ui_text(srna, "Built-In Function F-Modifier", "Generate values using a Built-In Function");
RNA_def_struct_sdna_from(srna, "FMod_FunctionGenerator", "data");
-
+
/* coefficients */
prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop, "Amplitude", "Scale factor determining the maximum/minimum values");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "phase_multiplier", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop, "Phase Multiplier", "Scale factor determining the 'speed' of the function");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "phase_offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop, "Phase Offset", "Constant factor to offset time by for function");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "value_offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop, "Value Offset", "Constant factor to offset values by");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
/* flags */
prop = RNA_def_property(srna, "use_additive", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_GENERATOR_ADDITIVE);
@@ -1032,7 +1032,7 @@ static void rna_def_fmodifier_function_generator(BlenderRNA *brna)
"Values generated by this modifier are applied on top of "
"the existing values instead of overwriting them");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "function_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, prop_type_items);
@@ -1046,11 +1046,11 @@ static void rna_def_fmodifier_envelope_ctrl(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "FModifierEnvelopeControlPoint", NULL);
RNA_def_struct_ui_text(srna, "Envelope Control Point", "Control point for envelope F-Modifier");
RNA_def_struct_sdna(srna, "FCM_EnvelopeData");
-
+
/* min/max extents
* - for now, these are allowed to go past each other, so that we can have inverted action
* - technically, the range is limited by the settings in the envelope-modifier data, not here...
@@ -1059,18 +1059,18 @@ static void rna_def_fmodifier_envelope_ctrl(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Minimum Value", "Lower bound of envelope at this control-point");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_ui_text(prop, "Maximum Value", "Upper bound of envelope at this control-point");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
/* Frame */
prop = RNA_def_property(srna, "frame", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "time");
RNA_def_property_ui_text(prop, "Frame", "Frame this control-point occurs on");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
/* TODO: */
/* - selection flags (not implemented in UI yet though) */
}
@@ -1109,29 +1109,29 @@ static void rna_def_fmodifier_envelope(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "FModifierEnvelope", "FModifier");
RNA_def_struct_ui_text(srna, "Envelope F-Modifier", "Scale the values of the modified F-Curve");
RNA_def_struct_sdna_from(srna, "FMod_Envelope", "data");
-
+
/* Collections */
prop = RNA_def_property(srna, "control_points", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "data", "totvert");
RNA_def_property_struct_type(prop, "FModifierEnvelopeControlPoint");
RNA_def_property_ui_text(prop, "Control Points", "Control points defining the shape of the envelope");
rna_def_fmodifier_envelope_control_points(brna, prop);
-
+
/* Range Settings */
prop = RNA_def_property(srna, "reference_value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "midval");
RNA_def_property_ui_text(prop, "Reference Value", "Value that envelope's influence is centered around / based on");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "default_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Default Minimum", "Lower distance from Reference Value for 1:1 default influence");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "default_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_ui_text(prop, "Default Maximum", "Upper distance from Reference Value for 1:1 default influence");
@@ -1144,7 +1144,7 @@ static void rna_def_fmodifier_cycles(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_type_items[] = {
{FCM_EXTRAPOLATE_NONE, "NONE", 0, "No Cycles", "Don't do anything"},
{FCM_EXTRAPOLATE_CYCLIC, "REPEAT", 0, "Repeat Motion", "Repeat keyframe range as-is"},
@@ -1155,31 +1155,31 @@ static void rna_def_fmodifier_cycles(BlenderRNA *brna)
"Alternate between forward and reverse playback of keyframe range"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "FModifierCycles", "FModifier");
RNA_def_struct_ui_text(srna, "Cycles F-Modifier", "Repeat the values of the modified F-Curve");
RNA_def_struct_sdna_from(srna, "FMod_Cycles", "data");
-
+
/* before */
prop = RNA_def_property(srna, "mode_before", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "before_mode");
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Before Mode", "Cycling mode to use before first keyframe");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "cycles_before", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "before_cycles");
RNA_def_property_ui_text(prop, "Before Cycles",
"Maximum number of cycles to allow before first keyframe (0 = infinite)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
/* after */
prop = RNA_def_property(srna, "mode_after", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "after_mode");
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "After Mode", "Cycling mode to use after last keyframe");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "cycles_after", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "after_cycles");
RNA_def_property_ui_text(prop, "After Cycles",
@@ -1193,7 +1193,7 @@ static void rna_def_fmodifier_python(BlenderRNA *brna)
{
StructRNA *srna;
/*PropertyRNA *prop; */
-
+
srna = RNA_def_struct(brna, "FModifierPython", "FModifier");
RNA_def_struct_ui_text(srna, "Python F-Modifier", "Perform user-defined operation on the modified F-Curve");
RNA_def_struct_sdna_from(srna, "FMod_Python", "data");
@@ -1205,49 +1205,49 @@ static void rna_def_fmodifier_limits(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "FModifierLimits", "FModifier");
RNA_def_struct_ui_text(srna, "Limit F-Modifier", "Limit the time/value ranges of the modified F-Curve");
RNA_def_struct_sdna_from(srna, "FMod_Limits", "data");
-
+
prop = RNA_def_property(srna, "use_min_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_LIMIT_XMIN);
RNA_def_property_ui_text(prop, "Minimum X", "Use the minimum X value");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "use_min_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_LIMIT_YMIN);
RNA_def_property_ui_text(prop, "Minimum Y", "Use the minimum Y value");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "use_max_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_LIMIT_XMAX);
RNA_def_property_ui_text(prop, "Maximum X", "Use the maximum X value");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "use_max_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_LIMIT_YMAX);
RNA_def_property_ui_text(prop, "Maximum Y", "Use the maximum Y value");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "min_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rect.xmin");
RNA_def_property_float_funcs(prop, NULL, "rna_FModifierLimits_minx_set", "rna_FModifierLimits_minx_range");
RNA_def_property_ui_text(prop, "Minimum X", "Lowest X value to allow");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "min_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rect.ymin");
RNA_def_property_float_funcs(prop, NULL, "rna_FModifierLimits_miny_set", "rna_FModifierLimits_miny_range");
RNA_def_property_ui_text(prop, "Minimum Y", "Lowest Y value to allow");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "max_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rect.xmax");
RNA_def_property_float_funcs(prop, NULL, "rna_FModifierLimits_maxx_set", "rna_FModifierLimits_maxx_range");
RNA_def_property_ui_text(prop, "Maximum X", "Highest X value to allow");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "max_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rect.ymax");
RNA_def_property_float_funcs(prop, NULL, "rna_FModifierLimits_maxy_set", "rna_FModifierLimits_maxy_range");
@@ -1261,7 +1261,7 @@ static void rna_def_fmodifier_noise(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_modification_items[] = {
{FCM_NOISE_MODIF_REPLACE, "REPLACE", 0, "Replace", ""},
{FCM_NOISE_MODIF_ADD, "ADD", 0, "Add", ""},
@@ -1269,28 +1269,28 @@ static void rna_def_fmodifier_noise(BlenderRNA *brna)
{FCM_NOISE_MODIF_MULTIPLY, "MULTIPLY", 0, "Multiply", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "FModifierNoise", "FModifier");
RNA_def_struct_ui_text(srna, "Noise F-Modifier", "Give randomness to the modified F-Curve");
RNA_def_struct_sdna_from(srna, "FMod_Noise", "data");
-
+
prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "modification");
RNA_def_property_enum_items(prop, prop_modification_items);
RNA_def_property_ui_text(prop, "Blend Type", "Method of modifying the existing F-Curve");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_ui_text(prop, "Scale", "Scaling (in time) of the noise");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "strength");
RNA_def_property_ui_text(prop, "Strength",
"Amplitude of the noise - the amount that it modifies the underlying curve");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "phase", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "phase");
RNA_def_property_ui_text(prop, "Phase", "A random seed for the noise effect");
@@ -1300,7 +1300,7 @@ static void rna_def_fmodifier_noise(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "offset");
RNA_def_property_ui_text(prop, "Offset", "Time offset for the noise effect");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "depth", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "depth");
RNA_def_property_ui_text(prop, "Depth", "Amount of fine level detail present in the noise");
@@ -1314,42 +1314,42 @@ static void rna_def_fmodifier_stepped(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "FModifierStepped", "FModifier");
RNA_def_struct_ui_text(srna, "Stepped Interpolation F-Modifier",
"Hold each interpolated value from the F-Curve for several frames without "
"changing the timing");
RNA_def_struct_sdna_from(srna, "FMod_Stepped", "data");
-
+
/* properties */
prop = RNA_def_property(srna, "frame_step", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "step_size");
RNA_def_property_ui_text(prop, "Step Size", "Number of frames to hold each value");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "frame_offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "offset");
RNA_def_property_ui_text(prop, "Offset",
"Reference number of frames before frames get held "
"(use to get hold for '1-3' vs '5-7' holding patterns)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "use_frame_start", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_STEPPED_NO_BEFORE);
RNA_def_property_ui_text(prop, "Use Start Frame", "Restrict modifier to only act after its 'start' frame");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "use_frame_end", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCM_STEPPED_NO_AFTER);
RNA_def_property_ui_text(prop, "Use End Frame", "Restrict modifier to only act before its 'end' frame");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "start_frame");
RNA_def_property_float_funcs(prop, NULL, "rna_FModifierStepped_frame_start_set", "rna_FModifierStepped_start_frame_range");
RNA_def_property_ui_text(prop, "Start Frame", "Frame that modifier's influence starts (if applicable)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "end_frame");
RNA_def_property_float_funcs(prop, NULL, "rna_FModifierStepped_frame_end_set", "rna_FModifierStepped_end_frame_range");
@@ -1364,43 +1364,43 @@ static void rna_def_fmodifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
/* base struct definition */
srna = RNA_def_struct(brna, "FModifier", NULL);
RNA_def_struct_refine_func(srna, "rna_FModifierType_refine");
RNA_def_struct_ui_text(srna, "F-Modifier", "Modifier for values of F-Curve");
-
+
#if 0 /* XXX not used yet */
/* name */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
RNA_def_property_ui_text(prop, "Name", "Short description of F-Curve Modifier");
#endif /* XXX not used yet */
-
+
/* type */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, rna_enum_fmodifier_type_items);
RNA_def_property_ui_text(prop, "Type", "F-Curve Modifier Type");
-
+
/* settings */
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_EXPANDED);
RNA_def_property_ui_text(prop, "Expanded", "F-Curve Modifier's panel is expanded in UI");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
-
+
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_MUTED);
RNA_def_property_ui_text(prop, "Muted", "F-Curve Modifier will not be evaluated");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
RNA_def_property_ui_icon(prop, ICON_MUTE_IPO_OFF, 1);
-
+
prop = RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", FMODIFIER_FLAG_DISABLED);
RNA_def_property_ui_text(prop, "Disabled", "F-Curve Modifier has invalid settings and will not be evaluated");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
-
+
/* TODO: setting this to true must ensure that all others in stack are turned off too... */
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_ACTIVE);
@@ -1408,7 +1408,7 @@ static void rna_def_fmodifier(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, NULL, "rna_FModifier_active_set");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_active_update");
RNA_def_property_ui_icon(prop, ICON_RADIOBUT_OFF, 1);
-
+
/* restricted range */
prop = RNA_def_property(srna, "use_restricted_range", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_RANGERESTRICT);
@@ -1417,40 +1417,40 @@ static void rna_def_fmodifier(BlenderRNA *brna)
"mask off effects in order to chain them");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1); /* XXX: depends on UI implementation */
-
+
prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sfra");
RNA_def_property_float_funcs(prop, NULL, "rna_FModifier_start_frame_set", "rna_FModifier_start_frame_range");
RNA_def_property_ui_text(prop, "Start Frame",
"Frame that modifier's influence starts (if Restrict Frame Range is in use)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "efra");
RNA_def_property_float_funcs(prop, NULL, "rna_FModifer_end_frame_set", "rna_FModifier_end_frame_range");
RNA_def_property_ui_text(prop, "End Frame",
"Frame that modifier's influence ends (if Restrict Frame Range is in use)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "blendin");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_blending_range");
RNA_def_property_ui_text(prop, "Blend In", "Number of frames from start frame for influence to take effect");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
-
+
prop = RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "blendout");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_blending_range");
RNA_def_property_ui_text(prop, "Blend Out", "Number of frames from end frame for influence to fade out");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
-
+
/* influence */
prop = RNA_def_property(srna, "use_influence", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_USEINFLUENCE);
RNA_def_property_ui_text(prop, "Use Influence", "F-Curve Modifier's effects will be tempered by a default factor");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1); /* XXX: depends on UI implementation */
-
+
prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "influence");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -1466,7 +1466,7 @@ static void rna_def_drivertarget(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_trans_chan_items[] = {
{DTAR_TRANSCHAN_LOCX, "LOC_X", 0, "X Location", ""},
{DTAR_TRANSCHAN_LOCY, "LOC_Y", 0, "Y Location", ""},
@@ -1479,7 +1479,7 @@ static void rna_def_drivertarget(BlenderRNA *brna)
{DTAR_TRANSCHAN_SCALEZ, "SCALE_Z", 0, "Z Scale", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem prop_local_space_items[] = {
{0, "WORLD_SPACE", 0, "World Space", "Transforms include effects of parenting/restpose and constraints"},
{DTAR_FLAG_LOCALSPACE, "TRANSFORM_SPACE", 0, "Transform Space",
@@ -1489,15 +1489,15 @@ static void rna_def_drivertarget(BlenderRNA *brna)
"parenting/restpose"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "DriverTarget", NULL);
RNA_def_struct_ui_text(srna, "Driver Target", "Source of input values for driver variables");
-
+
/* Target Properties - ID-block to Drive */
prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ID");
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_editable_func(prop, "rna_DriverTarget_id_editable");
/* note: custom set function is ONLY to avoid rna setting a user for this. */
RNA_def_property_pointer_funcs(prop, NULL, "rna_DriverTarget_id_set", "rna_DriverTarget_id_typef", NULL);
@@ -1505,7 +1505,7 @@ static void rna_def_drivertarget(BlenderRNA *brna)
"ID-block that the specific property used can be found from "
"(id_type property must be set first)");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
-
+
prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "idtype");
RNA_def_property_enum_items(prop, rna_enum_id_type_items);
@@ -1515,25 +1515,25 @@ static void rna_def_drivertarget(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
-
+
/* Target Properties - Property to Drive */
prop = RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_DriverTarget_RnaPath_get", "rna_DriverTarget_RnaPath_length",
"rna_DriverTarget_RnaPath_set");
RNA_def_property_ui_text(prop, "Data Path", "RNA Path (from ID-block) to property used");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
-
+
prop = RNA_def_property(srna, "bone_target", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "pchan_name");
RNA_def_property_ui_text(prop, "Bone Name", "Name of PoseBone to use as target");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
-
+
prop = RNA_def_property(srna, "transform_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "transChan");
RNA_def_property_enum_items(prop, prop_trans_chan_items);
RNA_def_property_ui_text(prop, "Type", "Driver variable type");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
-
+
prop = RNA_def_property(srna, "transform_space", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, prop_local_space_items);
@@ -1545,7 +1545,7 @@ static void rna_def_drivervar(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_type_items[] = {
{DVAR_TYPE_SINGLE_PROP, "SINGLE_PROP", ICON_RNA, "Single Property", "Use the value from some RNA property (Default)"},
{DVAR_TYPE_TRANSFORM_CHAN, "TRANSFORMS", ICON_MANIPUL, "Transform Channel",
@@ -1554,12 +1554,12 @@ static void rna_def_drivervar(BlenderRNA *brna)
{DVAR_TYPE_LOC_DIFF, "LOC_DIFF", ICON_FULLSCREEN_ENTER, "Distance", "Distance between two bones or objects"}, /* XXX: Icon... */
{0, NULL, 0, NULL, NULL}
};
-
-
+
+
srna = RNA_def_struct(brna, "DriverVariable", NULL);
RNA_def_struct_sdna(srna, "DriverVar");
RNA_def_struct_ui_text(srna, "Driver Variable", "Variable from some source/target for driver relationship");
-
+
/* Variable Name */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
@@ -1568,28 +1568,28 @@ static void rna_def_drivervar(BlenderRNA *brna)
"Name to use in scripted expressions/functions (no spaces or dots are allowed, "
"and must start with a letter)");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_name"); /* XXX */
-
+
/* Enums */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_enum_funcs(prop, NULL, "rna_DriverVariable_type_set", NULL);
RNA_def_property_ui_text(prop, "Type", "Driver variable type");
RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); /* XXX */
-
+
/* Targets */
/* TODO: for nicer api, only expose the relevant props via subclassing,
* instead of exposing the collection of targets */
prop = RNA_def_property(srna, "targets", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "targets", "num_targets");
RNA_def_property_struct_type(prop, "DriverTarget");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Targets", "Sources of input data for evaluating this variable");
-
+
/* Name Validity Flags */
prop = RNA_def_property(srna, "is_name_valid", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", DVAR_FLAG_INVALID_NAME);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Is Name Valid", "Is this a valid name for a driver variable");
+ RNA_def_property_ui_text(prop, "Is Name Valid", "Is this a valid name for a driver variable");
}
@@ -1598,16 +1598,16 @@ static void rna_def_channeldriver_variables(BlenderRNA *brna, PropertyRNA *cprop
{
StructRNA *srna;
/* PropertyRNA *prop; */
-
+
FunctionRNA *func;
PropertyRNA *parm;
-
+
RNA_def_property_srna(cprop, "ChannelDriverVariables");
srna = RNA_def_struct(brna, "ChannelDriverVariables", NULL);
RNA_def_struct_sdna(srna, "ChannelDriver");
RNA_def_struct_ui_text(srna, "ChannelDriver Variables", "Collection of channel driver Variables");
-
-
+
+
/* add variable */
func = RNA_def_function(srna, "new", "rna_Driver_new_variable");
RNA_def_function_ui_description(func, "Add a new variable for the driver");
@@ -1629,7 +1629,7 @@ static void rna_def_channeldriver(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_type_items[] = {
{DRIVER_TYPE_AVERAGE, "AVERAGE", 0, "Averaged Value", ""},
{DRIVER_TYPE_SUM, "SUM", 0, "Sum Values", ""},
@@ -1659,10 +1659,10 @@ static void rna_def_channeldriver(BlenderRNA *brna)
prop = RNA_def_property(srna, "variables", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "variables", NULL);
RNA_def_property_struct_type(prop, "DriverVariable");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Variables", "Properties acting as inputs for this driver");
rna_def_channeldriver_variables(brna, prop);
-
+
/* Settings */
prop = RNA_def_property(srna, "use_self", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", DRIVER_FLAG_USE_SELF);
@@ -1674,8 +1674,8 @@ static void rna_def_channeldriver(BlenderRNA *brna)
prop = RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", DRIVER_FLAG_INVALID);
RNA_def_property_ui_text(prop, "Invalid", "Driver could not be evaluated in past, so should be skipped");
-
-
+
+
/* Functions */
RNA_api_drivers(srna);
}
@@ -1686,17 +1686,17 @@ static void rna_def_fpoint(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "FCurveSample", NULL);
RNA_def_struct_sdna(srna, "FPoint");
RNA_def_struct_ui_text(srna, "F-Curve Sample", "Sample point for F-Curve");
-
+
/* Boolean values */
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", 1);
RNA_def_property_ui_text(prop, "Select", "Selection status");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
/* Vector value */
prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_COORDS); /* keyframes are dimensionless */
RNA_def_property_float_sdna(prop, NULL, "vec");
@@ -1713,40 +1713,40 @@ static void rna_def_fkeyframe(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "Keyframe", NULL);
RNA_def_struct_sdna(srna, "BezTriple");
RNA_def_struct_ui_text(srna, "Keyframe", "Bezier curve point with two handles defining a Keyframe on an F-Curve");
-
+
/* Boolean values */
prop = RNA_def_property(srna, "select_left_handle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "f1", 0);
RNA_def_property_ui_text(prop, "Handle 1 selected", "Left handle selection status");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
prop = RNA_def_property(srna, "select_right_handle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "f3", 0);
RNA_def_property_ui_text(prop, "Handle 2 selected", "Right handle selection status");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
prop = RNA_def_property(srna, "select_control_point", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "f2", 0);
RNA_def_property_ui_text(prop, "Select", "Control point selection status");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
/* Enums */
prop = RNA_def_property(srna, "handle_left_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "h1");
RNA_def_property_enum_items(prop, rna_enum_keyframe_handle_type_items);
RNA_def_property_ui_text(prop, "Left Handle Type", "Handle types");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
prop = RNA_def_property(srna, "handle_right_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "h2");
RNA_def_property_enum_items(prop, rna_enum_keyframe_handle_type_items);
RNA_def_property_ui_text(prop, "Right Handle Type", "Handle types");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ipo");
RNA_def_property_enum_items(prop, rna_enum_beztriple_interpolation_mode_items);
@@ -1754,18 +1754,18 @@ static void rna_def_fkeyframe(BlenderRNA *brna)
"Interpolation method to use for segment of the F-Curve from "
"this Keyframe until the next Keyframe");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "hide");
RNA_def_property_enum_items(prop, rna_enum_beztriple_keyframe_type_items);
RNA_def_property_ui_text(prop, "Type", "Type of keyframe (for visual purposes only)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
-
+
+
prop = RNA_def_property(srna, "easing", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "easing");
RNA_def_property_enum_items(prop, rna_enum_beztriple_interpolation_easing_items);
- RNA_def_property_ui_text(prop, "Easing",
+ RNA_def_property_ui_text(prop, "Easing",
"Which ends of the segment between this and the next keyframe easing "
"interpolation is applied to");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
@@ -1785,20 +1785,20 @@ static void rna_def_fkeyframe(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "period");
RNA_def_property_ui_text(prop, "Period", "Time between bounces for elastic easing");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
/* Vector values */
prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_COORDS); /* keyframes are dimensionless */
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_FKeyframe_handle1_get", "rna_FKeyframe_handle1_set", NULL);
RNA_def_property_ui_text(prop, "Left Handle", "Coordinates of the left handle (before the control point)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_COORDS); /* keyframes are dimensionless */
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_FKeyframe_ctrlpoint_get", "rna_FKeyframe_ctrlpoint_set", NULL);
RNA_def_property_ui_text(prop, "Control Point", "Coordinates of the control point");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "handle_right", PROP_FLOAT, PROP_COORDS); /* keyframes are dimensionless */
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_FKeyframe_handle2_get", "rna_FKeyframe_handle2_set", NULL);
@@ -1933,16 +1933,16 @@ static void rna_def_fcurve(BlenderRNA *brna)
prop = RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "extend");
RNA_def_property_enum_items(prop, prop_mode_extend_items);
- RNA_def_property_ui_text(prop, "Extrapolation",
+ RNA_def_property_ui_text(prop, "Extrapolation",
"Method used for evaluating value of F-Curve outside first and last keyframes");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FCurve_update_data");
/* Pointers */
prop = RNA_def_property(srna, "driver", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Driver", "Channel Driver (only set for Driver F-Curves)");
-
+
prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "grp");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -1964,35 +1964,35 @@ static void rna_def_fcurve(BlenderRNA *brna)
"Index to the specific property affected by F-Curve if applicable");
/* XXX need an update callback for this so that animation gets evaluated */
RNA_def_property_update(prop, NC_ANIMATION, NULL);
-
+
/* Color */
prop = RNA_def_property(srna, "color_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_mode_color_items);
RNA_def_property_ui_text(prop, "Color Mode", "Method used to determine color of F-Curve in Graph Editor");
RNA_def_property_update(prop, NC_ANIMATION, NULL);
-
+
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Color", "Color of the F-Curve in the Graph Editor");
RNA_def_property_update(prop, NC_ANIMATION, NULL);
-
+
/* Flags */
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCURVE_SELECTED);
RNA_def_property_ui_text(prop, "Select", "F-Curve is selected for editing");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
+
prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCURVE_PROTECTED);
RNA_def_property_ui_text(prop, "Lock", "F-Curve's settings cannot be edited");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FCURVE_MUTED);
RNA_def_property_ui_text(prop, "Muted", "F-Curve is not evaluated");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, "rna_FCurve_update_eval");
-
+
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", FCURVE_VISIBLE);
RNA_def_property_ui_text(prop, "Hide", "F-Curve and its keyframes are hidden in the Graph Editor graphs");
@@ -2010,7 +2010,7 @@ static void rna_def_fcurve(BlenderRNA *brna)
"False when F-Curve could not be evaluated in past, so should be skipped "
"when evaluating");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
-
+
/* Collections */
prop = RNA_def_property(srna, "sampled_points", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "fpt", "totvert");
@@ -2022,7 +2022,7 @@ static void rna_def_fcurve(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "Keyframe");
RNA_def_property_ui_text(prop, "Keyframes", "User-editable keyframes");
rna_def_fcurve_keyframe_points(brna, prop);
-
+
prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "FModifier");
RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting the shape of the F-Curve");
@@ -2038,11 +2038,11 @@ static void rna_def_fcurve(BlenderRNA *brna)
/* return value */
parm = RNA_def_float(func, "value", 0, -FLT_MAX, FLT_MAX, "Value", "Value of F-Curve specific frame", -FLT_MAX, FLT_MAX);
RNA_def_function_return(func, parm);
-
+
/* -- update / recalculate -- */
func = RNA_def_function(srna, "update", "rna_FCurve_update_data_ex");
RNA_def_function_ui_description(func, "Ensure keyframes are sorted in chronological order and handles are set correctly");
-
+
/* -- time extents/range -- */
func = RNA_def_function(srna, "range", "rna_FCurve_range");
RNA_def_function_ui_description(func, "Get the time extents for F-Curve");
@@ -2051,7 +2051,7 @@ static void rna_def_fcurve(BlenderRNA *brna)
"Min/Max values", -FLT_MAX, FLT_MAX);
RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0);
RNA_def_function_output(func, parm);
-
+
/* -- auto-flag validity (ensures valid handling for data type) -- */
func = RNA_def_function(srna, "update_autoflags", "update_autoflags_fcurve"); /* calls the C/API direct */
RNA_def_function_ui_description(func, "Update FCurve flags set automatically from affected property "
@@ -2073,13 +2073,13 @@ void RNA_def_fcurve(BlenderRNA *brna)
rna_def_fcurve(brna);
rna_def_fkeyframe(brna);
rna_def_fpoint(brna);
-
+
rna_def_drivertarget(brna);
rna_def_drivervar(brna);
rna_def_channeldriver(brna);
-
+
rna_def_fmodifier(brna);
-
+
rna_def_fmodifier_generator(brna);
rna_def_fmodifier_function_generator(brna);
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index 16b672ada49..23d9155fccd 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -125,7 +125,7 @@ static void rna_FluidSettings_update_type(Main *bmain, Scene *scene, PointerRNA
ParticleSystemModifierData *psmd;
ParticleSystem *psys, *next_psys;
ParticleSettings *part;
-
+
fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
fluidmd->fss->flag &= ~OB_FLUIDSIM_REVERSE; /* clear flag */
@@ -243,7 +243,7 @@ static void rna_def_fluid_mesh_vertices(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "FluidVertexVelocity", NULL);
RNA_def_struct_ui_text(srna, "Fluid Mesh Velocity", "Velocity of a simulated fluid mesh");
RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL);
@@ -279,7 +279,7 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "threads");
RNA_def_property_range(prop, 0, BLENDER_MAX_THREADS);
RNA_def_property_ui_text(prop, "Simulation Threads", "Override number of threads for the simulation, 0 is automatic");
-
+
prop = RNA_def_property(srna, "resolution", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolutionxyz");
RNA_def_property_range(prop, 1, 1024);
@@ -327,32 +327,32 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, -1000.1, 1000.1);
RNA_def_property_ui_text(prop, "Gravity", "Gravity in X, Y and Z direction");
-
+
prop = RNA_def_property(srna, "use_time_override", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", OB_FLUIDSIM_OVERRIDE_TIME);
RNA_def_property_ui_text(prop, "Override Time",
"Use a custom start and end time (in seconds) instead of the scene's timeline");
-
+
prop = RNA_def_property(srna, "start_time", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "animStart");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_text(prop, "Start Time", "Simulation time of the first blender frame (in seconds)");
-
+
prop = RNA_def_property(srna, "end_time", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "animEnd");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_text(prop, "End Time", "Simulation time of the last blender frame (in seconds)");
-
+
prop = RNA_def_property(srna, "frame_offset", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "frameOffset");
RNA_def_property_ui_text(prop, "Cache Offset", "Offset when reading baked cache");
RNA_def_property_update(prop, NC_OBJECT, "rna_fluid_update");
-
+
prop = RNA_def_property(srna, "simulation_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "realsize");
RNA_def_property_range(prop, 0.001, 10);
RNA_def_property_ui_text(prop, "Real World Size", "Size of the simulation domain in meters");
-
+
prop = RNA_def_property(srna, "simulation_rate", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "animRate");
RNA_def_property_range(prop, 0.0, 100.0);
@@ -431,7 +431,7 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0, 10.0);
RNA_def_property_ui_text(prop, "Generate Particles", "Amount of particles to generate (0=off, 1=normal, >1=more)");
-
+
/* simulated fluid mesh data */
prop = RNA_def_property(srna, "fluid_mesh_vertices", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "meshVelocities", "totvert");
@@ -471,7 +471,7 @@ static void rna_def_fluidsim_volume(StructRNA *srna)
static void rna_def_fluidsim_active(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", OB_FLUIDSIM_ACTIVE);
RNA_def_property_ui_text(prop, "Enabled", "Object contributes to the fluid simulation");
@@ -489,7 +489,7 @@ static void rna_def_fluidsim_fluid(BlenderRNA *brna)
rna_def_fluidsim_active(srna);
rna_def_fluidsim_volume(srna);
-
+
prop = RNA_def_property(srna, "initial_velocity", PROP_FLOAT, PROP_VELOCITY);
RNA_def_property_float_sdna(prop, NULL, "iniVelx");
RNA_def_property_array(prop, 3);
@@ -615,12 +615,12 @@ static void rna_def_fluidsim_control(BlenderRNA *brna)
"Fluid simulation settings for objects controlling the motion of fluid in the simulation");
rna_def_fluidsim_active(srna);
-
+
prop = RNA_def_property(srna, "start_time", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "cpsTimeStart");
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_text(prop, "Start Time", "Time when the control particles are activated");
-
+
prop = RNA_def_property(srna, "end_time", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "cpsTimeEnd");
RNA_def_property_range(prop, 0.0, FLT_MAX);
@@ -636,7 +636,7 @@ static void rna_def_fluidsim_control(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "attractforceRadius");
RNA_def_property_range(prop, 0.0, 10.0);
RNA_def_property_ui_text(prop, "Attraction Radius", "Force field radius around the control object");
-
+
prop = RNA_def_property(srna, "velocity_strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "velocityforceStrength");
RNA_def_property_range(prop, 0.0, 10.0);
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index b15f6dbccfa..51aed1ff296 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -82,7 +82,7 @@ static void rna_GPencil_onion_skinning_update(Main *bmain, Scene *scene, Pointer
bGPdata *gpd = (bGPdata *)ptr->id.data;
bGPDlayer *gpl;
bool enabled = false;
-
+
/* Ensure that the datablock's onionskinning toggle flag
* stays in sync with the status of the actual layers
*/
@@ -91,13 +91,13 @@ static void rna_GPencil_onion_skinning_update(Main *bmain, Scene *scene, Pointer
enabled = true;
}
}
-
+
if (enabled)
gpd->flag |= GP_DATA_SHOW_ONIONSKINS;
else
gpd->flag &= ~GP_DATA_SHOW_ONIONSKINS;
-
-
+
+
/* Now do standard updates... */
rna_GPencil_update(bmain, scene, ptr);
}
@@ -116,9 +116,9 @@ static char *rna_GPencilLayer_path(PointerRNA *ptr)
{
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
char name_esc[sizeof(gpl->info) * 2];
-
+
BLI_strescape(name_esc, gpl->info, sizeof(name_esc));
-
+
return BLI_sprintfN("layers[\"%s\"]", name_esc);
}
@@ -137,7 +137,7 @@ static void rna_GPencilLayer_line_width_range(PointerRNA *ptr, int *min, int *ma
int *softmin, int *softmax)
{
bGPDlayer *gpl = ptr->data;
-
+
/* The restrictions on max width here are due to OpenGL on Windows not supporting
* any widths greater than 10 (for driver-drawn) strokes/points.
*
@@ -150,14 +150,14 @@ static void rna_GPencilLayer_line_width_range(PointerRNA *ptr, int *min, int *ma
if (gpl->flag & GP_LAYER_VOLUMETRIC) {
*min = -300;
*max = 300;
-
+
*softmin = -100;
*softmax = 100;
}
else {
*min = -10;
*max = 10;
-
+
*softmin = -10;
*softmax = 10;
}
@@ -196,7 +196,7 @@ static void set_parent(bGPDlayer *gpl, Object *par, const int type, const char *
static void rna_GPencilLayer_parent_set(PointerRNA *ptr, PointerRNA value)
{
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
- Object *par = (Object *)value.data;
+ Object *par = (Object *)value.data;
if (par != NULL) {
set_parent(gpl, par, gpl->partype, gpl->parsubstr);
@@ -317,7 +317,7 @@ static void rna_GPencil_active_layer_set(PointerRNA *ptr, PointerRNA value)
gl->flag &= ~GP_LAYER_ACTIVE;
}
}
-
+
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
}
}
@@ -326,7 +326,7 @@ static int rna_GPencil_active_layer_index_get(PointerRNA *ptr)
{
bGPdata *gpd = (bGPdata *)ptr->id.data;
bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
-
+
return BLI_findindex(&gpd->layers, gpl);
}
@@ -370,7 +370,7 @@ static void rna_GPencil_use_onion_skinning_set(PointerRNA *ptr, const int value)
{
bGPdata *gpd = ptr->id.data;
bGPDlayer *gpl;
-
+
/* set new value */
if (value) {
/* enable on active layer (it's the one that's most likely to be of interest right now) */
@@ -378,7 +378,7 @@ static void rna_GPencil_use_onion_skinning_set(PointerRNA *ptr, const int value)
if (gpl) {
gpl->flag |= GP_LAYER_ONIONSKIN;
}
-
+
gpd->flag |= GP_DATA_SHOW_ONIONSKINS;
}
else {
@@ -386,7 +386,7 @@ static void rna_GPencil_use_onion_skinning_set(PointerRNA *ptr, const int value)
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
gpl->flag &= ~GP_LAYER_ONIONSKIN;
}
-
+
gpd->flag &= ~GP_DATA_SHOW_ONIONSKINS;
}
}
@@ -395,15 +395,15 @@ static bGPDstroke *rna_GPencil_stroke_point_find_stroke(const bGPdata *gpd, cons
{
bGPDlayer *gpl;
bGPDstroke *gps;
-
+
/* sanity checks */
if (ELEM(NULL, gpd, pt)) {
return NULL;
}
-
+
if (r_gpl) *r_gpl = NULL;
if (r_gpf) *r_gpf = NULL;
-
+
/* there's no faster alternative than just looping over everything... */
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl->actframe) {
@@ -412,13 +412,13 @@ static bGPDstroke *rna_GPencil_stroke_point_find_stroke(const bGPdata *gpd, cons
/* found it */
if (r_gpl) *r_gpl = gpl;
if (r_gpf) *r_gpf = gpl->actframe;
-
+
return gps;
}
}
}
}
-
+
/* didn't find it */
return NULL;
}
@@ -428,8 +428,8 @@ static void rna_GPencil_stroke_point_select_set(PointerRNA *ptr, const int value
bGPdata *gpd = ptr->id.data;
bGPDspoint *pt = ptr->data;
bGPDstroke *gps = NULL;
-
- /* Ensure that corresponding stroke is set
+
+ /* Ensure that corresponding stroke is set
* - Since we don't have direct access, we're going to have to search
* - We don't apply selection value unless we can find the corresponding
* stroke, so that they don't get out of sync
@@ -441,7 +441,7 @@ static void rna_GPencil_stroke_point_select_set(PointerRNA *ptr, const int value
pt->flag |= GP_SPOINT_SELECT;
else
pt->flag &= ~GP_SPOINT_SELECT;
-
+
/* Check if the stroke should be selected or not... */
BKE_gpencil_stroke_sync_selection(gps);
}
@@ -454,7 +454,7 @@ static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count, float pr
stroke->points = MEM_recallocN_id(stroke->points,
sizeof(bGPDspoint) * (stroke->totpoints + count),
"gp_stroke_points");
-
+
/* init the pressure and strength values so that old scripts won't need to
* be modified to give these initial values...
*/
@@ -463,7 +463,7 @@ static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count, float pr
pt->pressure = pressure;
pt->strength = strength;
}
-
+
stroke->totpoints += count;
}
}
@@ -530,13 +530,13 @@ static void rna_GPencil_stroke_select_set(PointerRNA *ptr, const int value)
bGPDstroke *gps = ptr->data;
bGPDspoint *pt;
int i;
-
+
/* set new value */
if (value)
gps->flag |= GP_STROKE_SELECT;
else
gps->flag &= ~GP_STROKE_SELECT;
-
+
/* ensure that the stroke's points are selected in the same way */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (value)
@@ -800,9 +800,9 @@ static char *rna_GPencilPalette_path(PointerRNA *ptr)
{
bGPDpalette *palette = ptr->data;
char name_esc[sizeof(palette->info) * 2];
-
+
BLI_strescape(name_esc, palette->info, sizeof(name_esc));
-
+
return BLI_sprintfN("palettes[\"%s\"]", name_esc);
}
@@ -826,7 +826,7 @@ static void rna_GPencilPaletteColor_info_set(PointerRNA *ptr, const char *value)
bGPdata *gpd = ptr->id.data;
bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
bGPDpalettecolor *palcolor = ptr->data;
-
+
char oldname[64] = "";
BLI_strncpy(oldname, palcolor->info, sizeof(oldname));
@@ -834,7 +834,7 @@ static void rna_GPencilPaletteColor_info_set(PointerRNA *ptr, const char *value)
BLI_strncpy_utf8(palcolor->info, value, sizeof(palcolor->info));
BLI_uniquename(&palette->colors, palcolor, DATA_("Color"), '.', offsetof(bGPDpalettecolor, info),
sizeof(palcolor->info));
-
+
/* rename all strokes */
BKE_gpencil_palettecolor_changename(gpd, oldname, palcolor->info);
@@ -895,23 +895,23 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "GPencilStrokePoint", NULL);
RNA_def_struct_sdna(srna, "bGPDspoint");
RNA_def_struct_ui_text(srna, "Grease Pencil Stroke Point", "Data point for freehand stroke curve");
-
+
prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "x");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Coordinates", "");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "pressure", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pressure");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "strength");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -988,18 +988,18 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna)
{GP_STROKE_2DIMAGE, "2DIMAGE", 0, "2D Image", "Stroke is in 2D-space (but with special 'image' scaling)"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "GPencilStroke", NULL);
RNA_def_struct_sdna(srna, "bGPDstroke");
RNA_def_struct_ui_text(srna, "Grease Pencil Stroke", "Freehand curve defining part of a sketch");
-
+
/* Points */
prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "points", "totpoints");
RNA_def_property_struct_type(prop, "GPencilStrokePoint");
RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points");
rna_def_gpencil_stroke_points_api(brna, prop);
-
+
/* Triangles */
prop = RNA_def_property(srna, "triangles", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "triangles", "tot_triangles");
@@ -1019,7 +1019,7 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna)
RNA_def_property_enum_items(prop, stroke_draw_mode_items);
RNA_def_property_ui_text(prop, "Draw Mode", "");
RNA_def_property_update(prop, 0, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_SELECT);
RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_select_set");
@@ -1080,11 +1080,11 @@ static void rna_def_gpencil_frame(BlenderRNA *brna)
PropertyRNA *prop;
FunctionRNA *func;
-
+
srna = RNA_def_struct(brna, "GPencilFrame", NULL);
RNA_def_struct_sdna(srna, "bGPDframe");
RNA_def_struct_ui_text(srna, "Grease Pencil Frame", "Collection of related sketches on a particular frame");
-
+
/* Strokes */
prop = RNA_def_property(srna, "strokes", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "strokes", NULL);
@@ -1098,17 +1098,17 @@ static void rna_def_gpencil_frame(BlenderRNA *brna)
/* XXX note: this cannot occur on the same frame as another sketch */
RNA_def_property_range(prop, -MAXFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Frame Number", "The frame on which this sketch appears");
-
+
/* Flags */
prop = RNA_def_property(srna, "is_edited", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_PAINT); /* XXX should it be editable? */
RNA_def_property_ui_text(prop, "Paint Lock", "Frame is being edited (painted on)");
-
+
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_SELECT);
RNA_def_property_ui_text(prop, "Select", "Frame is selected for editing in the Dope Sheet");
-
-
+
+
/* API */
func = RNA_def_function(srna, "clear", "rna_GPencil_frame_clear");
RNA_def_function_ui_description(func, "Remove all the grease pencil frame data");
@@ -1156,12 +1156,12 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
PropertyRNA *prop;
FunctionRNA *func;
-
+
srna = RNA_def_struct(brna, "GPencilLayer", NULL);
RNA_def_struct_sdna(srna, "bGPDlayer");
RNA_def_struct_ui_text(srna, "Grease Pencil Layer", "Collection of related sketches");
RNA_def_struct_path_func(srna, "rna_GPencilLayer_path");
-
+
/* Name */
prop = RNA_def_property(srna, "info", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Info", "Layer name");
@@ -1190,13 +1190,13 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Volumetric Strokes",
"Draw strokes as a series of circular blobs, resulting in a volumetric effect");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "opacity");
RNA_def_property_range(prop, 0.0, 1.0f);
RNA_def_property_ui_text(prop, "Opacity", "Layer Opacity");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
/* Tint Color */
prop = RNA_def_property(srna, "tint_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "tintcolor");
@@ -1204,14 +1204,14 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Tint Color", "Color for tinting stroke colors");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
/* Tint factor */
prop = RNA_def_property(srna, "tint_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "tintcolor[3]");
RNA_def_property_range(prop, 0.0, 1.0f);
RNA_def_property_ui_text(prop, "Tint Factor", "Factor of tinting color");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
/* Line Thickness change */
prop = RNA_def_property(srna, "line_change", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "thickness");
@@ -1219,13 +1219,13 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_GPencilLayer_line_width_range");
RNA_def_property_ui_text(prop, "Thickness", "Thickness change to apply to current strokes (in pixels)");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
/* Onion-Skinning */
prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ONIONSKIN);
RNA_def_property_ui_text(prop, "Onion Skinning", "Ghost frames on either side of frame");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_onion_skinning_update");
-
+
prop = RNA_def_property(srna, "ghost_before_range", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gstep");
RNA_def_property_range(prop, -1, 120);
@@ -1233,7 +1233,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
"Maximum number of frames to show before current frame "
"(0 = show only the previous sketch, -1 = don't show any frames before current)");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "ghost_after_range", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gstep_next");
RNA_def_property_range(prop, -1, 120);
@@ -1241,46 +1241,46 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
"Maximum number of frames to show after current frame "
"(0 = show only the next sketch, -1 = don't show any frames after current)");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "use_ghost_custom_colors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_GHOST_PREVCOL | GP_LAYER_GHOST_NEXTCOL);
RNA_def_property_ui_text(prop, "Use Custom Ghost Colors", "Use custom colors for ghost frames");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "before_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "gcolor_prev");
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Before Color", "Base color for ghosts before the active frame");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "after_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "gcolor_next");
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "use_ghosts_always", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_GHOST_ALWAYS);
RNA_def_property_ui_text(prop, "Always Show Ghosts",
"Ghosts are shown in renders and animation playback. Useful for special effects (e.g. motion blur)");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
-
+
+
/* Flags */
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
RNA_def_property_ui_text(prop, "Hide", "Set layer Visibility");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_LOCKED);
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
RNA_def_property_ui_text(prop, "Locked", "Protect layer from further editing and/or frame changes");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
prop = RNA_def_property(srna, "lock_frame", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_FRAMELOCK);
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
@@ -1309,23 +1309,23 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT);
RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the Dope Sheet");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, "rna_GPencil_update");
-
+
/* XXX keep this option? */
prop = RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_DRAWDEBUG);
RNA_def_property_ui_text(prop, "Show Points", "Draw the points which make up the strokes (for debugging purposes)");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
/* X-Ray */
prop = RNA_def_property(srna, "show_x_ray", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_LAYER_NO_XRAY);
RNA_def_property_ui_text(prop, "X Ray", "Make the layer draw in front of objects");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
/* Parent object */
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_funcs(prop, NULL, "rna_GPencilLayer_parent_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_ui_text(prop, "Parent", "Parent Object");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
@@ -1397,11 +1397,11 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Layer", "Active grease pencil layer");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
-
+
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop,
- "rna_GPencil_active_layer_index_get",
- "rna_GPencil_active_layer_index_set",
+ "rna_GPencil_active_layer_index_get",
+ "rna_GPencil_active_layer_index_set",
"rna_GPencil_active_layer_index_range");
RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
@@ -1620,14 +1620,14 @@ static void rna_def_gpencil_data(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "bGPdata");
RNA_def_struct_ui_text(srna, "Grease Pencil", "Freehand annotation sketchbook");
RNA_def_struct_ui_icon(srna, ICON_GREASEPENCIL);
-
+
/* Layers */
prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "layers", NULL);
RNA_def_property_struct_type(prop, "GPencilLayer");
RNA_def_property_ui_text(prop, "Layers", "");
rna_def_gpencil_layers_api(brna, prop);
-
+
/* Palettes */
prop = RNA_def_property(srna, "palettes", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "palettes", NULL);
@@ -1637,20 +1637,20 @@ static void rna_def_gpencil_data(BlenderRNA *brna)
/* Animation Data */
rna_def_animdata_common(srna);
-
+
/* Flags */
prop = RNA_def_property(srna, "use_stroke_edit_mode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_EDITMODE);
RNA_def_property_ui_text(prop, "Stroke Edit Mode", "Edit Grease Pencil strokes instead of viewport data");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update");
-
+
prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_SHOW_ONIONSKINS);
RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_use_onion_skinning_set");
- RNA_def_property_ui_text(prop, "Onion Skins",
+ RNA_def_property_ui_text(prop, "Onion Skins",
"Show ghosts of the frames before and after the current frame, toggle to enable on active layer or disable all");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
-
+
prop = RNA_def_property(srna, "show_stroke_direction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_SHOW_DIRECTION);
RNA_def_property_ui_text(prop, "Show Direction", "Show stroke drawing direction with a bigger green dot (start) "
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index 116c0bc4a26..de6c6883977 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -158,7 +158,7 @@ static void rna_def_collection_objects(BlenderRNA *brna, PropertyRNA *cprop)
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
-
+
RNA_def_property_srna(cprop, "CollectionObjects");
srna = RNA_def_struct(brna, "CollectionObjects", NULL);
RNA_def_struct_sdna(srna, "Collection");
@@ -227,6 +227,7 @@ void RNA_def_collections(BlenderRNA *brna)
prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Objects", "Objects that are directly in this collection");
RNA_def_property_collection_funcs(prop, "rna_Collection_objects_begin",
"rna_iterator_listbase_next",
@@ -257,21 +258,21 @@ void RNA_def_collections(BlenderRNA *brna)
/* Flags */
prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_SELECT);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 1);
RNA_def_property_ui_text(prop, "Restrict Select", "Disable collection object selection in the 3D viewport");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
prop = RNA_def_property(srna, "hide_viewport", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_VIEW);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
RNA_def_property_ui_text(prop, "Restrict Viewport", "Hide collection objects in the 3D viewport");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", COLLECTION_RESTRICT_RENDER);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1);
RNA_def_property_ui_text(prop, "Restrict Render", "Hide collection objects in renders");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index c554ab8e0fd..47e78b8e2a6 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -175,7 +175,7 @@ static char *rna_ImageUser_path(PointerRNA *ptr)
{
if (ptr->id.data) {
/* ImageUser *iuser = ptr->data; */
-
+
switch (GS(((ID *)ptr->id.data)->name)) {
case ID_OB:
case ID_TE:
@@ -190,7 +190,7 @@ static char *rna_ImageUser_path(PointerRNA *ptr)
break;
}
}
-
+
return BLI_strdup("");
}
@@ -200,7 +200,7 @@ static const EnumPropertyItem *rna_Image_source_itemf(bContext *UNUSED(C), Point
Image *ima = (Image *)ptr->data;
EnumPropertyItem *item = NULL;
int totitem = 0;
-
+
if (ima->source == IMA_SRC_VIEWER) {
RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_VIEWER);
}
@@ -304,7 +304,7 @@ static int rna_Image_depth_get(PointerRNA *ptr)
ImBuf *ibuf;
void *lock;
int planes;
-
+
ibuf = BKE_image_acquire_ibuf(im, NULL, &lock);
if (!ibuf)
@@ -652,7 +652,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_IMAGE_DATA);
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "File Name", "Image/Movie file name");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_reload_update");
@@ -692,7 +692,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Packed Files", "Collection of packed images");
prop = RNA_def_property(srna, "field_order", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, prop_field_order_items);
RNA_def_property_ui_text(prop, "Field Order", "Order of video fields (select which lines are displayed first)");
@@ -700,51 +700,51 @@ static void rna_def_image(BlenderRNA *brna)
/* booleans */
prop = RNA_def_property(srna, "use_fields", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_FIELDS);
RNA_def_property_ui_text(prop, "Fields", "Use fields of the image");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_fields_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
-
+
prop = RNA_def_property(srna, "use_view_as_render", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_VIEW_AS_RENDER);
RNA_def_property_ui_text(prop, "View as Render", "Apply render part of display transformation when displaying this image on the screen");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMA_IGNORE_ALPHA);
RNA_def_property_ui_text(prop, "Use Alpha", "Use the alpha channel information from the image or make image fully opaque");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_colormanage_update");
prop = RNA_def_property(srna, "use_deinterlace", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_DEINTERLACE);
RNA_def_property_ui_text(prop, "Deinterlace", "Deinterlace movie file on load");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_reload_update");
prop = RNA_def_property(srna, "use_multiview", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_USE_VIEWS);
RNA_def_property_ui_text(prop, "Use Multi-View", "Use Multiple Views (when available)");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_views_format_update");
prop = RNA_def_property(srna, "is_stereo_3d", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_boolean_funcs(prop, "rna_Image_is_stereo_3d_get", NULL);
RNA_def_property_ui_text(prop, "Stereo 3D", "Image has left and right views");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_multiview", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_boolean_funcs(prop, "rna_Image_is_multiview_get", NULL);
RNA_def_property_ui_text(prop, "Multiple Views", "Image has more than one view");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_boolean_funcs(prop, "rna_Image_dirty_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Dirty", "Image has changed and is not saved");
@@ -756,7 +756,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Generated Type", "Generated image type");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
-
+
prop = RNA_def_property(srna, "generated_width", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gen_x");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
@@ -764,7 +764,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Generated Width", "Generated image width");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
-
+
prop = RNA_def_property(srna, "generated_height", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gen_y");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
@@ -772,7 +772,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Generated Height", "Generated image height");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
-
+
prop = RNA_def_property(srna, "use_generated_float", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gen_flag", IMA_GEN_FLOAT);
RNA_def_property_ui_text(prop, "Float Buffer", "Generate floating point buffer");
@@ -787,7 +787,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "display_aspect", PROP_FLOAT, PROP_XYZ);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_float_sdna(prop, NULL, "aspx");
RNA_def_property_array(prop, 2);
RNA_def_property_range(prop, 0.1f, FLT_MAX);
@@ -829,7 +829,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_float_vector(srna, "resolution", 2, NULL, 0, 0, "Resolution", "X/Y pixels per meter", 0, 0);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_float_funcs(prop, "rna_Image_resolution_get", "rna_Image_resolution_set", NULL);
prop = RNA_def_property(srna, "frame_duration", PROP_INT, PROP_UNSIGNED);
@@ -864,14 +864,14 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
prop = RNA_def_property(srna, "alpha_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_enum_items(prop, alpha_mode_items);
RNA_def_property_ui_text(prop, "Alpha Mode", "Representation of alpha information in the RGBA pixels");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_colormanage_update");
/* multiview */
prop = RNA_def_property(srna, "views_format", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_enum_sdna(prop, NULL, "views_format");
RNA_def_property_enum_items(prop, rna_enum_views_format_items);
RNA_def_property_ui_text(prop, "Views Format", "Mode to load image views");
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index bcac4b7e9a6..2070ea0a559 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -63,7 +63,7 @@
static void rna_ImagePackedFile_save(ImagePackedFile *imapf, Main *bmain, ReportList *reports)
{
- if (writePackedFile(reports, bmain->name, imapf->filepath, imapf->packedfile, 0) != RET_OK) {
+ if (writePackedFile(reports, BKE_main_blendfile_path(bmain), imapf->filepath, imapf->packedfile, 0) != RET_OK) {
BKE_reportf(reports, RPT_ERROR, "Could not save packed file to disk as '%s'",
imapf->filepath);
}
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 88efff30481..4536b970f91 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -206,6 +206,8 @@ struct PropertyRNA {
const char *identifier;
/* various options */
int flag;
+ /* various override options */
+ int flag_override;
/* Function parameters flags. */
short flag_parameter;
/* Internal ("private") flags. */
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index 472298a3053..11fb5f7f94b 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -75,20 +75,20 @@ static void rna_ShapeKey_name_set(PointerRNA *ptr, const char *value)
{
KeyBlock *kb = ptr->data;
char oldname[sizeof(kb->name)];
-
+
/* make a copy of the old name first */
BLI_strncpy(oldname, kb->name, sizeof(kb->name));
-
+
/* copy the new name into the name slot */
BLI_strncpy_utf8(kb->name, value, sizeof(kb->name));
-
+
/* make sure the name is truly unique */
if (ptr->id.data) {
Key *key = rna_ShapeKey_find_key(ptr->id.data);
BLI_uniquename(&key->block, kb, CTX_DATA_(BLT_I18NCONTEXT_ID_SHAPEKEY, "Key"), '.',
offsetof(KeyBlock, name), sizeof(kb->name));
}
-
+
/* fix all the animation data which may link to this */
BKE_animdata_fix_paths_rename_all(NULL, "key_blocks", oldname, kb->name);
}
@@ -131,7 +131,7 @@ static void rna_ShapeKey_slider_min_set(PointerRNA *ptr, float value)
{
KeyBlock *data = (KeyBlock *)ptr->data;
float min, max, softmin, softmax;
-
+
rna_ShapeKey_slider_min_range(ptr, &min, &max, &softmin, &softmax);
CLAMP(value, min, max);
data->slidermin = value;
@@ -150,7 +150,7 @@ static void rna_ShapeKey_slider_max_set(PointerRNA *ptr, float value)
{
KeyBlock *data = (KeyBlock *)ptr->data;
float min, max, softmin, softmax;
-
+
rna_ShapeKey_slider_max_range(ptr, &min, &max, &softmin, &softmax);
CLAMP(value, min, max);
data->slidermax = value;
@@ -274,7 +274,7 @@ PointerRNA rna_object_shapekey_index_get(ID *id, int value)
if (key && value < key->totkey)
kb = BLI_findlink(&key->block, value);
-
+
RNA_pointer_create(id, &RNA_ShapeKey, kb, &ptr);
return ptr;
@@ -288,7 +288,7 @@ int rna_object_shapekey_index_set(ID *id, PointerRNA value, int current)
int a = BLI_findindex(&key->block, value.data);
if (a != -1) return a;
}
-
+
return current;
}
@@ -411,17 +411,17 @@ static void rna_ShapeKey_data_begin(CollectionPropertyIterator *iter, PointerRNA
Curve *cu;
Nurb *nu;
int tot = kb->totelem, size = key->elemsize;
-
+
if (GS(key->from->name) == ID_CU) {
cu = (Curve *)key->from;
nu = cu->nurb.first;
-
+
if (nu->bezt) {
tot /= 3;
size *= 3;
}
}
-
+
rna_iterator_array_begin(iter, (void *)kb->data, size, tot, 0, NULL);
}
@@ -432,15 +432,15 @@ static int rna_ShapeKey_data_length(PointerRNA *ptr)
Curve *cu;
Nurb *nu;
int tot = kb->totelem;
-
+
if (GS(key->from->name) == ID_CU) {
cu = (Curve *)key->from;
nu = cu->nurb.first;
-
+
if (nu->bezt)
tot /= 3;
}
-
+
return tot;
}
@@ -450,11 +450,11 @@ static PointerRNA rna_ShapeKey_data_get(CollectionPropertyIterator *iter)
StructRNA *type;
Curve *cu;
Nurb *nu;
-
+
if (GS(key->from->name) == ID_CU) {
cu = (Curve *)key->from;
nu = cu->nurb.first;
-
+
if (nu->bezt)
type = &RNA_ShapeKeyBezierPoint;
else
@@ -462,7 +462,7 @@ static PointerRNA rna_ShapeKey_data_get(CollectionPropertyIterator *iter)
}
else
type = &RNA_ShapeKeyPoint;
-
+
return rna_pointer_inherit_refine(&iter->parent, type, rna_iterator_array_get(iter));
}
@@ -496,11 +496,11 @@ static void rna_Key_update_data(Main *bmain, Scene *UNUSED(scene), PointerRNA *p
static KeyBlock *rna_ShapeKeyData_find_keyblock(Key *key, float *point)
{
KeyBlock *kb;
-
+
/* sanity checks */
if (ELEM(NULL, key, point))
return NULL;
-
+
/* we'll need to manually search through the keyblocks and check
* if the point is somewhere in the middle of each block's data
*/
@@ -508,7 +508,7 @@ static KeyBlock *rna_ShapeKeyData_find_keyblock(Key *key, float *point)
if (kb->data) {
float *start = (float *)kb->data;
float *end;
-
+
/* easy cases first */
if ((start == NULL) || (start > point)) {
/* there's no chance point is in array */
@@ -518,12 +518,12 @@ static KeyBlock *rna_ShapeKeyData_find_keyblock(Key *key, float *point)
/* exact match - point is first in array */
return kb;
}
-
+
/* determine where end of array is
* - elemsize is in bytes, so use (char *) cast to get array in terms of bytes
*/
end = (float *)((char *)start + (key->elemsize * kb->totelem));
-
+
/* if point's address is less than the end, then it is somewhere between start and end, so in array */
if (end > point) {
/* we've found the owner of the point data */
@@ -531,7 +531,7 @@ static KeyBlock *rna_ShapeKeyData_find_keyblock(Key *key, float *point)
}
}
}
-
+
return NULL;
}
@@ -543,18 +543,18 @@ static int rna_ShapeKeyPoint_get_index(Key *key, KeyBlock *kb, float *point)
*/
char *start = (char *)kb->data;
char *pt = (char *)point;
-
+
return (int)(pt - start) / key->elemsize;
}
static int rna_ShapeKeyBezierPoint_get_index(KeyBlock *kb, float *point)
{
float *start = (float *)kb->data;
-
+
/* Unlike with rna_ShapeKeyPoint_get_index(), we cannot use key->elemsize here
* since the default value for curves (16) is actually designed for BPoints
* (i.e. NURBS Surfaces). The magic number "12" here was found by empirical
- * testing on a 64-bit system, and is similar to what's used for meshes and
+ * testing on a 64-bit system, and is similar to what's used for meshes and
* lattices. For more details, see T38013
*/
return (int)(point - start) / 12;
@@ -566,21 +566,21 @@ static char *rna_ShapeKeyPoint_path(PointerRNA *ptr)
Key *key = rna_ShapeKey_find_key(ptr->id.data);
KeyBlock *kb;
float *point = (float *)ptr->data;
-
+
/* if we can get a key block, we can construct a path */
kb = rna_ShapeKeyData_find_keyblock(key, point);
-
+
if (kb) {
char name_esc_kb[sizeof(kb->name) * 2];
int index;
-
+
if (ptr->type == &RNA_ShapeKeyBezierPoint)
index = rna_ShapeKeyBezierPoint_get_index(kb, point);
else
index = rna_ShapeKeyPoint_get_index(key, kb, point);
BLI_strescape(name_esc_kb, kb->name, sizeof(name_esc_kb));
-
+
if (GS(id->name) == ID_KE)
return BLI_sprintfN("key_blocks[\"%s\"].data[%d]", name_esc_kb, index);
else
@@ -690,7 +690,7 @@ static void rna_def_keyblock(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, "rna_ShapeKey_frame_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Frame", "Frame for absolute keys");
RNA_def_property_update(prop, 0, "rna_Key_update_data");
-
+
/* for now, this is editable directly, as users can set this even if they're not animating them
* (to test results) */
prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_FACTOR);
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index d123cdb9773..dff27e1c625 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -105,7 +105,7 @@ static void rna_Lamp_use_nodes_update(bContext *C, PointerRNA *ptr)
if (la->use_nodes && la->nodetree == NULL)
ED_node_shader_default(C, &la->id);
-
+
rna_Lamp_update(CTX_data_main(C), CTX_data_scene(C), ptr);
}
@@ -155,6 +155,13 @@ static void rna_def_lamp(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Color", "Light color");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
+ prop = RNA_def_property(srna, "specular_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "spec_fac");
+ RNA_def_property_range(prop, 0.0f, 9999.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.01, 2);
+ RNA_def_property_ui_text(prop, "Specular Factor", "Specular reflection multiplier");
+ RNA_def_property_update(prop, 0, "rna_Lamp_update");
+
/* nodes */
prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
@@ -166,7 +173,7 @@ static void rna_def_lamp(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the lamp");
RNA_def_property_update(prop, 0, "rna_Lamp_use_nodes_update");
-
+
/* common */
rna_def_animdata_common(srna);
}
@@ -189,7 +196,7 @@ static void rna_def_lamp_falloff(StructRNA *srna)
RNA_def_property_enum_items(prop, prop_fallofftype_items);
RNA_def_property_ui_text(prop, "Falloff Type", "Intensity Decay with distance");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
-
+
prop = RNA_def_property(srna, "falloff_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "curfalloff");
RNA_def_property_ui_text(prop, "Falloff Curve", "Custom Lamp Falloff Curve");
@@ -312,13 +319,6 @@ static void rna_def_lamp_shadow(StructRNA *srna, int sun)
"in shadow maps");
RNA_def_property_update(prop, 0, "rna_Lamp_update");
- prop = RNA_def_property(srna, "specular_factor", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_float_sdna(prop, NULL, "spec_fac");
- RNA_def_property_range(prop, 0.0f, 9999.0f);
- RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.01, 2);
- RNA_def_property_ui_text(prop, "Specular Factor", "Specular reflection multiplier");
- RNA_def_property_update(prop, 0, "rna_Lamp_update");
-
prop = RNA_def_property(srna, "contact_shadow_distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "contact_dist");
RNA_def_property_range(prop, 0.0f, 9999.0f);
diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c
index 904a6289fc1..ace7ac30408 100644
--- a/source/blender/makesrna/intern/rna_lattice.c
+++ b/source/blender/makesrna/intern/rna_lattice.c
@@ -216,19 +216,19 @@ static char *rna_LatticePoint_path(PointerRNA *ptr)
Lattice *lt = (Lattice *)ptr->id.data;
void *point = ptr->data;
BPoint *points = NULL;
-
+
if (lt->editlatt && lt->editlatt->latt->def)
points = lt->editlatt->latt->def;
else
points = lt->def;
-
+
if (points && point) {
int tot = lt->pntsu * lt->pntsv * lt->pntsw;
-
+
/* only return index if in range */
if ((point >= (void *)points) && (point < (void *)(points + tot))) {
int pt_index = (int)((BPoint *)point - points);
-
+
return BLI_sprintfN("points[%d]", pt_index);
}
}
@@ -345,7 +345,7 @@ static void rna_def_lattice(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, NULL, "rna_Lattice_use_outside_set");
RNA_def_property_ui_text(prop, "Outside", "Only draw, and take into account, the outer vertices");
RNA_def_property_update(prop, 0, "rna_Lattice_update_data_editlatt");
-
+
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "vgroup");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group to apply the influence of the lattice");
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index e7efdc27647..060b075cb29 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -49,6 +49,10 @@
#ifdef RNA_RUNTIME
+#ifdef WITH_PYTHON
+# include "BPY_extern.h"
+#endif
+
#include "DNA_group_types.h"
#include "DNA_object_types.h"
@@ -163,22 +167,20 @@ static void rna_LayerObjects_selected_begin(CollectionPropertyIterator *iter, Po
rna_iterator_listbase_begin(iter, &view_layer->object_bases, rna_ViewLayer_objects_selected_skip);
}
-static void rna_ViewLayer_update_tagged(ViewLayer *UNUSED(view_layer), bContext *C)
+static void rna_ViewLayer_update_tagged(ID *id_ptr, ViewLayer *view_layer, Main *bmain)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- DEG_OBJECT_ITER_BEGIN(
- depsgraph, ob, DEG_ITER_OBJECT_MODE_VIEWPORT,
- DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
- DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
- DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY |
- DEG_ITER_OBJECT_FLAG_VISIBLE |
- DEG_ITER_OBJECT_FLAG_DUPLI)
- {
- /* Don't do anything, we just need to run the iterator to flush
- * the base info to the objects. */
- UNUSED_VARS(ob);
- }
- DEG_OBJECT_ITER_END;
+#ifdef WITH_PYTHON
+ /* Allow drivers to be evaluated */
+ BPy_BEGIN_ALLOW_THREADS;
+#endif
+
+ Scene *scene = (Scene *)id_ptr;
+ Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
+ BKE_scene_graph_update_tagged(depsgraph, bmain);
+
+#ifdef WITH_PYTHON
+ BPy_END_ALLOW_THREADS;
+#endif
}
static void rna_ObjectBase_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -351,7 +353,7 @@ void RNA_def_view_layer(BlenderRNA *brna)
/* debug update routine */
func = RNA_def_function(srna, "update", "rna_ViewLayer_update_tagged");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
RNA_def_function_ui_description(func,
"Update data tagged to be updated from previous access to data or operators");
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index d727b896223..7b9184eb5df 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -386,7 +386,7 @@ void RNA_def_main(BlenderRNA *brna)
};
int i;
-
+
srna = RNA_def_struct(brna, "BlendData", NULL);
RNA_def_struct_ui_text(srna, "Blendfile Data",
"Main data structure representing a .blend file and all its data-blocks");
@@ -397,7 +397,7 @@ void RNA_def_main(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, "rna_Main_filepath_get", "rna_Main_filepath_length", "rna_Main_filepath_set");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Filename", "Path to the .blend file");
-
+
prop = RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Main_is_dirty_get", NULL);
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 1aa6bdf9465..9b4d6ead53c 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -489,7 +489,7 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f
Text *txt;
errno = 0;
- txt = BKE_text_load_ex(bmain, filepath, bmain->name, is_internal);
+ txt = BKE_text_load_ex(bmain, filepath, BKE_main_blendfile_path(bmain), is_internal);
if (!txt)
BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath,
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 9f5b72ff13e..e1eadda3696 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -97,10 +97,10 @@ static void rna_Material_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Point
static void rna_Material_update_previews(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Material *ma = ptr->id.data;
-
+
if (ma->nodetree)
BKE_node_preview_clear_tree(ma->nodetree);
-
+
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_PREVIEW, ma);
}
@@ -226,7 +226,7 @@ void rna_mtex_texture_slots_clear(ID *self_id, struct bContext *C, ReportList *r
BKE_report(reports, RPT_ERROR, "Mtex not found for this type");
return;
}
-
+
if (index < 0 || index >= MAX_MTEX) {
BKE_reportf(reports, RPT_ERROR, "Index %d is invalid", index);
return;
@@ -254,7 +254,7 @@ static void rna_def_material_display(StructRNA *srna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Diffuse Color", "Diffuse color of the material");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
-
+
prop = RNA_def_property(srna, "specular_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "specr");
RNA_def_property_array(prop, 3);
@@ -267,7 +267,7 @@ static void rna_def_material_display(StructRNA *srna)
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Roughness", "Roughness of the material");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
-
+
prop = RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "spec");
RNA_def_property_float_default(prop, 0.5f);
@@ -334,7 +334,7 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Material",
"Material data-block to define the appearance of geometric objects for rendering");
RNA_def_struct_ui_icon(srna, ICON_MATERIAL_DATA);
-
+
/* Blending (only Eevee for now) */
prop = RNA_def_property(srna, "blend_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_eevee_blend_items);
@@ -386,7 +386,7 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_enum_items(prop, preview_type_items);
RNA_def_property_ui_text(prop, "Preview render type", "Type of preview render");
RNA_def_property_update(prop, 0, "rna_Material_update_previews");
-
+
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "index");
RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Material Index\" render pass");
@@ -432,14 +432,14 @@ static void rna_def_texture_slots(BlenderRNA *brna, PropertyRNA *cprop, const ch
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "mtex", structname, "", "The newly initialized mtex");
RNA_def_function_return(func, parm);
-
+
func = RNA_def_function(srna, "create", "rna_mtex_texture_slots_create");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
parm = RNA_def_int(func, "index", 0, 0, INT_MAX, "Index", "Slot index to initialize", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func, "mtex", structname, "", "The newly initialized mtex");
RNA_def_function_return(func, parm);
-
+
func = RNA_def_function(srna, "clear", "rna_mtex_texture_slots_clear");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
parm = RNA_def_int(func, "index", 0, 0, INT_MAX, "Index", "Slot index to clear", 0, INT_MAX);
@@ -490,7 +490,7 @@ static void rna_def_tex_slot(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "uvname");
RNA_def_property_ui_text(prop, "UV Map", "Name of UV map");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Material_update");
-
+
prop = RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "valid", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 9ec196034f3..d664415b8ad 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -3142,7 +3142,7 @@ static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA *UNUSED(cprop))
RNA_def_property_boolean_sdna(prop, NULL, "flag", MVERT_SKIN_ROOT);
RNA_def_property_ui_text(prop, "Root", "Vertex is a root for rotation calculations and armature generation");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
+
prop = RNA_def_property(srna, "use_loose", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MVERT_SKIN_LOOSE);
RNA_def_property_ui_text(prop, "Loose", "If vertex has multiple adjacent edges, it is hulled to them directly");
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index f1f7c9a3b99..ed19877ec0f 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -55,10 +55,10 @@
static const char *rna_Mesh_unit_test_compare(struct Mesh *mesh, struct Mesh *mesh2)
{
const char *ret = BKE_mesh_cmp(mesh, mesh2, FLT_EPSILON * 60);
-
+
if (!ret)
ret = "Same";
-
+
return ret;
}
diff --git a/source/blender/makesrna/intern/rna_mesh_utils.h b/source/blender/makesrna/intern/rna_mesh_utils.h
index a85e2095121..b16a7254a86 100644
--- a/source/blender/makesrna/intern/rna_mesh_utils.h
+++ b/source/blender/makesrna/intern/rna_mesh_utils.h
@@ -23,7 +23,7 @@
/** \file blender/makesrna/intern/rna_mesh_utils.h
* \ingroup RNA
*/
-
+
#ifndef __RNA_MESH_UTILS_H__
#define __RNA_MESH_UTILS_H__
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index 124f3a2fbe2..cdecba0760c 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -64,32 +64,32 @@ static int rna_Meta_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_inf
static void rna_Meta_texspace_loc_get(PointerRNA *ptr, float *values)
{
MetaBall *mb = (MetaBall *)ptr->data;
-
+
/* tex_space_mball() needs object.. ugh */
-
+
copy_v3_v3(values, mb->loc);
}
static void rna_Meta_texspace_loc_set(PointerRNA *ptr, const float *values)
{
MetaBall *mb = (MetaBall *)ptr->data;
-
+
copy_v3_v3(mb->loc, values);
}
static void rna_Meta_texspace_size_get(PointerRNA *ptr, float *values)
{
MetaBall *mb = (MetaBall *)ptr->data;
-
+
/* tex_space_mball() needs object.. ugh */
-
+
copy_v3_v3(values, mb->size);
}
static void rna_Meta_texspace_size_set(PointerRNA *ptr, const float *values)
{
MetaBall *mb = (MetaBall *)ptr->data;
-
+
copy_v3_v3(mb->size, values);
}
@@ -104,7 +104,7 @@ static void rna_MetaBall_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
for (ob = bmain->object.first; ob; ob = ob->id.next)
if (ob->data == mb)
BKE_mball_properties_copy(scene, ob);
-
+
DEG_id_tag_update(&mb->id, 0);
WM_main_add_notifier(NC_GEOM | ND_DATA, mb);
}
@@ -200,7 +200,7 @@ static void rna_def_metaelement(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_metaelem_type_items);
RNA_def_property_ui_text(prop, "Type", "Metaball types");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
/* number values */
prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "x");
@@ -239,19 +239,19 @@ static void rna_def_metaelement(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 20.0f);
RNA_def_property_ui_text(prop, "Size Z", "Size of element, use of components depends on element type");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
prop = RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "s");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Stiffness", "Stiffness defines how much of the element to fill");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
/* flags */
prop = RNA_def_property(srna, "use_negative", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MB_NEGATIVE);
RNA_def_property_ui_text(prop, "Negative", "Set metaball as negative one");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MB_HIDE);
RNA_def_property_ui_text(prop, "Hide", "Hide element");
@@ -304,7 +304,7 @@ static void rna_def_metaball(BlenderRNA *brna)
{MB_UPDATE_NEVER, "NEVER", 0, "Never", "While editing, don't update metaball at all"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "MetaBall", "ID");
RNA_def_struct_ui_text(srna, "MetaBall", "Metaball data-block to defined blobby surfaces");
RNA_def_struct_ui_icon(srna, ICON_META_DATA);
@@ -321,7 +321,7 @@ static void rna_def_metaball(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_update_items);
RNA_def_property_ui_text(prop, "Update", "Metaball edit update behavior");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
/* number values */
prop = RNA_def_property(srna, "resolution", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "wiresize");
@@ -329,14 +329,14 @@ static void rna_def_metaball(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.05f, 1000.0f, 2.5f, 3);
RNA_def_property_ui_text(prop, "Wire Size", "Polygonization resolution in the 3D viewport");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
prop = RNA_def_property(srna, "render_resolution", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "rendersize");
RNA_def_property_range(prop, 0.005f, 10000.0f);
RNA_def_property_ui_range(prop, 0.025f, 1000.0f, 2.5f, 3);
RNA_def_property_ui_text(prop, "Render Size", "Polygonization resolution in rendering");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "thresh");
RNA_def_property_range(prop, 0.0f, 5.0f);
@@ -348,14 +348,14 @@ static void rna_def_metaball(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MB_AUTOSPACE);
RNA_def_property_ui_text(prop, "Auto Texture Space",
"Adjust active object's texture space automatically when transforming object");
-
+
prop = RNA_def_property(srna, "texspace_location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Texture Space Location", "Texture space location");
RNA_def_property_editable_func(prop, "rna_Meta_texspace_editable");
RNA_def_property_float_funcs(prop, "rna_Meta_texspace_loc_get", "rna_Meta_texspace_loc_set", NULL);
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
prop = RNA_def_property(srna, "texspace_size", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 3);
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
@@ -363,7 +363,7 @@ static void rna_def_metaball(BlenderRNA *brna)
RNA_def_property_editable_func(prop, "rna_Meta_texspace_editable");
RNA_def_property_float_funcs(prop, "rna_Meta_texspace_size_get", "rna_Meta_texspace_size_set", NULL);
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
-
+
/* not supported yet */
#if 0
prop = RNA_def_property(srna, "texspace_rot", PROP_FLOAT, PROP_EULER);
@@ -372,7 +372,7 @@ static void rna_def_metaball(BlenderRNA *brna)
RNA_def_property_editable_func(prop, "rna_Meta_texspace_editable");
RNA_def_property_update(prop, 0, "rna_MetaBall_update_data");
#endif
-
+
/* materials */
prop = RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol");
@@ -380,7 +380,7 @@ static void rna_def_metaball(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Materials", "");
RNA_def_property_srna(prop, "IDMaterials"); /* see rna_ID.c */
RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "rna_IDMaterials_assign_int");
-
+
prop = RNA_def_property(srna, "is_editmode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Meta_is_editmode_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index b1716f6a176..bfc90557374 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -427,19 +427,19 @@ static void rna_Modifier_name_set(PointerRNA *ptr, const char *value)
{
ModifierData *md = ptr->data;
char oldname[sizeof(md->name)];
-
+
/* make a copy of the old name first */
BLI_strncpy(oldname, md->name, sizeof(md->name));
-
+
/* copy the new name into the name slot */
BLI_strncpy_utf8(md->name, value, sizeof(md->name));
-
+
/* make sure the name is truly unique */
if (ptr->id.data) {
Object *ob = ptr->id.data;
modifier_unique_name(&ob->modifiers, md);
}
-
+
/* fix all the animation data which may link to this */
BKE_animdata_fix_paths_rename_all(NULL, "modifiers", oldname, md->name);
}
@@ -697,7 +697,7 @@ static int rna_ShrinkwrapModifier_face_cull_get(PointerRNA *ptr)
static void rna_ShrinkwrapModifier_face_cull_set(struct PointerRNA *ptr, int value)
{
ShrinkwrapModifierData *swm = (ShrinkwrapModifierData *)ptr->data;
-
+
swm->shrinkOpts =
(swm->shrinkOpts & ~(MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE | MOD_SHRINKWRAP_CULL_TARGET_BACKFACE)) | value;
}
@@ -738,27 +738,27 @@ static void rna_UVProjectModifier_num_projectors_set(PointerRNA *ptr, int value)
static void rna_OceanModifier_init_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
OceanModifierData *omd = (OceanModifierData *)ptr->data;
-
+
omd->refresh |= (MOD_OCEAN_REFRESH_RESET | MOD_OCEAN_REFRESH_SIM | MOD_OCEAN_REFRESH_CLEAR_CACHE);
-
+
rna_Modifier_update(bmain, scene, ptr);
}
static void rna_OceanModifier_sim_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
OceanModifierData *omd = (OceanModifierData *)ptr->data;
-
+
omd->refresh |= MOD_OCEAN_REFRESH_SIM;
-
+
rna_Modifier_update(bmain, scene, ptr);
}
static void rna_OceanModifier_topology_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
OceanModifierData *omd = (OceanModifierData *)ptr->data;
-
+
omd->refresh |= MOD_OCEAN_REFRESH_TOPOLOGY;
-
+
rna_Modifier_update(bmain, scene, ptr);
}
@@ -766,9 +766,9 @@ static void rna_OceanModifier_ocean_chop_set(PointerRNA *ptr, float value)
{
OceanModifierData *omd = (OceanModifierData *)ptr->data;
float old_value = omd->chop_amount;
-
+
omd->chop_amount = value;
-
+
if ((old_value == 0.0f && value > 0.0f) ||
(old_value > 0.0f && value == 0.0f))
{
@@ -1243,7 +1243,7 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", eSubsurfModifierFlag_ControlEdges);
RNA_def_property_ui_text(prop, "Optimal Display", "Skip drawing/rendering of interior subdivided edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "use_subsurf_uv", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", eSubsurfModifierFlag_SubsurfUv);
RNA_def_property_ui_text(prop, "Subdivide UVs", "Use subsurf to subdivide UVs");
@@ -1429,7 +1429,7 @@ static void rna_def_modifier_lattice(BlenderRNA *brna)
"Name of Vertex Group which determines influence of modifier per point");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LatticeModifier_name_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 1, 10, 2);
@@ -1503,7 +1503,7 @@ static void rna_def_modifier_build(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_BUILD_FLAG_REVERSE);
RNA_def_property_ui_text(prop, "Reversed", "Deconstruct the mesh instead of building it");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "use_random_order", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_BUILD_FLAG_RANDOMIZE);
RNA_def_property_ui_text(prop, "Randomize", "Randomize the faces or edges during build");
@@ -1549,7 +1549,7 @@ static void rna_def_modifier_mirror(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_VGROUP);
RNA_def_property_ui_text(prop, "Mirror Vertex Groups", "Mirror vertex groups (e.g. .R->.L)");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "use_mirror_merge", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", MOD_MIR_NO_MERGE);
RNA_def_property_ui_text(prop, "Merge Vertices", "Merge vertices within the merge threshold");
@@ -1854,7 +1854,8 @@ static void rna_def_modifier_armature(BlenderRNA *brna)
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Object", "Armature object to deform with");
RNA_def_property_pointer_funcs(prop, NULL, "rna_ArmatureModifier_object_set", NULL, "rna_Armature_object_poll");
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK | PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "use_bone_envelopes", PROP_BOOLEAN, PROP_NONE);
@@ -1866,7 +1867,7 @@ static void rna_def_modifier_armature(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_VGROUP);
RNA_def_property_ui_text(prop, "Use Vertex Groups", "Bind vertex groups to armature modifier");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "use_deform_preserve_volume", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_QUATERNION);
RNA_def_property_ui_text(prop, "Preserve Volume", "Deform rotation interpolation with quaternions");
@@ -1877,7 +1878,7 @@ static void rna_def_modifier_armature(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Multi Modifier",
"Use same input as previous modifier, and mix results using overall vgroup");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group",
@@ -1941,7 +1942,7 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_pointer_funcs(prop, NULL, "rna_HookModifier_object_set", NULL, NULL);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
-
+
prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "subtarget");
RNA_def_property_ui_text(prop, "Sub-Target",
@@ -2087,7 +2088,7 @@ static void rna_def_modifier_array(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "offset_type", MOD_ARR_OFF_CONST);
RNA_def_property_ui_text(prop, "Constant Offset", "Add a constant offset");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "constant_offset_displace", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "offset");
RNA_def_property_ui_text(prop, "Constant Offset Displacement", "Value for the distance between arrayed items");
@@ -2137,7 +2138,7 @@ static void rna_def_modifier_array(BlenderRNA *brna)
"rotational change between arrayed items");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
-
+
/* Caps */
prop = RNA_def_property(srna, "start_cap", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Start Cap", "Mesh object to use as a start cap");
@@ -2150,7 +2151,7 @@ static void rna_def_modifier_array(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_end_cap_set", NULL, "rna_Mesh_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
-
+
prop = RNA_def_property(srna, "offset_u", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "uv_offset[0]");
RNA_def_property_range(prop, -1, 1);
@@ -2299,7 +2300,7 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 1000, 1, 3);
RNA_def_property_ui_text(prop, "Vertical Aspect Ratio", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "scalex");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
@@ -2364,7 +2365,7 @@ static void rna_def_modifier_smooth(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 30, 1, -1);
RNA_def_property_ui_text(prop, "Repeat", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group",
@@ -2486,7 +2487,7 @@ static void rna_def_modifier_laplaciansmooth(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME);
RNA_def_property_ui_text(prop, "Preserve Volume", "Apply volume preservation after smooth");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "use_normalized", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_LAPLACIANSMOOTH_NORMALIZED);
RNA_def_property_ui_text(prop, "Normalized", "Improve and stabilize the enhanced shape");
@@ -2511,7 +2512,7 @@ static void rna_def_modifier_laplaciansmooth(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 200, 1, -1);
RNA_def_property_ui_text(prop, "Repeat", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group",
@@ -2542,7 +2543,7 @@ static void rna_def_modifier_cast(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_cast_type_items);
RNA_def_property_ui_text(prop, "Cast Type", "Target object shape");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Object",
"Control object: if available, its location determines the center of the effect");
@@ -2564,17 +2565,17 @@ static void rna_def_modifier_cast(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_CAST_Z);
RNA_def_property_ui_text(prop, "Z", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "use_radius_as_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_CAST_SIZE_FROM_RADIUS);
RNA_def_property_ui_text(prop, "From Radius", "Use radius as size of projection shape (0 = auto)");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "use_transform", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_CAST_USE_OB_TRANSFORM);
RNA_def_property_ui_text(prop, "Use transform", "Use object transform to control projection shape");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fac");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
@@ -2625,12 +2626,12 @@ static void rna_def_modifier_meshdeform(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, NULL, "rna_MeshDeformModifier_object_set", NULL, "rna_Mesh_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
-
+
prop = RNA_def_property(srna, "is_bound", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_MeshDeformModifier_is_bound_get", NULL);
RNA_def_property_ui_text(prop, "Bound", "Whether geometry has been bound to control cage");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MDEF_INVERT_VGROUP);
RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
@@ -2672,7 +2673,7 @@ static void rna_def_modifier_particlesystem(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "ParticleSystem Modifier", "Particle system simulation modifier");
RNA_def_struct_sdna(srna, "ParticleSystemModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_PARTICLES);
-
+
prop = RNA_def_property(srna, "particle_system", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "psys");
@@ -2876,22 +2877,22 @@ static void rna_def_modifier_cloth(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Cloth Modifier", "Cloth simulation modifier");
RNA_def_struct_sdna(srna, "ClothModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_CLOTH);
-
+
prop = RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "sim_parms");
RNA_def_property_ui_text(prop, "Cloth Settings", "");
-
+
prop = RNA_def_property(srna, "collision_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "coll_parms");
RNA_def_property_ui_text(prop, "Cloth Collision Settings", "");
-
+
prop = RNA_def_property(srna, "solver_result", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ClothSolverResult");
RNA_def_property_pointer_sdna(prop, NULL, "solver_result");
RNA_def_property_ui_text(prop, "Solver Result", "");
-
+
prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Point Cache", "");
@@ -2916,7 +2917,7 @@ static void rna_def_modifier_smoke(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem prop_smoke_type_items[] = {
{0, "NONE", 0, "None", ""},
{MOD_SMOKE_TYPE_DOMAIN, "DOMAIN", 0, "Domain", ""},
@@ -2924,24 +2925,24 @@ static void rna_def_modifier_smoke(BlenderRNA *brna)
{MOD_SMOKE_TYPE_COLL, "COLLISION", 0, "Collision", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "SmokeModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Smoke Modifier", "Smoke simulation modifier");
RNA_def_struct_sdna(srna, "SmokeModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_SMOKE);
-
+
prop = RNA_def_property(srna, "domain_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "domain");
RNA_def_property_ui_text(prop, "Domain Settings", "");
-
+
prop = RNA_def_property(srna, "flow_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "flow");
RNA_def_property_ui_text(prop, "Flow Settings", "");
-
+
prop = RNA_def_property(srna, "coll_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "coll");
RNA_def_property_ui_text(prop, "Collision Settings", "");
-
+
prop = RNA_def_property(srna, "smoke_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, prop_smoke_type_items);
@@ -2954,16 +2955,16 @@ static void rna_def_modifier_dynamic_paint(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "DynamicPaintModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Dynamic Paint Modifier", "Dynamic Paint modifier");
RNA_def_struct_sdna(srna, "DynamicPaintModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_DYNAMICPAINT);
-
+
prop = RNA_def_property(srna, "canvas_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "canvas");
RNA_def_property_ui_text(prop, "Canvas Settings", "");
-
+
prop = RNA_def_property(srna, "brush_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "brush");
RNA_def_property_ui_text(prop, "Brush Settings", "");
@@ -3116,7 +3117,7 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
"Shrink the mesh to the nearest target vertex"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem shrink_face_cull_items[] = {
{0, "OFF", 0, "Off", "No culling"},
{MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE, "FRONT", 0, "Front", "No projection when in front of the face"},
@@ -3192,7 +3193,7 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "projAxis", MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS);
RNA_def_property_ui_text(prop, "Z", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "subsurf_levels", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "subsurfLevels");
RNA_def_property_range(prop, 0, 6);
@@ -4035,7 +4036,7 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem geometry_items[] = {
{MOD_OCEAN_GEOM_GENERATE, "GENERATE", 0, "Generate",
"Generate ocean surface geometry at the specified resolution"},
@@ -4046,24 +4047,24 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
#endif
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "OceanModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Ocean Modifier", "Simulate an ocean surface");
RNA_def_struct_sdna(srna, "OceanModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_OCEAN);
-
+
prop = RNA_def_property(srna, "geometry_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "geometry_mode");
RNA_def_property_enum_items(prop, geometry_items);
RNA_def_property_ui_text(prop, "Geometry", "Method of modifying geometry");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_ui_text(prop, "Size", "Surface scale factor (does not affect the height of the waves)");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, -1);
RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
-
+
prop = RNA_def_property(srna, "repeat_x", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "repeat_x");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -4071,7 +4072,7 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 100, 1, -1);
RNA_def_property_ui_text(prop, "Repeat X", "Repetitions of the generated surface in X");
RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
-
+
prop = RNA_def_property(srna, "repeat_y", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "repeat_y");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -4086,13 +4087,13 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Generate Normals",
"Output normals for bump mapping - disabling can speed up performance if its not needed");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "use_foam", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_OCEAN_GENERATE_FOAM);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Generate Foam", "Generate foam mask as a vertex color channel");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "resolution", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "resolution");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -4100,7 +4101,7 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 32, 1, -1);
RNA_def_property_ui_text(prop, "Resolution", "Resolution of the generated surface");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "spatial_size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "spatial_size");
RNA_def_property_ui_range(prop, 1, 512, 2, -1);
@@ -4108,66 +4109,66 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Spatial Size",
"Size of the simulation domain (in meters), and of the generated geometry (in BU)");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "wind_velocity", PROP_FLOAT, PROP_VELOCITY);
RNA_def_property_float_sdna(prop, NULL, "wind_velocity");
RNA_def_property_ui_text(prop, "Wind Velocity", "Wind speed");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "damping", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "damp");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Damping", "Damp reflected waves going in opposite direction to the wind");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "wave_scale_min", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "smallest_wave");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_text(prop, "Smallest Wave", "Shortest allowed wavelength");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "wave_alignment", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "wave_alignment");
RNA_def_property_range(prop, 0.0, 10.0);
RNA_def_property_ui_text(prop, "Wave Alignment", "How much the waves are aligned to each other");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "wave_direction", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "wave_direction");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Wave Direction", "Main direction of the waves when they are (partially) aligned");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "wave_scale", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "wave_scale");
RNA_def_property_ui_text(prop, "Wave Scale", "Scale of the displacement effect");
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
-
+
prop = RNA_def_property(srna, "depth", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "depth");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Depth", "Depth of the solid ground below the water surface");
RNA_def_property_ui_range(prop, 0, 250, 1, -1);
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "foam_coverage", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "foam_coverage");
RNA_def_property_ui_text(prop, "Foam Coverage", "Amount of generated foam");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "bake_foam_fade", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "foam_fade");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Foam Fade", "How much foam accumulates over time (baked ocean only)");
RNA_def_property_ui_range(prop, 0.0, 10.0, 1, -1);
RNA_def_property_update(prop, 0, NULL);
-
+
prop = RNA_def_property(srna, "foam_layer_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "foamlayername");
RNA_def_property_ui_text(prop, "Foam Layer Name", "Name of the vertex color layer used for foam");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "choppiness", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "chop_amount");
RNA_def_property_ui_text(prop, "Choppiness",
@@ -4175,31 +4176,31 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0, 4.0, 3, -1);
RNA_def_property_float_funcs(prop, NULL, "rna_OceanModifier_ocean_chop_set", NULL);
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
-
+
prop = RNA_def_property(srna, "time", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "time");
RNA_def_property_ui_text(prop, "Time", "Current time of the simulation");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, -1);
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
-
+
prop = RNA_def_property(srna, "random_seed", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "seed");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Random Seed", "Seed of the random generator");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "bakestart");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Bake Start", "Start frame of the ocean baking");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "bakeend");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Bake End", "End frame of the ocean baking");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
-
+
prop = RNA_def_property(srna, "is_cached", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cached", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -4896,58 +4897,59 @@ void RNA_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
/* data */
srna = RNA_def_struct(brna, "Modifier", NULL);
RNA_def_struct_ui_text(srna, "Modifier", "Modifier affecting the geometry data of an object");
RNA_def_struct_refine_func(srna, "rna_Modifier_refine");
RNA_def_struct_path_func(srna, "rna_Modifier_path");
RNA_def_struct_sdna(srna, "ModifierData");
-
+
/* strings */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Modifier_name_set");
RNA_def_property_ui_text(prop, "Name", "Modifier name");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER | NA_RENAME, NULL);
RNA_def_struct_name_property(srna, prop);
-
+
/* enums */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, rna_enum_object_modifier_type_items);
RNA_def_property_ui_text(prop, "Type", "");
-
+
/* flags */
prop = RNA_def_property(srna, "show_viewport", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Realtime);
RNA_def_property_ui_text(prop, "Realtime", "Display modifier in viewport");
- RNA_def_property_flag(prop, PROP_LIB_EXCEPTION | PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 0);
-
+
prop = RNA_def_property(srna, "show_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Render);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Render", "Use modifier during render");
RNA_def_property_ui_icon(prop, ICON_SCENE, 0);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL);
-
+
prop = RNA_def_property(srna, "show_in_editmode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Editmode);
RNA_def_property_ui_text(prop, "Edit Mode", "Display modifier in Edit mode");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
RNA_def_property_ui_icon(prop, ICON_EDITMODE_HLT, 0);
-
+
prop = RNA_def_property(srna, "show_on_cage", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_OnCage);
RNA_def_property_ui_text(prop, "On Cage", "Adjust edit cage to modifier result");
RNA_def_property_ui_icon(prop, ICON_MESH_DATA, 0);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
+
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Expanded);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Expanded", "Set modifier expanded in the user interface");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
index c663119eb42..aa976775ad1 100644
--- a/source/blender/makesrna/intern/rna_movieclip.c
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -56,11 +56,11 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-static void rna_MovieClip_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_MovieClip_reload_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
MovieClip *clip = (MovieClip *)ptr->id.data;
- BKE_movieclip_reload(clip);
+ BKE_movieclip_reload(bmain, clip);
DEG_id_tag_update(&clip->id, 0);
}
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 1301762a4bc..404d9089cd9 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -63,10 +63,10 @@
static void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
/* copy the name first */
BLI_strncpy_utf8(data->name, value, sizeof(data->name));
-
+
/* validate if there's enough info to do so */
if (ptr->id.data) {
AnimData *adt = BKE_animdata_from_id(ptr->id.data);
@@ -78,12 +78,12 @@ static char *rna_NlaStrip_path(PointerRNA *ptr)
{
NlaStrip *strip = (NlaStrip *)ptr->data;
AnimData *adt = BKE_animdata_from_id(ptr->id.data);
-
+
/* if we're attached to AnimData, try to resolve path back to AnimData */
if (adt) {
NlaTrack *nlt;
NlaStrip *nls;
-
+
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
for (nls = nlt->strips.first; nls; nls = nls->next) {
if (nls == strip) {
@@ -99,7 +99,7 @@ static char *rna_NlaStrip_path(PointerRNA *ptr)
}
}
}
-
+
/* no path */
return BLI_strdup("");
}
@@ -133,7 +133,7 @@ static void rna_NlaStrip_transform_update(Main *bmain, Scene *scene, PointerRNA
static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
/* clamp value to lie within valid limits
* - cannot start past the end of the strip + some flexibility threshold
* - cannot start before the previous strip (if present) ends
@@ -144,7 +144,7 @@ static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
if (data->prev) {
if (data->prev->type == NLASTRIP_TYPE_TRANSITION) {
CLAMP(value, data->prev->start + NLASTRIP_MIN_LEN_THRESH, data->end - NLASTRIP_MIN_LEN_THRESH);
-
+
/* re-adjust the transition to stick to the endpoints of the action-clips */
data->prev->end = value;
}
@@ -161,7 +161,7 @@ static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
/* clamp value to lie within valid limits
* - must not have zero or negative length strip, so cannot start before the first frame
* + some minimum-strip-length threshold
@@ -172,7 +172,7 @@ static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value)
if (data->next) {
if (data->next->type == NLASTRIP_TYPE_TRANSITION) {
CLAMP(value, data->start + NLASTRIP_MIN_LEN_THRESH, data->next->end - NLASTRIP_MIN_LEN_THRESH);
-
+
/* readjust the transition to stick to the endpoints of the action-clips */
data->next->start = value;
}
@@ -184,16 +184,16 @@ static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value)
CLAMP(value, data->start + NLASTRIP_MIN_LEN_THRESH, MAXFRAME);
}
data->end = value;
-
-
+
+
/* calculate the lengths the strip and its action (if applicable) */
if (data->type == NLASTRIP_TYPE_CLIP) {
float len, actlen;
-
+
len = data->end - data->start;
actlen = data->actend - data->actstart;
if (IS_EQF(actlen, 0.0f)) actlen = 1.0f;
-
+
/* now, adjust the 'scale' setting to reflect this (so that this change can be valid) */
data->scale = len / ((actlen) * data->repeat);
}
@@ -202,12 +202,12 @@ static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value)
static void rna_NlaStrip_scale_set(PointerRNA *ptr, float value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
/* set scale value */
/* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */
CLAMP(value, 0.0001f, 1000.0f);
data->scale = value;
-
+
/* adjust the strip extents in response to this */
BKE_nlastrip_recalculate_bounds(data);
}
@@ -215,12 +215,12 @@ static void rna_NlaStrip_scale_set(PointerRNA *ptr, float value)
static void rna_NlaStrip_repeat_set(PointerRNA *ptr, float value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
/* set repeat value */
/* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */
CLAMP(value, 0.01f, 1000.0f);
data->repeat = value;
-
+
/* adjust the strip extents in response to this */
BKE_nlastrip_recalculate_bounds(data);
}
@@ -229,11 +229,11 @@ static void rna_NlaStrip_blend_in_set(PointerRNA *ptr, float value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
float len;
-
+
/* blend-in is limited to the length of the strip, and also cannot overlap with blendout */
len = (data->end - data->start) - data->blendout;
CLAMP(value, 0, len);
-
+
data->blendin = value;
}
@@ -241,30 +241,30 @@ static void rna_NlaStrip_blend_out_set(PointerRNA *ptr, float value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
float len;
-
+
/* blend-out is limited to the length of the strip */
len = (data->end - data->start);
CLAMP(value, 0, len);
-
+
/* it also cannot overlap with blendin */
if ((len - value) < data->blendin)
value = len - data->blendin;
-
+
data->blendout = value;
}
static void rna_NlaStrip_use_auto_blend_set(PointerRNA *ptr, int value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
if (value) {
/* set the flag */
data->flag |= NLASTRIP_FLAG_AUTO_BLENDS;
-
+
/* validate state to ensure that auto-blend gets applied immediately */
if (ptr->id.data) {
IdAdtTemplate *iat = (IdAdtTemplate *)ptr->id.data;
-
+
if (iat->adt) {
BKE_nla_validate_state(iat->adt);
}
@@ -273,7 +273,7 @@ static void rna_NlaStrip_use_auto_blend_set(PointerRNA *ptr, int value)
else {
/* clear the flag */
data->flag &= ~NLASTRIP_FLAG_AUTO_BLENDS;
-
+
/* clear the values too, so that it's clear that there has been an effect */
/* TODO: it's somewhat debatable whether it's better to leave these in instead... */
data->blendin = 0.0f;
@@ -284,22 +284,22 @@ static void rna_NlaStrip_use_auto_blend_set(PointerRNA *ptr, int value)
static int rna_NlaStrip_action_editable(PointerRNA *ptr, const char **UNUSED(r_info))
{
NlaStrip *strip = (NlaStrip *)ptr->data;
-
+
/* strip actions shouldn't be editable if NLA tweakmode is on */
if (ptr->id.data) {
AnimData *adt = BKE_animdata_from_id(ptr->id.data);
-
+
if (adt) {
/* active action is only editable when it is not a tweaking strip */
if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact))
return 0;
}
}
-
+
/* check for clues that strip probably shouldn't be used... */
if (strip->flag & NLASTRIP_FLAG_TWEAKUSER)
return 0;
-
+
/* should be ok, though we may still miss some cases */
return PROP_EDITABLE;
}
@@ -307,11 +307,11 @@ static int rna_NlaStrip_action_editable(PointerRNA *ptr, const char **UNUSED(r_i
static void rna_NlaStrip_action_start_frame_set(PointerRNA *ptr, float value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
/* prevent start frame from occurring after end of action */
CLAMP(value, MINAFRAME, data->actend);
data->actstart = value;
-
+
/* adjust the strip extents in response to this */
/* TODO: should the strip be moved backwards instead as a special case? */
BKE_nlastrip_recalculate_bounds(data);
@@ -320,11 +320,11 @@ static void rna_NlaStrip_action_start_frame_set(PointerRNA *ptr, float value)
static void rna_NlaStrip_action_end_frame_set(PointerRNA *ptr, float value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
/* prevent end frame from starting before start of action */
CLAMP(value, data->actstart, MAXFRAME);
data->actend = value;
-
+
/* adjust the strip extents in response to this */
BKE_nlastrip_recalculate_bounds(data);
}
@@ -332,7 +332,7 @@ static void rna_NlaStrip_action_end_frame_set(PointerRNA *ptr, float value)
static void rna_NlaStrip_animated_influence_set(PointerRNA *ptr, int value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
if (value) {
/* set the flag, then make sure a curve for this exists */
data->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
@@ -345,7 +345,7 @@ static void rna_NlaStrip_animated_influence_set(PointerRNA *ptr, int value)
static void rna_NlaStrip_animated_time_set(PointerRNA *ptr, int value)
{
NlaStrip *data = (NlaStrip *)ptr->data;
-
+
if (value) {
/* set the flag, then make sure a curve for this exists */
data->flag |= NLASTRIP_FLAG_USR_TIME;
@@ -371,22 +371,22 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo
int start, bAction *action)
{
NlaStrip *strip = BKE_nlastrip_new(action);
-
+
if (strip == NULL) {
BKE_report(reports, RPT_ERROR, "Unable to create new strip");
return NULL;
}
-
+
strip->end += (start - strip->start);
strip->start = start;
-
+
if (BKE_nlastrips_add_strip(&track->strips, strip) == 0) {
BKE_report(reports, RPT_ERROR,
"Unable to add strip (the track does not have any space to accommodate this new strip)");
BKE_nlastrip_free(NULL, strip);
return NULL;
}
-
+
/* create dummy AnimData block so that BKE_nlastrip_validate_name()
* can be used to ensure a valid name, as we don't have one here...
* - only the nla_tracks list is needed there, which we aim to reverse engineer here...
@@ -394,25 +394,25 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo
{
AnimData adt = {NULL};
NlaTrack *nlt, *nlt_p;
-
+
/* 'first' NLA track is found by going back up chain of given track's parents until we fall off */
nlt_p = track; nlt = track;
while ((nlt = nlt->prev) != NULL)
nlt_p = nlt;
adt.nla_tracks.first = nlt_p;
-
+
/* do the same thing to find the last track */
nlt_p = track; nlt = track;
while ((nlt = nlt->next) != NULL)
nlt_p = nlt;
adt.nla_tracks.last = nlt_p;
-
+
/* now we can just auto-name as usual */
BKE_nlastrip_validate_name(&adt, strip);
}
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
-
+
return strip;
}
@@ -442,7 +442,7 @@ static void rna_NlaTrack_solo_set(PointerRNA *ptr, int value)
if (data == NULL) {
return;
}
-
+
/* firstly, make sure 'solo' flag for all tracks is disabled */
for (nt = data; nt; nt = nt->next) {
nt->flag &= ~NLATRACK_SOLO;
@@ -450,12 +450,12 @@ static void rna_NlaTrack_solo_set(PointerRNA *ptr, int value)
for (nt = data; nt; nt = nt->prev) {
nt->flag &= ~NLATRACK_SOLO;
}
-
+
/* now, enable 'solo' for the given track if appropriate */
if (value) {
/* set solo status */
data->flag |= NLATRACK_SOLO;
-
+
/* set solo-status on AnimData */
adt->flag |= ADT_NLA_SOLO_TRACK;
}
@@ -518,7 +518,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
/* enum defs */
static const EnumPropertyItem prop_type_items[] = {
{NLASTRIP_TYPE_CLIP, "CLIP", 0, "Action Clip", "NLA Strip references some Action"},
@@ -527,20 +527,20 @@ static void rna_def_nlastrip(BlenderRNA *brna)
{NLASTRIP_TYPE_SOUND, "SOUND", 0, "Sound Clip", "NLA Strip representing a sound event for speakers"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* struct definition */
srna = RNA_def_struct(brna, "NlaStrip", NULL);
RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action");
RNA_def_struct_path_func(srna, "rna_NlaStrip_path");
RNA_def_struct_ui_icon(srna, ICON_NLA); /* XXX */
-
+
/* name property */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NlaStrip_name_set");
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-
+
/* Enums */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
@@ -548,19 +548,19 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Type", "Type of NLA Strip");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
prop = RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "extendmode");
RNA_def_property_enum_items(prop, rna_enum_nla_mode_extend_items);
RNA_def_property_ui_text(prop, "Extrapolation", "Action to take for gaps past the strip extents");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "blendmode");
RNA_def_property_enum_items(prop, rna_enum_nla_mode_blend_items);
RNA_def_property_ui_text(prop, "Blending", "Method used for combining strip's result with accumulated result");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
/* Strip extents */
prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "start");
@@ -573,20 +573,20 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_end_frame_set", NULL);
RNA_def_property_ui_text(prop, "End Frame", "");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update");
-
+
/* Blending */
prop = RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "blendin");
RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_in_set", NULL);
RNA_def_property_ui_text(prop, "Blend In", "Number of frames at start of strip to fade in influence");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
prop = RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "blendout");
RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_out_set", NULL);
RNA_def_property_ui_text(prop, "Blend Out", "");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
prop = RNA_def_property(srna, "use_auto_blend", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_AUTO_BLENDS);
RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_use_auto_blend_set");
@@ -594,7 +594,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
"Number of frames for Blending In/Out is automatically determined from "
"overlapping strips");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
/* Action */
prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "act");
@@ -603,20 +603,20 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_editable_func(prop, "rna_NlaStrip_action_editable");
RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
/* Action extents */
prop = RNA_def_property(srna, "action_frame_start", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "actstart");
RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_start_frame_set", NULL);
RNA_def_property_ui_text(prop, "Action Start Frame", "First frame from action to use");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update");
-
+
prop = RNA_def_property(srna, "action_frame_end", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "actend");
RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_end_frame_set", NULL);
RNA_def_property_ui_text(prop, "Action End Frame", "Last frame from action to use");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update");
-
+
/* Action Reuse */
prop = RNA_def_property(srna, "repeat", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "repeat");
@@ -626,7 +626,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_range(prop, 0.1f, 1000.0f);
RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the action range");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update");
-
+
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "scale");
RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_scale_set", NULL);
@@ -635,7 +635,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0001f, 1000.0f);
RNA_def_property_ui_text(prop, "Scale", "Scaling factor for action");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update");
-
+
/* Strip's F-Curves */
prop = RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "fcurves", NULL);
@@ -647,29 +647,29 @@ static void rna_def_nlastrip(BlenderRNA *brna)
prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "FModifier");
RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting all the F-Curves in the referenced Action");
-
+
/* Strip's Sub-Strips (for Meta-Strips) */
prop = RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "NlaStrip");
RNA_def_property_ui_text(prop, "NLA Strips",
"NLA Strips that this strip acts as a container for (if it is of type Meta)");
-
+
/* Settings - Values necessary for evaluation */
- prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Influence", "Amount the strip contributes to the current result");
/* XXX: Update temporarily disabled so that the property can be edited at all!
* Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost
*/
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL);
-
+
prop = RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_TIME);
RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate");
/* XXX: Update temporarily disabled so that the property can be edited at all!
* Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost
*/
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL);
-
+
/* TODO: should the animated_influence/time settings be animatable themselves? */
prop = RNA_def_property(srna, "use_animated_influence", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE);
@@ -677,19 +677,19 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Animated Influence",
"Influence setting is controlled by an F-Curve rather than automatically determined");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
prop = RNA_def_property(srna, "use_animated_time", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME);
RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_time_set");
RNA_def_property_ui_text(prop, "Animated Strip Time",
"Strip time is controlled by an F-Curve rather than automatically determined");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
prop = RNA_def_property(srna, "use_animated_time_cyclic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME_CYCLIC);
RNA_def_property_ui_text(prop, "Cyclic Strip Time", "Cycle the animated time within the action start & end");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update");
-
+
/* settings */
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
/* can be made editable by hooking it up to the necessary NLA API methods */
@@ -697,24 +697,24 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_ACTIVE);
RNA_def_property_ui_text(prop, "Active", "NLA Strip is active");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-
+
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SELECT);
RNA_def_property_ui_text(prop, "Select", "NLA Strip is selected");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-
+
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_MUTED);
RNA_def_property_ui_text(prop, "Muted", "NLA Strip is not evaluated");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
prop = RNA_def_property(srna, "use_reverse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_REVERSE);
RNA_def_property_ui_text(prop, "Reversed",
"NLA Strip is played back in reverse order (only when timing is "
"automatically determined)");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
-
+
prop = RNA_def_property(srna, "use_sync_length", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SYNC_LENGTH);
RNA_def_property_ui_text(prop, "Sync Action Length",
@@ -760,11 +760,11 @@ static void rna_def_nlatrack(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "NlaTrack", NULL);
RNA_def_struct_ui_text(srna, "NLA Track", "A animation layer containing Actions referenced as NLA strips");
RNA_def_struct_ui_icon(srna, ICON_NLA);
-
+
/* strips collection */
prop = RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "NlaStrip");
@@ -777,7 +777,7 @@ static void rna_def_nlatrack(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-
+
/* settings */
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
/* can be made editable by hooking it up to the necessary NLA API methods */
@@ -785,7 +785,7 @@ static void rna_def_nlatrack(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_ACTIVE);
RNA_def_property_ui_text(prop, "Active", "NLA Track is active");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-
+
prop = RNA_def_property(srna, "is_solo", PROP_BOOLEAN, PROP_NONE);
/* can be made editable by hooking it up to the necessary NLA API methods */
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SOLO);
@@ -799,7 +799,7 @@ static void rna_def_nlatrack(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SELECTED);
RNA_def_property_ui_text(prop, "Select", "NLA Track is selected");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
-
+
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_MUTED);
RNA_def_property_ui_text(prop, "Muted", "NLA Track is not evaluated");
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index d2fb9d19acc..f9e288b348e 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -261,15 +261,15 @@ const EnumPropertyItem *rna_node_tree_type_itemf(void *data, int (*poll)(void *d
++i;
continue;
}
-
+
tmp.value = i;
tmp.identifier = nt->idname;
tmp.icon = nt->ui_icon;
tmp.name = nt->ui_name;
tmp.description = nt->ui_description;
-
+
RNA_enum_item_add(&item, &totitem, &tmp);
-
+
++i;
}
NODE_TREE_TYPES_END;
@@ -336,15 +336,15 @@ const EnumPropertyItem *rna_node_type_itemf(void *data, int (*poll)(void *data,
++i;
continue;
}
-
+
tmp.value = i;
tmp.identifier = ntype->idname;
tmp.icon = ntype->ui_icon;
tmp.name = ntype->ui_name;
tmp.description = ntype->ui_description;
-
+
RNA_enum_item_add(&item, &totitem, &tmp);
-
+
++i;
NODE_TYPES_END
@@ -412,16 +412,16 @@ const EnumPropertyItem *rna_node_socket_type_itemf(
++i;
continue;
}
-
+
srna = stype->ext_socket.srna;
tmp.value = i;
tmp.identifier = stype->idname;
tmp.icon = RNA_struct_ui_icon(srna);
tmp.name = RNA_struct_ui_name(srna);
tmp.description = RNA_struct_ui_description(srna);
-
+
RNA_enum_item_add(&item, &totitem, &tmp);
-
+
++i;
NODE_SOCKET_TYPES_END
@@ -525,7 +525,7 @@ static const EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), P
static StructRNA *rna_NodeTree_refine(struct PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->data;
-
+
if (ntree->typeinfo->ext.srna)
return ntree->typeinfo->ext.srna;
else
@@ -590,7 +590,7 @@ static void rna_NodeTree_get_from_context(const bContext *C, bNodeTreeType *ntre
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "context", &C);
ntreetype->ext.call((bContext *)C, &ptr, func, &list);
-
+
RNA_parameter_get_lookup(&list, "result_1", &ret1);
RNA_parameter_get_lookup(&list, "result_2", &ret2);
RNA_parameter_get_lookup(&list, "result_3", &ret3);
@@ -654,7 +654,7 @@ static StructRNA *rna_NodeTree_register(
nt->type = NTREE_CUSTOM;
- nt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, nt->idname, &RNA_NodeTree);
+ nt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, nt->idname, &RNA_NodeTree);
nt->ext.data = data;
nt->ext.call = call;
nt->ext.free = free;
@@ -671,7 +671,7 @@ static StructRNA *rna_NodeTree_register(
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
-
+
return nt->ext.srna;
}
@@ -680,7 +680,7 @@ static bool rna_NodeTree_check(bNodeTree *ntree, ReportList *reports)
if (!ntreeIsRegistered(ntree)) {
if (reports)
BKE_reportf(reports, RPT_ERROR, "Node tree '%s' has undefined type %s", ntree->id.name + 2, ntree->idname);
-
+
return false;
}
else
@@ -702,28 +702,28 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r
{
bNodeType *ntype;
bNode *node;
-
+
if (!rna_NodeTree_check(ntree, reports))
return NULL;
-
+
ntype = nodeTypeFind(type);
if (!ntype) {
BKE_reportf(reports, RPT_ERROR, "Node type %s undefined", type);
return NULL;
}
-
+
if (ntype->poll && !ntype->poll(ntype, ntree)) {
BKE_reportf(reports, RPT_ERROR, "Cannot add node of type %s to node tree '%s'", type, ntree->id.name + 2);
return NULL;
}
-
+
node = nodeAddNode(C, ntree, type);
BLI_assert(node && node->typeinfo);
-
+
if (ntree->type == NTREE_TEXTURE) {
ntreeTexCheckCyclics(ntree);
}
-
+
ntreeUpdateTree(CTX_data_main(C), ntree);
nodeUpdate(ntree, node);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
@@ -734,10 +734,10 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r
static void rna_NodeTree_node_remove(bNodeTree *ntree, Main *bmain, ReportList *reports, PointerRNA *node_ptr)
{
bNode *node = node_ptr->data;
-
+
if (!rna_NodeTree_check(ntree, reports))
return;
-
+
if (BLI_findindex(&ntree->nodes, node) == -1) {
BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in node tree", node->name);
return;
@@ -785,7 +785,7 @@ static void rna_NodeTree_active_node_set(PointerRNA *ptr, const PointerRNA value
{
bNodeTree *ntree = (bNodeTree *)ptr->data;
bNode *node = (bNode *)value.data;
-
+
if (node && BLI_findindex(&ntree->nodes, node) != -1)
nodeSetActive(ntree, node);
else
@@ -809,7 +809,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, Main *bmain, ReportLis
*/
if (!fromnode || !tonode)
return NULL;
-
+
if (&fromsock->in_out == &tosock->in_out) {
BKE_report(reports, RPT_ERROR, "Same input/output direction of sockets");
return NULL;
@@ -824,7 +824,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, Main *bmain, ReportLis
}
ret = nodeAddLink(ntree, fromnode, fromsock, tonode, tosock);
-
+
if (ret) {
/* not an issue from the UI, clear hidden from API to keep valid state. */
@@ -897,7 +897,7 @@ static void rna_NodeTree_active_input_set(PointerRNA *ptr, int value)
bNodeTree *ntree = (bNodeTree *)ptr->data;
bNodeSocket *gsock;
int index;
-
+
for (gsock = ntree->inputs.first, index = 0; gsock; gsock = gsock->next, ++index) {
if (index == value)
gsock->flag |= SELECT;
@@ -926,7 +926,7 @@ static void rna_NodeTree_active_output_set(PointerRNA *ptr, int value)
bNodeTree *ntree = (bNodeTree *)ptr->data;
bNodeSocket *gsock;
int index;
-
+
for (gsock = ntree->inputs.first; gsock; gsock = gsock->next) {
gsock->flag &= ~SELECT;
}
@@ -941,30 +941,30 @@ static void rna_NodeTree_active_output_set(PointerRNA *ptr, int value)
static bNodeSocket *rna_NodeTree_inputs_new(bNodeTree *ntree, Main *bmain, ReportList *reports, const char *type, const char *name)
{
bNodeSocket *sock;
-
+
if (!rna_NodeTree_check(ntree, reports))
return NULL;
-
+
sock = ntreeAddSocketInterface(ntree, SOCK_IN, type, name);
-
+
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
-
+
return sock;
}
static bNodeSocket *rna_NodeTree_outputs_new(bNodeTree *ntree, Main *bmain, ReportList *reports, const char *type, const char *name)
{
bNodeSocket *sock;
-
+
if (!rna_NodeTree_check(ntree, reports))
return NULL;
-
+
sock = ntreeAddSocketInterface(ntree, SOCK_OUT, type, name);
-
+
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
-
+
return sock;
}
@@ -972,13 +972,13 @@ static void rna_NodeTree_socket_remove(bNodeTree *ntree, Main *bmain, ReportList
{
if (!rna_NodeTree_check(ntree, reports))
return;
-
+
if (BLI_findindex(&ntree->inputs, sock) == -1 && BLI_findindex(&ntree->outputs, sock) == -1) {
BKE_reportf(reports, RPT_ERROR, "Unable to locate socket '%s' in node", sock->identifier);
}
else {
ntreeRemoveSocketInterface(ntree, sock);
-
+
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -987,10 +987,10 @@ static void rna_NodeTree_socket_remove(bNodeTree *ntree, Main *bmain, ReportList
static void rna_NodeTree_inputs_clear(bNodeTree *ntree, Main *bmain, ReportList *reports)
{
bNodeSocket *sock, *nextsock;
-
+
if (!rna_NodeTree_check(ntree, reports))
return;
-
+
for (sock = ntree->inputs.first; sock; sock = nextsock) {
nextsock = sock->next;
ntreeRemoveSocketInterface(ntree, sock);
@@ -1003,10 +1003,10 @@ static void rna_NodeTree_inputs_clear(bNodeTree *ntree, Main *bmain, ReportList
static void rna_NodeTree_outputs_clear(bNodeTree *ntree, Main *bmain, ReportList *reports)
{
bNodeSocket *sock, *nextsock;
-
+
if (!rna_NodeTree_check(ntree, reports))
return;
-
+
for (sock = ntree->outputs.first; sock; sock = nextsock) {
nextsock = sock->next;
ntreeRemoveSocketInterface(ntree, sock);
@@ -1019,12 +1019,12 @@ static void rna_NodeTree_outputs_clear(bNodeTree *ntree, Main *bmain, ReportList
static void rna_NodeTree_inputs_move(bNodeTree *ntree, Main *bmain, int from_index, int to_index)
{
bNodeSocket *sock;
-
+
if (from_index == to_index)
return;
if (from_index < 0 || to_index < 0)
return;
-
+
sock = BLI_findlink(&ntree->inputs, from_index);
if (to_index < from_index) {
bNodeSocket *nextsock = BLI_findlink(&ntree->inputs, to_index);
@@ -1040,9 +1040,9 @@ static void rna_NodeTree_inputs_move(bNodeTree *ntree, Main *bmain, int from_ind
BLI_insertlinkafter(&ntree->inputs, prevsock, sock);
}
}
-
+
ntree->update |= NTREE_UPDATE_GROUP_IN;
-
+
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1050,12 +1050,12 @@ static void rna_NodeTree_inputs_move(bNodeTree *ntree, Main *bmain, int from_ind
static void rna_NodeTree_outputs_move(bNodeTree *ntree, Main *bmain, int from_index, int to_index)
{
bNodeSocket *sock;
-
+
if (from_index == to_index)
return;
if (from_index < 0 || to_index < 0)
return;
-
+
sock = BLI_findlink(&ntree->outputs, from_index);
if (to_index < from_index) {
bNodeSocket *nextsock = BLI_findlink(&ntree->outputs, to_index);
@@ -1071,9 +1071,9 @@ static void rna_NodeTree_outputs_move(bNodeTree *ntree, Main *bmain, int from_in
BLI_insertlinkafter(&ntree->outputs, prevsock, sock);
}
}
-
+
ntree->update |= NTREE_UPDATE_GROUP_OUT;
-
+
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1084,7 +1084,7 @@ static void rna_NodeTree_interface_update(bNodeTree *ntree, bContext *C)
ntree->update |= NTREE_UPDATE_GROUP;
ntreeUpdateTree(bmain, ntree);
-
+
ED_node_tag_update_nodetree(bmain, ntree, NULL);
}
@@ -1103,7 +1103,7 @@ static int rna_NodeLink_is_hidden_get(PointerRNA *ptr)
static StructRNA *rna_Node_refine(struct PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
-
+
if (node->typeinfo->ext.srna)
return node->typeinfo->ext.srna;
else
@@ -1412,7 +1412,7 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc
if (nt) {
rna_Node_unregister(bmain, nt->ext.srna);
}
-
+
/* create a new node type */
nt = MEM_callocN(sizeof(bNodeType), "node type");
memcpy(nt, &dummynt, sizeof(dummynt));
@@ -1447,7 +1447,7 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc
nt->draw_buttons = (have_function[7]) ? rna_Node_draw_buttons : NULL;
nt->draw_buttons_ex = (have_function[8]) ? rna_Node_draw_buttons_ext : NULL;
nt->labelfunc = (have_function[9]) ? rna_Node_draw_label : NULL;
-
+
/* sanitize size values in case not all have been registered */
if (nt->maxwidth < nt->minwidth)
nt->maxwidth = nt->minwidth;
@@ -1455,7 +1455,7 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc
nt->maxheight = nt->minheight;
CLAMP(nt->width, nt->minwidth, nt->maxwidth);
CLAMP(nt->height, nt->minheight, nt->maxheight);
-
+
return nt;
}
@@ -1467,12 +1467,12 @@ static StructRNA *rna_Node_register(
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_Node, data, identifier, validate, call, free);
if (!nt)
return NULL;
-
+
nodeRegisterType(nt);
-
+
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
-
+
return nt->ext.srna;
}
@@ -1484,12 +1484,12 @@ static StructRNA *rna_ShaderNode_register(
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_ShaderNode, data, identifier, validate, call, free);
if (!nt)
return NULL;
-
+
nodeRegisterType(nt);
-
+
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
-
+
return nt->ext.srna;
}
@@ -1501,12 +1501,12 @@ static StructRNA *rna_CompositorNode_register(
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_CompositorNode, data, identifier, validate, call, free);
if (!nt)
return NULL;
-
+
nodeRegisterType(nt);
-
+
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
-
+
return nt->ext.srna;
}
@@ -1518,24 +1518,24 @@ static StructRNA *rna_TextureNode_register(
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_TextureNode, data, identifier, validate, call, free);
if (!nt)
return NULL;
-
+
nodeRegisterType(nt);
-
+
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
-
+
return nt->ext.srna;
}
static IDProperty *rna_Node_idprops(PointerRNA *ptr, bool create)
{
bNode *node = ptr->data;
-
+
if (create && !node->prop) {
IDPropertyTemplate val = {0};
node->prop = IDP_New(IDP_GROUP, &val, "RNA_Node ID properties");
}
-
+
return node->prop;
}
@@ -1543,19 +1543,19 @@ static void rna_Node_parent_set(PointerRNA *ptr, PointerRNA value)
{
bNode *node = ptr->data;
bNode *parent = value.data;
-
+
if (parent) {
/* XXX only Frame node allowed for now,
* in the future should have a poll function or so to test possible attachment.
*/
if (parent->type != NODE_FRAME)
return;
-
+
/* make sure parent is not attached to the node */
if (nodeAttachNodeCheck(parent, node))
return;
}
-
+
nodeDetachNode(node);
if (parent) {
nodeAttachNode(node, parent);
@@ -1566,17 +1566,17 @@ static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value)
{
bNode *node = ptr->data;
bNode *parent = value.data;
-
+
/* XXX only Frame node allowed for now,
* in the future should have a poll function or so to test possible attachment.
*/
if (parent->type != NODE_FRAME)
return false;
-
+
/* make sure parent is not attached to the node */
if (nodeAttachNodeCheck(parent, node))
return false;
-
+
return true;
}
@@ -1603,14 +1603,14 @@ static void rna_Node_name_set(PointerRNA *ptr, const char *value)
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
bNode *node = (bNode *)ptr->data;
char oldname[sizeof(node->name)];
-
+
/* make a copy of the old name first */
BLI_strncpy(oldname, node->name, sizeof(node->name));
/* set new name */
BLI_strncpy_utf8(node->name, value, sizeof(node->name));
-
+
nodeUniqueName(ntree, node);
-
+
/* fix all the animation data which may link to this */
BKE_animdata_fix_paths_rename_all(NULL, "nodes", oldname, node->name);
}
@@ -1619,9 +1619,9 @@ static bNodeSocket *rna_Node_inputs_new(ID *id, bNode *node, Main *bmain, Report
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
-
+
sock = nodeAddSocket(ntree, node, SOCK_IN, type, identifier, name);
-
+
if (sock == NULL) {
BKE_report(reports, RPT_ERROR, "Unable to create socket");
}
@@ -1629,7 +1629,7 @@ static bNodeSocket *rna_Node_inputs_new(ID *id, bNode *node, Main *bmain, Report
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-
+
return sock;
}
@@ -1637,9 +1637,9 @@ static bNodeSocket *rna_Node_outputs_new(ID *id, bNode *node, Main *bmain, Repor
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
-
+
sock = nodeAddSocket(ntree, node, SOCK_OUT, type, identifier, name);
-
+
if (sock == NULL) {
BKE_report(reports, RPT_ERROR, "Unable to create socket");
}
@@ -1647,20 +1647,20 @@ static bNodeSocket *rna_Node_outputs_new(ID *id, bNode *node, Main *bmain, Repor
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-
+
return sock;
}
static void rna_Node_socket_remove(ID *id, bNode *node, Main *bmain, ReportList *reports, bNodeSocket *sock)
{
bNodeTree *ntree = (bNodeTree *)id;
-
+
if (BLI_findindex(&node->inputs, sock) == -1 && BLI_findindex(&node->outputs, sock) == -1) {
BKE_reportf(reports, RPT_ERROR, "Unable to locate socket '%s' in node", sock->identifier);
}
else {
nodeRemoveSocket(ntree, node, sock);
-
+
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1670,7 +1670,7 @@ static void rna_Node_inputs_clear(ID *id, bNode *node, Main *bmain)
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock, *nextsock;
-
+
for (sock = node->inputs.first; sock; sock = nextsock) {
nextsock = sock->next;
nodeRemoveSocket(ntree, node, sock);
@@ -1684,7 +1684,7 @@ static void rna_Node_outputs_clear(ID *id, bNode *node, Main *bmain)
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock, *nextsock;
-
+
for (sock = node->outputs.first; sock; sock = nextsock) {
nextsock = sock->next;
nodeRemoveSocket(ntree, node, sock);
@@ -1698,12 +1698,12 @@ static void rna_Node_inputs_move(ID *id, bNode *node, Main *bmain, int from_inde
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
-
+
if (from_index == to_index)
return;
if (from_index < 0 || to_index < 0)
return;
-
+
sock = BLI_findlink(&node->inputs, from_index);
if (to_index < from_index) {
bNodeSocket *nextsock = BLI_findlink(&node->inputs, to_index);
@@ -1719,7 +1719,7 @@ static void rna_Node_inputs_move(ID *id, bNode *node, Main *bmain, int from_inde
BLI_insertlinkafter(&node->inputs, prevsock, sock);
}
}
-
+
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1728,12 +1728,12 @@ static void rna_Node_outputs_move(ID *id, bNode *node, Main *bmain, int from_ind
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
-
+
if (from_index == to_index)
return;
if (from_index < 0 || to_index < 0)
return;
-
+
sock = BLI_findlink(&node->outputs, from_index);
if (to_index < from_index) {
bNodeSocket *nextsock = BLI_findlink(&node->outputs, to_index);
@@ -1749,7 +1749,7 @@ static void rna_Node_outputs_move(ID *id, bNode *node, Main *bmain, int from_ind
BLI_insertlinkafter(&node->outputs, prevsock, sock);
}
}
-
+
ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -1825,7 +1825,7 @@ static void rna_NodeSocket_unregister(Main *UNUSED(bmain), StructRNA *type)
bNodeSocketType *st = RNA_struct_blender_type_get(type);
if (!st)
return;
-
+
RNA_struct_free_extension(type, &st->ext_socket);
RNA_struct_free(&BLENDER_RNA, type);
@@ -1847,7 +1847,7 @@ static StructRNA *rna_NodeSocket_register(
/* setup dummy socket & socket type to store static properties in */
memset(&dummyst, 0, sizeof(bNodeSocketType));
-
+
memset(&dummysock, 0, sizeof(bNodeSocket));
dummysock.typeinfo = &dummyst;
RNA_pointer_create(NULL, &RNA_NodeSocket, &dummysock, &dummyptr);
@@ -1855,7 +1855,7 @@ static StructRNA *rna_NodeSocket_register(
/* validate the python class */
if (validate(&dummyptr, data, have_function) != 0)
return NULL;
-
+
if (strlen(identifier) >= sizeof(dummyst.idname)) {
BKE_reportf(reports, RPT_ERROR, "Registering node socket class: '%s' is too long, maximum length is %d",
identifier, (int)sizeof(dummyst.idname));
@@ -1868,22 +1868,22 @@ static StructRNA *rna_NodeSocket_register(
/* create a new node socket type */
st = MEM_callocN(sizeof(bNodeSocketType), "node socket type");
memcpy(st, &dummyst, sizeof(dummyst));
-
+
nodeRegisterSocketType(st);
}
-
+
/* if RNA type is already registered, unregister first */
if (st->ext_socket.srna) {
StructRNA *srna = st->ext_socket.srna;
RNA_struct_free_extension(srna, &st->ext_socket);
RNA_struct_free(&BLENDER_RNA, srna);
}
- st->ext_socket.srna = RNA_def_struct_ptr(&BLENDER_RNA, st->idname, &RNA_NodeSocket);
+ st->ext_socket.srna = RNA_def_struct_ptr(&BLENDER_RNA, st->idname, &RNA_NodeSocket);
st->ext_socket.data = data;
st->ext_socket.call = call;
st->ext_socket.free = free;
RNA_struct_blender_type_set(st->ext_socket.srna, st);
-
+
/* XXX bad level call! needed to initialize the basic draw functions ... */
ED_init_custom_node_socket_type(st);
@@ -1892,14 +1892,14 @@ static StructRNA *rna_NodeSocket_register(
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
-
+
return st->ext_socket.srna;
}
static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
-
+
if (sock->typeinfo->ext_socket.srna)
return sock->typeinfo->ext_socket.srna;
else
@@ -1913,10 +1913,10 @@ static char *rna_NodeSocket_path(PointerRNA *ptr)
bNode *node;
int socketindex;
char name_esc[sizeof(node->name) * 2];
-
+
if (!nodeFindNode(ntree, sock, &node, &socketindex))
return NULL;
-
+
BLI_strescape(name_esc, node->name, sizeof(name_esc));
if (sock->in_out == SOCK_IN) {
@@ -1930,12 +1930,12 @@ static char *rna_NodeSocket_path(PointerRNA *ptr)
static IDProperty *rna_NodeSocket_idprops(PointerRNA *ptr, bool create)
{
bNodeSocket *sock = ptr->data;
-
+
if (create && !sock->prop) {
IDPropertyTemplate val = {0};
sock->prop = IDP_New(IDP_GROUP, &val, "RNA_NodeSocket ID properties");
}
-
+
return sock->prop;
}
@@ -1945,9 +1945,9 @@ static PointerRNA rna_NodeSocket_node_get(PointerRNA *ptr)
bNodeSocket *sock = (bNodeSocket *)ptr->data;
bNode *node;
PointerRNA r_ptr;
-
+
nodeFindNode(ntree, sock, &node, NULL);
-
+
RNA_pointer_create((ID *)ntree, &RNA_Node, node, &r_ptr);
return r_ptr;
}
@@ -1977,11 +1977,11 @@ static void rna_NodeSocket_link_limit_set(PointerRNA *ptr, int value)
static void rna_NodeSocket_hide_set(PointerRNA *ptr, int value)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
-
+
/* don't hide linked sockets */
if (sock->flag & SOCK_IN_USE)
return;
-
+
if (value)
sock->flag |= SOCK_HIDDEN;
else
@@ -2109,11 +2109,11 @@ static void rna_NodeSocketInterface_unregister(Main *UNUSED(bmain), StructRNA *t
bNodeSocketType *st = RNA_struct_blender_type_get(type);
if (!st)
return;
-
+
RNA_struct_free_extension(type, &st->ext_interface);
-
+
RNA_struct_free(&BLENDER_RNA, type);
-
+
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
}
@@ -2129,7 +2129,7 @@ static StructRNA *rna_NodeSocketInterface_register(
/* setup dummy socket & socket type to store static properties in */
memset(&dummyst, 0, sizeof(bNodeSocketType));
-
+
memset(&dummysock, 0, sizeof(bNodeSocket));
dummysock.typeinfo = &dummyst;
RNA_pointer_create(NULL, &RNA_NodeSocketInterface, &dummysock, &dummyptr);
@@ -2147,38 +2147,38 @@ static StructRNA *rna_NodeSocketInterface_register(
/* create a new node socket type */
st = MEM_callocN(sizeof(bNodeSocketType), "node socket type");
memcpy(st, &dummyst, sizeof(dummyst));
-
+
nodeRegisterSocketType(st);
}
-
+
/* if RNA type is already registered, unregister first */
if (st->ext_interface.srna) {
StructRNA *srna = st->ext_interface.srna;
RNA_struct_free_extension(srna, &st->ext_interface);
RNA_struct_free(&BLENDER_RNA, srna);
}
- st->ext_interface.srna = RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_NodeSocketInterface);
+ st->ext_interface.srna = RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_NodeSocketInterface);
st->ext_interface.data = data;
st->ext_interface.call = call;
st->ext_interface.free = free;
RNA_struct_blender_type_set(st->ext_interface.srna, st);
-
+
st->interface_draw = (have_function[0]) ? rna_NodeSocketInterface_draw : NULL;
st->interface_draw_color = (have_function[1]) ? rna_NodeSocketInterface_draw_color : NULL;
st->interface_register_properties = (have_function[2]) ? rna_NodeSocketInterface_register_properties : NULL;
st->interface_init_socket = (have_function[3]) ? rna_NodeSocketInterface_init_socket : NULL;
st->interface_from_socket = (have_function[4]) ? rna_NodeSocketInterface_from_socket : NULL;
-
+
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
-
+
return st->ext_interface.srna;
}
static StructRNA *rna_NodeSocketInterface_refine(PointerRNA *ptr)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
-
+
if (sock->typeinfo && sock->typeinfo->ext_interface.srna)
return sock->typeinfo->ext_interface.srna;
else
@@ -2190,27 +2190,27 @@ static char *rna_NodeSocketInterface_path(PointerRNA *ptr)
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
bNodeSocket *sock = (bNodeSocket *)ptr->data;
int socketindex;
-
+
socketindex = BLI_findindex(&ntree->inputs, sock);
if (socketindex != -1)
return BLI_sprintfN("inputs[%d]", socketindex);
-
+
socketindex = BLI_findindex(&ntree->outputs, sock);
if (socketindex != -1)
return BLI_sprintfN("outputs[%d]", socketindex);
-
+
return NULL;
}
static IDProperty *rna_NodeSocketInterface_idprops(PointerRNA *ptr, bool create)
{
bNodeSocket *sock = ptr->data;
-
+
if (create && !sock->prop) {
IDPropertyTemplate val = {0};
sock->prop = IDP_New(IDP_GROUP, &val, "RNA_NodeSocketInterface ID properties");
}
-
+
return sock->prop;
}
@@ -2218,13 +2218,13 @@ static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), Po
{
bNodeTree *ntree = ptr->id.data;
bNodeSocket *stemp = ptr->data;
-
+
if (!stemp->typeinfo)
return;
-
+
ntree->update |= NTREE_UPDATE_GROUP;
ntreeUpdateTree(bmain, ntree);
-
+
ED_node_tag_update_nodetree(bmain, ntree, NULL);
}
@@ -2265,11 +2265,11 @@ static void rna_NodeSocketStandard_float_range(PointerRNA *ptr, float *min, floa
bNodeSocket *sock = ptr->data;
bNodeSocketValueFloat *dval = sock->default_value;
int subtype = sock->typeinfo->subtype;
-
+
if (dval->max < dval->min) {
dval->max = dval->min;
}
-
+
*min = (subtype == PROP_UNSIGNED ? 0.0f : -FLT_MAX);
*max = FLT_MAX;
*softmin = dval->min;
@@ -2281,11 +2281,11 @@ static void rna_NodeSocketStandard_int_range(PointerRNA *ptr, int *min, int *max
bNodeSocket *sock = ptr->data;
bNodeSocketValueInt *dval = sock->default_value;
int subtype = sock->typeinfo->subtype;
-
+
if (dval->max < dval->min) {
dval->max = dval->min;
}
-
+
*min = (subtype == PROP_UNSIGNED ? 0 : INT_MIN);
*max = INT_MAX;
*softmin = dval->min;
@@ -2296,49 +2296,31 @@ static void rna_NodeSocketStandard_vector_range(PointerRNA *ptr, float *min, flo
{
bNodeSocket *sock = ptr->data;
bNodeSocketValueVector *dval = sock->default_value;
-
+
if (dval->max < dval->min) {
dval->max = dval->min;
}
-
+
*min = -FLT_MAX;
*max = FLT_MAX;
*softmin = dval->min;
*softmax = dval->max;
}
-static void rna_NodeSocket_value_update(Main *bmain, Scene *scene, PointerRNA *ptr)
-{
- bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- bNodeSocket *sock = ptr->data;
-
- if (ntree->type == NTREE_SHADER) {
- DEG_id_tag_update_ex(bmain, &ntree->id, DEG_TAG_SHADING_UPDATE);
- WM_main_add_notifier(NC_MATERIAL | ND_SHADING, NULL);
-
- if (sock->type == SOCK_STRING) {
- rna_NodeSocket_update(bmain, scene, ptr);
- }
- }
- else {
- rna_NodeSocket_update(bmain, scene, ptr);
- }
-}
-
/* using a context update function here, to avoid searching the node if possible */
static void rna_NodeSocketStandard_value_update(struct bContext *C, PointerRNA *ptr)
{
bNode *node;
-
+
/* default update */
- rna_NodeSocket_value_update(CTX_data_main(C), CTX_data_scene(C), ptr);
-
+ rna_NodeSocket_update(CTX_data_main(C), CTX_data_scene(C), ptr);
+
/* try to use node from context, faster */
node = CTX_data_pointer_get(C, "node").data;
if (!node) {
bNodeTree *ntree = ptr->id.data;
bNodeSocket *sock = ptr->data;
-
+
/* fall back to searching node in the tree */
nodeFindNode(ntree, sock, &node, NULL);
}
@@ -2471,15 +2453,15 @@ static StructRNA *rna_NodeCustomGroup_register(
bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_NodeCustomGroup, data, identifier, validate, call, free);
if (!nt)
return NULL;
-
+
/* this updates the group node instance from the tree's interface */
nt->verifyfunc = node_group_verify;
-
+
nodeRegisterType(nt);
-
+
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
-
+
return nt->ext.srna;
}
@@ -2501,10 +2483,10 @@ static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
bNode *node = (bNode *)ptr->data;
-
+
if (node->id)
ntreeUpdateTree(bmain, (bNodeTree *)node->id);
-
+
ED_node_tag_update_nodetree(bmain, ntree, node);
}
@@ -2513,13 +2495,13 @@ static void rna_NodeGroup_node_tree_set(PointerRNA *ptr, const PointerRNA value)
bNodeTree *ntree = ptr->id.data;
bNode *node = ptr->data;
bNodeTree *ngroup = value.data;
-
+
if (nodeGroupPoll(ntree, ngroup)) {
if (node->id)
id_us_min(node->id);
if (ngroup)
id_us_plus(&ngroup->id);
-
+
node->id = &ngroup->id;
}
}
@@ -2528,11 +2510,11 @@ static int rna_NodeGroup_node_tree_poll(PointerRNA *ptr, const PointerRNA value)
{
bNodeTree *ntree = ptr->id.data;
bNodeTree *ngroup = value.data;
-
+
/* only allow node trees of the same type as the group node's tree */
if (ngroup->type != ntree->type)
return false;
-
+
return nodeGroupPoll(ntree, ngroup);
}
@@ -2553,7 +2535,7 @@ static StructRNA *rna_NodeGroup_interface_typef(PointerRNA *ptr)
static StructRNA *rna_NodeGroupInputOutput_interface_typef(PointerRNA *ptr)
{
bNodeTree *ntree = ptr->id.data;
-
+
if (ntree) {
StructRNA *srna = ntreeInterfaceTypeGet(ntree, true);
if (srna)
@@ -2599,10 +2581,10 @@ static void rna_Matte_t1_set(PointerRNA *ptr, float value)
{
bNode *node = (bNode *)ptr->data;
NodeChroma *chroma = node->storage;
-
+
chroma->t1 = value;
-
- if (value < chroma->t2)
+
+ if (value < chroma->t2)
chroma->t2 = value;
}
@@ -2610,10 +2592,10 @@ static void rna_Matte_t2_set(PointerRNA *ptr, float value)
{
bNode *node = (bNode *)ptr->data;
NodeChroma *chroma = node->storage;
-
- if (value > chroma->t1)
+
+ if (value > chroma->t1)
value = chroma->t1;
-
+
chroma->t2 = value;
}
@@ -2636,10 +2618,10 @@ static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *p
bNode *node = (bNode *)ptr->data;
Image *ima = (Image *)node->id;
ImageUser *iuser = node->storage;
-
+
BKE_image_multilayer_index(ima->rr, iuser);
BKE_image_signal(ima, iuser, IMA_SIGNAL_SRC_CHANGE);
-
+
rna_Node_update(bmain, scene, ptr);
if (scene->nodetree != NULL) {
@@ -2794,7 +2776,7 @@ static const EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), Point
EnumPropertyItem *item = NULL;
EnumPropertyItem tmp = {0};
int totitem = 0;
-
+
switch (node->custom1) {
case CMP_NODE_CHANNEL_MATTE_CS_RGB:
tmp.identifier = "R"; tmp.name = "R"; tmp.value = 1;
@@ -2834,7 +2816,7 @@ static const EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), Point
RNA_enum_item_end(&item, &totitem);
*r_free = true;
-
+
return item;
}
@@ -2894,7 +2876,7 @@ static int rna_NodeOutputFileSocket_find_node(bNodeTree *ntree, NodeImageMultiFi
{
bNode *node;
bNodeSocket *sock;
-
+
for (node = ntree->nodes.first; node; node = node->next) {
for (sock = node->inputs.first; sock; sock = sock->next) {
NodeImageMultiFileSocket *sockdata = sock->storage;
@@ -2905,7 +2887,7 @@ static int rna_NodeOutputFileSocket_find_node(bNodeTree *ntree, NodeImageMultiFi
}
}
}
-
+
*nodep = NULL;
*sockp = NULL;
return 0;
@@ -2917,7 +2899,7 @@ static void rna_NodeOutputFileSlotFile_path_set(PointerRNA *ptr, const char *val
NodeImageMultiFileSocket *sockdata = ptr->data;
bNode *node;
bNodeSocket *sock;
-
+
if (rna_NodeOutputFileSocket_find_node(ntree, sockdata, &node, &sock)) {
ntreeCompositOutputFileSetPath(node, sock, value);
}
@@ -2929,7 +2911,7 @@ static void rna_NodeOutputFileSlotLayer_name_set(PointerRNA *ptr, const char *va
NodeImageMultiFileSocket *sockdata = ptr->data;
bNode *node;
bNodeSocket *sock;
-
+
if (rna_NodeOutputFileSocket_find_node(ntree, sockdata, &node, &sock)) {
ntreeCompositOutputFileSetLayer(node, sock, value);
}
@@ -2943,12 +2925,12 @@ static bNodeSocket *rna_NodeOutputFile_slots_new(ID *id, bNode *node, bContext *
bNodeSocket *sock;
if (scene)
im_format = &scene->r.im_format;
-
+
sock = ntreeCompositOutputFileAddSocket(ntree, node, name, im_format);
-
+
ntreeUpdateTree(CTX_data_main(C), ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
-
+
return sock;
}
@@ -2967,7 +2949,7 @@ static void rna_ShaderNodeTexIES_mode_set(PointerRNA *ptr, int value)
if (value == NODE_IES_EXTERNAL && text->name) {
BLI_strncpy(nss->filepath, text->name, sizeof(nss->filepath));
- BLI_path_rel(nss->filepath, G.main->name);
+ BLI_path_rel(nss->filepath, BKE_main_blendfile_path_from_global());
}
id_us_min(node->id);
@@ -2992,7 +2974,7 @@ static void rna_ShaderNodeScript_mode_set(PointerRNA *ptr, int value)
if (value == NODE_SCRIPT_EXTERNAL && text->name) {
BLI_strncpy(nss->filepath, text->name, sizeof(nss->filepath));
- BLI_path_rel(nss->filepath, G.main->name);
+ BLI_path_rel(nss->filepath, BKE_main_blendfile_path_from_global());
}
id_us_min(node->id);
@@ -3342,7 +3324,7 @@ static const EnumPropertyItem node_subsurface_method_items[] = {
static void def_group_input(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "interface", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_NodeGroupInputOutput_interface_typef", NULL);
RNA_def_property_struct_type(prop, "PropertyGroup");
@@ -3353,13 +3335,13 @@ static void def_group_input(StructRNA *srna)
static void def_group_output(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "interface", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_NodeGroupInputOutput_interface_typef", NULL);
RNA_def_property_struct_type(prop, "PropertyGroup");
RNA_def_property_flag(prop, PROP_IDPROPERTY);
RNA_def_property_ui_text(prop, "Interface", "Interface socket data");
-
+
prop = RNA_def_property(srna, "is_active_output", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_DO_OUTPUT);
RNA_def_property_ui_text(prop, "Active Output", "True if this node is used as the active group output");
@@ -3369,7 +3351,7 @@ static void def_group_output(StructRNA *srna)
static void def_group(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_struct_type(prop, "NodeTree");
@@ -3388,7 +3370,7 @@ static void def_group(StructRNA *srna)
static void def_custom_group(BlenderRNA *brna)
{
StructRNA *srna;
-
+
srna = RNA_def_struct(brna, "NodeCustomGroup", "Node");
RNA_def_struct_ui_text(srna, "Custom Group", "Base node type for custom registered node group types");
RNA_def_struct_sdna(srna, "bNode");
@@ -3400,8 +3382,8 @@ static void def_custom_group(BlenderRNA *brna)
static void def_frame(StructRNA *srna)
{
- PropertyRNA *prop;
-
+ PropertyRNA *prop;
+
prop = RNA_def_property(srna, "text", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_struct_type(prop, "Text");
@@ -3411,7 +3393,7 @@ static void def_frame(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeFrame", "storage");
RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_ID_NODETREE);
-
+
prop = RNA_def_property(srna, "shrink", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_FRAME_SHRINK);
RNA_def_property_ui_text(prop, "Shrink", "Shrink the frame to minimal bounding box");
@@ -3427,7 +3409,7 @@ static void def_frame(StructRNA *srna)
static void def_math(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_enum_node_math_items);
@@ -3443,7 +3425,7 @@ static void def_math(StructRNA *srna)
static void def_vector_math(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_enum_node_vec_math_items);
@@ -3454,7 +3436,7 @@ static void def_vector_math(StructRNA *srna)
static void def_rgb_curve(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "mapping", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "CurveMapping");
@@ -3465,7 +3447,7 @@ static void def_rgb_curve(StructRNA *srna)
static void def_vector_curve(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "mapping", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "CurveMapping");
@@ -3476,18 +3458,18 @@ static void def_vector_curve(StructRNA *srna)
static void def_time(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "CurveMapping");
RNA_def_property_ui_text(prop, "Curve", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_ui_text(prop, "Start Frame", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
RNA_def_property_ui_text(prop, "End Frame", "");
@@ -3497,7 +3479,7 @@ static void def_time(StructRNA *srna)
static void def_colorramp(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "ColorRamp");
@@ -3508,13 +3490,13 @@ static void def_colorramp(StructRNA *srna)
static void def_mix_rgb(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_enum_ramp_blend_items);
RNA_def_property_ui_text(prop, "Blend Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_MIXRGB_USE_ALPHA);
RNA_def_property_ui_text(prop, "Alpha", "Include alpha of second input in this operation");
@@ -3529,14 +3511,14 @@ static void def_mix_rgb(StructRNA *srna)
static void def_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);
RNA_def_property_ui_text(prop, "Texture", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "node_output", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_ui_text(prop, "Node Output", "For node-based textures, which output node to use");
@@ -3549,7 +3531,7 @@ static void def_texture(StructRNA *srna)
static void def_sh_output(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "is_active_output", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_DO_OUTPUT);
RNA_def_property_ui_text(prop, "Active Output", "True if this node is used as the active output");
@@ -3575,7 +3557,7 @@ static void def_sh_mapping(StructRNA *srna)
static float default_1[3] = {1.f, 1.f, 1.f};
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "TexMapping", "storage");
prop = RNA_def_property(srna, "vector_type", PROP_ENUM, PROP_NONE);
@@ -3588,36 +3570,36 @@ static void def_sh_mapping(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_ui_text(prop, "Location", "");
RNA_def_property_update(prop, 0, "rna_Mapping_Node_update");
-
+
/* Not PROP_XYZ, this is now in radians, no more degrees */
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "rot");
RNA_def_property_ui_text(prop, "Rotation", "");
RNA_def_property_update(prop, 0, "rna_Mapping_Node_update");
-
+
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_float_array_default(prop, default_1);
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
RNA_def_property_ui_text(prop, "Scale", "");
RNA_def_property_update(prop, 0, "rna_Mapping_Node_update");
-
+
prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Minimum", "Minimum value for clipping");
RNA_def_property_update(prop, 0, "rna_Mapping_Node_update");
-
+
prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_float_array_default(prop, default_1);
RNA_def_property_ui_text(prop, "Maximum", "Maximum value for clipping");
RNA_def_property_update(prop, 0, "rna_Mapping_Node_update");
-
+
prop = RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN);
RNA_def_property_ui_text(prop, "Has Minimum", "Whether to use minimum clipping value");
RNA_def_property_update(prop, 0, "rna_Mapping_Node_update");
-
+
prop = RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX);
RNA_def_property_ui_text(prop, "Has Maximum", "Whether to use maximum clipping value");
@@ -3627,9 +3609,9 @@ static void def_sh_mapping(StructRNA *srna)
static void def_sh_attribute(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeShaderAttribute", "storage");
-
+
prop = RNA_def_property(srna, "attribute_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Attribute Name", "");
@@ -3659,9 +3641,9 @@ static void def_sh_tex_sky(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
static float default_dir[3] = {0.0f, 0.0f, 1.0f};
-
+
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeTexSky", "storage");
def_sh_tex(srna);
@@ -3670,19 +3652,19 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_enum_items(prop, prop_sky_type);
RNA_def_property_ui_text(prop, "Sky Type", "");
RNA_def_property_update(prop, 0, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "sun_direction", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_ui_text(prop, "Sun Direction", "Direction from where the sun is shining");
RNA_def_property_array(prop, 3);
RNA_def_property_float_array_default(prop, default_dir);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "turbidity", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 1.0f, 10.0f);
RNA_def_property_ui_range(prop, 1.0f, 10.0f, 10, 3);
RNA_def_property_ui_text(prop, "Turbidity", "Atmospheric turbidity");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "ground_albedo", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Ground Albedo", "Ground color that is subtly reflected in the sky");
@@ -3837,7 +3819,7 @@ static void def_sh_tex_gradient(StructRNA *srna)
};
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeTexGradient", "storage");
def_sh_tex(srna);
@@ -3862,44 +3844,44 @@ static void def_sh_tex_checker(StructRNA *srna)
static void def_sh_tex_brick(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeTexBrick", "storage");
def_sh_tex(srna);
-
+
prop = RNA_def_property(srna, "offset_frequency", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "offset_freq");
RNA_def_property_int_default(prop, 2);
RNA_def_property_range(prop, 1, 99);
RNA_def_property_ui_text(prop, "Offset Frequency", "");
RNA_def_property_update(prop, 0, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "squash_frequency", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "squash_freq");
RNA_def_property_int_default(prop, 2);
RNA_def_property_range(prop, 1, 99);
RNA_def_property_ui_text(prop, "Squash Frequency", "");
RNA_def_property_update(prop, 0, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "offset");
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Offset Amount", "");
RNA_def_property_update(prop, 0, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "squash", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "squash");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0.0f, 99.0f);
RNA_def_property_ui_text(prop, "Squash Amount", "");
RNA_def_property_update(prop, 0, "rna_Node_update");
-
+
}
static void def_sh_tex_magic(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeTexMagic", "storage");
def_sh_tex(srna);
@@ -3922,7 +3904,7 @@ static void def_sh_tex_musgrave(StructRNA *srna)
};
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeTexMusgrave", "storage");
def_sh_tex(srna);
@@ -3942,7 +3924,7 @@ static void def_sh_tex_voronoi(StructRNA *srna)
};
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeTexVoronoi", "storage");
def_sh_tex(srna);
@@ -3968,7 +3950,7 @@ static void def_sh_tex_wave(StructRNA *srna)
};
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeTexWave", "storage");
def_sh_tex(srna);
@@ -4019,20 +4001,20 @@ static void def_sh_vect_transform(StructRNA *srna)
};
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeShaderVectTransform", "storage");
-
+
prop = RNA_def_property(srna, "vector_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, prop_vect_type_items);
RNA_def_property_ui_text(prop, "Type", "");
RNA_def_property_update(prop, 0, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "convert_from", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_vect_space_items);
RNA_def_property_ui_text(prop, "Convert From", "Space to convert from");
RNA_def_property_update(prop, 0, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "convert_to", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_vect_space_items);
RNA_def_property_ui_text(prop, "Convert To", "Space to convert to");
@@ -4042,7 +4024,7 @@ static void def_sh_vect_transform(StructRNA *srna)
static void def_sh_tex_wireframe(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "use_pixel_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
RNA_def_property_ui_text(prop, "Pixel Size", "Use screen pixel size instead of world units");
@@ -4185,7 +4167,7 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
static void def_glossy(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_glossy_items);
@@ -4196,7 +4178,7 @@ static void def_glossy(StructRNA *srna)
static void def_glass(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_glass_items);
@@ -4224,7 +4206,7 @@ static void def_principled(StructRNA *srna)
static void def_refraction(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_refraction_items);
@@ -4235,7 +4217,7 @@ static void def_refraction(StructRNA *srna)
static void def_anisotropic(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_anisotropic_items);
@@ -4246,7 +4228,7 @@ static void def_anisotropic(StructRNA *srna)
static void def_toon(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "component", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_toon_items);
@@ -4257,7 +4239,7 @@ static void def_toon(StructRNA *srna)
static void def_sh_bump(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
RNA_def_property_ui_text(prop, "Invert", "Invert the bump mapping direction to push into the surface instead of out");
@@ -4267,7 +4249,7 @@ static void def_sh_bump(StructRNA *srna)
static void def_hair(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "component", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_hair_items);
@@ -4427,7 +4409,7 @@ static void def_sh_subsurface(StructRNA *srna)
};
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "falloff", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, prop_subsurface_falloff_items);
@@ -4471,9 +4453,9 @@ static void def_sh_script(StructRNA *srna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Script", "Internal shader script to define the shader");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodeScript_update");
-
+
RNA_def_struct_sdna_from(srna, "NodeShaderScript", "storage");
-
+
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
RNA_def_property_ui_text(prop, "File Path", "Shader script path");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodeScript_update");
@@ -4488,7 +4470,7 @@ static void def_sh_script(StructRNA *srna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_SCRIPT_AUTO_UPDATE);
RNA_def_property_ui_text(prop, "Auto Update",
"Automatically update the shader when the .osl file changes (external scripts only)");
-
+
prop = RNA_def_property(srna, "bytecode", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_ShaderNodeScript_bytecode_get", "rna_ShaderNodeScript_bytecode_length",
"rna_ShaderNodeScript_bytecode_set");
@@ -4501,7 +4483,7 @@ static void def_sh_script(StructRNA *srna)
/* needs to be reset to avoid bad pointer type in API functions below */
RNA_def_struct_sdna_from(srna, "bNode", NULL);
-
+
/* API functions */
#if 0 /* XXX TODO use general node api for this */
@@ -4512,7 +4494,7 @@ static void def_sh_script(StructRNA *srna)
/*parm =*/ RNA_def_boolean(func, "is_output", false, "Output", "Whether the socket is an output");
parm = RNA_def_pointer(func, "result", "NodeSocket", "", "");
RNA_def_function_return(func, parm);
-
+
func = RNA_def_function(srna, "add_socket", "rna_ShaderNodeScript_add_socket");
RNA_def_function_ui_description(func, "Add a socket socket");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
@@ -4523,7 +4505,7 @@ static void def_sh_script(StructRNA *srna)
/*parm =*/ RNA_def_boolean(func, "is_output", false, "Output", "Whether the socket is an output");
parm = RNA_def_pointer(func, "result", "NodeSocket", "", "");
RNA_def_function_return(func, parm);
-
+
func = RNA_def_function(srna, "remove_socket", "rna_ShaderNodeScript_remove_socket");
RNA_def_function_ui_description(func, "Remove a socket socket");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
@@ -4537,15 +4519,15 @@ static void def_sh_script(StructRNA *srna)
static void def_cmp_alpha_over(StructRNA *srna)
{
PropertyRNA *prop;
-
+
/* XXX: Tooltip */
prop = RNA_def_property(srna, "use_premultiply", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
RNA_def_property_ui_text(prop, "Convert Premul", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
RNA_def_struct_sdna_from(srna, "NodeTwoFloats", "storage");
-
+
prop = RNA_def_property(srna, "premul", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "x");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -4556,7 +4538,7 @@ static void def_cmp_alpha_over(StructRNA *srna)
static void def_cmp_blur(StructRNA *srna)
{
PropertyRNA *prop;
-
+
static const EnumPropertyItem filter_type_items[] = {
{R_FILTER_BOX, "FLAT", 0, "Flat", ""},
{R_FILTER_TENT, "TENT", 0, "Tent", ""},
@@ -4588,13 +4570,13 @@ static void def_cmp_blur(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
RNA_def_struct_sdna_from(srna, "NodeBlurData", "storage");
-
+
prop = RNA_def_property(srna, "size_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "sizex");
RNA_def_property_range(prop, 0, 2048);
RNA_def_property_ui_text(prop, "Size X", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "size_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "sizey");
RNA_def_property_range(prop, 0, 2048);
@@ -4605,7 +4587,7 @@ static void def_cmp_blur(StructRNA *srna)
RNA_def_property_boolean_sdna(prop, NULL, "relative", 1);
RNA_def_property_ui_text(prop, "Relative", "Use relative (percent) values to define blur radius");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "aspect_correction", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "aspect");
RNA_def_property_enum_items(prop, aspect_correction_type_items);
@@ -4617,30 +4599,30 @@ static void def_cmp_blur(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 2.0f);
RNA_def_property_ui_text(prop, "Factor", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "factor_x", PROP_FLOAT, PROP_PERCENTAGE);
RNA_def_property_float_sdna(prop, NULL, "percentx");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Relative Size X", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "factor_y", PROP_FLOAT, PROP_PERCENTAGE);
RNA_def_property_float_sdna(prop, NULL, "percenty");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Relative Size Y", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "filtertype");
RNA_def_property_enum_items(prop, filter_type_items);
RNA_def_property_ui_text(prop, "Filter Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_bokeh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bokeh", 1);
RNA_def_property_ui_text(prop, "Bokeh", "Use circular filter (slower)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_gamma_correction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gamma", 1);
RNA_def_property_ui_text(prop, "Gamma", "Apply filter on gamma corrected values");
@@ -4661,40 +4643,40 @@ static void def_cmp_filter(StructRNA *srna)
static void def_cmp_map_value(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "TexMapping", "storage");
-
+
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_array(prop, 1);
RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Offset", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_array(prop, 1);
RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Size", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN);
RNA_def_property_ui_text(prop, "Use Minimum", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX);
RNA_def_property_ui_text(prop, "Use Maximum", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_array(prop, 1);
RNA_def_property_range(prop, -1000.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Minimum", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_array(prop, 1);
@@ -4706,7 +4688,7 @@ static void def_cmp_map_value(StructRNA *srna)
static void def_cmp_map_range(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range");
@@ -4716,28 +4698,28 @@ static void def_cmp_map_range(StructRNA *srna)
static void def_cmp_vector_blur(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeBlurData", "storage");
-
+
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samples");
RNA_def_property_range(prop, 1, 256);
RNA_def_property_ui_text(prop, "Samples", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "speed_min", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "minspeed");
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_text(prop, "Min Speed",
"Minimum speed for a pixel to be blurred (used to separate background from foreground)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "speed_max", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "maxspeed");
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_ui_text(prop, "Max Speed", "Maximum speed, or zero for none");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fac");
RNA_def_property_range(prop, 0.0, 20.0);
@@ -4745,7 +4727,7 @@ static void def_cmp_vector_blur(StructRNA *srna)
RNA_def_property_ui_text(prop, "Blur Factor",
"Scaling factor for motion vectors (actually, 'shutter speed', in frames)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_curved", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "curved", 1);
RNA_def_property_ui_text(prop, "Curved", "Interpolate between frames in a Bezier curve, rather than linearly");
@@ -4755,7 +4737,7 @@ static void def_cmp_vector_blur(StructRNA *srna)
static void def_cmp_levels(StructRNA *srna)
{
PropertyRNA *prop;
-
+
static const EnumPropertyItem channel_items[] = {
{1, "COMBINED_RGB", 0, "C", "Combined RGB"},
{2, "RED", 0, "R", "Red Channel"},
@@ -4764,7 +4746,7 @@ static void def_cmp_levels(StructRNA *srna)
{5, "LUMINANCE", 0, "L", "Luminance Channel"},
{0, NULL, 0, NULL, NULL}
};
-
+
prop = RNA_def_property(srna, "channel", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, channel_items);
@@ -4781,7 +4763,7 @@ static void def_node_image_user(StructRNA *srna)
RNA_def_property_range(prop, 0, MAXFRAMEF);
RNA_def_property_ui_text(prop, "Frames", "Number of images of a movie to use"); /* copied from the rna_image.c */
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "sfra");
RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
@@ -4789,19 +4771,19 @@ static void def_node_image_user(StructRNA *srna)
RNA_def_property_ui_text(prop, "Start Frame",
"Global starting frame of the movie/sequence, assuming first picture has a #1");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "frame_offset", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "offset");
RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
/* copied from the rna_image.c */
RNA_def_property_ui_text(prop, "Offset", "Offset the number of the frame to use in the animation");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cycl", 1);
RNA_def_property_ui_text(prop, "Cyclic", "Cycle the images in the movie"); /* copied from the rna_image.c */
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_auto_refresh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_ANIM_ALWAYS);
/* copied from the rna_image.c */
@@ -4838,7 +4820,7 @@ static void def_node_image_user(StructRNA *srna)
static void def_cmp_image(StructRNA *srna)
{
PropertyRNA *prop;
-
+
#if 0
static const EnumPropertyItem type_items[] = {
{IMA_SRC_FILE, "IMAGE", 0, "Image", ""},
@@ -4848,7 +4830,7 @@ static void def_cmp_image(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
#endif
-
+
prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_struct_type(prop, "Image");
@@ -4872,7 +4854,7 @@ static void def_cmp_image(StructRNA *srna)
static void def_cmp_render_layers(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_scene_set", NULL, NULL);
@@ -4880,7 +4862,7 @@ static void def_cmp_render_layers(StructRNA *srna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Scene", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_view_layer_update");
-
+
prop = RNA_def_property(srna, "layer", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, prop_view_layer_items);
@@ -4894,19 +4876,19 @@ static void rna_def_cmp_output_file_slot_file(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "NodeOutputFileSlotFile", NULL);
RNA_def_struct_sdna(srna, "NodeImageMultiFileSocket");
RNA_def_struct_ui_text(srna, "Output File Slot", "Single layer file slot of the file output node");
-
+
prop = RNA_def_property(srna, "use_node_format", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_node_format", 1);
RNA_def_property_ui_text(prop, "Use Node Format", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, NULL);
-
+
prop = RNA_def_property(srna, "format", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ImageFormatSettings");
-
+
prop = RNA_def_property(srna, "path", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "path");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NodeOutputFileSlotFile_path_set");
@@ -4918,11 +4900,11 @@ static void rna_def_cmp_output_file_slot_layer(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "NodeOutputFileSlotLayer", NULL);
RNA_def_struct_sdna(srna, "NodeImageMultiFileSocket");
RNA_def_struct_ui_text(srna, "Output File Layer Slot", "Multilayer slot of the file output node");
-
+
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "layer");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NodeOutputFileSlotLayer_name_set");
@@ -4975,33 +4957,33 @@ static void rna_def_cmp_output_file_slots_api(BlenderRNA *brna, PropertyRNA *cpr
static void def_cmp_output_file(BlenderRNA *brna, StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeImageMultiFile", "storage");
-
+
prop = RNA_def_property(srna, "base_path", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "base_path");
RNA_def_property_ui_text(prop, "Base Path", "Base output path for the image");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "active_input_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "active_input");
RNA_def_property_ui_text(prop, "Active Input Index", "Active input index in details view list");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "format", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ImageFormatSettings");
-
+
/* XXX using two different collections here for the same basic DNA list!
* Details of the output slots depend on whether the node is in Multilayer EXR mode.
*/
-
+
prop = RNA_def_property(srna, "file_slots", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_funcs(prop, "rna_NodeOutputFile_slots_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end",
"rna_NodeOutputFile_slot_file_get", NULL, NULL, NULL, NULL);
RNA_def_property_struct_type(prop, "NodeOutputFileSlotFile");
RNA_def_property_ui_text(prop, "File Slots", "");
rna_def_cmp_output_file_slots_api(brna, prop, "CompositorNodeOutputFileFileSlots");
-
+
prop = RNA_def_property(srna, "layer_slots", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_funcs(prop, "rna_NodeOutputFile_slots_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end",
"rna_NodeOutputFile_slot_layer_get", NULL, NULL, NULL, NULL);
@@ -5021,13 +5003,13 @@ static void def_cmp_dilate_erode(StructRNA *srna)
{CMP_NODE_DILATEERODE_DISTANCE_FEATHER, "FEATHER", 0, "Feather", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, mode_items);
RNA_def_property_ui_text(prop, "Mode", "Growing/shrinking mode");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
RNA_def_property_range(prop, -5000, 5000);
@@ -5065,7 +5047,7 @@ static void def_cmp_inpaint(StructRNA *srna)
RNA_def_property_ui_text(prop, "Type", "Type of inpaint algorithm");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
#endif
-
+
prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
RNA_def_property_range(prop, 1, 10000);
@@ -5101,7 +5083,7 @@ static void def_cmp_scale(StructRNA *srna)
{CMP_SCALE_RENDERPERCENT, "RENDER_SIZE", 0, "Render Size", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* matching bgpic_camera_frame_items[] */
static const EnumPropertyItem space_frame_items[] = {
{0, "STRETCH", 0, "Stretch", ""},
@@ -5137,7 +5119,7 @@ static void def_cmp_scale(StructRNA *srna)
static void def_cmp_rotate(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_sampler_type_items);
@@ -5150,14 +5132,14 @@ static void def_cmp_diff_matte(StructRNA *srna)
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
-
+
prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_float_funcs(prop, NULL, "rna_difference_matte_t1_set", NULL);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_float_funcs(prop, NULL, "rna_difference_matte_t2_set", NULL);
@@ -5169,7 +5151,7 @@ static void def_cmp_diff_matte(StructRNA *srna)
static void def_cmp_color_matte(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
prop = RNA_def_property(srna, "color_hue", PROP_FLOAT, PROP_NONE);
@@ -5177,13 +5159,13 @@ static void def_cmp_color_matte(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "H", "Hue tolerance for colors to be considered a keying color");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "color_saturation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "S", "Saturation Tolerance for the color");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "color_value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t3");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -5194,7 +5176,7 @@ static void def_cmp_color_matte(StructRNA *srna)
static void def_cmp_distance_matte(StructRNA *srna)
{
PropertyRNA *prop;
-
+
static const EnumPropertyItem color_space_items[] = {
{1, "RGB", 0, "RGB", "RGB color space"},
{2, "YCC", 0, "YCC", "YCbCr Suppression"},
@@ -5209,14 +5191,14 @@ static void def_cmp_distance_matte(StructRNA *srna)
RNA_def_property_ui_text(prop, "Channel", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_float_funcs(prop, NULL, "rna_distance_matte_t1_set", NULL);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Tolerance", "Color distances below this threshold are keyed");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_float_funcs(prop, NULL, "rna_distance_matte_t2_set", NULL);
@@ -5248,13 +5230,13 @@ static void def_cmp_color_spill(StructRNA *srna)
{1, "AVERAGE", 0, "Average", "Average Limit Algorithm"},
{0, NULL, 0, NULL, NULL}
};
-
+
prop = RNA_def_property(srna, "channel", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, channel_items);
RNA_def_property_ui_text(prop, "Channel", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "limit_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom2");
RNA_def_property_enum_items(prop, algorithm_items);
@@ -5302,16 +5284,16 @@ static void def_cmp_color_spill(StructRNA *srna)
static void def_cmp_luma_matte(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
-
+
prop = RNA_def_property(srna, "limit_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t1_set", NULL);
RNA_def_property_ui_range(prop, 0, 1, 0.1f, 3);
RNA_def_property_ui_text(prop, "High", "Values higher than this setting are 100% opaque");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "limit_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t2_set", NULL);
@@ -5333,16 +5315,16 @@ static void def_cmp_brightcontrast(StructRNA *srna)
static void def_cmp_chroma_matte(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeChroma", "storage");
-
+
prop = RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t1_set", NULL);
RNA_def_property_range(prop, DEG2RADF(1.0f), DEG2RADF(80.0f));
RNA_def_property_ui_text(prop, "Acceptance", "Tolerance for a color to be considered a keying color");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t2_set", NULL);
@@ -5355,13 +5337,13 @@ static void def_cmp_chroma_matte(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Lift", "Alpha lift");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fstrength");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Falloff", "Alpha falloff");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "shadow_adjust", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t3");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -5372,7 +5354,7 @@ static void def_cmp_chroma_matte(StructRNA *srna)
static void def_cmp_channel_matte(StructRNA *srna)
{
PropertyRNA *prop;
-
+
static const EnumPropertyItem color_space_items[] = {
{CMP_NODE_CHANNEL_MATTE_CS_RGB, "RGB", 0, "RGB", "RGB Color Space"},
{CMP_NODE_CHANNEL_MATTE_CS_HSV, "HSV", 0, "HSV", "HSV Color Space"},
@@ -5386,13 +5368,13 @@ static void def_cmp_channel_matte(StructRNA *srna)
{1, "MAX", 0, "Max", "Limit by max of other channels "},
{0, NULL, 0, NULL, NULL}
};
-
+
prop = RNA_def_property(srna, "color_space", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_ui_text(prop, "Color Space", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "matte_channel", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom2");
RNA_def_property_enum_items(prop, prop_tri_channel_items);
@@ -5414,14 +5396,14 @@ static void def_cmp_channel_matte(StructRNA *srna)
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Node_channel_itemf");
RNA_def_property_ui_text(prop, "Limit Channel", "Limit by this channel's value");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "limit_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t1");
RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t1_set", NULL);
RNA_def_property_ui_range(prop, 0, 1, 0.1f, 3);
RNA_def_property_ui_text(prop, "High", "Values higher than this setting are 100% opaque");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "limit_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "t2");
RNA_def_property_float_funcs(prop, NULL, "rna_Matte_t2_set", NULL);
@@ -5433,7 +5415,7 @@ static void def_cmp_channel_matte(StructRNA *srna)
static void def_cmp_flip(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_flip_items);
@@ -5444,7 +5426,7 @@ static void def_cmp_flip(StructRNA *srna)
static void def_cmp_splitviewer(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom2");
RNA_def_property_enum_items(prop, rna_enum_axis_xy_items);
@@ -5461,7 +5443,7 @@ static void def_cmp_splitviewer(StructRNA *srna)
static void def_cmp_id_mask(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_range(prop, 0, 32767);
@@ -5551,7 +5533,7 @@ static void def_cmp_defocus(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, DEG2RADF(90.0f));
RNA_def_property_ui_text(prop, "Angle", "Bokeh shape rotation offset");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_gamma_correction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gamco", 1);
RNA_def_property_ui_text(prop, "Gamma Correction", "Enable gamma correction before and after main process");
@@ -5565,20 +5547,20 @@ static void def_cmp_defocus(StructRNA *srna)
"Amount of focal blur, 128=infinity=perfect focus, half the value doubles "
"the blur radius");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "blur_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "maxblur");
RNA_def_property_range(prop, 0.0f, 10000.0f);
RNA_def_property_ui_text(prop, "Max Blur", "Blur limit, maximum CoC radius");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bthresh");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Threshold",
"CoC radius threshold, prevents background bleed on in-focus midground, 0=off");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_preview", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "preview", 1);
RNA_def_property_ui_text(prop, "Preview", "Enable low quality mode, useful for preview");
@@ -5590,7 +5572,7 @@ static void def_cmp_defocus(StructRNA *srna)
"Disable when using an image as input instead of actual z-buffer "
"(auto enabled if node not image based, eg. time node)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "z_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "scale");
RNA_def_property_range(prop, 0.0f, 1000.0f);
@@ -5603,12 +5585,12 @@ static void def_cmp_defocus(StructRNA *srna)
static void def_cmp_invert(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "invert_rgb", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_CHAN_RGB);
RNA_def_property_ui_text(prop, "RGB", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "invert_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_CHAN_A);
RNA_def_property_ui_text(prop, "Alpha", "");
@@ -5618,7 +5600,7 @@ static void def_cmp_invert(StructRNA *srna)
static void def_cmp_crop(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "use_crop_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
RNA_def_property_ui_text(prop, "Crop Image Size", "Whether to crop the size of the input image");
@@ -5636,19 +5618,19 @@ static void def_cmp_crop(StructRNA *srna)
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "X1", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "max_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "x2");
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "X2", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "min_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "y1");
RNA_def_property_range(prop, 0, 10000);
RNA_def_property_ui_text(prop, "Y1", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "max_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "y2");
RNA_def_property_range(prop, 0, 10000);
@@ -5683,50 +5665,50 @@ static void def_cmp_crop(StructRNA *srna)
static void def_cmp_dblur(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeDBlurData", "storage");
-
+
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "iter");
RNA_def_property_range(prop, 1, 32);
RNA_def_property_ui_text(prop, "Iterations", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_wrap", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "wrap", 1);
RNA_def_property_ui_text(prop, "Wrap", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "center_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "center_x");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Center X", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "center_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "center_y");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Center Y", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "distance");
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_ui_text(prop, "Distance", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "angle");
RNA_def_property_range(prop, 0.0f, DEG2RADF(360.0f));
RNA_def_property_ui_text(prop, "Angle", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "spin", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "spin");
RNA_def_property_range(prop, DEG2RADF(-360.0f), DEG2RADF(360.0f));
RNA_def_property_ui_text(prop, "Spin", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "zoom", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "zoom");
RNA_def_property_range(prop, 0.0f, 100.0f);
@@ -5737,21 +5719,21 @@ static void def_cmp_dblur(StructRNA *srna)
static void def_cmp_bilateral_blur(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeBilateralBlurData", "storage");
-
+
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "iter");
RNA_def_property_range(prop, 1, 128);
RNA_def_property_ui_text(prop, "Iterations", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "sigma_color", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sigma_color");
RNA_def_property_range(prop, 0.01f, 3.0f);
RNA_def_property_ui_text(prop, "Color Sigma", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "sigma_space", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sigma_space");
RNA_def_property_range(prop, 0.01f, 30.0f);
@@ -5762,25 +5744,25 @@ static void def_cmp_bilateral_blur(StructRNA *srna)
static void def_cmp_premul_key(StructRNA *srna)
{
PropertyRNA *prop;
-
+
static const EnumPropertyItem type_items[] = {
{0, "STRAIGHT_TO_PREMUL", 0, "Straight to Premul", ""},
{1, "PREMUL_TO_STRAIGHT", 0, "Premul to Straight", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Mapping", "Conversion between premultiplied alpha and key alpha");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
}
static void def_cmp_glare(StructRNA *srna)
{
PropertyRNA *prop;
-
+
static const EnumPropertyItem type_items[] = {
{3, "GHOSTS", 0, "Ghosts", ""},
{2, "STREAKS", 0, "Streaks", ""},
@@ -5788,22 +5770,22 @@ static void def_cmp_glare(StructRNA *srna)
{0, "SIMPLE_STAR", 0, "Simple Star", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem quality_items[] = {
{0, "HIGH", 0, "High", ""},
{1, "MEDIUM", 0, "Medium", ""},
{2, "LOW", 0, "Low", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
RNA_def_struct_sdna_from(srna, "NodeGlare", "storage");
-
+
prop = RNA_def_property(srna, "glare_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Glare Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "quality", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "quality");
RNA_def_property_enum_items(prop, quality_items);
@@ -5811,13 +5793,13 @@ static void def_cmp_glare(StructRNA *srna)
"If not set to high quality, the effect will be applied to a low-res copy "
"of the source image");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "iter");
RNA_def_property_range(prop, 2, 5);
RNA_def_property_ui_text(prop, "Iterations", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "color_modulation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colmod");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -5825,109 +5807,109 @@ static void def_cmp_glare(StructRNA *srna)
"Amount of Color Modulation, modulates colors of streaks and ghosts for "
"a spectral dispersion effect");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "mix", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mix");
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_ui_text(prop, "Mix",
"-1 is original image only, 0 is exact 50/50 mix, 1 is processed image only");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "threshold");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Threshold",
"The glare filter will only be applied to pixels brighter than this value");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "streaks", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "streaks");
RNA_def_property_range(prop, 1, 16);
RNA_def_property_ui_text(prop, "Streaks", "Total number of streaks");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "angle_offset", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "angle_ofs");
RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
RNA_def_property_ui_text(prop, "Angle Offset", "Streak angle offset");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "fade", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fade");
RNA_def_property_range(prop, 0.75f, 1.0f);
RNA_def_property_ui_text(prop, "Fade", "Streak fade-out factor");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_rotate_45", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "star_45", 0);
RNA_def_property_ui_text(prop, "Rotate 45", "Simple star filter: add 45 degree rotation offset");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "size", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "size");
RNA_def_property_range(prop, 6, 9);
RNA_def_property_ui_text(prop, "Size",
"Glow/glare size (not actual size; relative to initial size of bright area of pixels)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
/* TODO */
}
static void def_cmp_tonemap(StructRNA *srna)
{
PropertyRNA *prop;
-
+
static const EnumPropertyItem type_items[] = {
{1, "RD_PHOTORECEPTOR", 0, "R/D Photoreceptor", ""},
{0, "RH_SIMPLE", 0, "Rh Simple", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
RNA_def_struct_sdna_from(srna, "NodeTonemap", "storage");
-
+
prop = RNA_def_property(srna, "tonemap_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Tonemap Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "key", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "key");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Key", "The value the average luminance is mapped to");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "offset");
RNA_def_property_range(prop, 0.001f, 10.0f);
RNA_def_property_ui_text(prop, "Offset",
"Normally always 1, but can be used as an extra control to alter the brightness curve");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "gamma");
RNA_def_property_range(prop, 0.001f, 3.0f);
RNA_def_property_ui_text(prop, "Gamma", "If not used, set to 1");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f");
RNA_def_property_range(prop, -8.0f, 8.0f);
RNA_def_property_ui_text(prop, "Intensity", "If less than zero, darkens image; otherwise, makes it brighter");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "m");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Contrast", "Set to 0 to use estimate from input image");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "adaptation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "a");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Adaptation", "If 0, global; if 1, based on pixel intensity");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "correction", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "c");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -5938,20 +5920,20 @@ static void def_cmp_tonemap(StructRNA *srna)
static void def_cmp_lensdist(StructRNA *srna)
{
PropertyRNA *prop;
-
+
RNA_def_struct_sdna_from(srna, "NodeLensDist", "storage");
-
+
prop = RNA_def_property(srna, "use_projector", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "proj", 1);
RNA_def_property_ui_text(prop, "Projector",
"Enable/disable projector mode (the effect is applied in horizontal direction only)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_jitter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "jit", 1);
RNA_def_property_ui_text(prop, "Jitter", "Enable/disable jittering (faster, but also noisier)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "use_fit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "fit", 1);
RNA_def_property_ui_text(prop, "Fit",
@@ -5963,21 +5945,21 @@ static void def_cmp_colorbalance(StructRNA *srna)
{
PropertyRNA *prop;
static float default_1[3] = {1.f, 1.f, 1.f};
-
+
static const EnumPropertyItem type_items[] = {
{0, "LIFT_GAMMA_GAIN", 0, "Lift/Gamma/Gain", ""},
{1, "OFFSET_POWER_SLOPE", 0, "Offset/Power/Slope (ASC-CDL)", "ASC-CDL standard color correction"},
{0, NULL, 0, NULL, NULL}
};
-
+
prop = RNA_def_property(srna, "correction_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Correction Formula", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
RNA_def_struct_sdna_from(srna, "NodeColorBalance", "storage");
-
+
prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "lift");
RNA_def_property_array(prop, 3);
@@ -5985,7 +5967,7 @@ static void def_cmp_colorbalance(StructRNA *srna)
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_ui_text(prop, "Lift", "Correction for Shadows");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_lgg");
-
+
prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "gamma");
RNA_def_property_array(prop, 3);
@@ -5993,7 +5975,7 @@ static void def_cmp_colorbalance(StructRNA *srna)
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_ui_text(prop, "Gamma", "Correction for Midtones");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_lgg");
-
+
prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "gain");
RNA_def_property_array(prop, 3);
@@ -6001,15 +5983,15 @@ static void def_cmp_colorbalance(StructRNA *srna)
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_ui_text(prop, "Gain", "Correction for Highlights");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_lgg");
-
-
+
+
prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "offset");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_range(prop, 0, 1, 0.1, 3);
RNA_def_property_ui_text(prop, "Offset", "Correction for Shadows");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_cdl");
-
+
prop = RNA_def_property(srna, "power", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "power");
RNA_def_property_array(prop, 3);
@@ -6018,7 +6000,7 @@ static void def_cmp_colorbalance(StructRNA *srna)
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_ui_text(prop, "Power", "Correction for Midtones");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_cdl");
-
+
prop = RNA_def_property(srna, "slope", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "slope");
RNA_def_property_array(prop, 3);
@@ -6038,7 +6020,7 @@ static void def_cmp_colorbalance(StructRNA *srna)
static void def_cmp_huecorrect(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "mapping", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "storage");
RNA_def_property_struct_type(prop, "CurveMapping");
@@ -6049,7 +6031,7 @@ static void def_cmp_huecorrect(StructRNA *srna)
static void def_cmp_zcombine(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0);
RNA_def_property_ui_text(prop, "Use Alpha", "Take Alpha channel into account when doing the Z operation");
@@ -6064,7 +6046,7 @@ static void def_cmp_zcombine(StructRNA *srna)
static void def_cmp_ycc(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_ycc_items);
@@ -6219,7 +6201,7 @@ static const EnumPropertyItem node_masktype_items[] = {
{0, NULL, 0, NULL, NULL}
};
-static void def_cmp_boxmask(StructRNA *srna)
+static void def_cmp_boxmask(StructRNA *srna)
{
PropertyRNA *prop;
@@ -6345,7 +6327,7 @@ static void def_cmp_bokehblur(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 10000.0f);
RNA_def_property_ui_text(prop, "Max Blur", "Blur limit, maximum CoC radius");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
}
static void def_cmp_bokehimage(StructRNA *srna)
@@ -6413,21 +6395,21 @@ static void def_cmp_colorcorrection(StructRNA *srna)
RNA_def_property_boolean_default(prop, true);
RNA_def_property_ui_text(prop, "Red", "Red channel active");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "green", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 2);
RNA_def_property_boolean_default(prop, true);
RNA_def_property_ui_text(prop, "Green", "Green channel active");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "blue", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 4);
RNA_def_property_boolean_default(prop, true);
RNA_def_property_ui_text(prop, "Blue", "Blue channel active");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
RNA_def_struct_sdna_from(srna, "NodeColorCorrection", "storage");
-
+
prop = RNA_def_property(srna, "midtones_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "startmidtones");
RNA_def_property_float_default(prop, 0.2f);
@@ -6441,35 +6423,35 @@ static void def_cmp_colorcorrection(StructRNA *srna)
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Midtones End", "End of midtones");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "master_saturation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "master.saturation");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Master Saturation", "Master saturation");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "master_contrast", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "master.contrast");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Master Contrast", "Master contrast");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "master_gamma", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "master.gamma");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Master Gamma", "Master gamma");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "master_gain", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "master.gain");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Master Gain", "Master gain");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "master_lift", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "master.lift");
RNA_def_property_float_default(prop, 0.0f);
@@ -6484,28 +6466,28 @@ static void def_cmp_colorcorrection(StructRNA *srna)
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Shadows Saturation", "Shadows saturation");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "shadows_contrast", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shadows.contrast");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Shadows Contrast", "Shadows contrast");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "shadows_gamma", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shadows.gamma");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Shadows Gamma", "Shadows gamma");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "shadows_gain", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shadows.gain");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Shadows Gain", "Shadows gain");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "shadows_lift", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shadows.lift");
RNA_def_property_float_default(prop, 0.0f);
@@ -6519,28 +6501,28 @@ static void def_cmp_colorcorrection(StructRNA *srna)
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Midtones Saturation", "Midtones saturation");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "midtones_contrast", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "midtones.contrast");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Midtones Contrast", "Midtones contrast");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "midtones_gamma", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "midtones.gamma");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Midtones Gamma", "Midtones gamma");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "midtones_gain", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "midtones.gain");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Midtones Gain", "Midtones gain");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "midtones_lift", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "midtones.lift");
RNA_def_property_float_default(prop, 0.0f);
@@ -6554,28 +6536,28 @@ static void def_cmp_colorcorrection(StructRNA *srna)
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Highlights Saturation", "Highlights saturation");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "highlights_contrast", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "highlights.contrast");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Highlights Contrast", "Highlights contrast");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "highlights_gamma", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "highlights.gamma");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Highlights Gamma", "Highlights gamma");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "highlights_gain", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "highlights.gain");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0, 4);
RNA_def_property_ui_text(prop, "Highlights Gain", "Highlights gain");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "highlights_lift", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "highlights.lift");
RNA_def_property_float_default(prop, 0.0f);
@@ -6607,7 +6589,7 @@ static void def_cmp_viewer(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "X", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "center_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "custom4");
RNA_def_property_float_default(prop, 0.5f);
@@ -6871,7 +6853,7 @@ static void def_tex_output(StructRNA *srna)
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "TexNodeOutput", "storage");
-
+
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Output Name", "");
@@ -6906,19 +6888,19 @@ static void def_tex_bricks(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Offset Amount", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "offset_frequency", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom1");
RNA_def_property_range(prop, 2, 99);
RNA_def_property_ui_text(prop, "Offset Frequency", "Offset every N rows");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "squash", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "custom4");
RNA_def_property_range(prop, 0.0f, 99.0f);
RNA_def_property_ui_text(prop, "Squash Amount", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "squash_frequency", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "custom2");
RNA_def_property_range(prop, 2, 99);
@@ -6931,7 +6913,7 @@ static void def_tex_bricks(StructRNA *srna)
static void rna_def_shader_node(BlenderRNA *brna)
{
StructRNA *srna;
-
+
srna = RNA_def_struct(brna, "ShaderNode", "NodeInternal");
RNA_def_struct_ui_text(srna, "Shader Node", "Material shader node");
RNA_def_struct_sdna(srna, "bNode");
@@ -6942,12 +6924,12 @@ static void rna_def_compositor_node(BlenderRNA *brna)
{
StructRNA *srna;
FunctionRNA *func;
-
+
srna = RNA_def_struct(brna, "CompositorNode", "NodeInternal");
RNA_def_struct_ui_text(srna, "Compositor Node", "");
RNA_def_struct_sdna(srna, "bNode");
RNA_def_struct_register_funcs(srna, "rna_CompositorNode_register", "rna_Node_unregister", NULL);
-
+
/* compositor node need_exec flag */
func = RNA_def_function(srna, "tag_need_exec", "rna_CompositorNode_tag_need_exec");
RNA_def_function_ui_description(func, "Tag the node for compositor update");
@@ -6956,7 +6938,7 @@ static void rna_def_compositor_node(BlenderRNA *brna)
static void rna_def_texture_node(BlenderRNA *brna)
{
StructRNA *srna;
-
+
srna = RNA_def_struct(brna, "TextureNode", "NodeInternal");
RNA_def_struct_ui_text(srna, "Texture Node", "");
RNA_def_struct_sdna(srna, "bNode");
@@ -6971,9 +6953,9 @@ static void rna_def_node_socket(BlenderRNA *brna)
PropertyRNA *prop;
PropertyRNA *parm;
FunctionRNA *func;
-
+
static float default_draw_color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
-
+
srna = RNA_def_struct(brna, "NodeSocket", NULL);
RNA_def_struct_ui_text(srna, "Node Socket", "Input or output socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
@@ -7100,9 +7082,9 @@ static void rna_def_node_socket_interface(BlenderRNA *brna)
PropertyRNA *prop;
PropertyRNA *parm;
FunctionRNA *func;
-
+
static float default_draw_color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
-
+
srna = RNA_def_struct(brna, "NodeSocketInterface", NULL);
RNA_def_struct_ui_text(srna, "Node Socket Template", "Parameters to define node sockets");
/* XXX Using bNodeSocket DNA for templates is a compatibility hack.
@@ -7184,7 +7166,7 @@ static void rna_def_node_socket_float(BlenderRNA *brna, const char *idname, cons
StructRNA *srna;
PropertyRNA *prop;
float value_default;
-
+
/* choose sensible common default based on subtype */
switch (subtype) {
case PROP_FACTOR:
@@ -7197,46 +7179,46 @@ static void rna_def_node_socket_float(BlenderRNA *brna, const char *idname, cons
value_default = 0.0f;
break;
}
-
+
srna = RNA_def_struct(brna, idname, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Float Node Socket", "Floating point number socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueFloat", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype);
RNA_def_property_float_sdna(prop, NULL, "value");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_float_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
-
+
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(srna, "Float Node Socket Interface", "Floating point number socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueFloat", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype);
RNA_def_property_float_sdna(prop, NULL, "value");
RNA_def_property_float_default(prop, value_default);
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_float_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
prop = RNA_def_property(srna, "min_value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
prop = RNA_def_property(srna, "max_value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
}
@@ -7245,7 +7227,7 @@ static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, co
StructRNA *srna;
PropertyRNA *prop;
int value_default;
-
+
/* choose sensible common default based on subtype */
switch (subtype) {
case PROP_FACTOR:
@@ -7258,13 +7240,13 @@ static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, co
value_default = 0;
break;
}
-
+
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Integer Node Socket", "Integer number socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueInt", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_INT, subtype);
RNA_def_property_int_sdna(prop, NULL, "value");
RNA_def_property_int_default(prop, value_default);
@@ -7272,32 +7254,32 @@ static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, co
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
-
+
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(srna, "Integer Node Socket Interface", "Integer number socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
RNA_def_struct_sdna_from(srna, "bNodeSocketValueInt", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_INT, subtype);
RNA_def_property_int_sdna(prop, NULL, "value");
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_int_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
prop = RNA_def_property(srna, "min_value", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
prop = RNA_def_property(srna, "max_value", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "max");
RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
}
@@ -7305,33 +7287,33 @@ static void rna_def_node_socket_bool(BlenderRNA *brna, const char *identifier, c
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Boolean Node Socket", "Boolean value socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueBoolean", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "value", 1);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
-
+
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(srna, "Boolean Node Socket Interface", "Boolean value socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueBoolean", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "value", 1);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
}
@@ -7340,7 +7322,7 @@ static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier,
StructRNA *srna;
PropertyRNA *prop;
const float *value_default;
-
+
/* choose sensible common default based on subtype */
switch (subtype) {
case PROP_DIRECTION: {
@@ -7354,13 +7336,13 @@ static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier,
break;
}
}
-
+
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Vector Node Socket", "3D vector socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueVector", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype);
RNA_def_property_float_sdna(prop, NULL, "value");
RNA_def_property_float_array_default(prop, value_default);
@@ -7368,32 +7350,32 @@ static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier,
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
-
+
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(srna, "Vector Node Socket Interface", "3D vector socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueVector", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype);
RNA_def_property_float_sdna(prop, NULL, "value");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_vector_range");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
prop = RNA_def_property(srna, "min_value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
prop = RNA_def_property(srna, "max_value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
}
@@ -7401,33 +7383,33 @@ static void rna_def_node_socket_color(BlenderRNA *brna, const char *identifier,
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Color Node Socket", "RGBA color socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueRGBA", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "value");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
-
+
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(srna, "Color Node Socket Interface", "RGBA color socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueRGBA", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "value");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
}
@@ -7435,44 +7417,44 @@ static void rna_def_node_socket_string(BlenderRNA *brna, const char *identifier,
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "String Node Socket", "String socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueString", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "value");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
-
+
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(srna, "String Node Socket Interface", "String socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocketValueString", "default_value");
-
+
prop = RNA_def_property(srna, "default_value", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "value");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
-
+
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
}
static void rna_def_node_socket_shader(BlenderRNA *brna, const char *identifier, const char *interface_idname)
{
StructRNA *srna;
-
+
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Shader Node Socket", "Shader socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(srna, "Shader Node Socket Interface", "Shader socket of a node");
@@ -7482,7 +7464,7 @@ static void rna_def_node_socket_shader(BlenderRNA *brna, const char *identifier,
static void rna_def_node_socket_virtual(BlenderRNA *brna, const char *identifier)
{
StructRNA *srna;
-
+
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Virtual Node Socket", "Virtual socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
@@ -7496,16 +7478,16 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna)
* so in order to call them in py scripts we need to overload and replace them with plain C callbacks.
* These types provide a usable basis for socket types defined in C.
*/
-
+
StructRNA *srna;
PropertyRNA *parm, *prop;
FunctionRNA *func;
-
+
static float default_draw_color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
-
+
srna = RNA_def_struct(brna, "NodeSocketStandard", "NodeSocket");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
/* draw socket */
func = RNA_def_function(srna, "draw", "rna_NodeSocketStandard_draw");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
@@ -7536,11 +7518,11 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna)
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
parm = RNA_def_float_array(func, "color", 4, default_draw_color, 0.0f, 1.0f, "Color", "", 0.0f, 1.0f);
RNA_def_function_output(func, parm);
-
-
+
+
srna = RNA_def_struct(brna, "NodeSocketInterfaceStandard", "NodeSocketInterface");
RNA_def_struct_sdna(srna, "bNodeSocket");
-
+
/* for easier type comparison in python */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "typeinfo->type");
@@ -7548,7 +7530,7 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna)
RNA_def_property_enum_default(prop, SOCK_FLOAT);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Type", "Data type");
-
+
func = RNA_def_function(srna, "draw", "rna_NodeSocketInterfaceStandard_draw");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
RNA_def_function_ui_description(func, "Draw template settings");
@@ -7572,7 +7554,7 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna)
* Then use the nodeStaticSocketType and nodeStaticSocketInterfaceType functions
* to get the idname strings from int type and subtype (see node_socket.c, register_standard_node_socket_types).
*/
-
+
rna_def_node_socket_float(brna, "NodeSocketFloat", "NodeSocketInterfaceFloat", PROP_NONE);
rna_def_node_socket_float(brna, "NodeSocketFloatUnsigned", "NodeSocketInterfaceFloatUnsigned", PROP_UNSIGNED);
rna_def_node_socket_float(brna, "NodeSocketFloatPercentage", "NodeSocketInterfaceFloatPercentage", PROP_PERCENTAGE);
@@ -7609,36 +7591,36 @@ static void rna_def_internal_node(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop, *parm;
FunctionRNA *func;
-
+
srna = RNA_def_struct(brna, "NodeInternalSocketTemplate", NULL);
RNA_def_struct_ui_text(srna, "Socket Template", "Type and default value of a node socket");
-
+
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_NodeInternalSocketTemplate_name_get", "rna_NodeInternalSocketTemplate_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "Name of the socket");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_NodeInternalSocketTemplate_identifier_get", "rna_NodeInternalSocketTemplate_identifier_length", NULL);
RNA_def_property_ui_text(prop, "Identifier", "Identifier of the socket");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_funcs(prop, "rna_NodeInternalSocketTemplate_type_get", NULL, NULL);
RNA_def_property_enum_items(prop, node_socket_type_items);
RNA_def_property_ui_text(prop, "Type", "Data type of the socket");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
/* XXX Workaround: Registered functions are not exposed in python by bpy,
* it expects them to be registered from python and use the native implementation.
* However, the standard node types are not registering these functions from python,
* so in order to call them in py scripts we need to overload and replace them with plain C callbacks.
* This type provides a usable basis for node types defined in C.
*/
-
+
srna = RNA_def_struct(brna, "NodeInternal", "Node");
RNA_def_struct_sdna(srna, "bNode");
-
+
/* poll */
func = RNA_def_function(srna, "poll", "rna_NodeInternal_poll");
RNA_def_function_ui_description(func, "If non-null output is returned, the node type can be added to the tree");
@@ -7646,18 +7628,18 @@ static void rna_def_internal_node(BlenderRNA *brna)
RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
-
+
func = RNA_def_function(srna, "poll_instance", "rna_NodeInternal_poll_instance");
RNA_def_function_ui_description(func, "If non-null output is returned, the node can be added to the tree");
RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
-
+
/* update */
func = RNA_def_function(srna, "update", "rna_NodeInternal_update");
RNA_def_function_ui_description(func, "Update on editor changes");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_ALLOW_WRITE);
-
+
/* draw buttons */
func = RNA_def_function(srna, "draw_buttons", "rna_NodeInternal_draw_buttons");
RNA_def_function_ui_description(func, "Draw node buttons");
@@ -7734,7 +7716,7 @@ static void rna_def_node(BlenderRNA *brna)
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
-
+
static const EnumPropertyItem dummy_static_type_items[] = {
{NODE_CUSTOM, "CUSTOM", 0, "Custom", "Custom Node"},
{0, NULL, 0, NULL, NULL}};
@@ -7753,7 +7735,7 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_Node_path");
RNA_def_struct_register_funcs(srna, "rna_Node_register", "rna_Node_unregister", NULL);
RNA_def_struct_idprops_func(srna, "rna_Node_idprops");
-
+
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, dummy_static_type_items);
@@ -7761,55 +7743,55 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_property_enum_default(prop, NODE_CUSTOM);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Type", "Node type (deprecated, use bl_static_type or bl_idname for the actual identifier string)");
-
+
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "locx");
RNA_def_property_array(prop, 2);
RNA_def_property_range(prop, -100000.0f, 100000.0f);
RNA_def_property_ui_text(prop, "Location", "");
RNA_def_property_update(prop, NC_NODE, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "width", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "width");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range");
RNA_def_property_ui_text(prop, "Width", "Width of the node");
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
-
+
prop = RNA_def_property(srna, "width_hidden", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "miniwidth");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range");
RNA_def_property_ui_text(prop, "Width Hidden", "Width of the node in hidden state");
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
-
+
prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "height");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_height_range");
RNA_def_property_ui_text(prop, "Height", "Height of the node");
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
-
+
prop = RNA_def_property(srna, "dimensions", PROP_FLOAT, PROP_XYZ_LENGTH);
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_Node_dimensions_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Dimensions", "Absolute bounding box dimensions of the node");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Unique node identifier");
RNA_def_struct_name_property(srna, prop);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Node_name_set");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
+
prop = RNA_def_property(srna, "label", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "label");
RNA_def_property_ui_text(prop, "Label", "Optional custom node label");
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
-
+
prop = RNA_def_property(srna, "inputs", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "inputs", NULL);
RNA_def_property_struct_type(prop, "NodeSocket");
RNA_def_property_ui_text(prop, "Inputs", "");
rna_def_node_sockets_api(brna, prop, SOCK_IN);
-
+
prop = RNA_def_property(srna, "outputs", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "outputs", NULL);
RNA_def_property_struct_type(prop, "NodeSocket");
@@ -7827,7 +7809,7 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Node");
RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to");
-
+
prop = RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_CUSTOM_COLOR);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -7904,7 +7886,7 @@ static void rna_def_node(BlenderRNA *brna)
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATION);
RNA_def_property_string_sdna(prop, NULL, "typeinfo->ui_description");
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
-
+
prop = RNA_def_property(srna, "bl_icon", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "typeinfo->ui_icon");
RNA_def_property_enum_items(prop, rna_enum_node_icon_items);
@@ -7952,26 +7934,26 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
-
+
func = RNA_def_function(srna, "poll_instance", NULL);
RNA_def_function_ui_description(func, "If non-null output is returned, the node can be added to the tree");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
RNA_def_function_return(func, RNA_def_boolean(func, "visible", false, "", ""));
parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
-
+
/* update */
func = RNA_def_function(srna, "update", NULL);
RNA_def_function_ui_description(func, "Update on editor changes");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
-
+
/* insert_link */
func = RNA_def_function(srna, "insert_link", NULL);
RNA_def_function_ui_description(func, "Handle creation of a link to or from the node");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
parm = RNA_def_pointer(func, "link", "NodeLink", "Link", "Node link that will be inserted");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
-
+
/* init */
func = RNA_def_function(srna, "init", NULL);
RNA_def_function_ui_description(func, "Initialize a new instance of this node");
@@ -8216,7 +8198,7 @@ static void rna_def_nodetree(BlenderRNA *brna)
RNA_def_property_array(prop, 2);
RNA_def_property_float_sdna(prop, NULL, "view_center");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
/* AnimData */
rna_def_animdata_common(srna);
@@ -8241,7 +8223,7 @@ static void rna_def_nodetree(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil data-block");
RNA_def_property_update(prop, NC_NODE, NULL);
-
+
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, static_type_items);
@@ -8291,7 +8273,7 @@ static void rna_def_nodetree(BlenderRNA *brna)
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATION);
RNA_def_property_string_sdna(prop, NULL, "typeinfo->ui_description");
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
-
+
prop = RNA_def_property(srna, "bl_icon", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "typeinfo->ui_icon");
RNA_def_property_enum_items(prop, rna_enum_node_icon_items);
@@ -8398,11 +8380,11 @@ static StructRNA *define_specific_node(BlenderRNA *brna, const char *struct_name
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
-
+
/* XXX hack, want to avoid "NodeInternal" prefix, so use "Node" in NOD_static_types.h and replace here */
if (STREQ(base_name, "Node"))
base_name = "NodeInternal";
-
+
srna = RNA_def_struct(brna, struct_name, base_name);
RNA_def_struct_ui_text(srna, ui_name, ui_desc);
RNA_def_struct_sdna(srna, "bNode");
@@ -8460,26 +8442,26 @@ static void rna_def_node_instance_hash(BlenderRNA *brna)
void RNA_def_nodetree(BlenderRNA *brna)
{
StructRNA *srna;
-
+
rna_def_node_socket(brna);
rna_def_node_socket_interface(brna);
-
+
rna_def_node(brna);
rna_def_node_link(brna);
-
+
rna_def_internal_node(brna);
rna_def_shader_node(brna);
rna_def_compositor_node(brna);
rna_def_texture_node(brna);
-
+
rna_def_nodetree(brna);
-
+
rna_def_node_socket_standard_types(brna);
-
+
rna_def_composite_nodetree(brna);
rna_def_shader_nodetree(brna);
rna_def_texture_nodetree(brna);
-
+
#define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
{ \
srna = define_specific_node(brna, #Category #StructName, #Category, UIName, UIDesc, DefFunc); \
@@ -8488,12 +8470,12 @@ void RNA_def_nodetree(BlenderRNA *brna)
def_cmp_output_file(brna, srna); \
} \
}
-
+
/* hack, don't want to add include path to RNA just for this, since in the future RNA types
* for nodes should be defined locally at runtime anyway ...
*/
#include "../../nodes/NOD_static_types.h"
-
+
/* Node group types need to be defined for shader, compositor, texture nodes individually.
* Cannot use the static types header for this, since they share the same int id.
*/
@@ -8501,11 +8483,11 @@ void RNA_def_nodetree(BlenderRNA *brna)
define_specific_node(brna, "CompositorNodeGroup", "CompositorNode", "Group", "", def_group);
define_specific_node(brna, "TextureNodeGroup", "TextureNode", "Group", "", def_group);
def_custom_group(brna);
-
+
/* special socket types */
rna_def_cmp_output_file_slot_file(brna);
rna_def_cmp_output_file_slot_layer(brna);
-
+
rna_def_node_instance_hash(brna);
}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 10a31c9c070..22a32586ff1 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -65,10 +65,10 @@ const EnumPropertyItem rna_enum_object_mode_items[] = {
{OB_MODE_OBJECT, "OBJECT", ICON_OBJECT_DATAMODE, "Object Mode", ""},
{OB_MODE_EDIT, "EDIT", ICON_EDITMODE_HLT, "Edit Mode", ""},
{OB_MODE_POSE, "POSE", ICON_POSE_HLT, "Pose Mode", ""},
- {OB_MODE_WEIGHT_PAINT, "WEIGHT_PAINT", ICON_WPAINT_HLT, "Weight Paint", ""},
+ {OB_MODE_SCULPT, "SCULPT", ICON_SCULPTMODE_HLT, "Sculpt Mode", ""},
{OB_MODE_VERTEX_PAINT, "VERTEX_PAINT", ICON_VPAINT_HLT, "Vertex Paint", ""},
+ {OB_MODE_WEIGHT_PAINT, "WEIGHT_PAINT", ICON_WPAINT_HLT, "Weight Paint", ""},
{OB_MODE_TEXTURE_PAINT, "TEXTURE_PAINT", ICON_TPAINT_HLT, "Texture Paint", ""},
- {OB_MODE_SCULPT, "SCULPT", ICON_SCULPTMODE_HLT, "Sculpt Mode", ""},
{OB_MODE_PARTICLE_EDIT, "PARTICLE_EDIT", ICON_PARTICLEMODE, "Particle Edit", ""},
{OB_MODE_GPENCIL, "GPENCIL_EDIT", ICON_GREASEPENCIL, "Edit Strokes", "Edit Grease Pencil Strokes"},
{0, NULL, 0, NULL, NULL}
@@ -300,7 +300,7 @@ static void rna_Object_active_shape_update(bContext *C, PointerRNA *ptr)
break;
case OB_CURVE:
case OB_SURF:
- ED_curve_editnurb_load(ob);
+ ED_curve_editnurb_load(bmain, ob);
ED_curve_editnurb_make(ob);
break;
case OB_LATTICE:
@@ -417,7 +417,7 @@ static const EnumPropertyItem *rna_Object_parent_type_itemf(bContext *UNUSED(C),
if (ob->parent) {
Object *par = ob->parent;
-
+
if (par->type == OB_LATTICE) {
/* special hack: prevents this overriding others */
RNA_enum_items_add_value(&item, &totitem, &parent_type_items[2], PARSKEL);
@@ -475,7 +475,7 @@ static void rna_Object_dup_group_set(PointerRNA *ptr, PointerRNA value)
{
Object *ob = (Object *)ptr->data;
Collection *grp = (Collection *)value.data;
-
+
/* must not let this be set if the object belongs in this group already,
* thus causing a cycle/infinite-recursion leading to crashes on load [#25298]
*/
@@ -735,7 +735,7 @@ static PointerRNA rna_Object_active_material_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
Material *ma;
-
+
ma = (ob->totcol) ? give_current_material(ob, ob->actcol) : NULL;
return rna_pointer_inherit_refine(ptr, &RNA_Material, ma);
}
@@ -800,7 +800,7 @@ static void rna_Object_particle_update(Main *UNUSED(bmain), Scene *scene, Pointe
static void rna_Object_rotation_axis_angle_get(PointerRNA *ptr, float *value)
{
Object *ob = ptr->data;
-
+
/* for now, assume that rotation mode is axis-angle */
value[0] = ob->rotAngle;
copy_v3_v3(&value[1], ob->rotAxis);
@@ -810,21 +810,21 @@ static void rna_Object_rotation_axis_angle_get(PointerRNA *ptr, float *value)
static void rna_Object_rotation_axis_angle_set(PointerRNA *ptr, const float *value)
{
Object *ob = ptr->data;
-
+
/* for now, assume that rotation mode is axis-angle */
ob->rotAngle = value[0];
copy_v3_v3(ob->rotAxis, &value[1]);
-
+
/* TODO: validate axis? */
}
static void rna_Object_rotation_mode_set(PointerRNA *ptr, int value)
{
Object *ob = ptr->data;
-
+
/* use API Method for conversions... */
BKE_rotMode_change_values(ob->quat, ob->rot, ob->rotAxis, &ob->rotAngle, ob->rotmode, (short)value);
-
+
/* finally, set the new rotation type */
ob->rotmode = value;
}
@@ -844,7 +844,7 @@ static void rna_Object_dimensions_set(PointerRNA *ptr, const float *value)
static int rna_Object_location_editable(PointerRNA *ptr, int index)
{
Object *ob = (Object *)ptr->data;
-
+
/* only if the axis in question is locked, not editable... */
if ((index == 0) && (ob->protectflag & OB_LOCK_LOCX))
return 0;
@@ -859,7 +859,7 @@ static int rna_Object_location_editable(PointerRNA *ptr, int index)
static int rna_Object_scale_editable(PointerRNA *ptr, int index)
{
Object *ob = (Object *)ptr->data;
-
+
/* only if the axis in question is locked, not editable... */
if ((index == 0) && (ob->protectflag & OB_LOCK_SCALEX))
return 0;
@@ -874,7 +874,7 @@ static int rna_Object_scale_editable(PointerRNA *ptr, int index)
static int rna_Object_rotation_euler_editable(PointerRNA *ptr, int index)
{
Object *ob = (Object *)ptr->data;
-
+
/* only if the axis in question is locked, not editable... */
if ((index == 0) && (ob->protectflag & OB_LOCK_ROTX))
return 0;
@@ -889,7 +889,7 @@ static int rna_Object_rotation_euler_editable(PointerRNA *ptr, int index)
static int rna_Object_rotation_4d_editable(PointerRNA *ptr, int index)
{
Object *ob = (Object *)ptr->data;
-
+
/* only consider locks if locking components individually... */
if (ob->protectflag & OB_LOCK_ROT4D) {
/* only if the axis in question is locked, not editable... */
@@ -902,7 +902,7 @@ static int rna_Object_rotation_4d_editable(PointerRNA *ptr, int index)
else if ((index == 3) && (ob->protectflag & OB_LOCK_ROTZ))
return 0;
}
-
+
return PROP_EDITABLE;
}
@@ -937,7 +937,7 @@ static void rna_MaterialSlot_link_set(PointerRNA *ptr, int value)
{
Object *ob = (Object *)ptr->id.data;
int index = (Material **)ptr->data - ob->mat;
-
+
if (value) {
ob->matbits[index] = 1;
/* ob->colbits |= (1 << index); */ /* DEPRECATED */
@@ -958,7 +958,7 @@ static int rna_MaterialSlot_name_length(PointerRNA *ptr)
if (ma)
return strlen(ma->id.name + 2);
-
+
return 0;
}
@@ -1051,7 +1051,7 @@ static PointerRNA rna_Object_active_shape_key_get(PointerRNA *ptr)
if (key == NULL)
return PointerRNA_NULL;
-
+
kb = BLI_findlink(&key->block, ob->shapenr - 1);
RNA_pointer_create((ID *)key, &RNA_ShapeKey, kb, &keyptr);
return keyptr;
@@ -1064,7 +1064,7 @@ static PointerRNA rna_Object_field_get(PointerRNA *ptr)
/* weak */
if (!ob->pd)
ob->pd = object_add_collision_fields(0);
-
+
return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, ob->pd);
}
@@ -1078,7 +1078,7 @@ static PointerRNA rna_Object_collision_get(PointerRNA *ptr)
/* weak */
if (!ob->pd)
ob->pd = object_add_collision_fields(0);
-
+
return rna_pointer_inherit_refine(ptr, &RNA_CollisionSettings, ob->pd);
}
@@ -1465,7 +1465,7 @@ static void rna_def_vertex_group(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_VertexGroup_name_set");
/* update data because modifiers may use [#24761] */
RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data");
-
+
prop = RNA_def_property(srna, "lock_weight", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "", "Maintain the relative weights for the group");
RNA_def_property_boolean_sdna(prop, NULL, "flag", 0);
@@ -1521,7 +1521,7 @@ static void rna_def_face_map(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_FaceMap_name_set");
/* update data because modifiers may use [#24761] */
RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data");
-
+
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
RNA_def_property_ui_text(prop, "Select", "Face-map selection state (for tools to use)");
@@ -1557,7 +1557,7 @@ static void rna_def_material_slot(BlenderRNA *brna)
{0, "DATA", 0, "Data", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
/* NOTE: there is no MaterialSlot equivalent in DNA, so the internal
* pointer data points to ob->mat + index, and we manually implement
* get/set for the properties. */
@@ -1566,19 +1566,23 @@ static void rna_def_material_slot(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Material Slot", "Material slot in an object");
RNA_def_struct_ui_icon(srna, ICON_MATERIAL_DATA);
+ /* WARNING! Order is crucial for override to work properly here... :/
+ * 'link' must come before material pointer, since it defines where (in object or obdata) that one is set! */
+ prop = RNA_def_property(srna, "link", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, link_items);
+ RNA_def_property_enum_funcs(prop, "rna_MaterialSlot_link_get", "rna_MaterialSlot_link_set", NULL);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
+ RNA_def_property_ui_text(prop, "Link", "Link material to object or the object's data");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_MaterialSlot_update");
+
prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Material");
RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_pointer_funcs(prop, "rna_MaterialSlot_material_get", "rna_MaterialSlot_material_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Material", "Material data-block used by this material slot");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_MaterialSlot_update");
- prop = RNA_def_property(srna, "link", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, link_items);
- RNA_def_property_enum_funcs(prop, "rna_MaterialSlot_link_get", "rna_MaterialSlot_link_set", NULL);
- RNA_def_property_ui_text(prop, "Link", "Link material to object or the object's data");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_MaterialSlot_update");
-
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_MaterialSlot_name_get", "rna_MaterialSlot_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "Material slot name");
@@ -1693,7 +1697,7 @@ static void rna_def_object_modifiers(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_object_particle_systems(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
-
+
PropertyRNA *prop;
/* FunctionRNA *func; */
@@ -1709,7 +1713,7 @@ static void rna_def_object_particle_systems(BlenderRNA *brna, PropertyRNA *cprop
RNA_def_property_pointer_funcs(prop, "rna_Object_active_particle_system_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Active Particle System", "Active particle system being displayed");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_funcs(prop, "rna_Object_active_particle_system_index_get",
@@ -1724,7 +1728,7 @@ static void rna_def_object_particle_systems(BlenderRNA *brna, PropertyRNA *cprop
static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
-
+
PropertyRNA *prop;
FunctionRNA *func;
@@ -1750,7 +1754,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Object_active_vertex_group_index_range");
RNA_def_property_ui_text(prop, "Active Vertex Group Index", "Active index in vertex group array");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
-
+
/* vertex groups */ /* add_vertex_group */
func = RNA_def_function(srna, "new", "rna_Object_vgroup_new");
RNA_def_function_ui_description(func, "Add vertex group to object");
@@ -1773,7 +1777,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_object_face_maps(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
-
+
PropertyRNA *prop;
FunctionRNA *func;
@@ -1799,7 +1803,7 @@ static void rna_def_object_face_maps(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Object_active_face_map_index_range");
RNA_def_property_ui_text(prop, "Active Face Map Index", "Active index in face map array");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
-
+
/* face maps */ /* add_face_map */
func = RNA_def_function(srna, "new", "rna_Object_fmap_new");
RNA_def_function_ui_description(func, "Add face map to object");
@@ -1865,7 +1869,7 @@ static void rna_def_object(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
-
+
/* XXX: this RNA enum define is currently duplicated for objects,
* since there is some text here which is not applicable */
static const EnumPropertyItem prop_rotmode_items[] = {
@@ -1880,7 +1884,7 @@ static void rna_def_object(BlenderRNA *brna)
"Axis Angle (W+XYZ), defines a rotation around some axis defined by 3D-Vector"},
{0, NULL, 0, NULL, NULL}
};
-
+
static float default_quat[4] = {1, 0, 0, 0}; /* default quaternion values */
static float default_axisAngle[4] = {0, 0, 1, 0}; /* default axis-angle rotation values */
static float default_scale[3] = {1, 1, 1}; /* default scale values */
@@ -1895,6 +1899,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "ID");
RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_data_set", "rna_Object_data_typef", NULL);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Data", "Object data");
RNA_def_property_update(prop, 0, "rna_Object_internal_update_data");
@@ -1928,10 +1933,11 @@ static void rna_def_object(BlenderRNA *brna)
/* parent */
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_parent_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK | PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Parent", "Parent Object");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_dependency_update");
-
+
prop = RNA_def_property(srna, "parent_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "partype");
RNA_def_property_enum_items(prop, parent_type_items);
@@ -1950,7 +1956,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Object_parent_bone_set");
RNA_def_property_ui_text(prop, "Parent Bone", "Name of parent bone in case of a bone parenting relation");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_dependency_update");
-
+
/* Track and Up flags */
/* XXX: these have been saved here for a bit longer (after old track was removed),
* since some other tools still refer to this */
@@ -1969,7 +1975,7 @@ static void rna_def_object(BlenderRNA *brna)
"Axis that points in the upward direction (applies to DupliFrame when "
"parent 'Follow' is enabled)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
-
+
/* proxy */
prop = RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Proxy", "Library object this proxy object controls");
@@ -1981,6 +1987,7 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "material_slots", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol");
RNA_def_property_struct_type(prop, "MaterialSlot");
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC | PROPOVERRIDE_NO_PROP_NAME);
/* don't dereference pointer! */
RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_iterator_array_get", NULL, NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Material Slots", "Material slots in the object");
@@ -1997,28 +2004,29 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "active_material_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "actcol");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_int_funcs(prop, "rna_Object_active_material_index_get", "rna_Object_active_material_index_set",
"rna_Object_active_material_index_range");
RNA_def_property_ui_text(prop, "Active Material Index", "Index of active material slot");
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, NULL);
-
+
/* transform */
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "loc");
RNA_def_property_editable_array_func(prop, "rna_Object_location_editable");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Location", "Location of the object");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
prop = RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION);
RNA_def_property_float_sdna(prop, NULL, "quat");
RNA_def_property_editable_array_func(prop, "rna_Object_rotation_4d_editable");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_float_array_default(prop, default_quat);
RNA_def_property_ui_text(prop, "Quaternion Rotation", "Rotation in Quaternions");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
/* XXX: for axis-angle, it would have been nice to have 2 separate fields for UI purposes, but
* having a single one is better for Keyframing and other property-management situations...
*/
@@ -2028,27 +2036,28 @@ static void rna_def_object(BlenderRNA *brna)
"rna_Object_rotation_axis_angle_set", NULL);
RNA_def_property_editable_array_func(prop, "rna_Object_rotation_4d_editable");
RNA_def_property_float_array_default(prop, default_axisAngle);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
prop = RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "rot");
RNA_def_property_editable_array_func(prop, "rna_Object_rotation_euler_editable");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
prop = RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rotmode");
RNA_def_property_enum_items(prop, prop_rotmode_items); /* XXX move to using a single define of this someday */
RNA_def_property_enum_funcs(prop, NULL, "rna_Object_rotation_mode_set", NULL);
RNA_def_property_ui_text(prop, "Rotation Mode", "");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
- RNA_def_property_flag(prop, PROP_PROPORTIONAL | PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_PROPORTIONAL);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_editable_array_func(prop, "rna_Object_scale_editable");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 3);
RNA_def_property_float_array_default(prop, default_scale);
@@ -2063,7 +2072,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_ui_text(prop, "Dimensions", "Absolute bounding box dimensions of the object");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
/* delta transforms */
prop = RNA_def_property(srna, "delta_location", PROP_FLOAT, PROP_TRANSLATION);
@@ -2071,20 +2080,20 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Delta Location", "Extra translation added to the location of the object");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
prop = RNA_def_property(srna, "delta_rotation_euler", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "drot");
RNA_def_property_ui_text(prop, "Delta Rotation (Euler)",
"Extra rotation added to the rotation of the object (when using Euler rotations)");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
prop = RNA_def_property(srna, "delta_rotation_quaternion", PROP_FLOAT, PROP_QUATERNION);
RNA_def_property_float_sdna(prop, NULL, "dquat");
RNA_def_property_float_array_default(prop, default_quat);
RNA_def_property_ui_text(prop, "Delta Rotation (Quaternion)",
"Extra rotation added to the rotation of the object (when using Quaternion rotations)");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
#if 0 /* XXX not supported well yet... */
prop = RNA_def_property(srna, "delta_rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE);
/* FIXME: this is not a single field any more! (drotAxis and drotAngle) */
@@ -2102,7 +2111,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_float_array_default(prop, default_scale);
RNA_def_property_ui_text(prop, "Delta Scale", "Extra scaling added to the scale of the object");
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
/* transform locks */
prop = RNA_def_property(srna, "lock_location", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_LOCX);
@@ -2117,7 +2126,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Lock Rotation", "Lock editing of rotation in the interface");
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update");
-
+
/* XXX this is sub-optimal - it really should be included above,
* but due to technical reasons we can't do this! */
prop = RNA_def_property(srna, "lock_rotation_w", PROP_BOOLEAN, PROP_NONE);
@@ -2176,13 +2185,13 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "Modifier");
RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting the geometric data of the object");
RNA_def_property_override_funcs(prop, NULL, NULL, "rna_Object_modifiers_override_apply");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC | PROP_OVERRIDABLE_STATIC_INSERTION);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC | PROPOVERRIDE_STATIC_INSERTION);
rna_def_object_modifiers(brna, prop);
/* constraints */
prop = RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Constraint");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC | PROP_OVERRIDABLE_STATIC_INSERTION);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC | PROPOVERRIDE_STATIC_INSERTION);
RNA_def_property_ui_text(prop, "Constraints", "Constraints affecting the transformation of the object");
RNA_def_property_override_funcs(prop, NULL, NULL, "rna_Object_constraints_override_apply");
/* RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "constraints__add", "constraints__remove"); */
@@ -2195,14 +2204,14 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vertex Groups", "Vertex groups of the object");
rna_def_object_vertex_groups(brna, prop);
-
+
/* face maps */
prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "fmaps", NULL);
RNA_def_property_struct_type(prop, "FaceMap");
RNA_def_property_ui_text(prop, "Face Maps", "Maps of faces of the object");
rna_def_object_face_maps(brna, prop);
-
+
/* empty */
prop = RNA_def_property(srna, "empty_draw_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype");
@@ -2236,7 +2245,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "index");
RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Object Index\" render pass");
RNA_def_property_update(prop, NC_OBJECT, "rna_Object_internal_update_draw");
-
+
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "col");
RNA_def_property_ui_text(prop, "Color", "Object color and alpha, used when faces have the ObColor mode enabled");
@@ -2267,7 +2276,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Particle Systems", "Particle systems emitted from the object");
rna_def_object_particle_systems(brna, prop);
-
+
prop = RNA_def_property(srna, "rigid_body", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "rigidbody_object");
RNA_def_property_struct_type(prop, "RigidBodyObject");
@@ -2277,7 +2286,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "rigidbody_constraint");
RNA_def_property_struct_type(prop, "RigidBodyConstraint");
RNA_def_property_ui_text(prop, "Rigid Body Constraint", "Constraint constraining rigid bodies");
-
+
/* restrict */
prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", OB_RESTRICT_RENDER);
@@ -2300,10 +2309,10 @@ static void rna_def_object(BlenderRNA *brna)
/* anim */
rna_def_animdata_common(srna);
-
+
rna_def_animviz_common(srna);
rna_def_motionpath_common(srna);
-
+
/* slow parenting */
/* XXX: evil old crap */
prop = RNA_def_property(srna, "use_slow_parent", PROP_BOOLEAN, PROP_NONE);
@@ -2312,7 +2321,7 @@ static void rna_def_object(BlenderRNA *brna)
"Create a delay in the parent relationship (beware: this isn't renderfarm "
"safe and may be invalid after jumping around the timeline)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
-
+
prop = RNA_def_property(srna, "slow_parent_offset", PROP_FLOAT, PROP_NONE | PROP_UNIT_TIME);
RNA_def_property_float_sdna(prop, NULL, "sf");
RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
@@ -2386,7 +2395,7 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "is_duplicator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLI);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
/* drawing */
prop = RNA_def_property(srna, "draw_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "dt");
@@ -2404,22 +2413,22 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_enum_items(prop, boundtype_items);
RNA_def_property_ui_text(prop, "Draw Bounds Type", "Object boundary display type");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
prop = RNA_def_property(srna, "show_name", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAWNAME);
RNA_def_property_ui_text(prop, "Draw Name", "Display the object's name");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
prop = RNA_def_property(srna, "show_axis", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_AXIS);
RNA_def_property_ui_text(prop, "Draw Axes", "Display the object's origin and axes");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
prop = RNA_def_property(srna, "show_texture_space", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_TEXSPACE);
RNA_def_property_ui_text(prop, "Draw Texture Space", "Display the object's texture space");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAWWIRE);
RNA_def_property_ui_text(prop, "Draw Wire", "Add the object's wireframe over solid drawing");
@@ -2435,13 +2444,13 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Transparent",
"Display material transparency in the object (unsupported for duplicator drawing)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
prop = RNA_def_property(srna, "show_x_ray", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAWXRAY);
RNA_def_property_ui_text(prop, "X-Ray",
"Make the object draw in front of others (unsupported for duplicator drawing)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
/* Grease Pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
@@ -2449,7 +2458,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil data-block");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
+
/* pose */
prop = RNA_def_property(srna, "pose_library", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "poselib");
@@ -2460,7 +2469,7 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "pose", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "pose");
RNA_def_property_struct_type(prop, "Pose");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Pose", "Current pose for armatures");
/* shape keys */
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index a837a2ff032..fb27af7c464 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -218,7 +218,7 @@ static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *
RNA_pointer_create((ID *)ob->data, &RNA_ShapeKey, kb, &keyptr);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
-
+
return keyptr;
}
else {
@@ -355,7 +355,7 @@ static void rna_Object_closest_point_on_mesh(
int *r_success, float r_location[3], float r_normal[3], int *r_index)
{
BVHTreeFromMesh treeData = {NULL};
-
+
if (ob->derivedFinal == NULL) {
BKE_reportf(reports, RPT_ERROR, "Object '%s' has no mesh data to be used for finding nearest point",
ob->id.name + 2);
@@ -591,7 +591,7 @@ void RNA_api_object(StructRNA *srna)
func = RNA_def_function(srna, "ray_cast", "rna_Object_ray_cast");
RNA_def_function_ui_description(func, "Cast a ray onto in object space");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
-
+
/* ray start and end */
parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 4c09f7cf4cf..b79dee63136 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -219,7 +219,7 @@ static void rna_Cache_active_point_cache_index_range(PointerRNA *ptr, int *min,
Object *ob = ptr->id.data;
PointCache *cache = ptr->data;
PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
-
+
*min = 0;
*max = 0;
@@ -247,7 +247,7 @@ static void rna_Cache_active_point_cache_index_set(struct PointerRNA *ptr, int v
Object *ob = ptr->id.data;
PointCache *cache = ptr->data;
PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
-
+
if (pid.cache) {
*(pid.cache_ptr) = BLI_findlink(pid.ptcaches, value);
}
@@ -527,13 +527,13 @@ static void rna_FieldSettings_dependency_update(Main *bmain, Scene *scene, Point
static char *rna_FieldSettings_path(PointerRNA *ptr)
{
PartDeflect *pd = (PartDeflect *)ptr->data;
-
+
/* Check through all possible places the settings can be to find the right one */
-
+
if (particle_id_check(ptr)) {
/* particle system force field */
ParticleSettings *part = (ParticleSettings *)ptr->id.data;
-
+
if (part->pd == pd)
return BLI_sprintfN("force_field_1");
else if (part->pd2 == pd)
@@ -542,7 +542,7 @@ static char *rna_FieldSettings_path(PointerRNA *ptr)
else {
/* object force field */
Object *ob = (Object *)ptr->id.data;
-
+
if (ob->pd == pd)
return BLI_sprintfN("field");
}
@@ -580,11 +580,11 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
{
EffectorWeights *ew = (EffectorWeights *)ptr->data;
/* Check through all possible places the settings can be to find the right one */
-
+
if (particle_id_check(ptr)) {
/* particle effector weights */
ParticleSettings *part = (ParticleSettings *)ptr->id.data;
-
+
if (part->effector_weights == ew)
return BLI_sprintfN("effector_weights");
}
@@ -602,7 +602,7 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
return BLI_sprintfN("modifiers[\"%s\"].settings.effector_weights", name_esc);
}
}
-
+
/* check cloth modifier */
md = (ModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
if (md) {
@@ -613,7 +613,7 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
return BLI_sprintfN("modifiers[\"%s\"].settings.effector_weights", name_esc);
}
}
-
+
/* check smoke modifier */
md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke);
if (md) {
@@ -693,9 +693,9 @@ static const EnumPropertyItem *rna_Effector_shape_itemf(bContext *UNUSED(C), Poi
if (particle_id_check(ptr))
return empty_shape_items;
-
+
ob = (Object *)ptr->id.data;
-
+
if (ob->type == OB_CURVE) {
if (ob->pd->forcefield == PFIELD_VORTEX)
return curve_vortex_shape_items;
@@ -880,44 +880,44 @@ static void rna_def_collision(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "PartDeflect");
RNA_def_struct_path_func(srna, "rna_CollisionSettings_path");
RNA_def_struct_ui_text(srna, "Collision Settings", "Collision settings for object in physics simulation");
-
+
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "deflect", 1);
RNA_def_property_ui_text(prop, "Enabled", "Enable this objects as a collider for physics systems");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_dependency_update");
-
+
/* Particle Interaction */
-
+
prop = RNA_def_property(srna, "damping_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pdef_damp");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Damping Factor", "Amount of damping during particle collision");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
-
+
prop = RNA_def_property(srna, "damping_random", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pdef_rdamp");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Random Damping", "Random variation of damping");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
-
+
prop = RNA_def_property(srna, "friction_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pdef_frict");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Friction Factor", "Amount of friction during particle collision");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
-
+
prop = RNA_def_property(srna, "friction_random", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pdef_rfrict");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Random Friction", "Random variation of friction");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
-
+
prop = RNA_def_property(srna, "permeability", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pdef_perm");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Permeability", "Chance that the particle will pass through the mesh");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
-
+
prop = RNA_def_property(srna, "use_particle_kill", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PDEFLE_KILL_PART);
RNA_def_property_ui_text(prop, "Kill Particles", "Kill collided particles");
@@ -928,21 +928,21 @@ static void rna_def_collision(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Stickiness", "Amount of stickiness to surface collision");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
-
+
/* Soft Body and Cloth Interaction */
-
+
prop = RNA_def_property(srna, "thickness_inner", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pdef_sbift");
RNA_def_property_range(prop, 0.001f, 1.0f);
RNA_def_property_ui_text(prop, "Inner Thickness", "Inner face thickness (only used by softbodies)");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
-
+
prop = RNA_def_property(srna, "thickness_outer", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pdef_sboft");
RNA_def_property_range(prop, 0.001f, 1.0f);
RNA_def_property_ui_text(prop, "Outer Thickness", "Outer face thickness");
RNA_def_property_update(prop, 0, "rna_CollisionSettings_update");
-
+
prop = RNA_def_property(srna, "damping", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pdef_sbdamp");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -973,7 +973,7 @@ static void rna_def_effector_weight(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", EFF_WEIGHT_DO_HAIR);
RNA_def_property_ui_text(prop, "Use For Growing Hair", "Use force fields when growing hair");
RNA_def_property_update(prop, 0, "rna_EffectorWeight_update");
-
+
/* General */
prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Collection");
@@ -1092,7 +1092,7 @@ static void rna_def_field(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem field_type_items[] = {
{0, "NONE", 0, "None", ""},
{PFIELD_FORCE, "FORCE", ICON_FORCE_FORCE, "Force", "Radial field toward the center of object"},
@@ -1122,7 +1122,7 @@ static void rna_def_field(BlenderRNA *brna)
{PFIELD_FALL_CONE, "CONE", 0, "Cone", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem texture_items[] = {
{PFIELD_TEX_RGB, "RGB", 0, "RGB", ""},
{PFIELD_TEX_GRAD, "GRADIENT", 0, "Gradient", ""},
@@ -1136,7 +1136,7 @@ static void rna_def_field(BlenderRNA *brna)
{PFIELD_Z_NEG, "NEGATIVE", 0, "-Z", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem guide_kink_items[] = {
{0, "NONE", 0, "Nothing", ""},
{1, "CURL", 0, "Curl", ""},
@@ -1153,9 +1153,9 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_FieldSettings_path");
RNA_def_struct_ui_text(srna, "Field Settings", "Field settings for an object in physics simulation");
RNA_def_struct_ui_icon(srna, ICON_PHYSICS);
-
+
/* Enums */
-
+
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "forcefield");
RNA_def_property_enum_items(prop, field_type_items);
@@ -1168,13 +1168,13 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Effector_shape_itemf");
RNA_def_property_ui_text(prop, "Shape", "Which direction is used to calculate the effector force");
RNA_def_property_update(prop, 0, "rna_FieldSettings_shape_update");
-
+
prop = RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "falloff");
RNA_def_property_enum_items(prop, falloff_items);
RNA_def_property_ui_text(prop, "Fall-Off", "");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "texture_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "tex_mode");
RNA_def_property_enum_items(prop, texture_items);
@@ -1188,9 +1188,9 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_enum_items(prop, zdirection_items);
RNA_def_property_ui_text(prop, "Z Direction", "Effect in full or only positive/negative Z direction");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
/* Float */
-
+
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f_strength");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
@@ -1242,38 +1242,38 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Rest Length", "Rest length of the harmonic force");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "falloff_power", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f_power");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Falloff Power", "");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "distance_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mindist");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Minimum Distance", "Minimum distance for the field's fall-off");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "distance_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "maxdist");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 1000.0f, 1.0f, 3);
RNA_def_property_ui_text(prop, "Maximum Distance", "Maximum distance for the field to work");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "radial_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "minrad");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Minimum Radial Distance", "Minimum radial distance for the field's fall-off");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "radial_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "maxrad");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_text(prop, "Maximum Radial Distance", "Maximum radial distance for the field to work");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "radial_falloff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f_power_r");
RNA_def_property_range(prop, 0.0f, 10.0f);
@@ -1286,7 +1286,7 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Nabla",
"Defines size of derivative offset used for calculating gradient and curl");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "noise", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f_noise");
RNA_def_property_range(prop, 0.0f, 10.0f);
@@ -1299,23 +1299,23 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
/* Boolean */
-
+
prop = RNA_def_property(srna, "use_min_distance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_USEMIN);
RNA_def_property_ui_text(prop, "Use Min", "Use a minimum distance for the field's fall-off");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "use_max_distance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_USEMAX);
RNA_def_property_ui_text(prop, "Use Max", "Use a maximum distance for the field to work");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "use_radial_min", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_USEMINR);
RNA_def_property_ui_text(prop, "Use Min", "Use a minimum radial distance for the field's fall-off");
/* "Use a minimum angle for the field's fall-off" */
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "use_radial_max", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_USEMAXR);
RNA_def_property_ui_text(prop, "Use Max", "Use a maximum radial distance for the field to work");
@@ -1331,12 +1331,12 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GLOBAL_CO);
RNA_def_property_ui_text(prop, "Use Global Coordinates", "Use effector/global coordinates for turbulence");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "use_2d_force", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_2D);
RNA_def_property_ui_text(prop, "2D", "Apply force only in 2D");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "use_root_coords", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_ROOTCO);
RNA_def_property_ui_text(prop, "Root Texture Coordinates", "Texture coordinates from root particle locations");
@@ -1371,9 +1371,9 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Gravity Falloff", "Multiply force by 1/distance²");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
/* Pointer */
-
+
prop = RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tex");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -1385,9 +1385,9 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Domain Object", "Select domain object of the smoke simulation");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
/********** Curve Guide Field Settings **********/
-
+
prop = RNA_def_property(srna, "guide_minimum", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f_strength");
RNA_def_property_range(prop, 0.0f, 1000.0f);
@@ -1409,29 +1409,29 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GUIDE_PATH_WEIGHT);
RNA_def_property_ui_text(prop, "Weights", "Use curve weights to influence the particle influence along the curve");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
/* Clump Settings */
-
+
prop = RNA_def_property(srna, "guide_clump_amount", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clump_fac");
RNA_def_property_range(prop, -1.0f, 1.0f);
RNA_def_property_ui_text(prop, "Amount", "Amount of clumping");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "guide_clump_shape", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clump_pow");
RNA_def_property_range(prop, -0.999f, 0.999f);
RNA_def_property_ui_text(prop, "Shape", "Shape of clumping");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
/* Kink Settings */
-
+
prop = RNA_def_property(srna, "guide_kink_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "kink");
RNA_def_property_enum_items(prop, guide_kink_items);
RNA_def_property_ui_text(prop, "Kink", "Type of periodic offset on the curve");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "guide_kink_axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "kink_axis");
RNA_def_property_enum_items(prop, rna_enum_axis_xyz_items);
@@ -1443,13 +1443,13 @@ static void rna_def_field(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Frequency", "The frequency of the offset (1/total length)");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "guide_kink_shape", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "kink_shape");
RNA_def_property_range(prop, -0.999f, 0.999f);
RNA_def_property_ui_text(prop, "Shape", "Adjust the offset to the beginning/end");
RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
-
+
prop = RNA_def_property(srna, "guide_kink_amplitude", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "kink_amp");
RNA_def_property_range(prop, 0.0f, 10.0f);
@@ -1464,7 +1464,7 @@ static void rna_def_softbody(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem collision_type_items[] = {
{SBC_MODE_MANUAL, "MANUAL", 0, "Manual", "Manual adjust"},
{SBC_MODE_AVG, "AVERAGE", 0, "Average", "Average Spring length * Ball Size"},
@@ -1473,7 +1473,7 @@ static void rna_def_softbody(BlenderRNA *brna)
{SBC_MODE_AVGMINMAX, "MINMAX", 0, "AvMinMax", "(Min+Max)/2 * Ball Size"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem aerodynamics_type[] = {
{0, "SIMPLE", 0, "Simple", "Edges receive a drag force from surrounding media"},
{1, "LIFT_FORCE", 0, "Lift Force", "Edges receive a lift force when passing through surrounding media"},
@@ -1484,42 +1484,42 @@ static void rna_def_softbody(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "SoftBody");
RNA_def_struct_path_func(srna, "rna_SoftBodySettings_path");
RNA_def_struct_ui_text(srna, "Soft Body Settings", "Soft body simulation settings for an object");
-
+
/* General Settings */
-
+
prop = RNA_def_property(srna, "friction", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mediafrict");
RNA_def_property_range(prop, 0.0f, 50.0f);
RNA_def_property_ui_text(prop, "Friction", "General media friction for point movements");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "nodemass");
RNA_def_property_range(prop, 0.0f, 50000.0f);
RNA_def_property_ui_text(prop, "Mass", "General Mass value");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "vertex_group_mass", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "namedVG_Mass");
RNA_def_property_ui_text(prop, "Mass Vertex Group", "Control point mass values");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SoftBodySettings_mass_vgroup_set");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
/* no longer used */
prop = RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION);
RNA_def_property_float_sdna(prop, NULL, "grav");
RNA_def_property_range(prop, -10.0f, 10.0f);
RNA_def_property_ui_text(prop, "Gravitation", "Apply gravitation to point movement");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "physics_speed");
RNA_def_property_range(prop, 0.01f, 100.0f);
RNA_def_property_ui_text(prop, "Speed", "Tweak timing for physics to control frequency and speed");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
/* Goal */
-
+
prop = RNA_def_property(srna, "vertex_group_goal", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "vertgroup");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* not impossible .. but not supported yet */
@@ -1527,7 +1527,7 @@ static void rna_def_softbody(BlenderRNA *brna)
"rna_SoftBodySettings_goal_vgroup_length",
"rna_SoftBodySettings_goal_vgroup_set");
RNA_def_property_ui_text(prop, "Goal Vertex Group", "Control point weight values");
-
+
prop = RNA_def_property(srna, "goal_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "mingoal");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -1547,104 +1547,104 @@ static void rna_def_softbody(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Goal Default",
"Default Goal (vertex target position) value");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "goalspring");
RNA_def_property_range(prop, 0.0f, 0.999f);
RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "goalfrict");
RNA_def_property_range(prop, 0.0f, 50.0f);
RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
/* Edge Spring Settings */
-
+
prop = RNA_def_property(srna, "pull", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "inspring");
RNA_def_property_range(prop, 0.0f, 0.999f);
RNA_def_property_ui_text(prop, "Pull", "Edge spring stiffness when longer than rest length");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "push", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "inpush");
RNA_def_property_range(prop, 0.0f, 0.999f);
RNA_def_property_ui_text(prop, "Push", "Edge spring stiffness when shorter than rest length");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "damping", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "infrict");
RNA_def_property_range(prop, 0.0f, 50.0f);
RNA_def_property_ui_text(prop, "Damp", "Edge spring friction");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "spring_length", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "springpreload");
RNA_def_property_range(prop, 0.0f, 200.0f);
RNA_def_property_ui_text(prop, "view_layer", "Alter spring length to shrink/blow up (unit %) 0 to disable");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "aero", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "aeroedge");
RNA_def_property_range(prop, 0.0f, 30000.0f);
RNA_def_property_ui_text(prop, "Aero", "Make edges 'sail'");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "plastic", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "plastic");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Plastic", "Permanent deform");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "bend", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "secondspring");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Bending", "Bending Stiffness");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "shear", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "shearstiff");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Shear", "Shear Stiffness");
-
+
prop = RNA_def_property(srna, "vertex_group_spring", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "namedVG_Spring_K");
RNA_def_property_ui_text(prop, "Spring Vertex Group", "Control point spring strength values");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SoftBodySettings_spring_vgroup_set");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
/* Collision */
-
+
prop = RNA_def_property(srna, "collision_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "sbc_mode");
RNA_def_property_enum_items(prop, collision_type_items);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Collision Type", "Choose Collision Type");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "ball_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colball");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* code is not ready for that yet */
RNA_def_property_range(prop, -10.0f, 10.0f);
RNA_def_property_ui_text(prop, "Ball Size", "Absolute ball size or factor if not manually adjusted");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "ball_stiff", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ballstiff");
RNA_def_property_range(prop, 0.001f, 100.0f);
RNA_def_property_ui_text(prop, "Ball Size", "Ball inflating pressure");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "ball_damp", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "balldamp");
RNA_def_property_range(prop, 0.001f, 1.0f);
RNA_def_property_ui_text(prop, "Ball Size", "Blending to inelastic collision");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
/* Solver */
-
+
prop = RNA_def_property(srna, "error_threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rklimit");
RNA_def_property_range(prop, 0.001f, 10.0f);
@@ -1652,25 +1652,25 @@ static void rna_def_softbody(BlenderRNA *brna)
"The Runge-Kutta ODE solver error limit, low value gives more precision, "
"high values speed");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "step_min", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "minloops");
RNA_def_property_range(prop, 0, 30000);
RNA_def_property_ui_text(prop, "Min Step", "Minimal # solver steps/frame");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "step_max", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "maxloops");
RNA_def_property_range(prop, 0, 30000);
RNA_def_property_ui_text(prop, "Max Step", "Maximal # solver steps/frame");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "choke", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "choke");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Choke", "'Viscosity' inside collision target");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "fuzzy", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "fuzzyness");
RNA_def_property_range(prop, 1, 100);
@@ -1678,16 +1678,16 @@ static void rna_def_softbody(BlenderRNA *brna)
"Fuzziness while on collision, high values make collision handling faster "
"but less stable");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "use_auto_step", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_OLDERR);
RNA_def_property_ui_text(prop, "V", "Use velocities for automagic step sizes");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "use_diagnose", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_MONITOR);
RNA_def_property_ui_text(prop, "Print Performance to Console", "Turn on SB diagnose console prints");
-
+
prop = RNA_def_property(srna, "use_estimate_matrix", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_ESTIMATEIPO);
RNA_def_property_ui_text(prop, "Estimate matrix", "Estimate matrix... split to COM, ROT, SCALE");
@@ -1717,44 +1717,44 @@ static void rna_def_softbody(BlenderRNA *brna)
/* Flags */
-
+
prop = RNA_def_property(srna, "use_goal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_goal_get", "rna_SoftBodySettings_use_goal_set");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Use Goal", "Define forces for vertices to stick to animated position");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "use_edges", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_edges_get", "rna_SoftBodySettings_use_edges_set");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Use Edges", "Use Edges as springs");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "use_stiff_quads", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_stiff_quads_get",
"rna_SoftBodySettings_stiff_quads_set");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Stiff Quads", "Add diagonal springs on 4-gons");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "use_edge_collision", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_edge_collision_get",
"rna_SoftBodySettings_edge_collision_set");
RNA_def_property_ui_text(prop, "Edge Collision", "Edges collide too");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "use_face_collision", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_face_collision_get",
"rna_SoftBodySettings_face_collision_set");
RNA_def_property_ui_text(prop, "Face Collision", "Faces collide too, can be very slow");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "aerodynamics_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, aerodynamics_type);
RNA_def_property_enum_funcs(prop, "rna_SoftBodySettings_new_aero_get", "rna_SoftBodySettings_new_aero_set", NULL);
RNA_def_property_ui_text(prop, "Aerodynamics Type", "Method of calculating aerodynamic interaction");
RNA_def_property_update(prop, 0, "rna_softbody_update");
-
+
prop = RNA_def_property(srna, "use_self_collision", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_self_collision_get",
"rna_SoftBodySettings_self_collision_set");
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index c32314fba71..573bbb5345b 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -115,7 +115,7 @@ static const EnumPropertyItem part_ren_as_items[] = {
{PART_DRAW_LINE, "LINE", 0, "Line", ""},
{PART_DRAW_PATH, "PATH", 0, "Path", ""},
{PART_DRAW_OB, "OBJECT", 0, "Object", ""},
- {PART_DRAW_GR, "GROUP", 0, "Group", ""},
+ {PART_DRAW_GR, "COLLECTION", 0, "Collection", ""},
{PART_DRAW_BB, "BILLBOARD", 0, "Billboard", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -125,7 +125,7 @@ static const EnumPropertyItem part_hair_ren_as_items[] = {
{PART_DRAW_NOT, "NONE", 0, "None", ""},
{PART_DRAW_PATH, "PATH", 0, "Path", ""},
{PART_DRAW_OB, "OBJECT", 0, "Object", ""},
- {PART_DRAW_GR, "GROUP", 0, "Group", ""},
+ {PART_DRAW_GR, "COLLECTION", 0, "Collection", ""},
{0, NULL, 0, NULL, NULL}
};
#endif
@@ -134,6 +134,7 @@ static const EnumPropertyItem part_hair_ren_as_items[] = {
#include "BLI_math.h"
+#include "BKE_boids.h"
#include "BKE_context.h"
#include "BKE_cloth.h"
#include "BKE_colortools.h"
@@ -301,7 +302,7 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, ReportList *repor
/* get uvco */
if (r_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
-
+
if (num != DMCACHE_NOTFOUND) {
MFace *mface;
MTFace *mtface;
@@ -341,7 +342,7 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
if (part == NULL || pars == NULL)
return;
-
+
if (part->ren_as == PART_DRAW_OB || part->ren_as == PART_DRAW_GR || part->ren_as == PART_DRAW_NOT)
return;
@@ -638,9 +639,31 @@ static void rna_Particle_change_type(Main *bmain, Scene *UNUSED(scene), PointerR
DEG_relations_tag_update(bmain);
}
-static void rna_Particle_change_physics(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Particle_change_physics_type(Main *bmain, Scene *scene, PointerRNA *ptr)
{
particle_recalc(bmain, scene, ptr, PSYS_RECALC_RESET | PSYS_RECALC_PHYS);
+
+ ParticleSettings *part = (ParticleSettings *)ptr->data;
+
+ if (part->phystype == PART_PHYS_BOIDS && part->boids == NULL) {
+ BoidState *state;
+
+ part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings");
+ boid_default_settings(part->boids);
+
+ state = boid_new_state(part->boids);
+ BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Separate));
+ BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Flock));
+
+ ((BoidRule *)state->rules.first)->flag |= BOIDRULE_CURRENT;
+
+ state->flag |= BOIDSTATE_CURRENT;
+ BLI_addtail(&part->boids->states, state);
+ }
+ else if (part->phystype == PART_PHYS_FLUID && part->fluid == NULL) {
+ part->fluid = MEM_callocN(sizeof(SPHFluidSettings), "SPH Fluid Settings");
+ BKE_particlesettings_fluid_default_settings(part);
+ }
}
static void rna_Particle_redo_child(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -666,7 +689,7 @@ static ParticleSystem *rna_particle_system_for_target(Object *ob, ParticleTarget
for (pt = psys->targets.first; pt; pt = pt->next)
if (pt == target)
return psys;
-
+
return NULL;
}
@@ -694,7 +717,7 @@ static void rna_Particle_target_reset(Main *bmain, Scene *UNUSED(scene), Pointer
else
pt->flag &= ~PTARGET_VALID;
}
-
+
psys->recalc = PSYS_RECALC_RESET;
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -710,7 +733,7 @@ static void rna_Particle_target_redo(Main *UNUSED(bmain), Scene *UNUSED(scene),
Object *ob = (Object *)ptr->id.data;
ParticleTarget *pt = (ParticleTarget *)ptr->data;
ParticleSystem *psys = rna_particle_system_for_target(ob, pt);
-
+
psys->recalc = PSYS_RECALC_REDO;
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -722,7 +745,7 @@ static void rna_Particle_hair_dynamics_update(Main *bmain, Scene *scene, Pointer
{
Object *ob = (Object *)ptr->id.data;
ParticleSystem *psys = (ParticleSystem *)ptr->data;
-
+
if (psys && !psys->clmd) {
psys->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
psys->clmd->sim_parms->goalspring = 0.0f;
@@ -884,26 +907,26 @@ static int rna_PartSettings_is_fluid_get(PointerRNA *ptr)
static void rna_ParticleSettings_use_clump_curve_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
ParticleSettings *part = ptr->data;
-
+
if (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) {
if (!part->clumpcurve) {
BKE_particlesettings_clump_curve_init(part);
}
}
-
+
rna_Particle_redo_child(bmain, scene, ptr);
}
static void rna_ParticleSettings_use_roughness_curve_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
ParticleSettings *part = ptr->data;
-
+
if (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) {
if (!part->roughcurve) {
BKE_particlesettings_rough_curve_init(part);
}
}
-
+
rna_Particle_redo_child(bmain, scene, ptr);
}
@@ -991,7 +1014,7 @@ static void rna_ParticleTarget_name_get(PointerRNA *ptr, char *str)
Object *ob = (Object *) ptr->id.data;
psys = BLI_findlink(&ob->particlesystem, pt->psys - 1);
}
-
+
if (psys) {
if (pt->ob)
sprintf(str, "%s: %s", pt->ob->id.name + 2, psys->name);
@@ -1024,10 +1047,10 @@ static int particle_id_check(PointerRNA *ptr)
static char *rna_SPHFluidSettings_path(PointerRNA *ptr)
{
SPHFluidSettings *fluid = (SPHFluidSettings *)ptr->data;
-
+
if (particle_id_check(ptr)) {
ParticleSettings *part = (ParticleSettings *)ptr->id.data;
-
+
if (part->fluid == fluid)
return BLI_sprintfN("fluid");
}
@@ -1169,7 +1192,7 @@ static PointerRNA rna_Particle_field1_get(PointerRNA *ptr)
/* weak */
if (!part->pd)
part->pd = object_add_collision_fields(0);
-
+
return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, part->pd);
}
@@ -1180,7 +1203,7 @@ static PointerRNA rna_Particle_field2_get(PointerRNA *ptr)
/* weak */
if (!part->pd2)
part->pd2 = object_add_collision_fields(0);
-
+
return rna_pointer_inherit_refine(ptr, &RNA_FieldSettings, part->pd2);
}
@@ -1333,7 +1356,7 @@ static void rna_def_particle_hair_key(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Location (Object Space)", "Location of the hair key in object space");
RNA_def_property_float_funcs(prop, "rna_ParticleHairKey_location_object_get",
"rna_ParticleHairKey_location_object_set", NULL);
-
+
prop = RNA_def_property(srna, "co_local", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "co");
RNA_def_property_ui_text(prop, "Location",
@@ -1719,7 +1742,7 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna)
{MTEX_SPHERE, "SPHERE", 0, "Sphere", "Map with Z as central axis"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem prop_x_mapping_items[] = {
{0, "NONE", 0, "None", ""},
{1, "X", 0, "X", ""},
@@ -1727,7 +1750,7 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna)
{3, "Z", 0, "Z", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem prop_y_mapping_items[] = {
{0, "NONE", 0, "None", ""},
{1, "X", 0, "X", ""},
@@ -1735,7 +1758,7 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna)
{3, "Z", 0, "Z", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem prop_z_mapping_items[] = {
{0, "NONE", 0, "None", ""},
{1, "X", 0, "X", ""},
@@ -1773,19 +1796,19 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_x_mapping_items);
RNA_def_property_ui_text(prop, "X Mapping", "");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
+
prop = RNA_def_property(srna, "mapping_y", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projy");
RNA_def_property_enum_items(prop, prop_y_mapping_items);
RNA_def_property_ui_text(prop, "Y Mapping", "");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
+
prop = RNA_def_property(srna, "mapping_z", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projz");
RNA_def_property_enum_items(prop, prop_z_mapping_items);
RNA_def_property_ui_text(prop, "Z Mapping", "");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
+
prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_mapping_items);
RNA_def_property_ui_text(prop, "Mapping", "");
@@ -2227,7 +2250,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_items(prop, phys_type_items);
RNA_def_property_ui_text(prop, "Physics Type", "Particle physics type");
- RNA_def_property_update(prop, 0, "rna_Particle_change_physics");
+ RNA_def_property_update(prop, 0, "rna_Particle_change_physics_type");
prop = RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rotmode");
@@ -3050,7 +3073,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1.0f, 100.0f, 0.1, 3);
RNA_def_property_ui_text(prop, "Loop count", "Number of times the keys are looped");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
-
+
/* modified dm support */
prop = RNA_def_property(srna, "use_modifier_stack", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_modifier_stack", 0);
@@ -3101,7 +3124,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "BoidSettings");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Boid Settings", "");
-
+
/* Fluid particles */
prop = RNA_def_property(srna, "fluid", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "SPHFluidSettings");
@@ -3113,7 +3136,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "EffectorWeights");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Effector Weights", "");
-
+
/* animation here? */
rna_def_animdata_common(srna);
@@ -3272,13 +3295,13 @@ static void rna_def_particle_system(BlenderRNA *brna)
prop = RNA_def_property(srna, "particles", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "particles", "totpart");
RNA_def_property_struct_type(prop, "Particle");
- RNA_def_property_flag(prop, PROP_NO_COMPARISON);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Particles", "Particles generated by the particle system");
prop = RNA_def_property(srna, "child_particles", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "child", "totchild");
RNA_def_property_struct_type(prop, "ChildParticle");
- RNA_def_property_flag(prop, PROP_NO_COMPARISON);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Child Particles", "Child particles generated by the particle system");
prop = RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED);
@@ -3611,7 +3634,7 @@ void RNA_def_particle(BlenderRNA *brna)
rna_def_fluid_settings(brna);
rna_def_particle_hair_key(brna);
rna_def_particle_key(brna);
-
+
rna_def_child_particle(brna);
rna_def_particle(brna);
rna_def_particle_dupliweight(brna);
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index c25601a25fe..6a5f6485029 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -106,6 +106,7 @@ const EnumPropertyItem rna_enum_color_sets_items[] = {
#include "BKE_context.h"
#include "BKE_constraint.h"
+#include "BKE_global.h"
#include "BKE_idprop.h"
#include "DEG_depsgraph.h"
@@ -175,11 +176,11 @@ static void rna_bone_group_remove(ID *id, bPose *pose, ReportList *reports, Poin
void rna_ActionGroup_colorset_set(PointerRNA *ptr, int value)
{
bActionGroup *grp = ptr->data;
-
+
/* ensure only valid values get set */
if ((value >= -1) && (value < 21)) {
grp->customCol = value;
-
+
/* sync colors stored with theme colors based on the index specified */
action_group_colors_sync(grp, NULL);
}
@@ -188,7 +189,7 @@ void rna_ActionGroup_colorset_set(PointerRNA *ptr, int value)
int rna_ActionGroup_is_custom_colorset_get(PointerRNA *ptr)
{
bActionGroup *grp = ptr->data;
-
+
return (grp->customCol < 0);
}
@@ -239,9 +240,9 @@ static void rna_Pose_ik_solver_update(Main *bmain, Scene *UNUSED(scene), Pointer
BKE_pose_tag_recalc(bmain, pose); /* checks & sorts pose channels */
DEG_relations_tag_update(bmain);
-
+
BKE_pose_update_constraint_flags(pose);
-
+
object_test_constraints(bmain, ob);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB);
@@ -251,7 +252,7 @@ static void rna_Pose_ik_solver_update(Main *bmain, Scene *UNUSED(scene), Pointer
static void rna_PoseChannel_rotation_axis_angle_get(PointerRNA *ptr, float *value)
{
bPoseChannel *pchan = ptr->data;
-
+
/* for now, assume that rotation mode is axis-angle */
value[0] = pchan->rotAngle;
copy_v3_v3(&value[1], pchan->rotAxis);
@@ -261,22 +262,22 @@ static void rna_PoseChannel_rotation_axis_angle_get(PointerRNA *ptr, float *valu
static void rna_PoseChannel_rotation_axis_angle_set(PointerRNA *ptr, const float *value)
{
bPoseChannel *pchan = ptr->data;
-
+
/* for now, assume that rotation mode is axis-angle */
pchan->rotAngle = value[0];
copy_v3_v3(pchan->rotAxis, &value[1]);
-
+
/* TODO: validate axis? */
}
static void rna_PoseChannel_rotation_mode_set(PointerRNA *ptr, int value)
{
bPoseChannel *pchan = ptr->data;
-
+
/* use API Method for conversions... */
BKE_rotMode_change_values(pchan->quat, pchan->eul, pchan->rotAxis, &pchan->rotAngle,
pchan->rotmode, (short)value);
-
+
/* finally, set the new rotation type */
pchan->rotmode = value;
}
@@ -291,7 +292,7 @@ static void rna_PoseChannel_name_set(PointerRNA *ptr, const char *value)
BLI_strncpy_utf8(newname, value, sizeof(pchan->name));
BLI_strncpy(oldname, pchan->name, sizeof(pchan->name));
- ED_armature_bone_rename(ob->data, oldname, newname);
+ ED_armature_bone_rename(G.main, ob->data, oldname, newname);
}
static int rna_PoseChannel_has_ik_get(PointerRNA *ptr)
@@ -387,12 +388,12 @@ static PointerRNA rna_PoseChannel_bone_group_get(PointerRNA *ptr)
bPose *pose = (ob) ? ob->pose : NULL;
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
bActionGroup *grp;
-
+
if (pose)
grp = BLI_findlink(&pose->agroups, pchan->agrp_index - 1);
else
grp = NULL;
-
+
return rna_pointer_inherit_refine(ptr, &RNA_BoneGroup, grp);
}
@@ -401,7 +402,7 @@ static void rna_PoseChannel_bone_group_set(PointerRNA *ptr, PointerRNA value)
Object *ob = (Object *)ptr->id.data;
bPose *pose = (ob) ? ob->pose : NULL;
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
+
if (pose)
pchan->agrp_index = BLI_findindex(&pose->agroups, value.data) + 1;
else
@@ -425,7 +426,7 @@ static void rna_PoseChannel_bone_group_index_range(PointerRNA *ptr, int *min, in
{
Object *ob = (Object *)ptr->id.data;
bPose *pose = (ob) ? ob->pose : NULL;
-
+
*min = 0;
*max = pose ? max_ii(0, BLI_listbase_count(&pose->agroups) - 1) : 0;
}
@@ -489,14 +490,14 @@ static void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, s
bPose *pose = (bPose *)ptr->data;
bActionGroup *grp;
int a;
-
+
for (a = 1, grp = pose->agroups.first; grp; grp = grp->next, a++) {
if (STREQ(grp->name, value)) {
*index = a;
return;
}
}
-
+
*index = 0;
}
@@ -504,14 +505,14 @@ static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *r
{
bPose *pose = (bPose *)ptr->data;
bActionGroup *grp;
-
+
for (grp = pose->agroups.first; grp; grp = grp->next) {
if (STREQ(grp->name, value)) {
BLI_strncpy(result, value, maxlen);
return;
}
}
-
+
result[0] = '\0';
}
#endif
@@ -619,12 +620,12 @@ static int rna_PoseChannel_proxy_editable(PointerRNA *ptr, const char **r_info)
Object *ob = (Object *)ptr->id.data;
bArmature *arm = ob->data;
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
+
if (ob->proxy && pchan->bone && (pchan->bone->layer & arm->layer_protected)) {
*r_info = "Can't edit property of a proxy on a protected layer";
return 0;
}
-
+
return PROP_EDITABLE;
}
@@ -646,7 +647,7 @@ static int rna_PoseChannel_location_editable(PointerRNA *ptr, int index)
static int rna_PoseChannel_scale_editable(PointerRNA *ptr, int index)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
+
/* only if the axis in question is locked, not editable... */
if ((index == 0) && (pchan->protectflag & OB_LOCK_SCALEX))
return 0;
@@ -661,7 +662,7 @@ static int rna_PoseChannel_scale_editable(PointerRNA *ptr, int index)
static int rna_PoseChannel_rotation_euler_editable(PointerRNA *ptr, int index)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
+
/* only if the axis in question is locked, not editable... */
if ((index == 0) && (pchan->protectflag & OB_LOCK_ROTX))
return 0;
@@ -676,7 +677,7 @@ static int rna_PoseChannel_rotation_euler_editable(PointerRNA *ptr, int index)
static int rna_PoseChannel_rotation_4d_editable(PointerRNA *ptr, int index)
{
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
+
/* only consider locks if locking components individually... */
if (pchan->protectflag & OB_LOCK_ROT4D) {
/* only if the axis in question is locked, not editable... */
@@ -689,7 +690,7 @@ static int rna_PoseChannel_rotation_4d_editable(PointerRNA *ptr, int index)
else if ((index == 3) && (pchan->protectflag & OB_LOCK_ROTZ))
return 0;
}
-
+
return PROP_EDITABLE;
}
@@ -736,7 +737,7 @@ static void rna_PoseChannel_matrix_set(PointerRNA *ptr, const float *values)
void rna_def_actionbone_group_common(StructRNA *srna, int update_flag, const char *update_cb)
{
PropertyRNA *prop;
-
+
/* color set + colors */
prop = RNA_def_property(srna, "color_set", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "customCol");
@@ -744,12 +745,12 @@ void rna_def_actionbone_group_common(StructRNA *srna, int update_flag, const cha
RNA_def_property_enum_funcs(prop, NULL, "rna_ActionGroup_colorset_set", NULL);
RNA_def_property_ui_text(prop, "Color Set", "Custom color set to use");
RNA_def_property_update(prop, update_flag, update_cb);
-
+
prop = RNA_def_property(srna, "is_custom_color_set", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_ActionGroup_is_custom_colorset_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Custom Color Set", "Color set is user-defined instead of a fixed theme color set");
-
+
/* TODO: editing the colors for this should result in changes to the color type... */
prop = RNA_def_property(srna, "colors", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -764,21 +765,21 @@ static void rna_def_bone_group(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
/* struct */
srna = RNA_def_struct(brna, "BoneGroup", NULL);
RNA_def_struct_sdna(srna, "bActionGroup");
RNA_def_struct_ui_text(srna, "Bone Group", "Groups of Pose Channels (Bones)");
RNA_def_struct_ui_icon(srna, ICON_GROUP_BONE);
-
+
/* name */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_BoneGroup_name_set");
RNA_def_struct_name_property(srna, prop);
-
+
/* TODO: add some runtime-collections stuff to access grouped bones */
-
+
/* color set */
rna_def_actionbone_group_common(srna, NC_OBJECT | ND_POSE, "rna_Pose_update");
}
@@ -853,11 +854,11 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_PoseBone_path");
RNA_def_struct_idprops_func(srna, "rna_PoseBone_idprops");
RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
-
+
/* Bone Constraints */
prop = RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "Constraint");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC | PROP_OVERRIDABLE_STATIC_INSERTION);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC | PROPOVERRIDE_STATIC_INSERTION);
RNA_def_property_ui_text(prop, "Constraints", "Constraints that act on this PoseChannel");
RNA_def_property_override_funcs(prop, NULL, NULL, "rna_PoseChannel_constraints_override_apply");
@@ -872,7 +873,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
/* Baked Bone Path cache data */
rna_def_motionpath_common(srna);
-
+
/* Relationships to other bones */
prop = RNA_def_property(srna, "bone", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -892,11 +893,11 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Child", "Child of this pose bone");
-
+
/* Transformation settings */
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "loc");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_location_editable");
RNA_def_property_ui_text(prop, "Location", "");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
@@ -904,7 +905,8 @@ static void rna_def_pose_channel(BlenderRNA *brna)
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
- RNA_def_property_flag(prop, PROP_PROPORTIONAL | PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_flag(prop, PROP_PROPORTIONAL);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_scale_editable");
RNA_def_property_float_array_default(prop, default_scale);
RNA_def_property_ui_text(prop, "Scale", "");
@@ -912,17 +914,17 @@ static void rna_def_pose_channel(BlenderRNA *brna)
prop = RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_QUATERNION);
RNA_def_property_float_sdna(prop, NULL, "quat");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_rotation_4d_editable");
RNA_def_property_float_array_default(prop, default_quat);
RNA_def_property_ui_text(prop, "Quaternion Rotation", "Rotation in Quaternions");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
/* XXX: for axis-angle, it would have been nice to have 2 separate fields for UI purposes, but
* having a single one is better for Keyframing and other property-management situations...
*/
prop = RNA_def_property(srna, "rotation_axis_angle", PROP_FLOAT, PROP_AXISANGLE);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_array(prop, 4);
RNA_def_property_float_funcs(prop, "rna_PoseChannel_rotation_axis_angle_get",
"rna_PoseChannel_rotation_axis_angle_set", NULL);
@@ -930,14 +932,14 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_float_array_default(prop, default_axisAngle);
RNA_def_property_ui_text(prop, "Axis-Angle Rotation", "Angle of Rotation for Axis-Angle rotation representation");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "eul");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_rotation_euler_editable");
RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "rotmode");
RNA_def_property_enum_items(prop, rna_enum_posebone_rotmode_items); /* XXX move to using a single define of this someday */
@@ -946,19 +948,19 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_ui_text(prop, "Rotation Mode", "");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
/* Curved bones settings - Applied on top of restpose values */
rna_def_bone_curved_common(srna, true);
-
+
/* Custom BBone next/prev sources */
prop = RNA_def_property(srna, "use_bbone_custom_handles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_HANDLES);
- RNA_def_property_ui_text(prop, "Use Custom Handle References",
+ RNA_def_property_ui_text(prop, "Use Custom Handle References",
"Use custom reference bones as handles for B-Bones instead of next/previous bones, "
"leave these blank to use only B-Bone offset properties to control the shape");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "bbone_custom_handle_start", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "bbone_prev");
RNA_def_property_struct_type(prop, "PoseBone");
@@ -967,14 +969,14 @@ static void rna_def_pose_channel(BlenderRNA *brna)
"Bone that serves as the start handle for the B-Bone curve");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "use_bbone_relative_start_handle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_START_REL);
- RNA_def_property_ui_text(prop, "Relative B-Bone Start Handle",
+ RNA_def_property_ui_text(prop, "Relative B-Bone Start Handle",
"Treat custom start handle position as a relative value");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "bbone_custom_handle_end", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "bbone_next");
RNA_def_property_struct_type(prop, "PoseBone");
@@ -983,14 +985,14 @@ static void rna_def_pose_channel(BlenderRNA *brna)
"Bone that serves as the end handle for the B-Bone curve");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "use_bbone_relative_end_handle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_END_REL);
- RNA_def_property_ui_text(prop, "Relative B-Bone End Handle",
+ RNA_def_property_ui_text(prop, "Relative B-Bone End Handle",
"Treat custom end handle position as a relative value");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
/* transform matrices - should be read-only since these are set directly by AnimSys evaluation */
prop = RNA_def_property(srna, "matrix_channel", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "chan_mat");
@@ -1028,7 +1030,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Tail Position", "Location of tail of the channel's bone");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
-
+
/* IK Settings */
prop = RNA_def_property(srna, "is_in_ik_chain", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_PoseChannel_has_ik_get", NULL);
@@ -1074,19 +1076,19 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "IK Z Limit", "Limit movement around the Z axis");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update");
-
+
prop = RNA_def_property(srna, "use_ik_rotation_control", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_ROTCTL);
RNA_def_property_ui_text(prop, "IK rot control", "Apply channel rotation as IK constraint");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update");
-
+
prop = RNA_def_property(srna, "use_ik_linear_control", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_LINCTL);
RNA_def_property_ui_text(prop, "IK rot control", "Apply channel size as IK constraint if stretching is enabled");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update");
-
+
prop = RNA_def_property(srna, "ik_min_x", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "limitmin[0]");
RNA_def_property_range(prop, -M_PI, 0.0f);
@@ -1156,21 +1158,21 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "IK Stretch", "Allow scaling of the bone for IK");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update");
-
+
prop = RNA_def_property(srna, "ik_rotation_weight", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ikrotweight");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "IK Rot Weight", "Weight of rotation constraint for IK");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "ik_linear_weight", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "iklinweight");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "IK Lin Weight", "Weight of scale constraint for IK");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
/* custom bone shapes */
prop = RNA_def_property(srna, "custom_shape", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "custom");
@@ -1180,7 +1182,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Custom Object", "Object that defines custom draw type for this bone");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "custom_shape_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "custom_scale");
RNA_def_property_range(prop, 0.0f, 1000.0f);
@@ -1200,7 +1202,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
"Bone that defines the display transform of this custom shape");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
/* bone groups */
prop = RNA_def_property(srna, "bone_group_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "agrp_index");
@@ -1211,7 +1213,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bone Group Index", "Bone Group this pose channel belongs to (0=no group)");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "bone_group", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "BoneGroup");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -1220,7 +1222,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bone Group", "Bone Group this pose channel belongs to");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
/* transform locks */
prop = RNA_def_property(srna, "lock_location", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "protectflag", OB_LOCK_LOCX);
@@ -1237,7 +1239,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
/* XXX this is sub-optimal - it really should be included above, but due to technical reasons
* we can't do this! */
prop = RNA_def_property(srna, "lock_rotation_w", PROP_BOOLEAN, PROP_NONE);
@@ -1437,7 +1439,7 @@ static void rna_def_bone_groups(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Pose_active_bone_group_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active Bone Group", "Active bone group for this pose");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
-
+
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "active_group");
RNA_def_property_int_funcs(prop, "rna_Pose_active_bone_group_index_get", "rna_Pose_active_bone_group_index_set",
@@ -1450,7 +1452,7 @@ static void rna_def_pose(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
/* struct definition */
srna = RNA_def_struct(brna, "Pose", NULL);
RNA_def_struct_sdna(srna, "bPose");
@@ -1460,7 +1462,7 @@ static void rna_def_pose(BlenderRNA *brna)
prop = RNA_def_property(srna, "bones", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "chanbase", NULL);
RNA_def_property_struct_type(prop, "PoseBone");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
RNA_def_property_ui_text(prop, "Pose Bones", "Individual pose bones for the armature");
/* can be removed, only for fast lookup */
RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL, "rna_PoseBones_lookup_string", NULL);
@@ -1471,7 +1473,7 @@ static void rna_def_pose(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "BoneGroup");
RNA_def_property_ui_text(prop, "Bone Groups", "Groups of the bones");
rna_def_bone_groups(brna, prop);
-
+
/* ik solvers */
prop = RNA_def_property(srna, "ik_solver", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "iksolver");
@@ -1485,10 +1487,10 @@ static void rna_def_pose(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_Pose_ikparam_get", NULL, "rna_Pose_ikparam_typef", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "IK Param", "Parameters for IK solver");
-
+
/* animviz */
rna_def_animviz_common(srna);
-
+
RNA_api_pose(srna);
}
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index fe12e1cd528..0dd33944dda 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -291,7 +291,7 @@ static void rna_RenderEngine_unregister(Main *bmain, StructRNA *type)
if (!et)
return;
-
+
RNA_struct_free_extension(type, &et->ext);
RNA_struct_free(&BLENDER_RNA, type);
BLI_freelinkN(&R_engines, et);
@@ -332,7 +332,7 @@ static StructRNA *rna_RenderEngine_register(
break;
}
}
-
+
/* create a new engine type */
et = MEM_callocN(sizeof(RenderEngineType), "python render engine");
memcpy(et, &dummyet, sizeof(dummyet));
@@ -790,7 +790,7 @@ static void rna_def_render_result(BlenderRNA *brna)
FunctionRNA *func;
PropertyRNA *parm;
-
+
srna = RNA_def_struct(brna, "RenderResult", NULL);
RNA_def_struct_ui_text(srna, "Render Result", "Result of rendering, including all layers and passes");
@@ -890,7 +890,7 @@ static void rna_def_render_layer(BlenderRNA *brna)
FunctionRNA *func;
PropertyRNA *parm;
-
+
srna = RNA_def_struct(brna, "RenderLayer", NULL);
RNA_def_struct_ui_text(srna, "Render Layer", "");
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index 0a8a99d779a..60a1783f118 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -108,19 +108,19 @@ static const EnumPropertyItem rigidbody_mesh_source_items[] = {
static void rna_RigidBodyWorld_reset(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
-
+
BKE_rigidbody_cache_reset(rbw);
}
static char *rna_RigidBodyWorld_path(PointerRNA *UNUSED(ptr))
-{
+{
return BLI_sprintfN("rigidbody_world");
}
static void rna_RigidBodyWorld_num_solver_iterations_set(PointerRNA *ptr, int value)
{
RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
-
+
rbw->num_solver_iterations = value;
#ifdef WITH_BULLET
@@ -133,7 +133,7 @@ static void rna_RigidBodyWorld_num_solver_iterations_set(PointerRNA *ptr, int va
static void rna_RigidBodyWorld_split_impulse_set(PointerRNA *ptr, int value)
{
RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
-
+
RB_FLAG_SET(rbw->flag, value, RBW_FLAG_USE_SPLIT_IMPULSE);
#ifdef WITH_BULLET
@@ -148,16 +148,16 @@ static void rna_RigidBodyWorld_split_impulse_set(PointerRNA *ptr, int value)
static void rna_RigidBodyOb_reset(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
RigidBodyWorld *rbw = scene->rigidbody_world;
-
+
BKE_rigidbody_cache_reset(rbw);
}
static void rna_RigidBodyOb_shape_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Object *ob = ptr->id.data;
-
+
rna_RigidBodyOb_reset(bmain, scene, ptr);
-
+
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
@@ -165,7 +165,7 @@ static void rna_RigidBodyOb_shape_reset(Main *UNUSED(bmain), Scene *scene, Point
{
RigidBodyWorld *rbw = scene->rigidbody_world;
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
BKE_rigidbody_cache_reset(rbw);
if (rbo->physics_shape)
rbo->flag |= RBO_FLAG_NEEDS_RESHAPE;
@@ -180,7 +180,7 @@ static char *rna_RigidBodyOb_path(PointerRNA *UNUSED(ptr))
static void rna_RigidBodyOb_type_set(PointerRNA *ptr, int value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->type = value;
rbo->flag |= RBO_FLAG_NEEDS_VALIDATE;
}
@@ -196,7 +196,7 @@ static void rna_RigidBodyOb_shape_set(PointerRNA *ptr, int value)
static void rna_RigidBodyOb_disabled_set(PointerRNA *ptr, int value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
RB_FLAG_SET(rbo->flag, !value, RBO_FLAG_DISABLED);
#ifdef WITH_BULLET
@@ -212,7 +212,7 @@ static void rna_RigidBodyOb_disabled_set(PointerRNA *ptr, int value)
static void rna_RigidBodyOb_mass_set(PointerRNA *ptr, float value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->mass = value;
#ifdef WITH_BULLET
@@ -226,7 +226,7 @@ static void rna_RigidBodyOb_mass_set(PointerRNA *ptr, float value)
static void rna_RigidBodyOb_friction_set(PointerRNA *ptr, float value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->friction = value;
#ifdef WITH_BULLET
@@ -239,7 +239,7 @@ static void rna_RigidBodyOb_friction_set(PointerRNA *ptr, float value)
static void rna_RigidBodyOb_restitution_set(PointerRNA *ptr, float value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->restitution = value;
#ifdef WITH_BULLET
if (rbo->physics_object) {
@@ -251,7 +251,7 @@ static void rna_RigidBodyOb_restitution_set(PointerRNA *ptr, float value)
static void rna_RigidBodyOb_collision_margin_set(PointerRNA *ptr, float value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->margin = value;
#ifdef WITH_BULLET
@@ -278,7 +278,7 @@ static void rna_RigidBodyOb_collision_groups_set(PointerRNA *ptr, const int *val
static void rna_RigidBodyOb_kinematic_state_set(PointerRNA *ptr, int value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
RB_FLAG_SET(rbo->flag, value, RBO_FLAG_KINEMATIC);
#ifdef WITH_BULLET
@@ -294,7 +294,7 @@ static void rna_RigidBodyOb_kinematic_state_set(PointerRNA *ptr, int value)
static void rna_RigidBodyOb_activation_state_set(PointerRNA *ptr, int value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
RB_FLAG_SET(rbo->flag, value, RBO_FLAG_USE_DEACTIVATION);
#ifdef WITH_BULLET
@@ -308,7 +308,7 @@ static void rna_RigidBodyOb_activation_state_set(PointerRNA *ptr, int value)
static void rna_RigidBodyOb_linear_sleepThresh_set(PointerRNA *ptr, float value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->lin_sleep_thresh = value;
#ifdef WITH_BULLET
@@ -322,7 +322,7 @@ static void rna_RigidBodyOb_linear_sleepThresh_set(PointerRNA *ptr, float value)
static void rna_RigidBodyOb_angular_sleepThresh_set(PointerRNA *ptr, float value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->ang_sleep_thresh = value;
#ifdef WITH_BULLET
@@ -336,7 +336,7 @@ static void rna_RigidBodyOb_angular_sleepThresh_set(PointerRNA *ptr, float value
static void rna_RigidBodyOb_linear_damping_set(PointerRNA *ptr, float value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->lin_damping = value;
#ifdef WITH_BULLET
@@ -350,7 +350,7 @@ static void rna_RigidBodyOb_linear_damping_set(PointerRNA *ptr, float value)
static void rna_RigidBodyOb_angular_damping_set(PointerRNA *ptr, float value)
{
RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
-
+
rbo->ang_damping = value;
#ifdef WITH_BULLET
@@ -737,7 +737,7 @@ static void rna_def_rigidbody_world(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "RigidBodyWorld");
RNA_def_struct_ui_text(srna, "Rigid Body World", "Self-contained rigid body simulation environment and settings");
RNA_def_struct_path_func(srna, "rna_RigidBodyWorld_path");
-
+
/* groups */
prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Collection");
@@ -750,13 +750,13 @@ static void rna_def_rigidbody_world(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_ui_text(prop, "Constraints", "Collection containing rigid body constraint objects");
RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
-
+
/* booleans */
prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", RBW_FLAG_MUTED);
RNA_def_property_ui_text(prop, "Enabled", "Simulation will be evaluated");
RNA_def_property_update(prop, NC_SCENE, NULL);
-
+
/* time scale */
prop = RNA_def_property(srna, "time_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "time_scale");
@@ -765,7 +765,7 @@ static void rna_def_rigidbody_world(BlenderRNA *brna)
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Time Scale", "Change the speed of the simulation");
RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
-
+
/* timestep */
prop = RNA_def_property(srna, "steps_per_second", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "steps_per_second");
@@ -776,7 +776,7 @@ static void rna_def_rigidbody_world(BlenderRNA *brna)
"Number of simulation steps taken per second (higher values are more accurate "
"but slower)");
RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
-
+
/* constraint solver iterations */
prop = RNA_def_property(srna, "solver_iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "num_solver_iterations");
@@ -788,7 +788,7 @@ static void rna_def_rigidbody_world(BlenderRNA *brna)
"Number of constraint solver iterations made per simulation step (higher values are more "
"accurate but slower)");
RNA_def_property_update(prop, NC_SCENE, "rna_RigidBodyWorld_reset");
-
+
/* split impulse */
prop = RNA_def_property(srna, "use_split_impulse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBW_FLAG_USE_SPLIT_IMPULSE);
@@ -843,13 +843,13 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
-
+
+
srna = RNA_def_struct(brna, "RigidBodyObject", NULL);
RNA_def_struct_sdna(srna, "RigidBodyOb");
RNA_def_struct_ui_text(srna, "Rigid Body Object", "Settings for object participating in Rigid Body Simulation");
RNA_def_struct_path_func(srna, "rna_RigidBodyOb_path");
-
+
/* Enums */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
@@ -858,21 +858,21 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Type", "Role of object in Rigid Body Simulations");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
prop = RNA_def_property(srna, "mesh_source", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mesh_source");
RNA_def_property_enum_items(prop, rigidbody_mesh_source_items);
RNA_def_property_ui_text(prop, "Mesh Source", "Source of the mesh used to create collision shape");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
/* booleans */
prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", RBO_FLAG_DISABLED);
RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyOb_disabled_set");
RNA_def_property_ui_text(prop, "Enabled", "Rigid Body actively participates to the simulation");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
prop = RNA_def_property(srna, "collision_shape", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shape");
RNA_def_property_enum_items(prop, rna_enum_rigidbody_object_shape_items);
@@ -880,18 +880,18 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Collision Shape", "Collision Shape of object in Rigid Body Simulations");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_shape_update");
-
+
prop = RNA_def_property(srna, "kinematic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_KINEMATIC);
RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyOb_kinematic_state_set");
RNA_def_property_ui_text(prop, "Kinematic", "Allow rigid body to be controlled by the animation system");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
prop = RNA_def_property(srna, "use_deform", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_USE_DEFORM);
RNA_def_property_ui_text(prop, "Deforming", "Rigid body deforms during simulation");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
/* Physics Parameters */
prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_UNIT_MASS);
RNA_def_property_float_sdna(prop, NULL, "mass");
@@ -900,10 +900,10 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_mass_set", NULL);
RNA_def_property_ui_text(prop, "Mass", "How much the object 'weighs' irrespective of gravity");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
/* Dynamics Parameters - Activation */
// TODO: define and figure out how to implement these
-
+
/* Dynamics Parameters - Deactivation */
prop = RNA_def_property(srna, "use_deactivation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_USE_DEACTIVATION);
@@ -913,13 +913,13 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
"Enable deactivation of resting rigid bodies (increases performance and stability "
"but can cause glitches)");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
prop = RNA_def_property(srna, "use_start_deactivated", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_START_DEACTIVATED);
RNA_def_property_ui_text(prop, "Start Deactivated", "Deactivate rigid body at the start of the simulation");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
prop = RNA_def_property(srna, "deactivate_linear_velocity", PROP_FLOAT, PROP_UNIT_VELOCITY);
RNA_def_property_float_sdna(prop, NULL, "lin_sleep_thresh");
RNA_def_property_range(prop, FLT_MIN, FLT_MAX); // range must always be positive (and non-zero)
@@ -928,7 +928,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Linear Velocity Deactivation Threshold",
"Linear Velocity below which simulation stops simulating object");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
prop = RNA_def_property(srna, "deactivate_angular_velocity", PROP_FLOAT, PROP_UNIT_VELOCITY);
RNA_def_property_float_sdna(prop, NULL, "ang_sleep_thresh");
RNA_def_property_range(prop, FLT_MIN, FLT_MAX); // range must always be positive (and non-zero)
@@ -937,7 +937,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Angular Velocity Deactivation Threshold",
"Angular Velocity below which simulation stops simulating object");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
/* Dynamics Parameters - Damping Parameters */
prop = RNA_def_property(srna, "linear_damping", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "lin_damping");
@@ -946,7 +946,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_linear_damping_set", NULL);
RNA_def_property_ui_text(prop, "Linear Damping", "Amount of linear velocity that is lost over time");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
prop = RNA_def_property(srna, "angular_damping", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "ang_damping");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -954,7 +954,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_angular_damping_set", NULL);
RNA_def_property_ui_text(prop, "Angular Damping", "Amount of angular velocity that is lost over time");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
/* Collision Parameters - Surface Parameters */
prop = RNA_def_property(srna, "friction", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "friction");
@@ -964,7 +964,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyOb_friction_set", NULL);
RNA_def_property_ui_text(prop, "Friction", "Resistance of object to movement");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
prop = RNA_def_property(srna, "restitution", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "restitution");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
@@ -975,7 +975,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
"Tendency of object to bounce after colliding with another "
"(0 = stays still, 1 = perfectly elastic)");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
-
+
/* Collision Parameters - Sensitivity */
prop = RNA_def_property(srna, "use_margin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBO_FLAG_USE_MARGIN);
@@ -983,7 +983,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Collision Margin",
"Use custom collision margin (some shapes will have a visible gap around them)");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_shape_reset");
-
+
prop = RNA_def_property(srna, "collision_margin", PROP_FLOAT, PROP_UNIT_LENGTH);
RNA_def_property_float_sdna(prop, NULL, "margin");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -994,7 +994,7 @@ static void rna_def_rigidbody_object(BlenderRNA *brna)
"Threshold of distance near surface where collisions are still considered "
"(best results when non-zero)");
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_shape_reset");
-
+
prop = RNA_def_property(srna, "collision_groups", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "col_groups", 1);
RNA_def_property_array(prop, 20);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index f42bc1e1923..53b98928c31 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -595,7 +595,7 @@ static int rna_Property_overridable_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return (prop->flag & PROP_OVERRIDABLE_STATIC) != 0;
+ return (prop->flag_override & PROPOVERRIDE_OVERRIDABLE_STATIC) != 0;
}
static int rna_Property_use_output_get(PointerRNA *ptr)
@@ -945,10 +945,10 @@ static void rna_EnumProperty_items_begin(CollectionPropertyIterator *iter, Point
const EnumPropertyItem *item = NULL;
int totitem;
bool free;
-
+
rna_idproperty_check(&prop, ptr);
/* eprop = (EnumPropertyRNA *)prop; */
-
+
RNA_property_enum_items_ex(
NULL, ptr, prop, STREQ(iter->prop->identifier, "enum_items_static"), &item, &totitem, &free);
rna_iterator_array_begin(iter, (void *)item, sizeof(EnumPropertyItem), totitem, free, rna_enum_check_separator);
@@ -1121,7 +1121,7 @@ static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key
/* Ensures it makes sense to go inside the pointers to compare their content
* (if they are IDs, or have different names or RNA type, then this would be meaningless). */
static bool rna_property_override_diff_propptr_validate_diffing(
- PointerRNA *propptr_a, PointerRNA *propptr_b,
+ PointerRNA *propptr_a, PointerRNA *propptr_b, const bool no_prop_name,
bool *r_is_id, bool *r_is_null, bool *r_is_type_diff,
char **r_propname_a, char *propname_a_buff, size_t propname_a_buff_size,
char **r_propname_b, char *propname_b_buff, size_t propname_b_buff_size)
@@ -1129,7 +1129,7 @@ static bool rna_property_override_diff_propptr_validate_diffing(
BLI_assert(propptr_a != NULL);
bool is_valid_for_diffing = true;
- const bool do_force_name = r_propname_a != NULL;
+ const bool do_force_name = !no_prop_name && r_propname_a != NULL;
if (do_force_name) {
BLI_assert(r_propname_a != NULL);
@@ -1165,7 +1165,7 @@ static bool rna_property_override_diff_propptr_validate_diffing(
/* We do a generic quick first comparison checking for "name" and/or "type" properties.
* We assume that is any of those are false, then we are not handling the same data.
* This helps a lot in static override case, especially to detect inserted items in collections. */
- if (is_valid_for_diffing || do_force_name) {
+ if (!no_prop_name && (is_valid_for_diffing || do_force_name)) {
PropertyRNA *nameprop_a = RNA_struct_name_property(propptr_a->type);
PropertyRNA *nameprop_b = (propptr_b != NULL) ? RNA_struct_name_property(propptr_b->type) : NULL;
@@ -1222,7 +1222,8 @@ static bool rna_property_override_diff_propptr_validate_diffing(
/* Used for both Pointer and Collection properties. */
static int rna_property_override_diff_propptr(
- PointerRNA *propptr_a, PointerRNA *propptr_b, eRNACompareMode mode, const bool no_ownership,
+ PointerRNA *propptr_a, PointerRNA *propptr_b,
+ eRNACompareMode mode, const bool no_ownership, const bool no_prop_name,
IDOverrideStatic *override, const char *rna_path, const int flags, bool *r_override_changed)
{
const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
@@ -1232,7 +1233,7 @@ static int rna_property_override_diff_propptr(
bool is_type_diff = false;
/* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
bool is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
- propptr_a, propptr_b, &is_id, &is_null, &is_type_diff,
+ propptr_a, propptr_b, no_prop_name, &is_id, &is_null, &is_type_diff,
NULL, NULL, 0, NULL, NULL, 0);
if (is_id) {
@@ -1538,8 +1539,9 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
PointerRNA propptr_a = RNA_property_pointer_get(ptr_a, prop_a);
PointerRNA propptr_b = RNA_property_pointer_get(ptr_b, prop_b);
const bool no_ownership = (RNA_property_flag(prop_a) & PROP_PTR_NO_OWNERSHIP) != 0;
+ const bool no_prop_name = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_NO_PROP_NAME) != 0;
return rna_property_override_diff_propptr(
- &propptr_a, &propptr_b, mode, no_ownership,
+ &propptr_a, &propptr_b, mode, no_ownership, no_prop_name,
override, rna_path, flags, r_override_changed);
}
break;
@@ -1549,7 +1551,8 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
{
/* Note: we assume we only insert in ptr_a (i.e. we can only get new items in ptr_a),
* and that we never remove anything. */
- const bool use_insertion = (RNA_property_flag(prop_a) & PROP_OVERRIDABLE_STATIC_INSERTION) && do_create;
+ const bool use_insertion = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_STATIC_INSERTION) && do_create;
+ const bool no_prop_name = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_NO_PROP_NAME) != 0;
bool equals = true;
bool abort = false;
bool is_first_insert = true;
@@ -1590,16 +1593,18 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
/* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
if (iter_b.valid) {
is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
- &iter_a.ptr, &iter_b.ptr, &is_id, &is_null, &is_type_diff,
- &propname_a, buff_a, sizeof(buff_a),
- &propname_b, buff_b, sizeof(buff_b));
+ &iter_a.ptr, &iter_b.ptr, no_prop_name,
+ &is_id, &is_null, &is_type_diff,
+ &propname_a, buff_a, sizeof(buff_a),
+ &propname_b, buff_b, sizeof(buff_b));
}
else {
is_valid_for_diffing = false;
if (is_valid_for_insertion) {
/* We still need propname from 'a' item... */
rna_property_override_diff_propptr_validate_diffing(
- &iter_a.ptr, NULL, &is_id, &is_null, &is_type_diff,
+ &iter_a.ptr, NULL, no_prop_name,
+ &is_id, &is_null, &is_type_diff,
&propname_a, buff_a, sizeof(buff_a),
&propname_b, buff_b, sizeof(buff_b));
}
@@ -1615,7 +1620,7 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
printf("Checking %s, %s [%d] vs %s [%d]; diffing: %d; insert: %d (could be used: %d, do_create: %d)\n",
rna_path, propname_a ? propname_a : "", idx_a, propname_b ? propname_b : "", idx_b,
is_valid_for_diffing, is_valid_for_insertion,
- (RNA_property_flag(prop_a) & PROP_OVERRIDABLE_STATIC_INSERTION) != 0, do_create);
+ (RNA_property_override_flag(prop_a) & PROPOVERRIDE_STATIC_INSERTION) != 0, do_create);
}
#endif
@@ -1685,7 +1690,7 @@ int rna_property_override_diff_default(PointerRNA *ptr_a, PointerRNA *ptr_b,
if (equals || do_create) {
const bool no_ownership = (RNA_property_flag(prop_a) & PROP_PTR_NO_OWNERSHIP) != 0;
const int eq = rna_property_override_diff_propptr(
- &iter_a.ptr, &iter_b.ptr, mode, no_ownership,
+ &iter_a.ptr, &iter_b.ptr, mode, no_ownership, no_prop_name,
override, extended_rna_path, flags, r_override_changed);
equals = equals && eq;
}
@@ -2248,18 +2253,18 @@ static void rna_def_struct(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, "rna_Struct_identifier_get", "rna_Struct_identifier_length", NULL);
RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
RNA_def_struct_name_property(srna, prop);
-
+
prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Struct_description_get", "rna_Struct_description_length", NULL);
RNA_def_property_ui_text(prop, "Description", "Description of the Struct's purpose");
-
+
prop = RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Struct_translation_context_get",
"rna_Struct_translation_context_length", NULL);
RNA_def_property_ui_text(prop, "Translation Context", "Translation context of the struct's name");
-
+
prop = RNA_def_property(srna, "base", PROP_POINTER, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Struct");
@@ -2351,7 +2356,7 @@ static void rna_def_property(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, "rna_Property_identifier_get", "rna_Property_identifier_length", NULL);
RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
RNA_def_struct_name_property(srna, prop);
-
+
prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Property_description_get", "rna_Property_description_length", NULL);
@@ -2449,7 +2454,7 @@ static void rna_def_property(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_optional_get", NULL);
RNA_def_property_ui_text(prop, "Registered Optionally",
"Property is optionally registered as part of type registration");
-
+
prop = RNA_def_property(srna, "is_runtime", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Property_is_runtime_get", NULL);
@@ -2517,7 +2522,7 @@ static void rna_def_function(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Function_no_self_get", NULL);
RNA_def_property_ui_text(prop, "No Self",
"Function does not pass its self as an argument (becomes a static method in python)");
-
+
prop = RNA_def_property(srna, "use_self_type", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Function_use_self_type_get", NULL);
@@ -2776,7 +2781,7 @@ void RNA_def_rna(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Collection Definition",
"RNA collection property to define lists, arrays and mappings");
rna_def_pointer_property(srna, PROP_COLLECTION);
-
+
/* Function */
rna_def_function(brna);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 1530c7fc483..bec70cd6cf3 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -122,7 +122,7 @@ const EnumPropertyItem rna_enum_snap_target_items[] = {
{SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target"},
{0, NULL, 0, NULL, NULL}
};
-
+
const EnumPropertyItem rna_enum_proportional_falloff_items[] = {
{PROP_SMOOTH, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", "Smooth falloff"},
{PROP_SPHERE, "SPHERE", ICON_SPHERECURVE, "Sphere", "Spherical falloff"},
@@ -419,7 +419,7 @@ static const EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
{0, "", 0, N_("Interpolation"), "Standard transitions between keyframes"},
{GP_IPO_LINEAR, "LINEAR", ICON_IPO_LINEAR, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"},
{GP_IPO_CURVEMAP, "CUSTOM", ICON_IPO_BEZIER, "Custom", "Custom interpolation defined using a curve map"},
-
+
/* easing */
{0, "", 0, N_("Easing (by strength)"), "Predefined inertial transitions, useful for motion graphics (from least to most ''dramatic'')"},
{GP_IPO_SINE, "SINE", ICON_IPO_SINE, "Sinusoidal", "Sinusoidal easing (weakest, almost linear but with a slight curvature)"},
@@ -429,12 +429,12 @@ static const EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
{GP_IPO_QUINT, "QUINT", ICON_IPO_QUINT, "Quintic", "Quintic easing"},
{GP_IPO_EXPO, "EXPO", ICON_IPO_EXPO, "Exponential", "Exponential easing (dramatic)"},
{GP_IPO_CIRC, "CIRC", ICON_IPO_CIRC, "Circular", "Circular easing (strongest and most dynamic)"},
-
+
{0, "", 0, N_("Dynamic Effects"), "Simple physics-inspired easing effects"},
{GP_IPO_BACK, "BACK", ICON_IPO_BACK, "Back", "Cubic easing with overshoot and settle"},
{GP_IPO_BOUNCE, "BOUNCE", ICON_IPO_BOUNCE, "Bounce", "Exponentially decaying parabolic bounce, like when objects collide"},
{GP_IPO_ELASTIC, "ELASTIC", ICON_IPO_ELASTIC, "Elastic", "Exponentially decaying sine wave, like an elastic band"},
-
+
{0, NULL, 0, NULL, NULL}
};
@@ -524,12 +524,12 @@ static char *rna_GPencilInterpolateSettings_path(PointerRNA *UNUSED(ptr))
static void rna_GPencilInterpolateSettings_type_set(PointerRNA *ptr, int value)
{
GP_Interpolate_Settings *settings = (GP_Interpolate_Settings *)ptr->data;
-
+
/* NOTE: This cast should be fine, as we have a small + finite set of values (eGP_Interpolate_Type)
* that should fit well within a char
*/
settings->type = (char)value;
-
+
/* init custom interpolation curve here now the first time it's used */
if ((settings->type == GP_IPO_CURVEMAP) &&
(settings->custom_ipo == NULL))
@@ -772,7 +772,7 @@ static void rna_Scene_framelen_update(Main *UNUSED(bmain), Scene *scene, Pointer
static void rna_Scene_frame_current_set(PointerRNA *ptr, int value)
{
Scene *data = (Scene *)ptr->data;
-
+
/* if negative frames aren't allowed, then we can't use them */
FRAMENUMBER_MIN_CLAMP(value);
data->r.cfra = value;
@@ -826,14 +826,14 @@ static void rna_Scene_end_frame_set(PointerRNA *ptr, int value)
static void rna_Scene_use_preview_range_set(PointerRNA *ptr, int value)
{
Scene *data = (Scene *)ptr->data;
-
+
if (value) {
/* copy range from scene if not set before */
if ((data->r.psfra == data->r.pefra) && (data->r.psfra == 0)) {
data->r.psfra = data->r.sfra;
data->r.pefra = data->r.efra;
}
-
+
data->r.flag |= SCER_PRV_RANGE;
}
else
@@ -844,14 +844,14 @@ static void rna_Scene_use_preview_range_set(PointerRNA *ptr, int value)
static void rna_Scene_preview_range_start_frame_set(PointerRNA *ptr, int value)
{
Scene *data = (Scene *)ptr->data;
-
+
/* check if enabled already */
if ((data->r.flag & SCER_PRV_RANGE) == 0) {
/* set end of preview range to end frame, then clamp as per normal */
/* TODO: or just refuse to set instead? */
data->r.pefra = data->r.efra;
}
-
+
/* now set normally */
CLAMP(value, MINAFRAME, data->r.pefra);
data->r.psfra = value;
@@ -860,14 +860,14 @@ static void rna_Scene_preview_range_start_frame_set(PointerRNA *ptr, int value)
static void rna_Scene_preview_range_end_frame_set(PointerRNA *ptr, int value)
{
Scene *data = (Scene *)ptr->data;
-
+
/* check if enabled already */
if ((data->r.flag & SCER_PRV_RANGE) == 0) {
/* set start of preview range to start frame, then clamp as per normal */
/* TODO: or just refuse to set instead? */
data->r.psfra = data->r.sfra;
}
-
+
/* now set normally */
CLAMP(value, data->r.psfra, MAXFRAME);
data->r.pefra = value;
@@ -896,7 +896,7 @@ static void rna_Scene_active_keying_set_set(PointerRNA *ptr, PointerRNA value)
{
Scene *scene = (Scene *)ptr->data;
KeyingSet *ks = (KeyingSet *)value.data;
-
+
scene->active_keyingset = ANIM_scene_get_keyingset_index(scene, ks);
}
@@ -926,7 +926,7 @@ extern ListBase builtin_keyingsets;
static void rna_Scene_all_keyingsets_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->data;
-
+
/* start going over the scene KeyingSets first, while we still have pointer to it
* but only if we have any Keying Sets to use...
*/
@@ -940,13 +940,13 @@ static void rna_Scene_all_keyingsets_next(CollectionPropertyIterator *iter)
{
ListBaseIterator *internal = &iter->internal.listbase;
KeyingSet *ks = (KeyingSet *)internal->link;
-
+
/* if we've run out of links in Scene list, jump over to the builtins list unless we're there already */
if ((ks->next == NULL) && (ks != builtin_keyingsets.last))
internal->link = (Link *)builtin_keyingsets.first;
else
internal->link = (Link *)ks->next;
-
+
iter->valid = (internal->link != NULL);
}
@@ -1416,7 +1416,7 @@ static const EnumPropertyItem *rna_RenderSettings_engine_itemf(
tmp.name = type->name;
RNA_enum_item_add(&item, &totitem, &tmp);
}
-
+
RNA_enum_item_end(&item, &totitem);
*r_free = true;
@@ -1432,7 +1432,7 @@ static int rna_RenderSettings_engine_get(PointerRNA *ptr)
for (type = R_engines.first; type; type = type->next, a++)
if (STREQ(type->idname, rd->engine))
return a;
-
+
return 0;
}
@@ -1592,7 +1592,7 @@ static void object_simplify_update(Object *ob)
for (psys = ob->particlesystem.first; psys; psys = psys->next)
psys->recalc |= PSYS_RECALC_CHILD;
-
+
if (ob->dup_group) {
CollectionObject *cob;
@@ -1617,7 +1617,7 @@ static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), Poi
for (SETLOOPER_SET_ONLY(sce, sce_iter, base)) {
object_simplify_update(base->object);
}
-
+
WM_main_add_notifier(NC_GEOM | ND_DATA, NULL);
DEG_id_tag_update(&sce->id, 0);
}
@@ -1727,7 +1727,7 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons
/* call the API func, and set the active keyingset index */
ks = BKE_keyingset_add(&sce->keyingsets, idname, name, KEYINGSET_ABSOLUTE, 0);
-
+
if (ks) {
sce->active_keyingset = BLI_listbase_count(&sce->keyingsets);
return ks;
@@ -2103,13 +2103,13 @@ static void rna_def_gpencil_interpolate(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "GPencilInterpolateSettings", NULL);
RNA_def_struct_sdna(srna, "GP_Interpolate_Settings");
RNA_def_struct_path_func(srna, "rna_GPencilInterpolateSettings_path");
RNA_def_struct_ui_text(srna, "Grease Pencil Interpolate Settings",
"Settings for Grease Pencil interpolation tools");
-
+
/* flags */
prop = RNA_def_property(srna, "interpolate_all_layers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS);
@@ -2120,7 +2120,7 @@ static void rna_def_gpencil_interpolate(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED);
RNA_def_property_ui_text(prop, "Interpolate Selected Strokes", "Interpolate only selected strokes in the original frame");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
/* interpolation type */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
@@ -2129,38 +2129,38 @@ static void rna_def_gpencil_interpolate(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Type",
"Interpolation method to use the next time 'Interpolate Sequence' is run");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
/* easing */
prop = RNA_def_property(srna, "easing", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "easing");
RNA_def_property_enum_items(prop, rna_enum_beztriple_interpolation_easing_items);
- RNA_def_property_ui_text(prop, "Easing",
+ RNA_def_property_ui_text(prop, "Easing",
"Which ends of the segment between the preceding and following grease pencil frames "
"easing interpolation is applied to");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
/* easing options */
prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "back");
RNA_def_property_ui_text(prop, "Back", "Amount of overshoot for 'back' easing");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "amplitude");
RNA_def_property_range(prop, 0.0f, FLT_MAX); /* only positive values... */
RNA_def_property_ui_text(prop, "Amplitude", "Amount to boost elastic bounces for 'elastic' easing");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "period", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "period");
RNA_def_property_ui_text(prop, "Period", "Time between bounces for elastic easing");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
/* custom curvemap */
prop = RNA_def_property(srna, "interpolation_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "custom_ipo");
RNA_def_property_struct_type(prop, "CurveMapping");
- RNA_def_property_ui_text(prop, "Interpolation Curve",
+ RNA_def_property_ui_text(prop, "Interpolation Curve",
"Custom curve to control 'sequence' interpolation between Grease Pencil frames");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
}
@@ -2368,14 +2368,14 @@ static void rna_def_transform_orientation(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "TransformOrientation", NULL);
-
+
prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "mat");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_3x3);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
RNA_def_property_ui_text(prop, "Name", "Name of the custom transform orientation");
@@ -2394,7 +2394,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
{UV_SELECT_ISLAND, "ISLAND", ICON_UV_ISLANDSEL, "Island", "Island selection mode"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* the construction of this enum is quite special - everything is stored as bitflags,
* with 1st position only for for on/off (and exposed as boolean), while others are mutually
* exclusive options but which will only have any effect when autokey is enabled
@@ -2428,7 +2428,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
{WT_VGROUP_BONE_DEFORM_OFF, "OTHER_DEFORM", 0, "Other", "Vertex Groups assigned to non Deform Bones"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem gpencil_source_3d_items[] = {
{GP_TOOL_SOURCE_SCENE, "SCENE", 0, "Scene",
"Grease Pencil data attached to the current scene is used, "
@@ -2438,7 +2438,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
"(required when using pre 2.73 add-ons, e.g. BSurfaces)"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem gpencil_stroke_placement_items[] = {
{GP_PROJECT_VIEWSPACE, "CURSOR", 0, "Cursor", "Draw stroke at the 3D cursor"},
{0, "VIEW", 0, "View", "Stick stroke to the view "}, /* weird, GP_PROJECT_VIEWALIGN is inverted */
@@ -2446,16 +2446,16 @@ static void rna_def_tool_settings(BlenderRNA *brna)
{GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_STROKE, "STROKE", 0, "Stroke", "Stick stroke to other strokes"},
{0, NULL, 0, NULL, NULL}
};
-
-
+
+
srna = RNA_def_struct(brna, "ToolSettings", NULL);
RNA_def_struct_path_func(srna, "rna_ToolSettings_path");
RNA_def_struct_ui_text(srna, "Tool Settings", "");
-
+
prop = RNA_def_property(srna, "sculpt", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Sculpt");
RNA_def_property_ui_text(prop, "Sculpt", "");
-
+
prop = RNA_def_property(srna, "use_auto_normalize", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_normalize", 1);
@@ -2575,7 +2575,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "proportional_size");
RNA_def_property_ui_text(prop, "Proportional Size", "Display size for proportional editing circle");
RNA_def_property_range(prop, 0.00001, 5000.0);
-
+
prop = RNA_def_property(srna, "double_threshold", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "doublimit");
RNA_def_property_ui_text(prop, "Double Threshold", "Limit for removing duplicates and 'Auto Merge'");
@@ -2625,14 +2625,14 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
RNA_def_property_ui_text(prop, "Snap Element", "Type of element to snap to");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
-
+
/* node editor uses own set of snap modes */
prop = RNA_def_property(srna, "snap_node_element", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_node_mode");
RNA_def_property_enum_items(prop, rna_enum_snap_node_element_items);
RNA_def_property_ui_text(prop, "Snap Node Element", "Type of element to snap to");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
-
+
/* image editor uses own set of snap modes */
prop = RNA_def_property(srna, "snap_uv_element", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "snap_uv_mode");
@@ -2651,7 +2651,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Snap Peel Object", "Consider objects as whole when finding volume center");
RNA_def_property_ui_icon(prop, ICON_SNAP_PEEL_OBJECT, 0);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* header redraw */
-
+
prop = RNA_def_property(srna, "use_snap_project", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_PROJECT);
RNA_def_property_ui_text(prop, "Project Individual Elements",
@@ -2671,14 +2671,14 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Continuous Drawing",
"Allow drawing multiple strokes at a time with Grease Pencil");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* xxx: need toolbar to be redrawn... */
-
+
prop = RNA_def_property(srna, "use_gpencil_additive_drawing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_RETAIN_LAST);
RNA_def_property_ui_text(prop, "Use Additive Drawing",
"When creating new frames, the strokes from the previous/active frame "
"are included as the basis for the new one");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "use_gpencil_draw_onback", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_PAINT_ONBACK);
RNA_def_property_ui_text(prop, "Draw Strokes on Back",
@@ -2691,17 +2691,17 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Grease Pencil Source",
"Data-block where active Grease Pencil data is found from");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
-
+
prop = RNA_def_property(srna, "gpencil_sculpt", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gp_sculpt");
RNA_def_property_struct_type(prop, "GPencilSculptSettings");
RNA_def_property_ui_text(prop, "Grease Pencil Sculpt",
"Settings for stroke sculpting tools and brushes");
-
+
prop = RNA_def_property(srna, "gpencil_interpolate", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gp_interpolate");
RNA_def_property_struct_type(prop, "GPencilInterpolateSettings");
- RNA_def_property_ui_text(prop, "Grease Pencil Interpolate",
+ RNA_def_property_ui_text(prop, "Grease Pencil Interpolate",
"Settings for Grease Pencil Interpolation tools");
/* Grease Pencil - Drawing brushes */
@@ -2717,12 +2717,12 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, gpencil_stroke_placement_items);
RNA_def_property_ui_text(prop, "Stroke Placement (3D View)", "");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
-
+
prop = RNA_def_property(srna, "use_gpencil_stroke_endpoints", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gpencil_v3d_align", GP_PROJECT_DEPTH_STROKE_ENDPOINTS);
RNA_def_property_ui_text(prop, "Only Endpoints", "Only use the first and last parts of the stroke for snapping");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
-
+
/* Grease Pencil - 2D Views Stroke Placement */
prop = RNA_def_property(srna, "gpencil_stroke_placement_view2d", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_v2d_align");
@@ -2736,7 +2736,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, gpencil_stroke_placement_items);
RNA_def_property_ui_text(prop, "Stroke Placement (Sequencer Preview)", "");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
-
+
/* Grease Pencil - Image Editor Stroke Placement */
prop = RNA_def_property(srna, "gpencil_stroke_placement_image_editor", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_ima_align");
@@ -2744,36 +2744,36 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Stroke Placement (Image Editor)", "");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
-
+
/* Auto Keying */
prop = RNA_def_property(srna, "use_keyframe_insert_auto", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_mode", AUTOKEY_ON);
RNA_def_property_ui_text(prop, "Auto Keying", "Automatic keyframe insertion for Objects and Bones");
RNA_def_property_ui_icon(prop, ICON_REC, 0);
-
+
prop = RNA_def_property(srna, "auto_keying_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "autokey_mode");
RNA_def_property_enum_items(prop, auto_key_items);
RNA_def_property_ui_text(prop, "Auto-Keying Mode", "Mode of automatic keyframe insertion for Objects and Bones");
-
+
prop = RNA_def_property(srna, "use_record_with_nla", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", ANIMRECORD_FLAG_WITHNLA);
RNA_def_property_ui_text(prop, "Layered",
"Add a new NLA Track + Strip for every loop/pass made over the animation "
"to allow non-destructive tweaking");
-
+
prop = RNA_def_property(srna, "use_keyframe_insert_keyingset", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_ONLYKEYINGSET);
RNA_def_property_ui_text(prop, "Auto Keyframe Insert Keying Set",
"Automatic keyframe insertion using active Keying Set only");
RNA_def_property_ui_icon(prop, ICON_KEYINGSET, 0);
-
+
/* Keyframing */
prop = RNA_def_property(srna, "keyframe_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "keyframe_type");
RNA_def_property_enum_items(prop, rna_enum_beztriple_keyframe_type_items);
RNA_def_property_ui_text(prop, "New Keyframe Type", "Type of keyframes to create when inserting keyframes");
-
+
/* UV */
prop = RNA_def_property(srna, "uv_select_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "uv_selectmode");
@@ -3157,7 +3157,7 @@ static void rna_def_unit_settings(BlenderRNA *brna)
{USER_UNIT_IMPERIAL, "IMPERIAL", 0, "Imperial", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem rotation_units[] = {
{0, "DEGREES", 0, "Degrees", "Use degrees for measuring angles and rotations"},
{USER_UNIT_ROT_RADIANS, "RADIANS", 0, "Radians", ""},
@@ -3172,7 +3172,7 @@ static void rna_def_unit_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, unit_systems);
RNA_def_property_ui_text(prop, "Unit System", "The unit system to use for button display");
RNA_def_property_update(prop, NC_WINDOW, NULL);
-
+
prop = RNA_def_property(srna, "system_rotation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rotation_units);
RNA_def_property_ui_text(prop, "Rotation Units", "Unit to use for displaying/editing rotation values");
@@ -3284,7 +3284,7 @@ void rna_def_view_layer_common(StructRNA *srna, int scene)
RNA_def_property_ui_text(prop, "Z", "Deliver Z values pass");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
prop = RNA_def_property(srna, "use_pass_vector", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_VECTOR);
RNA_def_property_ui_text(prop, "Vector", "Deliver speed vector pass");
@@ -3338,7 +3338,7 @@ void rna_def_view_layer_common(StructRNA *srna, int scene)
RNA_def_property_ui_text(prop, "AO", "Deliver AO pass");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
prop = RNA_def_property(srna, "use_pass_emit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_EMIT);
RNA_def_property_ui_text(prop, "Emit", "Deliver emission pass");
@@ -3410,7 +3410,7 @@ void rna_def_view_layer_common(StructRNA *srna, int scene)
RNA_def_property_ui_text(prop, "Transmission Color", "Deliver transmission color pass");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+
prop = RNA_def_property(srna, "use_pass_subsurface_direct", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_DIRECT);
RNA_def_property_ui_text(prop, "Subsurface Direct", "Deliver subsurface direct pass");
@@ -4751,7 +4751,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem alpha_mode_items[] = {
{R_ADDSKY, "SKY", 0, "Sky", "Transparent pixels are filled with sky color"},
{R_ALPHAPREMUL, "TRANSPARENT", 0, "Transparent", "World background is transparent with premultiplied alpha"},
@@ -4845,7 +4845,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_range(prop, 4, 65536);
RNA_def_property_ui_text(prop, "Resolution X", "Number of horizontal pixels in the rendered image");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneCamera_update");
-
+
prop = RNA_def_property(srna, "resolution_y", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "ysch");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
@@ -4853,7 +4853,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_range(prop, 4, 65536);
RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the rendered image");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneCamera_update");
-
+
prop = RNA_def_property(srna, "resolution_percentage", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "size");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -4861,14 +4861,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 100, 10, 1);
RNA_def_property_ui_text(prop, "Resolution %", "Percentage scale for render resolution");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "tile_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "tilex");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 8, 65536);
RNA_def_property_ui_text(prop, "Tile X", "Horizontal tile size to use while rendering");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "tile_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "tiley");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -4898,7 +4898,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pixel Aspect X",
"Horizontal aspect ratio - for anamorphic or non-square pixel output");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneCamera_update");
-
+
prop = RNA_def_property(srna, "pixel_aspect_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "yasp");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
@@ -4921,7 +4921,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 120, 1, -1);
RNA_def_property_ui_text(prop, "FPS", "Framerate, expressed in frames per second");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_fps_update");
-
+
prop = RNA_def_property(srna, "fps_base", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "frs_sec_base");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -4929,7 +4929,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.1f, 120.0f, 2, -1);
RNA_def_property_ui_text(prop, "FPS Base", "Framerate base");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_fps_update");
-
+
/* frame mapping */
prop = RNA_def_property(srna, "frame_map_old", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "framapto");
@@ -4937,7 +4937,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_range(prop, 1, 900);
RNA_def_property_ui_text(prop, "Frame Map Old", "Old mapping value in frames");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, "rna_Scene_framelen_update");
-
+
prop = RNA_def_property(srna, "frame_map_new", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "images");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -4945,7 +4945,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Frame Map New", "How many frames the Map Old will last");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, "rna_Scene_framelen_update");
-
+
prop = RNA_def_property(srna, "dither_intensity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "dither_intensity");
RNA_def_property_range(prop, 0.0f, 2.0f);
@@ -4971,14 +4971,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Anti-Aliasing",
"Render and combine multiple samples per pixel to prevent jagged edges");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "antialiasing_samples", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "osa");
RNA_def_property_enum_items(prop, fixed_oversample_items);
RNA_def_property_ui_text(prop, "Anti-Aliasing Samples", "Amount of anti-aliasing samples per pixel");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE_FRS);
@@ -4994,21 +4994,21 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"Number of CPU threads to use simultaneously while rendering "
"(for multi-core/CPU systems)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "threads_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, threads_mode_items);
RNA_def_property_enum_funcs(prop, "rna_RenderSettings_threads_mode_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Threads Mode", "Determine the amount of render threads used");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
/* motion blur */
prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_MBLUR);
RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled 3D scene motion blur");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
-
+
prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "blurfac");
RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 2);
@@ -5038,7 +5038,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Border", "Render a user-defined border region, within the frame size ");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "border_min_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "border.xmin");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -5066,24 +5066,24 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Border Maximum Y", "Maximum Y value for the render border");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_crop_to_border", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_CROP);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Crop to Border", "Crop the rendered frame to the defined border size");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_placeholder", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_TOUCH);
RNA_def_property_ui_text(prop, "Placeholders",
"Create empty placeholder files while rendering frames (similar to Unix 'touch')");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_overwrite", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", R_NO_OVERWRITE);
RNA_def_property_ui_text(prop, "Overwrite", "Overwrite existing files while rendering");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_compositing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_DOCOMP);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -5091,7 +5091,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"Process the render result through the compositing pipeline, "
"if compositing nodes are enabled");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_sequencer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_DOSEQ);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -5099,7 +5099,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"Process the render (and composited) result through the video sequence "
"editor pipeline, if sequencer strips exist");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_file_extension", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION);
RNA_def_property_ui_text(prop, "File Extensions",
@@ -5131,7 +5131,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"Save tiles for all RenderLayers and SceneNodes to files in the temp directory "
"(saves memory, required for Full Sample)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_full_sample", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_FULL_SAMPLE);
RNA_def_property_ui_text(prop, "Full Sample",
@@ -5167,7 +5167,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
/* Bake */
-
+
prop = RNA_def_property(srna, "bake_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "bake_mode");
RNA_def_property_enum_items(prop, bake_mode_items);
@@ -5228,23 +5228,23 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"apply a user scale to the derivative map");
/* stamp */
-
+
prop = RNA_def_property(srna, "use_stamp_time", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_TIME);
RNA_def_property_ui_text(prop, "Stamp Time",
"Include the rendered frame timecode as HH:MM:SS.FF in image metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_stamp_date", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_DATE);
RNA_def_property_ui_text(prop, "Stamp Date", "Include the current date in image/video metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_stamp_frame", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_FRAME);
RNA_def_property_ui_text(prop, "Stamp Frame", "Include the frame number in image metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_stamp_frame_range", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_FRAME_RANGE);
RNA_def_property_ui_text(prop, "Stamp Frame", "Include the rendered frame range in image/video metadata");
@@ -5259,27 +5259,27 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_CAMERALENS);
RNA_def_property_ui_text(prop, "Stamp Lens", "Include the active camera's lens in image metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_stamp_scene", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_SCENE);
RNA_def_property_ui_text(prop, "Stamp Scene", "Include the name of the active scene in image/video metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_stamp_note", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_NOTE);
RNA_def_property_ui_text(prop, "Stamp Note", "Include a custom note in image/video metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_stamp_marker", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_MARKER);
RNA_def_property_ui_text(prop, "Stamp Marker", "Include the name of the last marker in image metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_stamp_filename", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_FILENAME);
RNA_def_property_ui_text(prop, "Stamp Filename", "Include the .blend filename in image/video metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "use_stamp_sequencer_strip", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_SEQSTRIP);
RNA_def_property_ui_text(prop, "Stamp Sequence Strip",
@@ -5290,7 +5290,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "stamp", R_STAMP_RENDERTIME);
RNA_def_property_ui_text(prop, "Stamp Render Time", "Include the render time in image metadata");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "stamp_note_text", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "stamp_udata");
RNA_def_property_ui_text(prop, "Stamp Note Text", "Custom text to appear in the stamp note");
@@ -5328,7 +5328,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_ui_text(prop, "Text Color", "Color to use for stamp text");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
prop = RNA_def_property(srna, "stamp_background", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "bg_stamp");
RNA_def_property_array(prop, 4);
@@ -5560,7 +5560,7 @@ static void rna_def_scene_keying_sets(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Scene_active_keying_set_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active Keying Set", "Active Keying Set used to insert/delete keyframes");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET, NULL);
-
+
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "active_keyingset");
RNA_def_property_int_funcs(prop, "rna_Scene_active_keying_set_index_get",
@@ -5574,14 +5574,14 @@ static void rna_def_scene_keying_sets_all(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
RNA_def_property_srna(cprop, "KeyingSetsAll");
srna = RNA_def_struct(brna, "KeyingSetsAll", NULL);
RNA_def_struct_sdna(srna, "Scene");
RNA_def_struct_ui_text(srna, "Keying Sets All", "All available keying sets");
-
+
/* NOTE: no add/remove available here, without screwing up this amalgamated list... */
-
+
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "KeyingSet");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -5589,7 +5589,7 @@ static void rna_def_scene_keying_sets_all(BlenderRNA *brna, PropertyRNA *cprop)
"rna_Scene_active_keying_set_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active Keying Set", "Active Keying Set used to insert/delete keyframes");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET, NULL);
-
+
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "active_keyingset");
RNA_def_property_int_funcs(prop, "rna_Scene_active_keying_set_index_get",
@@ -5759,7 +5759,7 @@ static void rna_def_scene_display(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 250.0f);
prop = RNA_def_property(srna, "matcap_ssao_factor_edge", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Edge Strength", "Strength of the Edge effect");
RNA_def_property_range(prop, 0.0f, 250.0f);
@@ -5837,337 +5837,337 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Diffuse Bounces", "Number of time the light is reinjected inside light grids, "
"0 disable indirect diffuse light");
RNA_def_property_range(prop, 0, INT_MAX);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "gi_cubemap_resolution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, eevee_shadow_size_items);
RNA_def_property_enum_default(prop, 512);
RNA_def_property_ui_text(prop, "Cubemap Size", "Size of every cubemaps");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "gi_visibility_resolution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, eevee_gi_visibility_size_items);
RNA_def_property_enum_default(prop, 32);
RNA_def_property_ui_text(prop, "Irradiance Visibility Size",
"Size of the shadow map applied to each irradiance sample");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Temporal Anti-Aliasing (super sampling) */
prop = RNA_def_property(srna, "taa_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_default(prop, 16);
RNA_def_property_ui_text(prop, "Viewport Samples", "Number of samples, unlimited if 0");
RNA_def_property_range(prop, 0, INT_MAX);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "taa_render_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_default(prop, 64);
RNA_def_property_ui_text(prop, "Render Samples", "Number of samples per pixels for rendering");
RNA_def_property_range(prop, 1, INT_MAX);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_taa_reprojection", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_TAA_REPROJECTION);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Viewport Denoising", "Denoise image using temporal reprojection "
"(can leave some ghosting)");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Screen Space Subsurface Scattering */
prop = RNA_def_property(srna, "use_sss", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSS_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Subsurface Scattering", "Enable screen space subsurface scattering");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "sss_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_default(prop, 7);
RNA_def_property_ui_text(prop, "Samples", "Number of samples to compute the scattering effect");
RNA_def_property_range(prop, 1, 32);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "sss_jitter_threshold", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 0.3f);
RNA_def_property_ui_text(prop, "Jitter Threshold", "Rotate samples that are below this threshold");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_sss_separate_albedo", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSS_SEPARATE_ALBEDO);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Separate Albedo", "Avoid albedo being blured by the subsurface scattering "
"but uses more video memory");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Screen Space Reflection */
prop = RNA_def_property(srna, "use_ssr", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Screen Space Reflections", "Enable screen space reflection");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_ssr_refraction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_REFRACTION);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Screen Space Refractions", "Enable screen space Refractions");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_ssr_halfres", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_HALF_RESOLUTION);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Half Res Trace", "Raytrace at a lower resolution");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "ssr_quality", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 0.25f);
RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the screen space raytracing");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "ssr_max_roughness", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_ui_text(prop, "Max Roughness", "Do not raytrace reflections for roughness above this value");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "ssr_thickness", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_default(prop, 0.2f);
RNA_def_property_ui_text(prop, "Thickness", "Pixel thickness used to detect intersection");
RNA_def_property_range(prop, 1e-6f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 5, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "ssr_border_fade", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 0.075f);
RNA_def_property_ui_text(prop, "Edge Fading", "Screen percentage used to fade the SSR");
RNA_def_property_range(prop, 0.0f, 0.5f);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "ssr_firefly_fac", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 10.0f);
RNA_def_property_ui_text(prop, "Clamp", "Clamp pixel intensity to remove noise (0 to disabled)");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Volumetrics */
prop = RNA_def_property(srna, "use_volumetric", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Volumetrics", "Enable scattering and absorbance of volumetric material");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "volumetric_start", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_default(prop, 0.1f);
RNA_def_property_ui_text(prop, "Start", "Start distance of the volumetric effect");
RNA_def_property_range(prop, 1e-6f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "volumetric_end", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_default(prop, 100.0f);
RNA_def_property_ui_text(prop, "End", "End distance of the volumetric effect");
RNA_def_property_range(prop, 1e-6f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "volumetric_tile_size", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_default(prop, 8);
RNA_def_property_enum_items(prop, eevee_volumetric_tile_size_items);
RNA_def_property_ui_text(prop, "Tile Size", "Control the quality of the volumetric effects "
"(lower size increase vram usage and quality)");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "volumetric_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_default(prop, 64);
RNA_def_property_ui_text(prop, "Samples", "Number of samples to compute volumetric effects");
RNA_def_property_range(prop, 1, 256);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "volumetric_sample_distribution", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 0.8f);
RNA_def_property_ui_text(prop, "Exponential Sampling", "Distribute more samples closer to the camera");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_volumetric_lights", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_LIGHTS);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Volumetric Lighting", "Enable scene lamps interactions with volumetrics");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "volumetric_light_clamp", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_default(prop, 0.0f);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Clamp", "Maximum light contribution, reducing noise");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_volumetric_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_SHADOWS);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Volumetric Shadows", "Generate shadows from volumetric material (Very expensive)");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "volumetric_shadow_samples", PROP_INT, PROP_NONE);
RNA_def_property_int_default(prop, 16);
RNA_def_property_range(prop, 1, 128);
RNA_def_property_ui_text(prop, "Volumetric Shadow Samples", "Number of samples to compute volumetric shadowing");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_volumetric_colored_transmittance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_COLORED);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Colored Transmittance", "Enable wavelength dependent volumetric transmittance");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Ambient Occlusion */
prop = RNA_def_property(srna, "use_gtao", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Ambient Occlusion", "Enable ambient occlusion to simulate medium scale indirect shadowing");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_gtao_bent_normals", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_BENT_NORMALS);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Bent Normals", "Compute main non occluded direction to sample the environment");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_gtao_bounce", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_BOUNCE);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Bounces Approximation", "An approximation to simulate light bounces "
"giving less occlusion on brighter objects");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "gtao_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Factor", "Factor for ambient occlusion blending");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 2);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "gtao_quality", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 0.25f);
RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the horizon search");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "gtao_distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_default(prop, 0.2f);
RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the ambient occlusion effect");
RNA_def_property_range(prop, 0.0f, 100000.0f);
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Depth of Field */
prop = RNA_def_property(srna, "use_dof", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_DOF_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Depth of Field", "Enable depth of field using the values from the active camera");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "bokeh_max_size", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 100.0f);
RNA_def_property_ui_text(prop, "Max Size", "Max size of the bokeh shape for the depth of field (lower is faster)");
RNA_def_property_range(prop, 0.0f, 2000.0f);
RNA_def_property_ui_range(prop, 2.0f, 200.0f, 1, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "bokeh_threshold", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Sprite Threshold", "Brightness threshold for using sprite base depth of field");
RNA_def_property_range(prop, 0.0f, 100000.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Bloom */
prop = RNA_def_property(srna, "use_bloom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_BLOOM_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Bloom", "High brighness pixels generate a glowing effect");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "bloom_threshold", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 0.8f);
RNA_def_property_ui_text(prop, "Threshold", "Filters out pixels under this level of brightness");
RNA_def_property_range(prop, 0.0f, 100000.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "bloom_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_array_default(prop, default_bloom_color);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Color", "Color applied to the bloom effect");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "bloom_knee", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_ui_text(prop, "Knee", "Makes transition between under/over-threshold gradual");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "bloom_radius", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 6.5f);
RNA_def_property_ui_text(prop, "Radius", "Bloom spread distance");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "bloom_clamp", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Clamp", "Maximum intensity a bloom pixel can have");
RNA_def_property_range(prop, 0.0f, 1000.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "bloom_intensity", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_default(prop, 0.8f);
RNA_def_property_ui_text(prop, "Intensity", "Blend factor");
RNA_def_property_range(prop, 0.0f, 10000.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Motion blur */
prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_MOTION_BLUR_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Motion Blur", "Enable motion blur effect (only in camera view)");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_default(prop, 8);
RNA_def_property_ui_text(prop, "Samples", "Number of samples to take with motion blur");
RNA_def_property_range(prop, 1, 64);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close");
RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 2);
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
/* Shadows */
prop = RNA_def_property(srna, "shadow_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_default(prop, SHADOW_ESM);
RNA_def_property_enum_items(prop, eevee_shadow_method_items);
RNA_def_property_ui_text(prop, "Method", "Technique use to compute the shadows");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "shadow_cube_size", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_default(prop, 512);
RNA_def_property_enum_items(prop, eevee_shadow_size_items);
RNA_def_property_ui_text(prop, "Cube Shadows Resolution", "Size of point and area lamps shadow maps");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "shadow_cascade_size", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_default(prop, 1024);
RNA_def_property_enum_items(prop, eevee_shadow_size_items);
RNA_def_property_ui_text(prop, "Directional Shadows Resolution", "Size of sun lamps shadow maps");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
prop = RNA_def_property(srna, "use_shadow_high_bitdepth", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHADOW_HIGH_BITDEPTH);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "High Bitdepth", "Use 32bit shadows");
- RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
}
void RNA_def_scene(BlenderRNA *brna)
@@ -6177,7 +6177,7 @@ void RNA_def_scene(BlenderRNA *brna)
FunctionRNA *func;
PropertyRNA *parm;
-
+
static const EnumPropertyItem audio_distance_model_items[] = {
{0, "NONE", 0, "None", "No distance attenuation"},
{1, "INVERSE", 0, "Inverse", "Inverse distance model"},
@@ -6202,7 +6202,7 @@ void RNA_def_scene(BlenderRNA *brna)
"defining time and render related settings");
RNA_def_struct_ui_icon(srna, ICON_SCENE_DATA);
RNA_def_struct_clear_flag(srna, STRUCT_ID_REFCOUNT);
-
+
/* Global Settings */
prop = RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -6270,7 +6270,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame",
"Current Frame, to update animation data from python frame_set() instead");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, "rna_Scene_frame_update");
-
+
prop = RNA_def_property(srna, "frame_subframe", PROP_FLOAT, PROP_TIME);
RNA_def_property_float_sdna(prop, NULL, "r.subframe");
RNA_def_property_ui_text(prop, "Current Sub-Frame", "");
@@ -6295,7 +6295,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_int_default(prop, 1);
RNA_def_property_ui_text(prop, "Start Frame", "First frame of the playback/rendering range");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME_RANGE, NULL);
-
+
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.efra");
@@ -6304,7 +6304,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_int_default(prop, 250);
RNA_def_property_ui_text(prop, "End Frame", "Final frame of the playback/rendering range");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME_RANGE, NULL);
-
+
prop = RNA_def_property(srna, "frame_step", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.frame_step");
@@ -6313,7 +6313,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Frame Step",
"Number of frames to skip forward while rendering/playing back each frame");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
-
+
prop = RNA_def_property(srna, "frame_current_final", PROP_FLOAT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
@@ -6338,14 +6338,14 @@ void RNA_def_scene(BlenderRNA *brna)
"OpenGL renders instead of the Render properties start/end frame range");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
RNA_def_property_ui_icon(prop, ICON_PREVIEW_RANGE, 0);
-
+
prop = RNA_def_property(srna, "frame_preview_start", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.psfra");
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_preview_range_start_frame_set", NULL);
RNA_def_property_ui_text(prop, "Preview Range Start Frame", "Alternative start frame for UI playback");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
-
+
prop = RNA_def_property(srna, "frame_preview_end", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.pefra");
@@ -6368,16 +6368,16 @@ void RNA_def_scene(BlenderRNA *brna)
"Consider keyframes for active Object and/or its selected bones only "
"(in timeline and when jumping between keyframes)");
RNA_def_property_update(prop, NC_SCENE | ND_FRAME, NULL);
-
+
/* Stamp */
prop = RNA_def_property(srna, "use_stamp_note", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "r.stamp_udata");
RNA_def_property_ui_text(prop, "Stamp Note", "User defined note for the render stamping");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
+
/* Animation Data (for Scene) */
rna_def_animdata_common(srna);
-
+
/* Readonly Properties */
prop = RNA_def_property(srna, "is_nla_tweakmode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_NLA_EDIT_ON);
@@ -6385,7 +6385,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "NLA TweakMode",
"Whether there is any action referenced by NLA being edited (strictly read-only)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
/* Frame dropping flag for playback and sync enum */
#if 0 /* XXX: Is this actually needed? */
prop = RNA_def_property(srna, "use_frame_drop", PROP_BOOLEAN, PROP_NONE);
@@ -6412,13 +6412,13 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Use Nodes", "Enable the compositing node tree");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_use_nodes_update");
-
+
/* Sequencer */
prop = RNA_def_property(srna, "sequence_editor", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ed");
RNA_def_property_struct_type(prop, "SequenceEditor");
RNA_def_property_ui_text(prop, "Sequence Editor", "");
-
+
/* Keying Sets */
prop = RNA_def_property(srna, "keying_sets", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "keyingsets", NULL);
@@ -6426,7 +6426,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Absolute Keying Sets", "Absolute Keying Sets for this Scene");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET, NULL);
rna_def_scene_keying_sets(brna, prop);
-
+
prop = RNA_def_property(srna, "keying_sets_all", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_funcs(prop, "rna_Scene_all_keyingsets_begin", "rna_Scene_all_keyingsets_next",
"rna_iterator_listbase_end", "rna_iterator_listbase_get",
@@ -6436,14 +6436,14 @@ void RNA_def_scene(BlenderRNA *brna)
"All Keying Sets available for use (Builtins and Absolute Keying Sets for this Scene)");
RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET, NULL);
rna_def_scene_keying_sets_all(brna, prop);
-
+
/* Rigid Body Simulation */
prop = RNA_def_property(srna, "rigidbody_world", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "rigidbody_world");
RNA_def_property_struct_type(prop, "RigidBodyWorld");
RNA_def_property_ui_text(prop, "Rigid Body World", "");
RNA_def_property_update(prop, NC_SCENE, NULL);
-
+
/* Tool Settings */
prop = RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -6470,7 +6470,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "physics_settings.flag", PHYS_GLOBAL_GRAVITY);
RNA_def_property_ui_text(prop, "Global Gravity", "Use global gravity for all dynamics");
RNA_def_property_update(prop, 0, "rna_Physics_update");
-
+
/* Render Data */
prop = RNA_def_property(srna, "render", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -6505,7 +6505,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "TransformOrientation");
RNA_def_property_pointer_funcs(prop, "rna_Scene_current_orientation_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Current Transform Orientation", "Current transformation orientation");
-
+
/* Audio Settings */
prop = RNA_def_property(srna, "use_audio", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Scene_use_audio_get", "rna_Scene_use_audio_set");
@@ -6560,7 +6560,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_string(func, "statistics", NULL, 0, "Statistics", "");
RNA_def_function_return(func, parm);
-
+
/* Grease Pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index a307aff6e96..003e2561a22 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -105,7 +105,7 @@ static void rna_Scene_frame_set(Scene *scene, Main *bmain, int frame, float subf
/* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call
* BKE_scene_graph_update_for_newframe which will loose any un-keyed changes [#24690] */
/* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */
-
+
/* instead just redraw the views */
WM_main_add_notifier(NC_WINDOW, NULL);
}
@@ -158,13 +158,13 @@ static void rna_SceneRender_get_frame_path(
}
else {
BKE_image_path_from_imformat(
- name, rd->pic, bmain->name, (frame == INT_MIN) ? rd->cfra : frame,
+ name, rd->pic, BKE_main_blendfile_path(bmain), (frame == INT_MIN) ? rd->cfra : frame,
&rd->im_format, (rd->scemode & R_EXTENSION) != 0, true, suffix);
}
}
static void rna_Scene_ray_cast(
- Scene *scene, ViewLayer *view_layer,
+ Scene *scene, Main *bmain, ViewLayer *view_layer,
float origin[3], float direction[3], float ray_dist,
int *r_success, float r_location[3], float r_normal[3], int *r_index,
Object **r_ob, float r_obmat[16])
@@ -172,8 +172,7 @@ static void rna_Scene_ray_cast(
normalize_v3(direction);
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
- SnapObjectContext *sctx = ED_transform_snap_object_context_create(
- scene, depsgraph, 0);
+ SnapObjectContext *sctx = ED_transform_snap_object_context_create(bmain, scene, depsgraph, 0);
bool ret = ED_transform_snap_object_project_ray_ex(
sctx,
@@ -306,9 +305,10 @@ void RNA_api_scene(StructRNA *srna)
parm = RNA_def_float_vector(func, "result", 2, NULL, 0.0f, FLT_MAX, "", "aspect", 0.0f, FLT_MAX);
RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0);
RNA_def_function_output(func, parm);
-
+
/* Ray Cast */
func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast");
+ RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Cast a ray onto in object space");
parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "Scene Layer");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 731333bd18a..e30b75b27bd 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -394,10 +394,10 @@ static void rna_def_view2d_api(StructRNA *srna)
{
FunctionRNA *func;
PropertyRNA *parm;
-
+
static const float view_default[2] = {0.0f, 0.0f};
static const int region_default[2] = {0.0f, 0.0f};
-
+
func = RNA_def_function(srna, "region_to_view", "rna_View2D_region_to_view");
RNA_def_function_ui_description(func, "Transform region coordinates to 2D view");
parm = RNA_def_int(func, "x", 0, INT_MIN, INT_MAX, "x", "Region x coordinate", -10000, 10000);
@@ -428,9 +428,9 @@ static void rna_def_view2d(BlenderRNA *brna)
srna = RNA_def_struct(brna, "View2D", NULL);
RNA_def_struct_ui_text(srna, "View2D", "Scroll and zoom for a 2D region");
RNA_def_struct_sdna(srna, "View2D");
-
+
/* TODO more View2D properties could be exposed here (read-only) */
-
+
rna_def_view2d_api(srna);
}
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 12b080a9284..1d6d7c49523 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -162,6 +162,8 @@ static void rna_ParticleEdit_redo(bContext *C, PointerRNA *UNUSED(ptr))
if (!edit)
return;
+ if (ob) DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+
BKE_particle_batch_cache_dirty(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
psys_free_path_cache(edit->psys, edit);
DEG_id_tag_update(&CTX_data_scene(C)->id, DEG_TAG_COPY_ON_WRITE);
@@ -181,7 +183,7 @@ static void rna_ParticleEdit_update(bContext *C, PointerRNA *UNUSED(ptr))
static void rna_ParticleEdit_tool_set(PointerRNA *ptr, int value)
{
ParticleEditSettings *pset = (ParticleEditSettings *)ptr->data;
-
+
/* redraw hair completely if weight brush is/was used */
if ((pset->brushtype == PE_BRUSH_WEIGHT || value == PE_BRUSH_WEIGHT) && pset->object) {
Object *ob = pset->object;
@@ -236,7 +238,7 @@ static int rna_ParticleEdit_hair_get(PointerRNA *ptr)
return (edit && edit->psys);
}
-
+
return 0;
}
@@ -400,7 +402,7 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
Object *obedit = OBEDIT_FROM_OBACT(ob);
bScreen *sc;
Image *ima = scene->toolsettings->imapaint.canvas;
-
+
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
ScrArea *sa;
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -408,14 +410,14 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
for (slink = sa->spacedata.first; slink; slink = slink->next) {
if (slink->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)slink;
-
+
if (!sima->pin)
ED_space_image_set(sima, scene, obedit, ima);
}
}
}
}
-
+
if (ob && ob->type == OB_MESH) {
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
@@ -432,7 +434,7 @@ static PointerRNA rna_GPencilSculptSettings_brush_get(PointerRNA *ptr)
{
GP_BrushEdit_Settings *gset = (GP_BrushEdit_Settings *)ptr->data;
GP_EditBrush_Data *brush = NULL;
-
+
if ((gset->brushtype >= 0) && (gset->brushtype < TOT_GP_EDITBRUSH_TYPES))
brush = &gset->brush[gset->brushtype];
@@ -745,35 +747,35 @@ static void rna_def_image_paint(BlenderRNA *brna)
"Image", "Set image for texture painting directly"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "ImagePaint", "Paint");
RNA_def_struct_sdna(srna, "ImagePaintSettings");
RNA_def_struct_path_func(srna, "rna_ImagePaintSettings_path");
RNA_def_struct_ui_text(srna, "Image Paint", "Properties of image and texture painting mode");
- /* functions */
+ /* functions */
func = RNA_def_function(srna, "detect_data", "rna_ImaPaint_detect_data");
RNA_def_function_ui_description(func, "Check if required texpaint data exist");
/* return type */
RNA_def_function_return(func, RNA_def_boolean(func, "ok", 1, "", ""));
-
- /* booleans */
+
+ /* booleans */
prop = RNA_def_property(srna, "use_occlude", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_XRAY);
RNA_def_property_ui_text(prop, "Occlude", "Only paint onto the faces directly under the brush (slower)");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "use_backface_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_BACKFACE);
RNA_def_property_ui_text(prop, "Cull", "Ignore faces pointing away from the view (faster)");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "use_normal_falloff", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_FLAT);
RNA_def_property_ui_text(prop, "Normal", "Paint most on faces pointing towards the view");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "use_stencil_layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL);
RNA_def_property_ui_text(prop, "Stencil Layer", "Set the mask layer from the UV map buttons");
@@ -794,13 +796,13 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Canvas", "Image used as canvas");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_canvas_update");
-
+
prop = RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "clone");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Clone Image", "Image used as clone source");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "stencil_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "stencil_col");
@@ -811,15 +813,15 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0, 2.0);
RNA_def_property_ui_text(prop, "Dither", "Amount of dithering when painting on byte images");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "use_clone_layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_CLONE);
RNA_def_property_ui_text(prop, "Clone Map",
"Use another UV map as clone source, otherwise use the 3D cursor as the source");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
-
+
/* integers */
-
+
prop = RNA_def_property(srna, "seam_bleed", PROP_INT, PROP_PIXEL);
RNA_def_property_ui_range(prop, 0, 8, 0, -1);
RNA_def_property_ui_text(prop, "Bleed", "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)");
@@ -831,37 +833,37 @@ static void rna_def_image_paint(BlenderRNA *brna)
prop = RNA_def_int_array(srna, "screen_grab_size", 2, NULL, 0, 0, "screen_grab_size",
"Size to capture the image for re-projecting", 0, 0);
RNA_def_property_range(prop, 512, 16384);
-
+
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_enum_items(prop, paint_type_items);
RNA_def_property_ui_text(prop, "Mode", "Mode of operation for projection painting");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update");
-
+
/* Missing data */
prop = RNA_def_property(srna, "missing_uvs", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_UVS);
RNA_def_property_ui_text(prop, "Missing UVs",
"A UV layer is missing on the mesh");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
prop = RNA_def_property(srna, "missing_materials", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_MATERIAL);
RNA_def_property_ui_text(prop, "Missing Materials",
"The mesh is missing materials");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "missing_stencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_STENCIL);
RNA_def_property_ui_text(prop, "Missing Stencil",
"Image Painting does not have a stencil");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "missing_texture", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_TEX);
RNA_def_property_ui_text(prop, "Missing Texture",
"Image Painting does not have a texture to paint on");
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
}
static void rna_def_particle_edit(BlenderRNA *brna)
@@ -1058,10 +1060,10 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna)
{0, "ADD", 0, "Add", "Add effect of brush"},
{GP_EDITBRUSH_FLAG_INVERT, "SUBTRACT", 0, "Subtract", "Subtract effect of brush"},
{0, NULL, 0, NULL, NULL}};
-
+
StructRNA *srna;
PropertyRNA *prop;
-
+
/* == Settings == */
srna = RNA_def_struct(brna, "GPencilSculptSettings", NULL);
RNA_def_struct_sdna(srna, "GP_BrushEdit_Settings");
@@ -1073,18 +1075,18 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_gpencil_sculpt_brush_items);
RNA_def_property_ui_text(prop, "Tool", "");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "brush", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "GPencilSculptBrush");
RNA_def_property_pointer_funcs(prop, "rna_GPencilSculptSettings_brush_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Brush", "");
-
+
prop = RNA_def_property(srna, "use_select_mask", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_SELECT_MASK);
RNA_def_property_ui_text(prop, "Selection Mask", "Only sculpt selected stroke points");
RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0); // FIXME: this needs a custom icon
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "affect_position", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_APPLY_POSITION);
RNA_def_property_ui_text(prop, "Affect Position", "The brush affects the position of the point");
@@ -1130,23 +1132,23 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna)
RNA_def_property_range(prop, 0.001, 1.0);
RNA_def_property_ui_text(prop, "Strength", "Brush strength");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "use_pressure_strength", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_EDITBRUSH_FLAG_USE_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "use_falloff", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_EDITBRUSH_FLAG_USE_FALLOFF);
RNA_def_property_ui_text(prop, "Use Falloff", "Strength of brush decays with distance from cursor");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "affect_pressure", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE);
RNA_def_property_ui_text(prop, "Affect Pressure", "Affect pressure values as well when smoothing strokes");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
-
+
prop = RNA_def_property(srna, "direction", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, prop_direction_items);
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 33621af69af..fb6953904b3 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -177,7 +177,7 @@ static int rna_SequenceEditor_elements_length(PointerRNA *ptr)
/* Hack? copied from sequencer.c::reload_sequence_new_file() */
size_t olen = MEM_allocN_len(seq->strip->stripdata) / sizeof(struct StripElem);
-
+
/* the problem with seq->strip->len and seq->len is that it's discounted from the offset (hard cut trim) */
return (int) olen;
}
@@ -232,7 +232,7 @@ static void rna_Sequence_start_frame_set(PointerRNA *ptr, int value)
{
Sequence *seq = (Sequence *)ptr->data;
Scene *scene = (Scene *)ptr->id.data;
-
+
BKE_sequence_translate(scene, seq, value - seq->start);
do_sequence_frame_change_update(scene, seq);
}
@@ -283,7 +283,7 @@ static void rna_Sequence_frame_length_set(PointerRNA *ptr, int value)
{
Sequence *seq = (Sequence *)ptr->data;
Scene *scene = (Scene *)ptr->id.data;
-
+
BKE_sequence_tx_set_final_right(seq, BKE_sequence_tx_get_final_left(seq, false) + value);
do_sequence_frame_change_update(scene, seq);
}
@@ -307,7 +307,7 @@ static void rna_Sequence_channel_set(PointerRNA *ptr, int value)
Scene *scene = (Scene *)ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, false);
ListBase *seqbase = BKE_sequence_seqbase(&ed->seqbase, seq);
-
+
/* check channel increment or decrement */
const int channel_delta = (value >= seq->machine) ? 1 : -1;
seq->machine = value;
@@ -480,16 +480,16 @@ static void rna_Sequence_name_set(PointerRNA *ptr, const char *value)
Sequence *seq = (Sequence *)ptr->data;
char oldname[sizeof(seq->name)];
AnimData *adt;
-
+
/* make a copy of the old name first */
BLI_strncpy(oldname, seq->name + 2, sizeof(seq->name) - 2);
-
+
/* copy the new name into the name slot */
BLI_strncpy_utf8(seq->name + 2, value, sizeof(seq->name) - 2);
-
+
/* make sure the name is unique */
BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
-
+
/* fix all the animation data which may link to this */
/* don't rename everywhere because these are per scene */
@@ -562,7 +562,7 @@ static StructRNA *rna_Sequence_refine(struct PointerRNA *ptr)
static char *rna_Sequence_path(PointerRNA *ptr)
{
Sequence *seq = (Sequence *)ptr->data;
-
+
/* sequencer data comes from scene...
* TODO: would be nice to make SequenceEditor data a data-block of its own (for shorter paths)
*/
@@ -1121,11 +1121,11 @@ static void rna_def_strip_element(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SequenceElement", NULL);
RNA_def_struct_ui_text(srna, "Sequence Element", "Sequence strip data for a single frame");
RNA_def_struct_sdna(srna, "StripElem");
-
+
prop = RNA_def_property(srna, "filename", PROP_STRING, PROP_FILENAME);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Filename", "Name of the source file");
@@ -1146,7 +1146,7 @@ static void rna_def_strip_crop(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SequenceCrop", NULL);
RNA_def_struct_ui_text(srna, "Sequence Crop", "Cropping parameters for a sequence strip");
RNA_def_struct_sdna(srna, "StripCrop");
@@ -1156,13 +1156,13 @@ static void rna_def_strip_crop(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Top", "Number of pixels to crop from the top");
RNA_def_property_ui_range(prop, 0, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
-
+
prop = RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "bottom");
RNA_def_property_ui_text(prop, "Bottom", "Number of pixels to crop from the bottom");
RNA_def_property_ui_range(prop, 0, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
-
+
prop = RNA_def_property(srna, "min_x", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "left");
RNA_def_property_ui_text(prop, "Left", "Number of pixels to crop from the left side");
@@ -1182,7 +1182,7 @@ static void rna_def_strip_transform(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SequenceTransform", NULL);
RNA_def_struct_ui_text(srna, "Sequence Transform", "Transform parameters for a sequence strip");
RNA_def_struct_sdna(srna, "StripTransform");
@@ -1222,16 +1222,16 @@ static void rna_def_strip_proxy(BlenderRNA *brna)
"changes in framerate or dropouts"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "SequenceProxy", NULL);
RNA_def_struct_ui_text(srna, "Sequence Proxy", "Proxy parameters for a sequence strip");
RNA_def_struct_sdna(srna, "StripProxy");
-
+
prop = RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_sdna(prop, NULL, "dir");
RNA_def_property_ui_text(prop, "Directory", "Location to store the proxy files");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceProxy_update");
-
+
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
RNA_def_property_ui_text(prop, "Path", "Location of custom proxy file");
RNA_def_property_string_funcs(prop, "rna_Sequence_proxy_filepath_get", "rna_Sequence_proxy_filepath_length",
@@ -1464,7 +1464,7 @@ static void rna_def_sequence(BlenderRNA *brna)
{SEQ_TYPE_COLORMIX, "COLORMIX", 0, "Color Mix", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "Sequence", NULL);
RNA_def_struct_ui_text(srna, "Sequence", "Sequence strip in the sequence editor");
RNA_def_struct_refine_func(srna, "rna_Sequence_refine");
@@ -1529,7 +1529,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_range(prop, 1, MAXFRAME);
RNA_def_property_ui_text(prop, "Length",
"The length of the contents of this strip before the handles are applied");
-
+
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "start");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -1537,7 +1537,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, NULL, "rna_Sequence_start_frame_set", NULL); /* overlap tests and calc_seq_disp */
RNA_def_property_editable_func(prop, "rna_Sequence_frame_editable");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "frame_final_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "startdisp");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -1579,14 +1579,14 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_text(prop, "Start Still", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_frame_change_update");
-
+
prop = RNA_def_property(srna, "frame_still_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "endstill");
// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_text(prop, "End Still", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_frame_change_update");
-
+
prop = RNA_def_property(srna, "channel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "machine");
RNA_def_property_range(prop, 1, MAXSEQ);
@@ -1606,14 +1606,14 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_enum_items(prop, blend_mode_items);
RNA_def_property_ui_text(prop, "Blend Mode", "Method for controlling how the strip combines with other strips");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "blend_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Blend Opacity", "Percentage of how much the strip's colors affect other strips");
/* stupid 0-100 -> 0-1 */
RNA_def_property_float_funcs(prop, "rna_Sequence_opacity_get", "rna_Sequence_opacity_set", NULL);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "effect_fader", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
@@ -1627,7 +1627,7 @@ static void rna_def_sequence(BlenderRNA *brna)
"Fade effect using the built-in default (usually make transition as long as "
"effect strip)");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "speed_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "speed_fader");
@@ -1679,7 +1679,7 @@ static void rna_def_editor(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Meta Stack", "Meta strip stack, last is currently edited meta strip");
RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_SequenceEditor_meta_stack_get",
NULL, NULL, NULL, NULL);
-
+
prop = RNA_def_property(srna, "active_strip", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "act_seq");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -1884,7 +1884,7 @@ static void rna_def_image(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ImageSequence", "Sequence");
RNA_def_struct_ui_text(srna, "Image Sequence", "Sequence strip to load one or more images");
RNA_def_struct_sdna(srna, "Sequence");
@@ -1931,7 +1931,7 @@ static void rna_def_meta(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "MetaSequence", "Sequence");
RNA_def_struct_ui_text(srna, "Meta Sequence", "Sequence strip to group other strips as a single sequence strip");
RNA_def_struct_sdna(srna, "Sequence");
@@ -1950,7 +1950,7 @@ static void rna_def_scene(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SceneSequence", "Sequence");
RNA_def_struct_ui_text(srna, "Scene Sequence", "Sequence strip to used the rendered image of a scene");
RNA_def_struct_sdna(srna, "Sequence");
@@ -2057,7 +2057,7 @@ static void rna_def_movieclip(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "MovieClipSequence", "Sequence");
RNA_def_struct_ui_text(srna, "MovieClip Sequence", "Sequence strip to load a video from the clip editor");
RNA_def_struct_sdna(srna, "Sequence");
@@ -2101,7 +2101,7 @@ static void rna_def_sound(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SoundSequence", "Sequence");
RNA_def_struct_ui_text(srna, "Sound Sequence",
"Sequence strip defining a sound to be played over a period of time");
@@ -2140,7 +2140,7 @@ static void rna_def_sound(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_AUDIO_DRAW_WAVEFORM);
RNA_def_property_ui_text(prop, "Draw Waveform", "Whether to draw the sound's waveform");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
-
+
rna_def_input(srna);
}
@@ -2160,7 +2160,7 @@ static void rna_def_effect(BlenderRNA *brna)
static void rna_def_multicam(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "multicam_source", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "multicam_source");
RNA_def_property_range(prop, 0, MAXSEQ - 1);
@@ -2173,7 +2173,7 @@ static void rna_def_multicam(StructRNA *srna)
static void rna_def_wipe(StructRNA *srna)
{
PropertyRNA *prop;
-
+
static const EnumPropertyItem wipe_type_items[] = {
{0, "SINGLE", 0, "Single", ""},
{1, "DOUBLE", 0, "Double", ""},
@@ -2209,7 +2209,7 @@ static void rna_def_wipe(StructRNA *srna)
RNA_def_property_enum_items(prop, wipe_direction_items);
RNA_def_property_ui_text(prop, "Direction", "Wipe direction");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "transition_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "wipetype");
RNA_def_property_enum_items(prop, wipe_type_items);
@@ -2223,37 +2223,37 @@ static void rna_def_glow(StructRNA *srna)
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "GlowVars", "effectdata");
-
+
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fMini");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Threshold", "Minimum intensity to trigger a glow");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "clamp", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fClamp");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Clamp", "Brightness limit of intensity");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "boost_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fBoost");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Boost Factor", "Brightness multiplier");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "blur_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "dDist");
RNA_def_property_range(prop, 0.5f, 20.0f);
RNA_def_property_ui_text(prop, "Blur Distance", "Radius of glow effect");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "quality", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "dQuality");
RNA_def_property_range(prop, 1, 5);
RNA_def_property_ui_text(prop, "Quality", "Accuracy of the blur effect");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "use_only_boost", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bNoComp", 0);
RNA_def_property_ui_text(prop, "Only Boost", "Show the glow buffer only");
@@ -2284,43 +2284,43 @@ static void rna_def_transform(StructRNA *srna)
RNA_def_property_ui_text(prop, "Scale X", "Amount to scale the input in the X axis");
RNA_def_property_ui_range(prop, 0, 10, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "scale_start_y", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "ScaleyIni");
RNA_def_property_ui_text(prop, "Scale Y", "Amount to scale the input in the Y axis");
RNA_def_property_ui_range(prop, 0, 10, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "use_uniform_scale", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uniform_scale", 0);
RNA_def_property_ui_text(prop, "Uniform Scale", "Scale uniformly, preserving aspect ratio");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "translate_start_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xIni");
RNA_def_property_ui_text(prop, "Translate X", "Amount to move the input on the X axis");
RNA_def_property_ui_range(prop, -4000.0f, 4000.0f, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "translate_start_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "yIni");
RNA_def_property_ui_text(prop, "Translate Y", "Amount to move the input on the Y axis");
RNA_def_property_ui_range(prop, -4000.0f, 4000.0f, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "rotation_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rotIni");
RNA_def_property_range(prop, -360.0f, 360.0f);
RNA_def_property_ui_text(prop, "Rotation", "Degrees to rotate the input");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "translation_unit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "percent");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* not meant to be animated */
RNA_def_property_enum_items(prop, translation_unit_items);
RNA_def_property_ui_text(prop, "Translation Unit", "Unit of measure to translate the input");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, interpolation_items);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* not meant to be animated */
@@ -2352,7 +2352,7 @@ static void rna_def_speed_control(StructRNA *srna)
RNA_def_property_ui_text(prop, "Multiply Speed", "Multiply the resulting speed after the speed factor");
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
-
+
prop = RNA_def_property(srna, "use_as_speed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SEQ_SPEED_INTEGRATE);
RNA_def_property_ui_text(prop, "Use as speed", "Interpret the value as speed instead of a frame number");
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index d447d2972f6..da8b19a1ff6 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -74,7 +74,7 @@ static void rna_Sequence_update_rnafunc(ID *id, Sequence *self, int do_data)
static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports, Sequence *seq_other)
{
const char *error_msg;
-
+
if (BKE_sequence_swap(seq_self, seq_other, &error_msg) == 0)
BKE_report(reports, RPT_ERROR, error_msg);
}
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index 832d5b28bd1..b4c9e7ba3a2 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -243,7 +243,7 @@ static void rna_SmokeModifier_density_grid_get(PointerRNA *ptr, float *values)
float *density;
BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
-
+
if (sds->flags & MOD_SMOKE_HIGHRES && sds->wt)
density = smoke_turbulence_get_density(sds->wt);
else
@@ -326,12 +326,12 @@ static void rna_SmokeModifier_flame_grid_get(PointerRNA *ptr, float *values)
float *flame;
BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
-
+
if (sds->flags & MOD_SMOKE_HIGHRES && sds->wt)
flame = smoke_turbulence_get_flame(sds->wt);
else
flame = smoke_get_flame(sds->fluid);
-
+
if (flame)
memcpy(values, flame, size * sizeof(float));
else
@@ -973,7 +973,7 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna)
RNA_def_property_ui_range(prop, -10, 10, 1, 1);
RNA_def_property_ui_text(prop, "Temp. Diff.", "Temperature difference to ambient temperature");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset");
-
+
prop = RNA_def_property(srna, "particle_system", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "psys");
RNA_def_property_struct_type(prop, "ParticleSystem");
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index b36014370f6..489f2b73bf3 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -114,13 +114,6 @@ const EnumPropertyItem rna_enum_space_image_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
-/* Expanded into the Space.ui_type enum. */
-const EnumPropertyItem rna_enum_space_button_mode_items[] = {
- {SB_SUBTYPE_DATA, "DATA_PROPERTIES", ICON_BUTS, "Data Properties", "Edit properties of active object and related data-blocks"},
- {SB_SUBTYPE_TOOL, "TOOL_PROPERTIES", ICON_PREFERENCES, "Tool Properties", "Edit tool settings"},
- {0, NULL, 0, NULL, NULL}
-};
-
#define V3D_S3D_CAMERA_LEFT {STEREO_LEFT_ID, "LEFT", ICON_RESTRICT_RENDER_OFF, "Left", ""},
#define V3D_S3D_CAMERA_RIGHT {STEREO_RIGHT_ID, "RIGHT", ICON_RESTRICT_RENDER_OFF, "Right", ""},
#define V3D_S3D_CAMERA_S3D {STEREO_3D_ID, "S3D", ICON_CAMERA_STEREO, "3D", ""},
@@ -194,46 +187,21 @@ const EnumPropertyItem rna_enum_shading_type_items[] = {
};
const EnumPropertyItem rna_enum_viewport_lighting_items[] = {
- {V3D_LIGHTING_FLAT, "FLAT", 0, "Flat Lighting", "Display using flat lighting"},
- {V3D_LIGHTING_STUDIO, "STUDIO", 0, "Studio Lighting", "Display using studio lighting"},
- /* {V3D_LIGHTING_SCENE, "SCENE", 0, "Scene Lighting", "Display using scene lighting"}, */
+ {V3D_LIGHTING_FLAT, "FLAT", 0, "Flat", "Display using flat lighting"},
+ {V3D_LIGHTING_STUDIO, "STUDIO", 0, "Studio", "Display using studio lighting"},
+ {V3D_LIGHTING_MATCAP, "MATCAP", 0, "MatCap", "Display using matcap material and lighting"},
{0, NULL, 0, NULL, NULL}
};
static const EnumPropertyItem rna_enum_studio_light_items[] = {
- {0, "STUDIOLIGHT_00", 0, "", ""},
- {1, "STUDIOLIGHT_01", 0, "", ""},
- {2, "STUDIOLIGHT_02", 0, "", ""},
- {3, "STUDIOLIGHT_03", 0, "", ""},
- {4, "STUDIOLIGHT_04", 0, "", ""},
- {5, "STUDIOLIGHT_05", 0, "", ""},
- {6, "STUDIOLIGHT_06", 0, "", ""},
- {7, "STUDIOLIGHT_07", 0, "", ""},
- {8, "STUDIOLIGHT_08", 0, "", ""},
- {9, "STUDIOLIGHT_09", 0, "", ""},
- {10, "STUDIOLIGHT_10", 0, "", ""},
- {11, "STUDIOLIGHT_11", 0, "", ""},
- {12, "STUDIOLIGHT_12", 0, "", ""},
- {13, "STUDIOLIGHT_13", 0, "", ""},
- {14, "STUDIOLIGHT_14", 0, "", ""},
- {15, "STUDIOLIGHT_15", 0, "", ""},
- {16, "STUDIOLIGHT_16", 0, "", ""},
- {17, "STUDIOLIGHT_17", 0, "", ""},
- {18, "STUDIOLIGHT_18", 0, "", ""},
- {19, "STUDIOLIGHT_19", 0, "", ""},
- {20, "STUDIOLIGHT_20", 0, "", ""},
- {21, "STUDIOLIGHT_21", 0, "", ""},
- {22, "STUDIOLIGHT_22", 0, "", ""},
- {23, "STUDIOLIGHT_23", 0, "", ""},
- {24, "STUDIOLIGHT_24", 0, "", ""},
- {25, "STUDIOLIGHT_25", 0, "", ""},
- {26, "STUDIOLIGHT_26", 0, "", ""},
- {27, "STUDIOLIGHT_27", 0, "", ""},
- {28, "STUDIOLIGHT_28", 0, "", ""},
- {29, "STUDIOLIGHT_29", 0, "", ""},
+ {0, "DEFAULT", 0, "Default", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static const EnumPropertyItem rna_enum_matcap_items[] = {
+ {0, "DEFAULT", 0, "Default", ""},
{0, NULL, 0, NULL, NULL}
};
-#define NUM_STUDIOLIGHT_ITEMS 30
const EnumPropertyItem rna_enum_clip_editor_mode_items[] = {
{SC_MODE_TRACKING, "TRACKING", ICON_ANIM_DATA, "Tracking", "Show tracking and solving tools"},
@@ -243,6 +211,7 @@ const EnumPropertyItem rna_enum_clip_editor_mode_items[] = {
/* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */
static const EnumPropertyItem buttons_context_items[] = {
+ {BCONTEXT_TOOL, "TOOL", ICON_PREFERENCES, "Tool", "Tool settings"},
{BCONTEXT_SCENE, "SCENE", ICON_SCENE_DATA, "Scene", "Scene"},
{BCONTEXT_RENDER, "RENDER", ICON_SCENE, "Render", "Render"},
{BCONTEXT_VIEW_LAYER, "VIEW_LAYER", ICON_RENDER_RESULT, "View Layer", "View layer"},
@@ -547,17 +516,6 @@ static void rna_3DViewShading_type_update(Main *bmain, Scene *UNUSED(scene), Poi
ED_view3d_shade_update(bmain, v3d, sa);
}
-static void rna_SpaceView3D_matcap_enable(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
-{
- View3D *v3d = (View3D *)(ptr->data);
-
- if (v3d->matcap_icon < ICON_MATCAP_01 ||
- v3d->matcap_icon > ICON_MATCAP_24)
- {
- v3d->matcap_icon = ICON_MATCAP_01;
- }
-}
-
static PointerRNA rna_SpaceView3D_region_3d_get(PointerRNA *ptr)
{
View3D *v3d = (View3D *)(ptr->data);
@@ -676,6 +634,9 @@ static void rna_3DViewShading_type_set(PointerRNA *ptr, int value)
if (value != v3d->drawtype && value == OB_RENDER) {
v3d->prev_drawtype = v3d->drawtype;
}
+ if (value == OB_TEXTURE && v3d->shading.light == V3D_LIGHTING_MATCAP) {
+ v3d->shading.light = V3D_LIGHTING_STUDIO;
+ }
v3d->drawtype = value;
}
@@ -713,17 +674,56 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf(
static int rna_View3DShading_studio_light_orientation_get(PointerRNA *ptr)
{
View3D *v3d = (View3D *)ptr->data;
- StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, 0);
- return sl->flag & (STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_CAMERA);
+ StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_FLAG_ALL);
+ return sl->flag & STUDIOLIGHT_FLAG_ORIENTATIONS;
}
static void rna_View3DShading_studio_light_orientation_set(PointerRNA *UNUSED(ptr), int UNUSED(value))
{
}
+/* shading.light */
+static int rna_View3DShading_light_get(PointerRNA *ptr)
+{
+ View3D *v3d = (View3D *)ptr->data;
+ return v3d->shading.light;
+}
+
+static void rna_View3DShading_light_set(PointerRNA *ptr, int value)
+{
+ View3D *v3d = (View3D *)ptr->data;
+ v3d->shading.light = value;
+}
+
+static const EnumPropertyItem *rna_View3DShading_light_itemf(
+ bContext *UNUSED(C), PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ View3D *v3d = (View3D *)ptr->data;
+
+ int totitem = 0;
+ EnumPropertyItem *item = NULL;
+
+ if (v3d->drawtype == OB_SOLID || v3d->drawtype == OB_TEXTURE) {
+ RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_lighting_items, V3D_LIGHTING_FLAT);
+ RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_lighting_items, V3D_LIGHTING_STUDIO);
+ }
+
+ if (v3d->drawtype == OB_SOLID) {
+ RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_lighting_items, V3D_LIGHTING_MATCAP);
+ }
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+ return item;
+}
+
+/* Studio light */
static int rna_View3DShading_studio_light_get(PointerRNA *ptr)
{
View3D *v3d = (View3D *)ptr->data;
- const int flag = (v3d->drawtype == OB_MATERIAL) ? STUDIOLIGHT_ORIENTATION_WORLD : 0;
+ int flag = STUDIOLIGHT_ORIENTATIONS_SOLID;
+ if (v3d->drawtype == OB_MATERIAL) {
+ flag = STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE;
+ }
StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, flag);
BLI_strncpy(v3d->shading.studio_light, sl->name, FILE_MAXFILE);
return sl->index;
@@ -732,7 +732,7 @@ static int rna_View3DShading_studio_light_get(PointerRNA *ptr)
static void rna_View3DShading_studio_light_set(PointerRNA *ptr, int value)
{
View3D *v3d = (View3D *)ptr->data;
- StudioLight *sl = BKE_studiolight_findindex(value);
+ StudioLight *sl = BKE_studiolight_findindex(value, STUDIOLIGHT_FLAG_ALL);
BLI_strncpy(v3d->shading.studio_light, sl->name, FILE_MAXFILE);
}
@@ -742,15 +742,13 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(
{
View3D *v3d = (View3D *)ptr->data;
EnumPropertyItem *item = NULL;
- EnumPropertyItem *lastitem;
int totitem = 0;
- bool show_studiolight;
LISTBASE_FOREACH(StudioLight *, sl, BKE_studiolight_listbase()) {
- show_studiolight = false;
int icon_id = sl->irradiance_icon_id;
+ bool show_studiolight = false;
- if ((sl->flag & STUDIOLIGHT_EXTERNAL_FILE) == 0) {
+ if ((sl->flag & STUDIOLIGHT_INTERNAL)) {
/* always show internal lights */
show_studiolight = true;
}
@@ -758,8 +756,9 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(
switch (v3d->drawtype) {
case OB_SOLID:
case OB_TEXTURE:
- show_studiolight = true;
+ show_studiolight = (sl->flag & (STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_CAMERA)) > 0;
break;
+
case OB_MATERIAL:
show_studiolight = (sl->flag & STUDIOLIGHT_ORIENTATION_WORLD) > 0;
icon_id = sl->radiance_icon_id;
@@ -767,12 +766,48 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(
}
}
- if (show_studiolight && totitem < NUM_STUDIOLIGHT_ITEMS) {
- RNA_enum_items_add_value(&item, &totitem, rna_enum_studio_light_items, sl->index);
- lastitem = &item[totitem - 1];
- lastitem->value = sl->index;
- lastitem->icon = icon_id;
- lastitem->name = sl->name;
+ if (show_studiolight) {
+ EnumPropertyItem tmp = {sl->index, sl->name, icon_id, sl->name, ""};
+ RNA_enum_item_add(&item, &totitem, &tmp);
+ }
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+ return item;
+}
+/* Matcap studiolight */
+static int rna_View3DShading_matcap_get(PointerRNA *ptr)
+{
+ View3D *v3d = (View3D *)ptr->data;
+ StudioLight *sl = BKE_studiolight_find(v3d->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+ BLI_strncpy(v3d->shading.matcap, sl->name, FILE_MAXFILE);
+ return sl->index;
+}
+
+static void rna_View3DShading_matcap_set(PointerRNA *ptr, int value)
+{
+ View3D *v3d = (View3D *)ptr->data;
+ StudioLight *sl = BKE_studiolight_findindex(value, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+ BLI_strncpy(v3d->shading.matcap, sl->name, FILE_MAXFILE);
+}
+
+static const EnumPropertyItem *rna_View3DShading_matcap_itemf(
+ bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+
+ const int flags = (STUDIOLIGHT_EXTERNAL_FILE | STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+
+ LISTBASE_FOREACH(StudioLight *, sl, BKE_studiolight_listbase()) {
+ int icon_id = sl->irradiance_icon_id;
+ bool show_studiolight = (sl->flag & flags) == flags;
+
+ if (show_studiolight) {
+ EnumPropertyItem tmp = {sl->index, sl->name, icon_id, sl->name, ""};
+ RNA_enum_item_add(&item, &totitem, &tmp);
}
}
@@ -1141,6 +1176,10 @@ static const EnumPropertyItem *rna_SpaceProperties_context_itemf(
EnumPropertyItem *item = NULL;
int totitem = 0;
+ if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) {
+ RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TOOL);
+ }
+
if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER);
}
@@ -1408,12 +1447,12 @@ static void rna_SpaceDopeSheetEditor_mode_update(bContext *C, PointerRNA *ptr)
else
saction->action = NULL;
}
-
+
/* Collapse summary channel and hide channel list for timeline */
if (saction->mode == SACTCONT_TIMELINE) {
saction->ads.flag |= ADS_FLAG_SUMMARY_COLLAPSED;
}
-
+
if (sa && sa->spacedata.first == saction) {
ARegion *channels_region = BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS);
if (channels_region) {
@@ -1426,7 +1465,7 @@ static void rna_SpaceDopeSheetEditor_mode_update(bContext *C, PointerRNA *ptr)
ED_region_visibility_change_update(C, channels_region);
}
}
-
+
/* recalculate extents of channel list */
saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
}
@@ -2261,9 +2300,10 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
};
static const EnumPropertyItem studio_light_orientation_items[] = {
- {0, "UNKNOWN", 0, "Unknown", "Studio light has no orientation"},
- {STUDIOLIGHT_ORIENTATION_CAMERA, "CAMERA", 0, "Camera", "Studio light is camera based"},
- {STUDIOLIGHT_ORIENTATION_WORLD, "WORLD", 0, "World", "Studio light is world based"},
+ {0, "UNKNOWN", 0, "Unknown", "Studio light has no orientation"},
+ {STUDIOLIGHT_ORIENTATION_CAMERA, "CAMERA", 0, "Camera", "Studio light is camera based"},
+ {STUDIOLIGHT_ORIENTATION_WORLD, "WORLD", 0, "World", "Studio light is world based"},
+ {STUDIOLIGHT_ORIENTATION_VIEWNORMAL, "VIEWNORMAL", 0, "Matcap", "Studio light is a matcap"},
{0, NULL, 0, NULL, NULL}
};
@@ -2284,6 +2324,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
prop = RNA_def_property(srna, "light", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shading.light");
RNA_def_property_enum_items(prop, rna_enum_viewport_lighting_items);
+ RNA_def_property_enum_funcs(prop, "rna_View3DShading_light_get", "rna_View3DShading_light_set", "rna_View3DShading_light_itemf");
RNA_def_property_ui_text(prop, "Lighting", "Lighting Method for Solid/Texture Viewport Shading");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
@@ -2300,6 +2341,37 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Studiolight", "Studio lighting setup");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "matcap", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_matcap_items);
+ RNA_def_property_enum_default(prop, 0);
+ RNA_def_property_enum_funcs(prop, "rna_View3DShading_matcap_get", "rna_View3DShading_matcap_set", "rna_View3DShading_matcap_itemf");
+ RNA_def_property_ui_text(prop, "Matcap", "Matcap material and lighting");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "show_cavity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_CAVITY);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Cavity", "Show Cavity");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "cavity_ridge_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "shading.cavity_ridge_factor");
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Ridge", "Factor for the ridges");
+ RNA_def_property_range(prop, 0.0f, 250.0f);
+ RNA_def_property_ui_range(prop, 0.00f, 2.5f, 1, 3);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "cavity_valley_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "shading.cavity_valley_factor");
+ RNA_def_property_float_default(prop, 1.0);
+ RNA_def_property_ui_text(prop, "Valley", "Factor for the valleys");
+ RNA_def_property_range(prop, 0.0f, 250.0f);
+ RNA_def_property_ui_range(prop, 0.00f, 2.5f, 1, 3);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "studio_light_orientation", PROP_ENUM, PROP_NONE);
RNA_define_verify_sdna(0);
RNA_def_property_enum_sdna(prop, NULL, "shading.flag");
@@ -2347,7 +2419,6 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_float_default(prop, 0.5);
RNA_def_property_ui_text(prop, "X-Ray Alpha", "Amount of alpha to use");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_range(prop, 0.04f, 1.0f, 1, 1);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
@@ -2498,6 +2569,14 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bone Selection", "Show the Bone Selection Overlay");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "bone_selection_alpha", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "overlay.bone_selection_alpha");
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_ui_text(prop, "Opacity", "Opacity to use for bone selection");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "show_motion_paths", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_HIDE_MOTION_PATHS);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -2516,6 +2595,14 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Wireframes", "Show face edges wires");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "wireframe_threshold", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "overlay.wireframe_threshold");
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_ui_text(prop, "Wireframe Threshold", "Adjust the number of wires displayed (1 for all wires)");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "show_paint_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.paint_flag", V3D_OVERLAY_PAINT_WIRE);
RNA_def_property_ui_text(prop, "Show Wire", "Use wireframe display in painting modes");
@@ -2588,34 +2675,6 @@ static void rna_def_space_view3d(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static const EnumPropertyItem view3d_matcap_items[] = {
- {ICON_MATCAP_01, "01", ICON_MATCAP_01, "", ""},
- {ICON_MATCAP_02, "02", ICON_MATCAP_02, "", ""},
- {ICON_MATCAP_03, "03", ICON_MATCAP_03, "", ""},
- {ICON_MATCAP_04, "04", ICON_MATCAP_04, "", ""},
- {ICON_MATCAP_05, "05", ICON_MATCAP_05, "", ""},
- {ICON_MATCAP_06, "06", ICON_MATCAP_06, "", ""},
- {ICON_MATCAP_07, "07", ICON_MATCAP_07, "", ""},
- {ICON_MATCAP_08, "08", ICON_MATCAP_08, "", ""},
- {ICON_MATCAP_09, "09", ICON_MATCAP_09, "", ""},
- {ICON_MATCAP_10, "10", ICON_MATCAP_10, "", ""},
- {ICON_MATCAP_11, "11", ICON_MATCAP_11, "", ""},
- {ICON_MATCAP_12, "12", ICON_MATCAP_12, "", ""},
- {ICON_MATCAP_13, "13", ICON_MATCAP_13, "", ""},
- {ICON_MATCAP_14, "14", ICON_MATCAP_14, "", ""},
- {ICON_MATCAP_15, "15", ICON_MATCAP_15, "", ""},
- {ICON_MATCAP_16, "16", ICON_MATCAP_16, "", ""},
- {ICON_MATCAP_17, "17", ICON_MATCAP_17, "", ""},
- {ICON_MATCAP_18, "18", ICON_MATCAP_18, "", ""},
- {ICON_MATCAP_19, "19", ICON_MATCAP_19, "", ""},
- {ICON_MATCAP_20, "20", ICON_MATCAP_20, "", ""},
- {ICON_MATCAP_21, "21", ICON_MATCAP_21, "", ""},
- {ICON_MATCAP_22, "22", ICON_MATCAP_22, "", ""},
- {ICON_MATCAP_23, "23", ICON_MATCAP_23, "", ""},
- {ICON_MATCAP_24, "24", ICON_MATCAP_24, "", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
srna = RNA_def_struct(brna, "SpaceView3D", "Space");
RNA_def_struct_sdna(srna, "View3D");
RNA_def_struct_ui_text(srna, "3D View Space", "3D View space data");
@@ -2832,17 +2891,6 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show 3D Marker Names", "Show names for reconstructed tracks objects");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
- prop = RNA_def_property(srna, "use_matcap", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_MATCAP);
- RNA_def_property_ui_text(prop, "Matcap", "Active Objects draw images mapped on normals, enhancing Solid Draw Mode");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_matcap_enable");
-
- prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "matcap_icon");
- RNA_def_property_enum_items(prop, view3d_matcap_items);
- RNA_def_property_ui_text(prop, "Matcap", "Image to use for Material Capture, active objects only");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
prop = RNA_def_property(srna, "fx_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "FX Options", "Options used for real time compositing");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
@@ -3026,13 +3074,6 @@ static void rna_def_space_buttons(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "SpaceButs");
RNA_def_struct_ui_text(srna, "Properties Space", "Properties space data");
- /* Not exposed to the UI (access via space-type selector). */
- prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "space_subtype");
- RNA_def_property_enum_items(prop, rna_enum_space_button_mode_items);
- RNA_def_property_ui_text(prop, "Mode", "Arrangement of the panels");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL);
-
prop = RNA_def_property(srna, "context", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mainb");
RNA_def_property_enum_items(prop, buttons_context_items);
@@ -3596,7 +3637,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
RNA_def_property_enum_items(prop, autosnap_items);
RNA_def_property_ui_text(prop, "Auto Snap", "Automatic time snapping settings for transformations");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
-
+
/* displaying cache status */
prop = RNA_def_property(srna, "show_cache", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_DISPLAY);
diff --git a/source/blender/makesrna/intern/rna_test.c b/source/blender/makesrna/intern/rna_test.c
index 46299799966..f6d38c309f3 100644
--- a/source/blender/makesrna/intern/rna_test.c
+++ b/source/blender/makesrna/intern/rna_test.c
@@ -150,7 +150,7 @@ void RNA_def_test(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_dynamic_array_funcs(prop, "rna_Test_idarr_get_length", "rna_Test_idarr_set_length");
RNA_def_property_int_funcs(prop, "rna_Test_idarr_get", "rna_Test_idarr_set", NULL);
-
+
prop = RNA_def_boolean_array(srna, "bdarr", DYNAMIC_ARRAY_SIZE, NULL, "bdarr", "boolean array");
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_dynamic_array_funcs(prop, "rna_Test_bdarr_get_length", "rna_Test_bdarr_set_length");
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index 474fc3e5dc7..1035a3f7f55 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -131,10 +131,10 @@ static void rna_def_text_line(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "TextLine", NULL);
RNA_def_struct_ui_text(srna, "Text Line", "Line of text in a Text data-block");
-
+
prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_TextLine_body_get", "rna_TextLine_body_length", "rna_TextLine_body_set");
RNA_def_property_ui_text(prop, "Line", "Text in the line");
@@ -146,12 +146,12 @@ static void rna_def_text(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "Text", "ID");
RNA_def_struct_ui_text(srna, "Text", "Text data-block referencing an external or packed text file");
RNA_def_struct_ui_icon(srna, ICON_TEXT);
RNA_def_struct_clear_flag(srna, STRUCT_ID_REFCOUNT);
-
+
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_Text_filename_get", "rna_Text_filename_length", "rna_Text_filename_set");
RNA_def_property_ui_text(prop, "File Path", "Filename of the text file");
@@ -170,7 +170,7 @@ static void rna_def_text(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", TXT_ISMEM);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Memory", "Text file is in memory, without a corresponding file on disk");
-
+
prop = RNA_def_property(srna, "use_module", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", TXT_ISSCRIPT);
RNA_def_property_ui_text(prop, "Register",
@@ -183,7 +183,7 @@ static void rna_def_text(BlenderRNA *brna)
prop = RNA_def_property(srna, "lines", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "TextLine");
RNA_def_property_ui_text(prop, "Lines", "Lines of text");
-
+
prop = RNA_def_property(srna, "current_line", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "curl");
@@ -197,7 +197,7 @@ static void rna_def_text(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Character",
"Index of current character in current line, and also start index of "
"character in selection if one exists");
-
+
prop = RNA_def_property(srna, "current_line_index", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(prop, "rna_Text_current_line_index_get", "rna_Text_current_line_index_set", NULL);
RNA_def_property_ui_text(prop, "Current Line Index", "Index of current TextLine in TextLine collection");
@@ -209,13 +209,13 @@ static void rna_def_text(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "TextLine");
RNA_def_property_ui_text(prop, "Selection End Line", "End line of selection");
-
+
prop = RNA_def_property(srna, "select_end_character", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "selc");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Selection End Character",
"Index of character after end of selection in the selection end line");
-
+
RNA_api_text(srna);
}
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 5449b67c040..b848bb96392 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -191,7 +191,7 @@ static void rna_Texture_nodes_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
static void rna_Texture_type_set(PointerRNA *ptr, int value)
{
Tex *tex = (Tex *)ptr->data;
-
+
BKE_texture_type_set(tex, value);
}
@@ -247,7 +247,7 @@ void rna_TextureSlot_update(bContext *C, PointerRNA *ptr)
char *rna_TextureSlot_path(PointerRNA *ptr)
{
MTex *mtex = ptr->data;
-
+
/* if there is ID-data, resolve the path using the index instead of by name,
* since the name used is the name of the texture assigned, but the texture
* may be used multiple times in the same stack
@@ -274,7 +274,7 @@ char *rna_TextureSlot_path(PointerRNA *ptr)
}
}
}
-
+
/* this is a compromise for the remaining cases... */
if (mtex->tex) {
char name_esc[(sizeof(mtex->tex->id.name) - 2) * 2];
@@ -293,7 +293,7 @@ static int rna_TextureSlot_name_length(PointerRNA *ptr)
if (mtex->tex)
return strlen(mtex->tex->id.name + 2);
-
+
return 0;
}
@@ -312,7 +312,7 @@ static int rna_TextureSlot_output_node_get(PointerRNA *ptr)
MTex *mtex = ptr->data;
Tex *tex = mtex->tex;
int cur = mtex->which_output;
-
+
if (tex) {
bNodeTree *ntree = tex->nodetree;
bNode *node;
@@ -325,7 +325,7 @@ static int rna_TextureSlot_output_node_get(PointerRNA *ptr)
}
}
}
-
+
mtex->which_output = 0;
return 0;
}
@@ -339,18 +339,18 @@ static const EnumPropertyItem *rna_TextureSlot_output_node_itemf(
Tex *tex = mtex->tex;
EnumPropertyItem *item = NULL;
int totitem = 0;
-
+
if (tex) {
bNodeTree *ntree = tex->nodetree;
if (ntree) {
EnumPropertyItem tmp = {0, "", 0, "", ""};
bNode *node;
-
+
tmp.value = 0;
tmp.name = "Not Specified";
tmp.identifier = "NOT_SPECIFIED";
RNA_enum_item_add(&item, &totitem, &tmp);
-
+
for (node = ntree->nodes.first; node; node = node->next) {
if (node->type == TEX_NODE_OUTPUT) {
tmp.value = node->custom1;
@@ -361,7 +361,7 @@ static const EnumPropertyItem *rna_TextureSlot_output_node_itemf(
}
}
}
-
+
RNA_enum_item_end(&item, &totitem);
*r_free = true;
@@ -382,14 +382,14 @@ static void rna_Texture_use_color_ramp_set(PointerRNA *ptr, int value)
static void rna_Texture_use_nodes_update(bContext *C, PointerRNA *ptr)
{
Tex *tex = (Tex *)ptr->data;
-
+
if (tex->use_nodes) {
tex->type = 0;
-
+
if (tex->nodetree == NULL)
ED_node_texture_default(C, tex);
}
-
+
rna_Texture_nodes_update(CTX_data_main(C), CTX_data_scene(C), ptr);
}
@@ -412,7 +412,7 @@ static void rna_def_texmapping(BlenderRNA *brna)
{MTEX_SPHERE, "SPHERE", 0, "Sphere", "Map with Z as central axis"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem prop_vect_type_items[] = {
{TEXMAP_TYPE_TEXTURE, "TEXTURE", 0, "Texture", "Transform a texture by inverse mapping the texture coordinate"},
{TEXMAP_TYPE_POINT, "POINT", 0, "Point", "Transform a point"},
@@ -431,7 +431,7 @@ static void rna_def_texmapping(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "TexMapping", NULL);
RNA_def_struct_ui_text(srna, "Texture Mapping", "Texture coordinate mapping settings");
@@ -446,34 +446,34 @@ static void rna_def_texmapping(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Location", "");
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
-
+
/* Not PROP_XYZ, this is now in radians, no more degrees */
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
RNA_def_property_float_sdna(prop, NULL, "rot");
RNA_def_property_ui_text(prop, "Rotation", "");
RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
-
+
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
RNA_def_property_ui_text(prop, "Scale", "");
RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
-
+
prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "min");
RNA_def_property_ui_text(prop, "Minimum", "Minimum value for clipping");
RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
-
+
prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "max");
RNA_def_property_ui_text(prop, "Maximum", "Maximum value for clipping");
RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
-
+
prop = RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN);
RNA_def_property_ui_text(prop, "Has Minimum", "Whether to use minimum clipping value");
RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
-
+
prop = RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX);
RNA_def_property_ui_text(prop, "Has Maximum", "Whether to use maximum clipping value");
@@ -484,13 +484,13 @@ static void rna_def_texmapping(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_xyz_mapping_items);
RNA_def_property_ui_text(prop, "X Mapping", "");
RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
-
+
prop = RNA_def_property(srna, "mapping_y", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projy");
RNA_def_property_enum_items(prop, prop_xyz_mapping_items);
RNA_def_property_ui_text(prop, "Y Mapping", "");
RNA_def_property_update(prop, 0, "rna_Texture_mapping_update");
-
+
prop = RNA_def_property(srna, "mapping_z", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projz");
RNA_def_property_enum_items(prop, prop_xyz_mapping_items);
@@ -507,7 +507,7 @@ static void rna_def_colormapping(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ColorMapping", NULL);
RNA_def_struct_ui_text(srna, "Color Mapping", "Color mapping settings");
@@ -562,7 +562,7 @@ static void rna_def_mtex(BlenderRNA *brna)
{0, "DUMMY", 0, "Dummy", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "TextureSlot", NULL);
RNA_def_struct_sdna(srna, "MTex");
RNA_def_struct_ui_text(srna, "Texture Slot", "Texture slot defining the mapping and influence of a texture");
@@ -639,7 +639,7 @@ static void rna_def_mtex(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Default Value",
"Value to use for Ref, Spec, Amb, Emit, Alpha, RayMir, TransLu and Hard");
RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
-
+
prop = RNA_def_property(srna, "output_node", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "which_output");
RNA_def_property_enum_items(prop, output_node_items);
@@ -652,24 +652,24 @@ static void rna_def_mtex(BlenderRNA *brna)
static void rna_def_filter_common(StructRNA *srna)
{
PropertyRNA *prop;
-
+
prop = RNA_def_property(srna, "use_mipmap", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_MIPMAP);
RNA_def_property_boolean_funcs(prop, NULL, "rna_ImageTexture_mipmap_set");
RNA_def_property_ui_text(prop, "MIP Map", "Use auto-generated MIP maps for the image");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "use_mipmap_gauss", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_GAUSS_MIP);
RNA_def_property_ui_text(prop, "MIP Map Gaussian filter", "Use Gauss filter to sample down MIP maps");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "texfilter");
RNA_def_property_enum_items(prop, texture_filter_items);
RNA_def_property_ui_text(prop, "Filter", "Texture filter to use for sampling image");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "filter_lightprobes", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "afmax");
RNA_def_property_range(prop, 1, 256);
@@ -677,7 +677,7 @@ static void rna_def_filter_common(StructRNA *srna)
"Maximum number of samples (higher gives less blur at distant/oblique angles, "
"but is also slower)");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "filter_eccentricity", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "afmax");
RNA_def_property_range(prop, 1, 256);
@@ -908,7 +908,7 @@ static void rna_def_texture_marble(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_marble_stype);
RNA_def_property_ui_text(prop, "Pattern", "");
RNA_def_property_update(prop, 0, "rna_Texture_nodes_update");
-
+
prop = RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
@@ -1016,7 +1016,7 @@ static void rna_def_texture_stucci(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
RNA_def_property_ui_text(prop, "Turbulence", "Turbulence of the noise");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
RNA_def_property_enum_items(prop, prop_noise_basis_items);
@@ -1329,19 +1329,19 @@ static void rna_def_texture_voronoi(BlenderRNA *brna)
RNA_def_property_range(prop, -2, 2);
RNA_def_property_ui_text(prop, "Weight 1", "Voronoi feature weight 1");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "weight_2", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vn_w2");
RNA_def_property_range(prop, -2, 2);
RNA_def_property_ui_text(prop, "Weight 2", "Voronoi feature weight 2");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "weight_3", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vn_w3");
RNA_def_property_range(prop, -2, 2);
RNA_def_property_ui_text(prop, "Weight 3", "Voronoi feature weight 3");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "weight_4", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vn_w4");
RNA_def_property_range(prop, -2, 2);
@@ -1451,7 +1451,7 @@ static void rna_def_texture(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TEX_NO_CLAMP);
RNA_def_property_ui_text(prop, "Clamp", "Set negative texture RGB and intensity values to zero, for some uses like displacement this option can be disabled to get the full range");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "use_color_ramp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_COLORBAND);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Texture_use_color_ramp_set");
@@ -1479,44 +1479,44 @@ static void rna_def_texture(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "Saturation", "Adjust the saturation of colors in the texture");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
/* RGB Factor */
prop = RNA_def_property(srna, "factor_red", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rfac");
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "Factor Red", "");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "factor_green", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "gfac");
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "Factor Green", "");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
prop = RNA_def_property(srna, "factor_blue", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bfac");
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "Factor Blue", "");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
/* Alpha for preview render */
prop = RNA_def_property(srna, "use_preview_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_PRV_ALPHA);
RNA_def_property_ui_text(prop, "Show Alpha", "Show Alpha in Preview Render");
RNA_def_property_update(prop, 0, "rna_Texture_update");
-
+
/* nodetree */
prop = RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Use Nodes", "Make this a node-based texture");
RNA_def_property_update(prop, 0, "rna_Texture_use_nodes_update");
-
+
prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node-based textures");
RNA_def_property_update(prop, 0, "rna_Texture_nodes_update");
-
+
rna_def_animdata_common(srna);
/* specific types */
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 173eaf56f0c..e02421b9270 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -93,7 +93,7 @@ static ARegionType *region_type_find(ReportList *reports, int space_type, int re
if (art->regionid == region_type)
break;
}
-
+
/* region type not found? abort */
if (art == NULL) {
BKE_report(reports, RPT_ERROR, "Region not found in space type");
@@ -175,10 +175,16 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
if (!(art = region_type_find(NULL, pt->space_type, pt->region_type)))
return;
-
+
RNA_struct_free_extension(type, &pt->ext);
RNA_struct_free(&BLENDER_RNA, type);
+ if (pt->parent) {
+ LinkData *link = BLI_findptr(&pt->parent->children, pt, offsetof(LinkData, data));
+ BLI_freelinkN(&pt->parent->children, link);
+ }
+
+ BLI_freelistN(&pt->children);
BLI_freelinkN(&art->paneltypes, pt);
/* update while blender is running */
@@ -190,7 +196,7 @@ static StructRNA *rna_Panel_register(
StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
ARegionType *art;
- PanelType *pt, dummypt = {NULL};
+ PanelType *pt, *parent = NULL, dummypt = {NULL};
Panel dummypanel = {NULL};
PointerRNA dummyptr;
int have_function[3];
@@ -205,7 +211,7 @@ static StructRNA *rna_Panel_register(
/* validate the python class */
if (validate(&dummyptr, data, have_function) != 0)
return NULL;
-
+
if (strlen(identifier) >= sizeof(dummypt.idname)) {
BKE_reportf(reports, RPT_ERROR, "Registering panel class: '%s' is too long, maximum length is %d",
identifier, (int)sizeof(dummypt.idname));
@@ -229,6 +235,10 @@ static StructRNA *rna_Panel_register(
BLI_freelinkN(&art->paneltypes, pt);
break;
}
+
+ if (dummypt.parent_id[0] && STREQ(pt->idname, dummypt.parent_id)) {
+ parent = pt;
+ }
}
if (!RNA_struct_available_or_report(reports, dummypt.idname)) {
return NULL;
@@ -236,7 +246,12 @@ static StructRNA *rna_Panel_register(
if (!RNA_struct_bl_idname_ok_or_report(reports, dummypt.idname, "_PT_")) {
return NULL;
}
-
+ if (dummypt.parent_id[0] && !parent) {
+ BKE_reportf(reports, RPT_ERROR, "Registering panel class: parent '%s' for '%s' not found",
+ dummypt.parent_id, dummypt.idname);
+ return NULL;
+ }
+
/* create a new panel type */
pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
memcpy(pt, &dummypt, sizeof(dummypt));
@@ -267,6 +282,11 @@ static StructRNA *rna_Panel_register(
else
BLI_addtail(&art->paneltypes, pt);
+ if (parent) {
+ pt->parent = parent;
+ BLI_addtail(&parent->children, BLI_genericNodeN(pt));
+ }
+
{
const char *owner_id = RNA_struct_state_owner_get();
if (owner_id) {
@@ -276,14 +296,14 @@ static StructRNA *rna_Panel_register(
/* update while blender is running */
WM_main_add_notifier(NC_WINDOW, NULL);
-
+
return pt->ext.srna;
}
static StructRNA *rna_Panel_refine(PointerRNA *ptr)
{
- Panel *hdr = (Panel *)ptr->data;
- return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Panel;
+ Panel *menu = (Panel *)ptr->data;
+ return (menu->type && menu->type->ext.srna) ? menu->type->ext.srna : &RNA_Panel;
}
/* UIList */
@@ -570,7 +590,7 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
if (!(art = region_type_find(NULL, ht->space_type, ht->region_type)))
return;
-
+
RNA_struct_free_extension(type, &ht->ext);
RNA_struct_free(&BLENDER_RNA, type);
@@ -622,7 +642,7 @@ static StructRNA *rna_Header_register(
if (!RNA_struct_bl_idname_ok_or_report(reports, dummyht.idname, "_HT_")) {
return NULL;
}
-
+
/* create a new header type */
ht = MEM_callocN(sizeof(HeaderType), "python buttons header");
memcpy(ht, &dummyht, sizeof(dummyht));
@@ -639,7 +659,7 @@ static StructRNA *rna_Header_register(
/* update while blender is running */
WM_main_add_notifier(NC_WINDOW, NULL);
-
+
return ht->ext.srna;
}
@@ -676,7 +696,7 @@ static int menu_poll(const bContext *C, MenuType *pt)
return visible;
}
-static void menu_draw(const bContext *C, Menu *hdr)
+static void menu_draw(const bContext *C, Menu *menu)
{
extern FunctionRNA rna_Menu_draw_func;
@@ -684,12 +704,12 @@ static void menu_draw(const bContext *C, Menu *hdr)
ParameterList list;
FunctionRNA *func;
- RNA_pointer_create(&CTX_wm_screen(C)->id, hdr->type->ext.srna, hdr, &mtr);
+ RNA_pointer_create(&CTX_wm_screen(C)->id, menu->type->ext.srna, menu, &mtr);
func = &rna_Menu_draw_func; /* RNA_struct_find_function(&mtr, "draw"); */
RNA_parameter_list_create(&list, &mtr, func);
RNA_parameter_set_lookup(&list, "context", &C);
- hdr->type->ext.call((bContext *)C, &mtr, func, &list);
+ menu->type->ext.call((bContext *)C, &mtr, func, &list);
RNA_parameter_list_free(&list);
}
@@ -700,7 +720,7 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
if (!mt)
return;
-
+
RNA_struct_free_extension(type, &mt->ext);
RNA_struct_free(&BLENDER_RNA, type);
@@ -734,7 +754,7 @@ static StructRNA *rna_Menu_register(
/* validate the python class */
if (validate(&dummymtr, data, have_function) != 0)
return NULL;
-
+
if (strlen(identifier) >= sizeof(dummymt.idname)) {
BKE_reportf(reports, RPT_ERROR, "Registering menu class: '%s' is too long, maximum length is %d",
identifier, (int)sizeof(dummymt.idname));
@@ -752,7 +772,7 @@ static StructRNA *rna_Menu_register(
if (!RNA_struct_bl_idname_ok_or_report(reports, dummymt.idname, "_MT_")) {
return NULL;
}
-
+
/* create a new menu type */
if (_menu_descr[0]) {
description_size = strlen(_menu_descr) + 1;
@@ -792,14 +812,14 @@ static StructRNA *rna_Menu_register(
/* update while blender is running */
WM_main_add_notifier(NC_WINDOW, NULL);
-
+
return mt->ext.srna;
}
static StructRNA *rna_Menu_refine(PointerRNA *mtr)
{
- Menu *hdr = (Menu *)mtr->data;
- return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Menu;
+ Menu *menu = (Menu *)mtr->data;
+ return (menu->type && menu->type->ext.srna) ? menu->type->ext.srna : &RNA_Menu;
}
static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value)
@@ -938,7 +958,7 @@ static void rna_def_ui_layout(BlenderRNA *brna)
{UI_LAYOUT_ALIGN_RIGHT, "RIGHT", 0, "Right", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem emboss_items[] = {
{UI_EMBOSS, "NORMAL", 0, "Normal", "Draw standard button emboss style"},
{UI_EMBOSS_NONE, "NONE", 0, "None", "Draw only text and icons"},
@@ -955,15 +975,15 @@ static void rna_def_ui_layout(BlenderRNA *brna)
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_UILayout_active_get", "rna_UILayout_active_set");
-
+
prop = RNA_def_property(srna, "operator_context", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_operator_context_items);
RNA_def_property_enum_funcs(prop, "rna_UILayout_op_context_get", "rna_UILayout_op_context_set", NULL);
-
+
prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_UILayout_enabled_get", "rna_UILayout_enabled_set");
RNA_def_property_ui_text(prop, "Enabled", "When false, this (sub)layout is grayed out");
-
+
prop = RNA_def_property(srna, "alert", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_UILayout_alert_get", "rna_UILayout_alert_set");
@@ -979,7 +999,7 @@ static void rna_def_ui_layout(BlenderRNA *brna)
prop = RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_funcs(prop, "rna_UILayout_scale_x_get", "rna_UILayout_scale_x_set", NULL);
RNA_def_property_ui_text(prop, "Scale X", "Scale factor along the X for items in this (sub)layout");
-
+
prop = RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_funcs(prop, "rna_UILayout_scale_y_get", "rna_UILayout_scale_y_set", NULL);
RNA_def_property_ui_text(prop, "Scale Y", "Scale factor along the Y for items in this (sub)layout");
@@ -988,7 +1008,7 @@ static void rna_def_ui_layout(BlenderRNA *brna)
prop = RNA_def_property(srna, "emboss", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, emboss_items);
RNA_def_property_enum_funcs(prop, "rna_UILayout_emboss_get", "rna_UILayout_emboss_set", NULL);
-
+
prop = RNA_def_property(srna, "use_property_split", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_UILayout_property_split_get", "rna_UILayout_property_split_set");
}
@@ -999,7 +1019,7 @@ static void rna_def_panel(BlenderRNA *brna)
PropertyRNA *prop;
PropertyRNA *parm;
FunctionRNA *func;
-
+
static const EnumPropertyItem panel_flag_items[] = {
{PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed",
"Defines if the panel has to be open or collapsed at the time of its creation"},
@@ -1008,7 +1028,7 @@ static void rna_def_panel(BlenderRNA *brna)
"arrow to collapse the panel and the label (see bl_label)"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "Panel", NULL);
RNA_def_struct_ui_text(srna, "Panel", "Panel containing UI elements");
RNA_def_struct_sdna(srna, "Panel");
@@ -1041,11 +1061,11 @@ static void rna_def_panel(BlenderRNA *brna)
prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "UILayout");
RNA_def_property_ui_text(prop, "Layout", "Defines the structure of the panel in the UI");
-
+
prop = RNA_def_property(srna, "text", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "drawname");
RNA_def_property_ui_text(prop, "Text", "XXX todo");
-
+
/* registration */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->idname");
@@ -1082,7 +1102,7 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_space_type_items);
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in");
-
+
prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
RNA_def_property_enum_items(prop, rna_enum_region_type_items);
@@ -1095,13 +1115,18 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Context",
"The context in which the panel belongs to. (TODO: explain the "
"possible combinations bl_context/bl_region_type/bl_space_type)");
-
+
prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type->flag");
RNA_def_property_enum_items(prop, panel_flag_items);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
RNA_def_property_ui_text(prop, "Options", "Options for this panel type");
+ prop = RNA_def_property(srna, "bl_parent_id", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->parent_id");
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_ui_text(prop, "Parent ID Name", "If this is set, the panel becomes a subpanel");
+
prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PNL_PIN);
RNA_def_property_ui_text(prop, "Pin", "");
@@ -1238,7 +1263,7 @@ static void rna_def_header(BlenderRNA *brna)
PropertyRNA *prop;
PropertyRNA *parm;
FunctionRNA *func;
-
+
srna = RNA_def_struct(brna, "Header", NULL);
RNA_def_struct_ui_text(srna, "Header", "Editor header containing UI elements");
RNA_def_struct_sdna(srna, "Header");
@@ -1293,7 +1318,7 @@ static void rna_def_menu(BlenderRNA *brna)
PropertyRNA *prop;
PropertyRNA *parm;
FunctionRNA *func;
-
+
srna = RNA_def_struct(brna, "Menu", NULL);
RNA_def_struct_ui_text(srna, "Menu", "Editor menu containing buttons");
RNA_def_struct_sdna(srna, "Menu");
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 882f85c5b1f..ab4bdc8164b 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -95,9 +95,10 @@ const char *rna_translate_ui_text(
return BLT_pgettext(BLT_I18NCONTEXT_DEFAULT, text);
}
-static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, const char *text_ctxt,
- int translate, int icon, int expand, int slider, int toggle, int icon_only, int event,
- int full_event, int emboss, int index, int icon_value)
+static void rna_uiItemR(
+ uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, const char *text_ctxt,
+ int translate, int icon, int expand, int slider, int toggle, int icon_only, int event,
+ int full_event, int emboss, int index, int icon_value)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
int flag = 0;
@@ -125,8 +126,9 @@ static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname,
uiItemFullR(layout, ptr, prop, index, 0, flag, name, icon);
}
-static void rna_uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name,
- const char *text_ctxt, int translate, int icon)
+static void rna_uiItemMenuEnumR(
+ uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name,
+ const char *text_ctxt, int translate, int icon)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
@@ -140,8 +142,9 @@ static void rna_uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const
uiItemMenuEnumR_prop(layout, ptr, prop, name, icon);
}
-static void rna_uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *value,
- const char *name, const char *text_ctxt, int translate, int icon)
+static void rna_uiItemEnumR_string(
+ uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *value,
+ const char *name, const char *text_ctxt, int translate, int icon)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
@@ -157,9 +160,10 @@ static void rna_uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, con
uiItemEnumR_string(layout, ptr, propname, value, name, icon);
}
-static void rna_uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
- struct PointerRNA *searchptr, const char *searchpropname,
- const char *name, const char *text_ctxt, int translate, int icon)
+static void rna_uiItemPointerR(
+ uiLayout *layout, struct PointerRNA *ptr, const char *propname,
+ struct PointerRNA *searchptr, const char *searchpropname,
+ const char *name, const char *text_ctxt, int translate, int icon)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
@@ -226,8 +230,9 @@ static PointerRNA rna_uiItemOMenuHold(
}
-static void rna_uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const char *propname, const char *name,
- const char *text_ctxt, int translate, int icon)
+static void rna_uiItemMenuEnumO(
+ uiLayout *layout, bContext *C, const char *opname, const char *propname, const char *name,
+ const char *text_ctxt, int translate, int icon)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
@@ -242,8 +247,9 @@ static void rna_uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opnam
uiItemMenuEnumO_ptr(layout, C, ot, propname, name, icon);
}
-static void rna_uiItemL(uiLayout *layout, const char *name, const char *text_ctxt, int translate,
- int icon, int icon_value)
+static void rna_uiItemL(
+ uiLayout *layout, const char *name, const char *text_ctxt, int translate,
+ int icon, int icon_value)
{
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
@@ -255,8 +261,9 @@ static void rna_uiItemL(uiLayout *layout, const char *name, const char *text_ctx
uiItemL(layout, name, icon);
}
-static void rna_uiItemM(uiLayout *layout, bContext *C, const char *menuname, const char *name, const char *text_ctxt,
- int translate, int icon, int icon_value)
+static void rna_uiItemM(
+ uiLayout *layout, bContext *C, const char *menuname, const char *name, const char *text_ctxt,
+ int translate, int icon, int icon_value)
{
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate);
@@ -291,8 +298,9 @@ static void rna_uiItemPopoverPanelFromGroup(
uiItemPopoverPanelFromGroup(layout, C, space_id, region_id, context, category);
}
-static void rna_uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename,
- const char *name, const char *text_ctxt, int translate)
+static void rna_uiTemplateAnyID(
+ uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename,
+ const char *name, const char *text_ctxt, int translate)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
@@ -308,8 +316,9 @@ static void rna_uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *p
uiTemplateAnyID(layout, ptr, propname, proptypename, name);
}
-static void rna_uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *root_ptr,
- const char *name, const char *text_ctxt, int translate)
+static void rna_uiTemplatePathBuilder(
+ uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *root_ptr,
+ const char *name, const char *text_ctxt, int translate)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
@@ -360,8 +369,9 @@ static const char *rna_ui_get_enum_name(bContext *C, PointerRNA *ptr, const char
return name;
}
-static const char *rna_ui_get_enum_description(bContext *C, PointerRNA *ptr, const char *propname,
- const char *identifier)
+static const char *rna_ui_get_enum_description(
+ bContext *C, PointerRNA *ptr, const char *propname,
+ const char *identifier)
{
PropertyRNA *prop = NULL;
const EnumPropertyItem *items = NULL, *item;
@@ -493,7 +503,7 @@ void RNA_api_ui_layout(StructRNA *srna)
"Sub-layout. Items placed in this sublayout are placed next to each other "
"in a row");
RNA_def_boolean(func, "align", false, "", "Align buttons to each other");
-
+
func = RNA_def_function(srna, "column", "uiLayoutColumn");
parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
RNA_def_function_return(func, parm);
@@ -527,7 +537,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_return(func, parm);
RNA_def_function_ui_description(func, "Sublayout (items placed in this sublayout are placed "
"under each other in a column and are surrounded by a box)");
-
+
/* split layout */
func = RNA_def_function(srna, "split", "uiLayoutSplit");
parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
@@ -738,7 +748,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func, "data", "AnyType", "", "Pointer to put in context");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
-
+
/* templates */
func = RNA_def_function(srna, "template_header", "uiTemplateHeader");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@@ -815,7 +825,7 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_pointer(func, "root", "ID", "", "ID-block from which path is evaluated from");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
api_ui_item_common_text(func);
-
+
func = RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Generates the UI layout for modifiers");
@@ -865,15 +875,15 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_histogram", "uiTemplateHistogram");
RNA_def_function_ui_description(func, "Item. A histogramm widget to analyze imaga data");
api_ui_item_rna_common(func);
-
+
func = RNA_def_function(srna, "template_waveform", "uiTemplateWaveform");
RNA_def_function_ui_description(func, "Item. A waveform widget to analyze imaga data");
api_ui_item_rna_common(func);
-
+
func = RNA_def_function(srna, "template_vectorscope", "uiTemplateVectorscope");
RNA_def_function_ui_description(func, "Item. A vectorscope widget to analyze imaga data");
api_ui_item_rna_common(func);
-
+
func = RNA_def_function(srna, "template_layers", "uiTemplateLayers");
api_ui_item_rna_common(func);
parm = RNA_def_pointer(func, "used_layers_data", "AnyType", "", "Data from which to take property");
@@ -882,7 +892,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_int(func, "active_layer", 0, 0, INT_MAX, "Active Layer", "", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
-
+
func = RNA_def_function(srna, "template_color_picker", "uiTemplateColorPicker");
RNA_def_function_ui_description(func, "Item. A color wheel widget to pick colors");
api_ui_item_rna_common(func);
@@ -998,7 +1008,7 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_edit_mode_selection", "uiTemplateEditModeSelection");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
RNA_def_function_ui_description(func, "Inserts common 3DView Edit modes header UI (selector for selection mode)");
-
+
func = RNA_def_function(srna, "template_reports_banner", "uiTemplateReportsBanner");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index fef4cc3ed8e..74f01c0a1a4 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -41,6 +41,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_sound.h"
#include "BKE_addon.h"
+#include "BKE_studiolight.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -77,6 +78,12 @@ const EnumPropertyItem rna_enum_navigation_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+static const EnumPropertyItem rna_enum_studio_light_icons_id_items[] = {
+ {0, "DEFAULT", 0, "Default", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+
#if defined(WITH_INTERNATIONAL) || !defined(RNA_RUNTIME)
static const EnumPropertyItem rna_enum_language_default_items[] = {
{0, "DEFAULT", 0, "Default (Default)", ""},
@@ -184,7 +191,7 @@ static void rna_userdef_show_manipulator_update(Main *bmain, Scene *scene, Point
}
}
}
-
+
rna_userdef_update(bmain, scene, ptr);
}
@@ -251,7 +258,7 @@ static int rna_userdef_autokeymode_get(PointerRNA *ptr)
{
UserDef *userdef = (UserDef *)ptr->data;
short retval = userdef->autokey_mode;
-
+
if (!(userdef->autokey_mode & AUTOKEY_ON))
retval |= AUTOKEY_ON;
@@ -284,10 +291,10 @@ static void rna_userdef_timecode_style_set(PointerRNA *ptr, int value)
{
UserDef *userdef = (UserDef *)ptr->data;
int required_size = userdef->v2d_min_gridsize;
-
+
/* set the timecode style */
userdef->timecode_style = value;
-
+
/* adjust the v2d gridsize if needed so that timecodes don't overlap
* NOTE: most of these have been hand-picked to avoid overlaps while still keeping
* things from getting too blown out
@@ -309,7 +316,7 @@ static void rna_userdef_timecode_style_set(PointerRNA *ptr, int value)
required_size = 45;
break;
}
-
+
if (U.v2d_min_gridsize < required_size)
U.v2d_min_gridsize = required_size;
}
@@ -653,6 +660,117 @@ static void rna_ThemeUI_roundness_set(PointerRNA *ptr, float value)
tui->roundness = value * 0.5f;
}
+/* Studio Light */
+static void rna_UserDef_studiolight_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+ rna_iterator_listbase_begin(iter, BKE_studiolight_listbase(), NULL);
+}
+
+static void rna_UserDef_studiolight_refresh(UserDef *UNUSED(userdef))
+{
+ BKE_studiolight_refresh();
+}
+
+/* StudioLight.name */
+static void rna_UserDef_studiolight_name_get(PointerRNA *ptr, char *value)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ BLI_strncpy(value, sl->name, FILE_MAXFILE);
+}
+
+static int rna_UserDef_studiolight_name_length(PointerRNA *ptr)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ return strlen(sl->name);
+}
+
+/* StudioLight.path */
+static void rna_UserDef_studiolight_path_get(PointerRNA *ptr, char *value)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ BLI_strncpy(value, sl->path, FILE_MAX);
+}
+
+static int rna_UserDef_studiolight_path_length(PointerRNA *ptr)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ return strlen(sl->path);
+}
+
+/* StudioLight.index */
+static int rna_UserDef_studiolight_index_get(PointerRNA *ptr)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ return sl->index;
+}
+
+/* StudioLight.icon_id */
+static int rna_UserDef_studiolight_icon_id_get(PointerRNA *ptr)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ if (sl->flag & (STUDIOLIGHT_ORIENTATION_VIEWNORMAL | STUDIOLIGHT_ORIENTATION_CAMERA)) {
+ return 1;
+ }
+ return 0;
+}
+
+static const EnumPropertyItem *rna_UserDef_studiolight_icon_id_itemf(
+ bContext *UNUSED(C), PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+ StudioLight *sl = (StudioLight *)ptr->data;
+
+ if ((sl->flag & (STUDIOLIGHT_ORIENTATION_VIEWNORMAL | STUDIOLIGHT_ORIENTATION_CAMERA)) == 0)
+ {
+ EnumPropertyItem tmp = {0, sl->name, sl->radiance_icon_id, sl->name, ""};
+ RNA_enum_item_add(&item, &totitem, &tmp);
+ }
+ {
+ EnumPropertyItem tmp = {1, sl->name, sl->irradiance_icon_id, sl->name, ""};
+ RNA_enum_item_add(&item, &totitem, &tmp);
+ }
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+ return item;
+}
+
+/* StudioLight.is_user_defined */
+static int rna_UserDef_studiolight_is_user_defined_get(PointerRNA *ptr)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ return (sl->flag & STUDIOLIGHT_USER_DEFINED) > 0;
+}
+
+/* StudioLight.show_expanded */
+static int rna_UserDef_studiolight_show_expanded_get(PointerRNA *ptr)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ return (sl->flag & STUDIOLIGHT_UI_EXPANDED) > 0;
+}
+
+static void rna_UserDef_studiolight_show_expanded_set(PointerRNA *ptr, const bool value)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ sl->flag ^= STUDIOLIGHT_UI_EXPANDED;
+ sl->flag |= value?STUDIOLIGHT_UI_EXPANDED: 0;
+}
+
+
+/* StudioLight.orientation */
+
+static int rna_UserDef_studiolight_orientation_get(PointerRNA *ptr)
+{
+ StudioLight *sl = (StudioLight *)ptr->data;
+ return sl->flag & STUDIOLIGHT_FLAG_ORIENTATIONS;
+}
+
+static void rna_UserDef_studiolight_orientation_set(PointerRNA *UNUSED(ptr), const int UNUSED(value))
+{
+}
+
+
#else
/* TODO(sergey): This technically belongs to blenlib, but we don't link
@@ -680,7 +798,7 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem font_kerning_style[] = {
{0, "UNFITTED", 0, "Unfitted", "Use scaled but un-grid-fitted kerning distances"},
{1, "FITTED", 0, "Fitted", "Use scaled and grid-fitted kerning distances"},
@@ -691,7 +809,7 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "uiFontStyle");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Font Style", "Theme settings for Font");
-
+
prop = RNA_def_property(srna, "points", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 6, 48);
RNA_def_property_ui_text(prop, "Points", "");
@@ -707,13 +825,13 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 5);
RNA_def_property_ui_text(prop, "Shadow Size", "Shadow size (0, 3 and 5 supported)");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "shadow_offset_x", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "shadx");
RNA_def_property_range(prop, -10, 10);
RNA_def_property_ui_text(prop, "Shadow X Offset", "Shadow offset in pixels");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "shadow_offset_y", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "shady");
RNA_def_property_range(prop, -10, 10);
@@ -737,14 +855,14 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
rna_def_userdef_theme_ui_font_style(brna);
-
+
srna = RNA_def_struct(brna, "ThemeStyle", NULL);
RNA_def_struct_sdna(srna, "uiStyle");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Style", "Theme settings for style sets");
-
+
prop = RNA_def_property(srna, "panel_title", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
@@ -759,66 +877,66 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "ThemeFontStyle");
RNA_def_property_ui_text(prop, "Widget Label Style", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "widget", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "widget");
RNA_def_property_struct_type(prop, "ThemeFontStyle");
RNA_def_property_ui_text(prop, "Widget Style", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
}
static void rna_def_userdef_theme_ui_wcol(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ThemeWidgetColors", NULL);
RNA_def_struct_sdna(srna, "uiWidgetColors");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Widget Color Set", "Theme settings for widget color sets");
-
+
prop = RNA_def_property(srna, "outline", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Outline", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "inner", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Inner", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "inner_sel", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Inner Selected", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "item", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Item", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Text", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "text_sel", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Text Selected", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "show_shaded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shaded", 1);
RNA_def_property_ui_text(prop, "Shaded", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "shadetop", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, -100, 100);
RNA_def_property_ui_text(prop, "Shade Top", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "shadedown", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, -100, 100);
RNA_def_property_ui_text(prop, "Shade Down", "");
@@ -834,12 +952,12 @@ static void rna_def_userdef_theme_ui_wcol_state(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ThemeWidgetStateColors", NULL);
RNA_def_struct_sdna(srna, "uiWidgetStateColors");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Widget State Color", "Theme settings for widget state colors");
-
+
prop = RNA_def_property(srna, "inner_anim", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Animated", "");
@@ -849,7 +967,7 @@ static void rna_def_userdef_theme_ui_wcol_state(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Animated Selected", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "inner_key", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Keyframe", "");
@@ -889,20 +1007,24 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ThemePanelColors", NULL);
RNA_def_struct_sdna(srna, "uiPanelColors");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Panel Color", "Theme settings for panel colors");
-
+
prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_ui_text(prop, "Header", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_ui_text(prop, "Background", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
+ prop = RNA_def_property(srna, "sub_back", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_ui_text(prop, "Sub Background", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
prop = RNA_def_property(srna, "show_header", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Show Header", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
@@ -957,7 +1079,7 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Regular Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_tool", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Tool Widget Colors", "");
@@ -967,17 +1089,17 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Toolbar Item Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_radio", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Radio Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_text", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Text Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_option", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Option Widget Colors", "");
@@ -987,32 +1109,32 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Toggle Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Number Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_numslider", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Slider Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_box", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Box Backdrop Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_menu", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Menu Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_pulldown", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Pulldown Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_menu_back", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Menu Backdrop Colors", "");
@@ -1027,7 +1149,7 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Tooltip Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_menu_item", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Menu Item Colors", "");
@@ -1037,7 +1159,7 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Scroll Widget Colors", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "wcol_progress", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Progress Bar Widget Colors", "");
@@ -1062,12 +1184,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Menu Shadow Strength", "Blending factor for menu shadows");
RNA_def_property_range(prop, 0.01f, 1.0f);
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "menu_shadow_width", PROP_INT, PROP_PIXEL);
RNA_def_property_ui_text(prop, "Menu Shadow Width", "Width of menu shadows, set to zero to disable");
RNA_def_property_range(prop, 0.0f, 24.0f);
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "iconfile");
RNA_def_property_ui_text(prop, "Icon File", "");
@@ -1080,7 +1202,7 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
prop = RNA_def_property(srna, "icon_saturation", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_ui_text(prop, "Icon Saturation", "Saturation of icons in the interface");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "widget_emboss", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "widget_emboss");
RNA_def_property_array(prop, 4);
@@ -1099,13 +1221,13 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "X Axis", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "axis_y", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "yaxis");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Y Axis", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "axis_z", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "zaxis");
RNA_def_property_array(prop, 3);
@@ -1378,7 +1500,7 @@ static void rna_def_userdef_theme_spaces_edge(StructRNA *srna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Edge Sharp", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "edge_crease", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Edge Crease", "");
@@ -1449,7 +1571,7 @@ static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, bool incl_nurbs
bool incl_vector, bool incl_verthandle)
{
PropertyRNA *prop;
-
+
if (incl_nurbs) {
prop = RNA_def_property(srna, "nurb_uline", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nurb_uline");
@@ -1539,7 +1661,7 @@ static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, bool incl_nurbs
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Auto-Clamped handle color", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "handle_sel_auto_clamped", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "handle_sel_auto_clamped");
RNA_def_property_array(prop, 3);
@@ -1628,7 +1750,7 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Wire Edit", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
/* Grease Pencil */
@@ -1819,7 +1941,7 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade1");
RNA_def_property_array(prop, 3);
@@ -1831,19 +1953,19 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Channels Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "dopesheet_channel", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "ds_channel");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Dope Sheet Channel", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "dopesheet_subchannel", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "ds_subchannel");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Dope Sheet Sub-Channel", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "channel_group", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "group");
RNA_def_property_array(prop, 3);
@@ -1855,7 +1977,7 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Active Channel Group", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
rna_def_userdef_theme_spaces_vertex(srna);
rna_def_userdef_theme_spaces_curves(srna, false, true, true, true);
}
@@ -1931,33 +2053,33 @@ static void rna_def_userdef_theme_space_console(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Console", "Theme settings for the Console");
-
+
rna_def_userdef_theme_spaces_main(srna);
-
+
prop = RNA_def_property(srna, "line_output", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "console_output");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Line Output", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "line_input", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "console_input");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Line Input", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "line_info", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "console_info");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Line Info", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "line_error", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "console_error");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Line Error", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "cursor", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "console_cursor");
RNA_def_property_array(prop, 3);
@@ -2088,13 +2210,13 @@ static void rna_def_userdef_theme_space_text(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Cursor", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "syntax_builtin", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "syntaxb");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Syntax Built-in", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "syntax_symbols", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "syntaxs");
RNA_def_property_array(prop, 3);
@@ -2124,7 +2246,7 @@ static void rna_def_userdef_theme_space_text(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Syntax Comment", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "syntax_string", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "syntaxl");
RNA_def_property_array(prop, 3);
@@ -2152,7 +2274,7 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
rna_def_userdef_theme_spaces_list_main(srna);
-
+
rna_def_userdef_theme_spaces_gpencil(srna);
prop = RNA_def_property(srna, "node_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
@@ -2196,13 +2318,13 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Node Backdrop", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "converter_node", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "syntaxv");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Converter Node", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "color_node", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "syntaxb");
RNA_def_property_array(prop, 3);
@@ -2226,7 +2348,7 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Frame Node", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "matte_node", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "syntaxs");
RNA_def_property_array(prop, 3);
@@ -2333,7 +2455,7 @@ static void rna_def_userdef_theme_space_image(BlenderRNA *brna)
rna_def_userdef_theme_spaces_gpencil(srna);
rna_def_userdef_theme_spaces_vertex(srna);
rna_def_userdef_theme_spaces_face(srna);
-
+
prop = RNA_def_property(srna, "editmesh_active", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
@@ -2523,7 +2645,7 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Draw Action", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "preview_back", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "preview_back");
RNA_def_property_array(prop, 3);
@@ -2562,13 +2684,13 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Grid", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "cframe");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "value_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "face");
RNA_def_property_array(prop, 3);
@@ -2580,21 +2702,21 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "View Sliders", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
-
+
+
prop = RNA_def_property(srna, "dopesheet_channel", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "ds_channel");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Dope Sheet Channel", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "dopesheet_subchannel", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "ds_subchannel");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Dope Sheet Sub-Channel", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
-
+
+
prop = RNA_def_property(srna, "channels", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade2");
RNA_def_property_array(prop, 3);
@@ -2618,8 +2740,8 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Active Channel Group", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
-
+
+
prop = RNA_def_property(srna, "long_key", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "strip");
RNA_def_property_array(prop, 3);
@@ -2632,76 +2754,76 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Long Key Selected", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
-
+
+
prop = RNA_def_property(srna, "keyframe", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keytype_keyframe");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Keyframe", "Color of Keyframe");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keytype_keyframe_select");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Keyframe Selected", "Color of selected keyframe");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_extreme", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keytype_extreme");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Extreme Keyframe", "Color of extreme keyframe");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_extreme_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keytype_extreme_select");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Extreme Keyframe Selected", "Color of selected extreme keyframe");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_breakdown", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keytype_breakdown");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Breakdown Keyframe", "Color of breakdown keyframe");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_breakdown_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keytype_breakdown_select");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Breakdown Keyframe Selected", "Color of selected breakdown keyframe");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_jitter", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keytype_jitter");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Jitter Keyframe", "Color of jitter keyframe");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_jitter_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keytype_jitter_select");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Jitter Keyframe Selected", "Color of selected jitter keyframe");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_border", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keyborder");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Keyframe Border", "Color of keyframe border");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_border_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keyborder_select");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Keyframe Border Selected", "Color of selected keyframe border");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_scale_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "keyframe_scale_fac");
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Keyframe Scale Factor", "Scale factor for adjusting the height of keyframes");
RNA_def_property_range(prop, 0.8f, 5.0f); /* Note: These limits prevent buttons overlapping (min), and excessive size... (max) */
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, "rna_userdef_update");
-
-
+
+
prop = RNA_def_property(srna, "summary", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "anim_active");
RNA_def_property_array(prop, 4);
@@ -2733,94 +2855,94 @@ static void rna_def_userdef_theme_space_nla(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "View Sliders", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "active_action", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "anim_active");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Active Action", "Animation data-block has active action");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "active_action_unset", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "anim_non_active");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "No Active Action", "Animation data-block doesn't have active action");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "strips", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "strip");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Strips", "Action-Clip Strip - Unselected");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "strip_select");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Strips Selected", "Action-Clip Strip - Selected");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "transition_strips", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nla_transition");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Transitions", "Transition Strip - Unselected");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "transition_strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nla_transition_sel");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Transitions Selected", "Transition Strip - Selected");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "meta_strips", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nla_meta");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Meta Strips", "Meta Strip - Unselected (for grouping related strips)");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "meta_strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nla_meta_sel");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Meta Strips Selected", "Meta Strip - Selected (for grouping related strips)");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "sound_strips", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nla_sound");
RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Sound Strips",
+ RNA_def_property_ui_text(prop, "Sound Strips",
"Sound Strip - Unselected (for timing speaker sounds)");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "sound_strips_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nla_sound_sel");
RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Sound Strips Selected",
+ RNA_def_property_ui_text(prop, "Sound Strips Selected",
"Sound Strip - Selected (for timing speaker sounds)");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "tweak", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nla_tweaking");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Tweak", "Color for strip/action being 'tweaked' or edited");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "tweak_duplicate", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "nla_tweakdupli");
RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Tweak Duplicate Flag",
+ RNA_def_property_ui_text(prop, "Tweak Duplicate Flag",
"Warning/error indicator color for strips referencing the strip being tweaked");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_border", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keyborder");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Keyframe Border", "Color of keyframe border");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "keyframe_border_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "keyborder_select");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Keyframe Border Selected", "Color of selected keyframe border");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "cframe");
RNA_def_property_array(prop, 3);
@@ -2876,7 +2998,7 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
rna_def_userdef_theme_spaces_list_main(srna);
-
+
rna_def_userdef_theme_spaces_gpencil(srna);
prop = RNA_def_property(srna, "marker_outline", PROP_FLOAT, PROP_COLOR_GAMMA);
@@ -2980,7 +3102,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem active_theme_area[] = {
{0, "USER_INTERFACE", ICON_UI, "User Interface", ""},
{19, "STYLE", ICON_FONTPREVIEW, "Text Style", ""},
@@ -3105,7 +3227,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "tuserpref");
RNA_def_property_struct_type(prop, "ThemeUserPreferences");
RNA_def_property_ui_text(prop, "User Preferences", "");
-
+
prop = RNA_def_property(srna, "console", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "tconsole");
@@ -3157,6 +3279,63 @@ static void rna_def_userdef_addon(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_Addon_preferences_get", NULL, NULL, NULL);
}
+static void rna_def_userdef_studiolight(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static const EnumPropertyItem rna_enum_studio_light_orientation_items[] = {
+ {STUDIOLIGHT_ORIENTATION_CAMERA, "CAMERA", 0, "Camera", ""},
+ {STUDIOLIGHT_ORIENTATION_WORLD, "WORLD", 0, "World", ""},
+ {STUDIOLIGHT_ORIENTATION_VIEWNORMAL, "MATCAP", 0, "MatCap", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ RNA_define_verify_sdna(false);
+ srna = RNA_def_struct(brna, "StudioLight", NULL);
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Studio Light", "Studio light");
+
+ prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE);
+ RNA_def_property_int_funcs(prop, "rna_UserDef_studiolight_index_get", NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Index", "");
+
+ prop = RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_UserDef_studiolight_is_user_defined_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "User Defined", "");
+
+ prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_UserDef_studiolight_show_expanded_get", "rna_UserDef_studiolight_show_expanded_set");
+ RNA_def_property_ui_text(prop, "Show Expanded", "");
+
+ prop = RNA_def_property(srna, "orientation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_studio_light_orientation_items);
+ RNA_def_property_enum_funcs(prop, "rna_UserDef_studiolight_orientation_get", "rna_UserDef_studiolight_orientation_set", NULL);
+ RNA_def_property_ui_text(prop, "Orientation", "");
+
+ prop = RNA_def_property(srna, "icon_id", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_funcs(prop, "rna_UserDef_studiolight_icon_id_get", NULL, "rna_UserDef_studiolight_icon_id_itemf");
+ RNA_def_property_enum_items(prop, rna_enum_studio_light_icons_id_items);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Preview", "Preview of the studiolight");
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_UserDef_studiolight_name_get", "rna_UserDef_studiolight_name_length", NULL);
+ RNA_def_property_ui_text(prop, "Name", "");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_struct_name_property(srna, prop);
+
+ prop = RNA_def_property(srna, "path", PROP_STRING, PROP_DIRPATH);
+ RNA_def_property_string_funcs(prop, "rna_UserDef_studiolight_path_get", "rna_UserDef_studiolight_path_length", NULL);
+ RNA_def_property_ui_text(prop, "Path", "");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ RNA_define_verify_sdna(true);
+
+}
+
static void rna_def_userdef_pathcompare(BlenderRNA *brna)
{
StructRNA *srna;
@@ -3201,14 +3380,14 @@ static void rna_def_userdef_addon_pref(BlenderRNA *brna)
static void rna_def_userdef_dothemes(BlenderRNA *brna)
{
-
+
rna_def_userdef_theme_ui_style(brna);
rna_def_userdef_theme_ui(brna);
rna_def_userdef_theme_space_generic(brna);
rna_def_userdef_theme_space_gradient(brna);
rna_def_userdef_theme_space_list_generic(brna);
-
+
rna_def_userdef_theme_space_view3d(brna);
rna_def_userdef_theme_space_graph(brna);
rna_def_userdef_theme_space_file(brna);
@@ -3240,7 +3419,7 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "SolidLight");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Solid Light", "Light used for OpenGL lighting in solid draw mode");
-
+
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", 1);
RNA_def_property_ui_text(prop, "Enabled", "Enable this OpenGL light in solid draw mode");
@@ -3345,7 +3524,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
PropertyRNA *prop;
StructRNA *srna;
-
+
srna = RNA_def_struct(brna, "UserPreferencesView", NULL);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
@@ -3417,7 +3596,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_MENUOPENAUTO);
RNA_def_property_ui_text(prop, "Open On Mouse Over",
"Open menu buttons and pulldowns automatically when the mouse is hovering");
-
+
prop = RNA_def_property(srna, "open_toplevel_delay", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "menuthreshold1");
RNA_def_property_range(prop, 1, 40);
@@ -3521,7 +3700,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_rotate_around_active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ORBIT_SELECTION);
RNA_def_property_ui_text(prop, "Rotate Around Selection", "Use selection as the pivot point");
-
+
/* mini axis */
prop = RNA_def_property(srna, "show_mini_axis", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_SHOW_ROTVIEWICON);
@@ -3561,7 +3740,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "manipulator_flag", USER_MANIPULATOR_DRAW_NAVIGATE);
RNA_def_property_ui_text(prop, "Navigate Manipulator", "Use 3D navigation manipulator");
RNA_def_property_update(prop, 0, "rna_userdef_show_manipulator_update");
-
+
/* TODO, expose once it's working. */
#if 0
prop = RNA_def_property(srna, "show_manipulator_shaded", PROP_BOOLEAN, PROP_NONE);
@@ -3582,7 +3761,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_range(prop, 4, 10);
RNA_def_property_ui_text(prop, "Object Origin Size", "Diameter in Pixels for Object/Lamp origin display");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
/* View2D Grid Displays */
prop = RNA_def_property(srna, "view2d_grid_spacing_min", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "v2d_min_gridsize");
@@ -3590,7 +3769,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "2D View Minimum Grid Spacing",
"Minimum number of pixels between each gridline in 2D Viewports");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
/* TODO: add a setter for this, so that we can bump up the minimum size as necessary... */
prop = RNA_def_property(srna, "timecode_style", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, timecode_styles);
@@ -3627,14 +3806,14 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
{AUTOKEY_MODE_EDITKEYS, "REPLACE_KEYS", 0, "Replace", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem material_link_items[] = {
{0, "OBDATA", 0, "ObData", "Toggle whether the material is linked to object data or the object block"},
{USER_MAT_ON_OB, "OBJECT", 0, "Object",
"Toggle whether the material is linked to object data or the object block"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem object_align_items[] = {
{0, "WORLD", 0, "World", "Align newly added objects to the world coordinate system"},
{USER_ADD_VIEWALIGNED, "VIEW", 0, "View", "Align newly added objects facing the active 3D View direction"},
@@ -3646,15 +3825,15 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_struct_nested(brna, srna, "UserPreferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Edit Methods", "Settings for interacting with Blender data");
-
+
/* Edit Methods */
-
+
prop = RNA_def_property(srna, "material_link", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, material_link_items);
RNA_def_property_ui_text(prop, "Material Link To",
"Toggle whether the material is linked to object data or the object block");
-
+
prop = RNA_def_property(srna, "object_align", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, object_align_items);
@@ -3670,7 +3849,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_RELEASECONFIRM);
RNA_def_property_ui_text(prop, "Release confirms",
"Moving things with a mouse drag confirms when releasing the button");
-
+
/* Undo */
prop = RNA_def_property(srna, "undo_steps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "undosteps");
@@ -3713,7 +3892,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_NOWARNING);
RNA_def_property_ui_text(prop, "Show Auto Keying Warning",
"Show warning indicators when transforming objects and bones if auto keying is enabled");
-
+
/* keyframing settings */
prop = RNA_def_property(srna, "use_keyframe_insert_needed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_INSERTNEEDED);
@@ -3722,13 +3901,13 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_visual_keying", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_AUTOMATKEY);
RNA_def_property_ui_text(prop, "Visual Keying", "Use Visual keying automatically for constrained objects");
-
+
prop = RNA_def_property(srna, "use_insertkey_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_XYZ2RGB);
RNA_def_property_ui_text(prop, "New F-Curve Colors - XYZ to RGB",
"Color for newly added transformation F-Curves (Location, Rotation, Scale) "
"and also Color is based on the transform axis");
-
+
prop = RNA_def_property(srna, "keyframe_new_interpolation_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_beztriple_interpolation_mode_items);
RNA_def_property_enum_sdna(prop, NULL, "ipo_new");
@@ -3740,7 +3919,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_keyframe_handle_type_items);
RNA_def_property_enum_sdna(prop, NULL, "keyhandles_new");
RNA_def_property_ui_text(prop, "New Handles Type", "Handle type for handles of new keyframes");
-
+
/* frame numbers */
prop = RNA_def_property(srna, "use_negative_frames", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_NONEGFRAMES);
@@ -3754,7 +3933,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Unselected F-Curve Visibility",
"Amount that unselected F-Curves stand out from the background (Graph Editor)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil_manhattan_distance", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "gp_manhattendist");
@@ -3776,13 +3955,13 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "gp_eraser");
RNA_def_property_range(prop, 1, 500);
RNA_def_property_ui_text(prop, "Grease Pencil Eraser Radius", "Radius of eraser 'brush'");
-
-
+
+
prop = RNA_def_property(srna, "grease_pencil_default_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "gpencil_new_layer_col");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Grease Pencil Default Color", "Color of new Grease Pencil layers");
-
+
/* sculpt and paint */
prop = RNA_def_property(srna, "sculpt_paint_overlay_color", PROP_FLOAT, PROP_COLOR_GAMMA);
@@ -3798,7 +3977,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_duplicate_surface", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_SURF);
RNA_def_property_ui_text(prop, "Duplicate Surface", "Causes surface data to be duplicated with the object");
-
+
prop = RNA_def_property(srna, "use_duplicate_curve", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_CURVE);
RNA_def_property_ui_text(prop, "Duplicate Curve", "Causes curve data to be duplicated with the object");
@@ -3810,7 +3989,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_duplicate_metaball", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_MBALL);
RNA_def_property_ui_text(prop, "Duplicate Metaball", "Causes metaball data to be duplicated with the object");
-
+
prop = RNA_def_property(srna, "use_duplicate_armature", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_ARM);
RNA_def_property_ui_text(prop, "Duplicate Armature", "Causes armature data to be duplicated with the object");
@@ -3826,7 +4005,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_duplicate_texture", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_TEX);
RNA_def_property_ui_text(prop, "Duplicate Texture", "Causes texture data to be duplicated with the object");
-
+
/* xxx */
prop = RNA_def_property(srna, "use_duplicate_fcurve", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_IPO);
@@ -3835,7 +4014,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_duplicate_action", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_ACT);
RNA_def_property_ui_text(prop, "Duplicate Action", "Causes actions to be duplicated with the object");
-
+
prop = RNA_def_property(srna, "use_duplicate_particle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_PSYS);
RNA_def_property_ui_text(prop, "Duplicate Particle", "Causes particle systems to be duplicated with the object");
@@ -3926,7 +4105,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{USER_CP_SQUARE_HV, "SQUARE_HV", 0, "Square (HV + S)", "A square showing Hue/Value, with Saturation slider"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem multi_sample_levels[] = {
{USER_MULTISAMPLE_NONE, "NONE", 0, "No MultiSample", "Do not use OpenGL MultiSample"},
{USER_MULTISAMPLE_2, "2", 0, "MultiSample: 2", "Use 2x OpenGL MultiSample (requires restart)"},
@@ -3957,7 +4136,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "System & OpenGL", "Graphics driver and operating system settings");
/* Language */
-
+
prop = RNA_def_property(srna, "use_international_fonts", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_DOTRANSLATE);
RNA_def_property_ui_text(prop, "International Fonts", "Use international fonts");
@@ -4057,7 +4236,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "color_picker_type");
RNA_def_property_ui_text(prop, "Color Picker Type", "Different styles of displaying the color picker widget");
RNA_def_property_update(prop, 0, "rna_userdef_update");
-
+
prop = RNA_def_property(srna, "use_preview_images", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ALLWINCODECS);
RNA_def_property_ui_text(prop, "Enable All Codecs",
@@ -4117,7 +4296,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
"Quality of the anisotropic filtering (values greater than 1.0 enable anisotropic "
"filtering)");
RNA_def_property_update(prop, 0, "rna_userdef_anisotropic_update");
-
+
prop = RNA_def_property(srna, "gl_texture_limit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "glreslimit");
RNA_def_property_enum_items(prop, gl_texture_clamp_items);
@@ -4206,7 +4385,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP);
RNA_def_property_ui_text(prop, "Region Overlap",
"Draw tool/property regions over the main region, when using Triple Buffer");
- RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
+ RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
#ifdef WITH_OPENSUBDIV
prop = RNA_def_property(srna, "opensubdiv_compute_type", PROP_ENUM, PROP_NONE);
@@ -4265,44 +4444,44 @@ static void rna_def_userdef_input(BlenderRNA *brna)
"Zoom in and out like scaling the view, mouse movements relative to center"},
{0, NULL, 0, NULL, NULL}
};
-
+
static const EnumPropertyItem view_zoom_axes[] = {
{0, "VERTICAL", 0, "Vertical", "Zoom in and out based on vertical mouse movement"},
{USER_ZOOM_HORIZ, "HORIZONTAL", 0, "Horizontal", "Zoom in and out based on horizontal mouse movement"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "UserPreferencesInput", NULL);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Input", "Settings for input devices");
-
+
prop = RNA_def_property(srna, "select_mouse", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, select_mouse_items);
RNA_def_property_enum_funcs(prop, NULL, "rna_userdef_select_mouse_set", NULL);
RNA_def_property_ui_text(prop, "Select Mouse", "Mouse button used for selection");
-
+
prop = RNA_def_property(srna, "view_zoom_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "viewzoom");
RNA_def_property_enum_items(prop, view_zoom_styles);
RNA_def_property_ui_text(prop, "Zoom Style", "Which style to use for viewport scaling");
-
+
prop = RNA_def_property(srna, "view_zoom_axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "uiflag");
RNA_def_property_enum_items(prop, view_zoom_axes);
RNA_def_property_ui_text(prop, "Zoom Axis", "Axis of mouse movement to zoom in or out on");
-
+
prop = RNA_def_property(srna, "invert_mouse_zoom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ZOOM_INVERT);
RNA_def_property_ui_text(prop, "Invert Zoom Direction", "Invert the axis of mouse movement for zooming");
-
+
prop = RNA_def_property(srna, "view_rotate_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, view_rotation_items);
RNA_def_property_ui_text(prop, "View Rotation", "Rotation style in the viewport");
-
+
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",
@@ -4340,7 +4519,7 @@ static void rna_def_userdef_input(BlenderRNA *brna)
prop = RNA_def_property(srna, "ndof_sensitivity", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.01f, 40.0f);
RNA_def_property_ui_text(prop, "Sensitivity", "Overall sensitivity of the 3D Mouse for panning");
-
+
prop = RNA_def_property(srna, "ndof_orbit_sensitivity", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.01f, 40.0f);
RNA_def_property_ui_text(prop, "Orbit Sensitivity", "Overall sensitivity of the 3D Mouse for orbiting");
@@ -4364,7 +4543,7 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_SHOW_GUIDE);
RNA_def_property_ui_text(prop, "Show Navigation Guide", "Display the center and axis during rotation");
/* TODO: update description when fly-mode visuals are in place ("projected position in fly mode")*/
-
+
/* 3D view */
prop = RNA_def_property(srna, "ndof_view_navigate_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "ndof_flag");
@@ -4436,13 +4615,13 @@ static void rna_def_userdef_input(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_emulate_numpad", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_NONUMPAD);
RNA_def_property_ui_text(prop, "Emulate Numpad", "Main 1 to 0 keys act as the numpad ones (useful for laptops)");
-
+
/* middle mouse button */
prop = RNA_def_property(srna, "use_mouse_mmb_paste", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_MMB_PASTE);
RNA_def_property_ui_text(prop, "Middle Mouse Paste",
"In text window, paste with middle mouse button instead of panning");
-
+
prop = RNA_def_property(srna, "invert_zoom_wheel", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_WHEELZOOMDIR);
RNA_def_property_ui_text(prop, "Wheel Invert Zoom", "Swap the Mouse Wheel zoom direction");
@@ -4451,7 +4630,7 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "wheellinescroll");
RNA_def_property_range(prop, 0, 32);
RNA_def_property_ui_text(prop, "Wheel Scroll Lines", "Number of lines scrolled at a time with the mouse wheel");
-
+
prop = RNA_def_property(srna, "use_trackpad_natural", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_TRACKPAD_NATURAL);
RNA_def_property_ui_text(prop, "Trackpad Natural",
@@ -4466,7 +4645,7 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
{
PropertyRNA *prop;
StructRNA *srna;
-
+
static const EnumPropertyItem anim_player_presets[] = {
{0, "INTERNAL", 0, "Internal", "Built-in animation player"},
{2, "DJV", 0, "Djv", "Open source frame player: http://djv.sourceforge.net"},
@@ -4476,22 +4655,22 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
{50, "CUSTOM", 0, "Custom", "Custom animation player executable path"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "UserPreferencesFilePaths", NULL);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "File Paths", "Default paths for external files");
-
+
prop = RNA_def_property(srna, "show_hidden_files_datablocks", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_HIDE_DOT);
RNA_def_property_ui_text(prop, "Hide Dot Files/Data-Blocks", "Hide files/data-blocks that start with a dot (.*)");
-
+
prop = RNA_def_property(srna, "use_filter_files", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_FILTERFILEEXTS);
RNA_def_property_ui_text(prop, "Filter File Extensions",
"Display only files with extensions in the image select window");
-
+
prop = RNA_def_property(srna, "hide_recent_locations", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_HIDE_RECENT);
RNA_def_property_ui_text(prop, "Hide Recent Locations", "Hide recent locations in the file selector");
@@ -4507,7 +4686,7 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_relative_paths", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_RELPATHS);
RNA_def_property_ui_text(prop, "Relative Paths", "Default relative path option for the file selector");
-
+
prop = RNA_def_property(srna, "use_file_compression", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_FILECOMPRESS);
RNA_def_property_ui_text(prop, "Compress File", "Enable file compression when saving .blend files");
@@ -4559,7 +4738,7 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
prop = RNA_def_property(srna, "image_editor", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "image_editor");
RNA_def_property_ui_text(prop, "Image Editor", "Path to an image editor");
-
+
prop = RNA_def_property(srna, "animation_player", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "anim_player");
RNA_def_property_ui_text(prop, "Animation Player", "Path to a custom animation/frame sequence player");
@@ -4568,7 +4747,7 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "anim_player_preset");
RNA_def_property_enum_items(prop, anim_player_presets);
RNA_def_property_ui_text(prop, "Animation Player Preset", "Preset configs for external animation players");
-
+
/* Autosave */
prop = RNA_def_property(srna, "save_version", PROP_INT, PROP_NONE);
@@ -4594,7 +4773,7 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_KEEP_SESSION);
RNA_def_property_ui_text(prop, "Keep Session",
"Always load session recovery and save it after quitting Blender");
-
+
prop = RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 30);
RNA_def_property_ui_text(prop, "Recent Files", "Maximum number of recently opened files to remember");
@@ -4661,6 +4840,7 @@ void RNA_def_userdef(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
static const EnumPropertyItem user_pref_sections[] = {
{USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""},
@@ -4668,6 +4848,7 @@ void RNA_def_userdef(BlenderRNA *brna)
{USER_SECTION_INPUT, "INPUT", 0, "Input", ""},
{USER_SECTION_ADDONS, "ADDONS", 0, "Add-ons", ""},
{USER_SECTION_THEME, "THEMES", 0, "Themes", ""},
+ {USER_SECTION_LIGHT, "LIGHTS", 0, "Lights", ""},
{USER_SECTION_FILE, "FILES", 0, "File", ""},
{USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""},
{0, NULL, 0, NULL, NULL}
@@ -4703,7 +4884,7 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "uistyles", NULL);
RNA_def_property_struct_type(prop, "ThemeStyle");
RNA_def_property_ui_text(prop, "Styles", "");
-
+
prop = RNA_def_property(srna, "addons", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "addons", NULL);
RNA_def_property_struct_type(prop, "Addon");
@@ -4728,31 +4909,42 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "UserPreferencesEdit");
RNA_def_property_pointer_funcs(prop, "rna_UserDef_edit_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Edit Methods", "Settings for interacting with Blender data");
-
+
prop = RNA_def_property(srna, "inputs", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "UserPreferencesInput");
RNA_def_property_pointer_funcs(prop, "rna_UserDef_input_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Inputs", "Settings for input devices");
-
+
prop = RNA_def_property(srna, "filepaths", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "UserPreferencesFilePaths");
RNA_def_property_pointer_funcs(prop, "rna_UserDef_filepaths_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "File Paths", "Default paths for external files");
-
+
prop = RNA_def_property(srna, "system", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "UserPreferencesSystem");
RNA_def_property_pointer_funcs(prop, "rna_UserDef_system_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "System & OpenGL", "Graphics driver and operating system settings");
-
+
prop = RNA_def_int_vector(srna, "version", 3, NULL, 0, INT_MAX,
"Version", "Version of Blender the userpref.blend was saved with", 0, INT_MAX);
RNA_def_property_int_funcs(prop, "rna_userdef_version_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_flag(prop, PROP_THICK_WRAP);
+ prop = RNA_def_property(srna, "studio_lights", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "StudioLight");
+ RNA_def_property_collection_funcs(prop, "rna_UserDef_studiolight_begin", "rna_iterator_listbase_next",
+ "rna_iterator_listbase_end", "rna_iterator_listbase_get",
+ NULL, NULL, NULL, NULL);
+
+ func = RNA_def_function(srna, "studio_lights_refresh", "rna_UserDef_studiolight_refresh");
+ RNA_def_function_ui_description(func, "Refresh Studio Lights");
+
+ RNA_def_property_ui_text(prop, "Studio Lights", "");
+
rna_def_userdef_view(brna);
rna_def_userdef_edit(brna);
rna_def_userdef_input(brna);
@@ -4760,8 +4952,9 @@ void RNA_def_userdef(BlenderRNA *brna)
rna_def_userdef_system(brna);
rna_def_userdef_addon(brna);
rna_def_userdef_addon_pref(brna);
+ rna_def_userdef_studiolight(brna);
rna_def_userdef_pathcompare(brna);
-
+
}
#endif
diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c
index 78d46d35246..487b5220c86 100644
--- a/source/blender/makesrna/intern/rna_vfont.c
+++ b/source/blender/makesrna/intern/rna_vfont.c
@@ -70,7 +70,7 @@ void RNA_def_vfont(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "VectorFont", "ID");
RNA_def_struct_ui_text(srna, "Vector Font", "Vector font for Text objects");
RNA_def_struct_sdna(srna, "VFont");
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 0fa7f53da9b..c4e15174c88 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -53,6 +53,7 @@ static const EnumPropertyItem event_keymouse_value_items[] = {
{KM_RELEASE, "RELEASE", 0, "Release", ""},
{KM_CLICK, "CLICK", 0, "Click", ""},
{KM_DBL_CLICK, "DOUBLE_CLICK", 0, "Double Click", ""},
+ {KM_CLICK_DRAG, "CLICK_DRAG", 0, "Click Drag", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -391,6 +392,7 @@ const EnumPropertyItem rna_enum_event_value_items[] = {
{KM_RELEASE, "RELEASE", 0, "Release", ""},
{KM_CLICK, "CLICK", 0, "Click", ""},
{KM_DBL_CLICK, "DOUBLE_CLICK", 0, "Double Click", ""},
+ {KM_CLICK_DRAG, "CLICK_DRAG", 0, "Click Drag", ""},
{EVT_GESTURE_N, "NORTH", 0, "North", ""},
{EVT_GESTURE_NE, "NORTH_EAST", 0, "North-East", ""},
{EVT_GESTURE_E, "EAST", 0, "East", ""},
@@ -498,7 +500,7 @@ static wmOperator *rna_OperatorProperties_find_operator(PointerRNA *ptr)
}
}
}
-
+
return NULL;
}
@@ -794,7 +796,7 @@ static PointerRNA rna_KeyMapItem_properties_get(PointerRNA *ptr)
if (kmi->ptr)
return *(kmi->ptr);
-
+
/*return rna_pointer_inherit_refine(ptr, &RNA_OperatorProperties, op->properties); */
return PointerRNA_NULL;
}
@@ -846,7 +848,7 @@ static void rna_wmKeyMapItem_map_type_set(PointerRNA *ptr, int value)
static void rna_wmKeyMapItem_keymodifier_set(PointerRNA *ptr, int value)
{
wmKeyMapItem *kmi = ptr->data;
-
+
/* XXX, this should really be managed in an _itemf function,
* giving a list of valid enums, then silently changing them when they are set is not
* a good precedent, don't do this unless you have a good reason! */
@@ -974,7 +976,7 @@ static PointerRNA rna_WindowManager_active_keyconfig_get(PointerRNA *ptr)
if (!kc)
kc = wm->defaultconf;
-
+
return rna_pointer_inherit_refine(ptr, &RNA_KeyConfig, kc);
}
@@ -1609,13 +1611,13 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "OperatorProperties");
RNA_def_property_ui_text(prop, "Properties", "");
RNA_def_property_pointer_funcs(prop, "rna_Operator_properties_get", NULL, NULL, NULL);
-
+
prop = RNA_def_property(srna, "has_reports", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* this is 'virtual' property */
RNA_def_property_boolean_funcs(prop, "rna_Operator_has_reports_get", NULL);
RNA_def_property_ui_text(prop, "Has Reports",
"Operator has a set of reports (warnings and errors) from last execution");
-
+
prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "UILayout");
@@ -1817,12 +1819,12 @@ static void rna_def_operator_filelist_element(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_IDPROPERTY);
RNA_def_property_ui_text(prop, "Name", "Name of a file or directory within a file list");
}
-
+
static void rna_def_event(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "Event", NULL);
RNA_def_struct_ui_text(srna, "Event", "Window Manager Event");
RNA_def_struct_sdna(srna, "wmEvent");
@@ -1847,7 +1849,7 @@ static void rna_def_event(BlenderRNA *brna)
RNA_def_property_enum_items(prop, rna_enum_event_value_items);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Value", "The type of event, only applies to some");
-
+
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, rna_enum_event_type_items);
@@ -1861,7 +1863,7 @@ static void rna_def_event(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "x");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Mouse X Position", "The window relative horizontal location of the mouse");
-
+
prop = RNA_def_property(srna, "mouse_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "y");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1876,12 +1878,12 @@ static void rna_def_event(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "mval[1]");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Mouse Y Position", "The region relative vertical location of the mouse");
-
+
prop = RNA_def_property(srna, "mouse_prev_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "prevx");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Mouse Previous X Position", "The window relative horizontal location of the mouse");
-
+
prop = RNA_def_property(srna, "mouse_prev_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "prevy");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1913,17 +1915,17 @@ static void rna_def_event(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "shift", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Shift", "True when the Shift key is held");
-
+
prop = RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Ctrl", "True when the Ctrl key is held");
-
+
prop = RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "alt", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Alt", "True when the Alt/Option key is held");
-
+
prop = RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "oskey", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -2117,7 +2119,7 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop)
"rna_WindowManager_active_keyconfig_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active KeyConfig", "Active key configuration (preset)");
-
+
prop = RNA_def_property(srna, "default", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "defaultconf");
RNA_def_property_struct_type(prop, "KeyConfig");
@@ -2136,7 +2138,7 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_ui_text(prop, "User Key Configuration",
"Final key configuration that combines keymaps from the active and add-on configurations, "
"and can be edited by the user");
-
+
RNA_api_keyconfigs(srna);
}
@@ -2175,7 +2177,7 @@ static void rna_def_windowmanager(BlenderRNA *brna)
static void rna_def_keymap_items(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
-
+
RNA_def_property_srna(cprop, "KeyMapItems");
srna = RNA_def_struct(brna, "KeyMapItems", NULL);
RNA_def_struct_sdna(srna, "wmKeyMap");
@@ -2280,7 +2282,7 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_EXPANDED);
RNA_def_property_ui_text(prop, "Items Expanded", "Expanded in the user interface");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
-
+
prop = RNA_def_property(srna, "show_expanded_children", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_CHILDREN_EXPANDED);
RNA_def_property_ui_text(prop, "Children Expanded", "Children expanded in the user interface");
@@ -2308,7 +2310,7 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Name", "Name of operator (translated) to call on input event");
RNA_def_property_string_funcs(prop, "rna_wmKeyMapItem_name_get", "rna_wmKeyMapItem_name_length", NULL);
-
+
prop = RNA_def_property(srna, "properties", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "OperatorProperties");
RNA_def_property_pointer_funcs(prop, "rna_KeyMapItem_properties_get", NULL, NULL, NULL);
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index ab534159a9e..aff696696af 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -98,7 +98,7 @@ static int rna_Operator_is_repeat(wmOperator *op, bContext *C)
static void rna_Operator_enum_search_invoke(bContext *C, wmOperator *op)
{
WM_enum_search_invoke(C, op, NULL);
-
+
}
static int rna_event_modal_handler_add(struct bContext *C, struct wmOperator *operator)
@@ -202,8 +202,9 @@ static int rna_Operator_props_popup(bContext *C, wmOperator *op, wmEvent *event)
return WM_operator_props_popup(C, op, event);
}
-static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value,
- int any, int shift, int ctrl, int alt, int oskey, int keymodifier, int head)
+static wmKeyMapItem *rna_KeyMap_item_new(
+ wmKeyMap *km, ReportList *reports, const char *idname, int type, int value,
+ int any, int shift, int ctrl, int alt, int oskey, int keymodifier, int head)
{
/* wmWindowManager *wm = CTX_wm_manager(C); */
wmKeyMapItem *kmi = NULL;
@@ -224,24 +225,25 @@ static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, cons
if (oskey) modifier |= KM_OSKEY;
if (any) modifier = KM_ANY;
-
+
/* create keymap item */
kmi = WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier);
-
- /* [#32437] allow scripts to define hotkeys that get added to start of keymap
+
+ /* [#32437] allow scripts to define hotkeys that get added to start of keymap
* so that they stand a chance against catch-all defines later on
*/
if (head) {
BLI_remlink(&km->items, kmi);
BLI_addhead(&km->items, kmi);
}
-
+
return kmi;
}
-static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, ReportList *reports, const char *propvalue_str,
- int type, int value, int any, int shift, int ctrl, int alt,
- int oskey, int keymodifier)
+static wmKeyMapItem *rna_KeyMap_item_new_modal(
+ wmKeyMap *km, ReportList *reports, const char *propvalue_str,
+ int type, int value, int any, int shift, int ctrl, int alt,
+ int oskey, int keymodifier)
{
int modifier = 0;
int propvalue = 0;
@@ -694,7 +696,7 @@ void RNA_api_operator(StructRNA *srna)
parm = RNA_def_boolean(func, "result", 0, "result", ""); /* better name? */
RNA_def_function_return(func, parm);
-
+
/* invoke */
func = RNA_def_function(srna, "invoke", NULL);
RNA_def_function_ui_description(func, "Invoke the operator");
@@ -822,7 +824,7 @@ void RNA_api_keymapitems(StructRNA *srna)
RNA_def_boolean(func, "alt", 0, "Alt", "");
RNA_def_boolean(func, "oskey", 0, "OS Key", "");
RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", "");
- RNA_def_boolean(func, "head", 0, "At Head",
+ RNA_def_boolean(func, "head", 0, "At Head",
"Force item to be added at start (not end) of key map so that "
"it doesn't get blocked by an existing key map item");
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item");
@@ -844,7 +846,7 @@ void RNA_api_keymapitems(StructRNA *srna)
RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", "");
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item");
RNA_def_function_return(func, parm);
-
+
func = RNA_def_function(srna, "remove", "rna_KeyMap_item_remove");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 92fbbd61898..ead67814f01 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -143,7 +143,7 @@ static void rna_def_world_mist(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static const EnumPropertyItem falloff_items[] = {
{WO_MIST_QUADRATIC, "QUADRATIC", 0, "Quadratic", "Use quadratic progression"},
{WO_MIST_LINEAR, "LINEAR", 0, "Linear", "Use linear progression"},
@@ -186,7 +186,7 @@ static void rna_def_world_mist(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Height", "Control how much mist density decreases with height");
RNA_def_property_update(prop, 0, "rna_World_update");
-
+
prop = RNA_def_property(srna, "falloff", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mistype");
RNA_def_property_enum_items(prop, falloff_items);
@@ -214,7 +214,7 @@ void RNA_def_world(BlenderRNA *brna)
/* RNA_def_property_update(prop, 0, "rna_World_update"); */
/* render-only uses this */
RNA_def_property_update(prop, 0, "rna_World_draw_update");
-
+
/* nested structs */
prop = RNA_def_property(srna, "light_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner.py b/source/blender/makesrna/rna_cleanup/rna_cleaner.py
index 8b4b10c490e..0b80a711c3b 100755
--- a/source/blender/makesrna/rna_cleanup/rna_cleaner.py
+++ b/source/blender/makesrna/rna_cleanup/rna_cleaner.py
@@ -19,7 +19,7 @@ def font_bold(mystring):
font_bold = "\033[1m"
font_reset = "\033[0;0m"
return font_bold + mystring + font_reset
-
+
def usage():
"""
@@ -102,30 +102,30 @@ def get_props_from_txt(input_filename):
"""
If the file is *.txt, the script assumes it is formatted as outlined in this script docstring
"""
-
+
file=open(input_filename,'r')
file_lines=file.readlines()
file.close()
props_list=[]
props_length_max=[0,0,0,0,0,0,0,0]
-
+
done_text = "+"
done = 0
tot = 0
-
+
for iii, line in enumerate(file_lines):
-
+
# debug
#print(line)
line_strip = line.strip()
# empty line or comment
if not line_strip:
continue
-
+
if line_strip == "EOF":
break
-
+
if line.startswith("#"):
line = line[1:]
@@ -162,18 +162,18 @@ def get_props_from_txt(input_filename):
# changed
changed = check_if_changed(bfrom, bto)
-
+
# lists formatting
props=[comment, changed, bclass, bfrom, bto, kwcheck, btype, description]
props_list.append(props)
props_length_max=list(map(max,zip(props_length_max,list(map(len,props)))))
-
+
if done_text in comment:
done += 1
tot += 1
-
+
print("Total done %.2f" % (done / tot * 100.0) )
-
+
return (props_list,props_length_max)
@@ -181,7 +181,7 @@ def get_props_from_py(input_filename):
"""
If the file is *.py, the script assumes it contains a python list (as "rna_api=[...]")
This means that this script executes the text in the py file with an exec(text).
- """
+ """
# adds the list "rna_api" to this function's scope
rna_api = __import__(input_filename[:-3]).rna_api
@@ -205,7 +205,7 @@ def get_props(input_filename):
props_list,props_length_max = get_props_from_py(input_filename)
return (props_list,props_length_max)
-
+
def sort(props_list, sort_priority):
"""
reminder
@@ -221,7 +221,7 @@ def sort(props_list, sort_priority):
props_list = sorted(props_list, key=lambda p: p[i], reverse=True)
else:
props_list = sorted(props_list, key=lambda p: p[i])
-
+
print ('\nSorted by %s.' % font_bold(sort_priority))
return props_list
@@ -260,11 +260,11 @@ def write_files(basename, props_list, props_length_max):
props_list = [['NOTE', 'CHANGED', 'CLASS', 'FROM', 'TO', 'KEYWORD-CHECK', 'TYPE', 'DESCRIPTION']] + props_list
for props in props_list:
#txt
-
+
# quick way we can tell if it changed
if props[3] == props[4]: txt += "#"
else: txt += " "
-
+
if props[0] != '': txt += '%s * ' % props[0] # comment
txt += '%s.%s -> %s: %s "%s"\n' % tuple(props[2:5] + props[6:]) # skipping keyword-check
# rna_api
@@ -279,7 +279,7 @@ def write_files(basename, props_list, props_length_max):
f_txt.write(txt)
f_py.write("rna_api = [\n%s]\n" % py)
f_rna.write("rna_api = [\n%s]\n" % rna)
-
+
# write useful py script, wont hurt
f_py.write("\n'''\n")
f_py.write("for p_note, p_changed, p_class, p_from, p_to, p_check, p_type, p_desc in rna_api:\n")
diff --git a/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py b/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
index 17ea5f9b0bd..a5d5cebcbb7 100755
--- a/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
+++ b/source/blender/makesrna/rna_cleanup/rna_cleaner_merge.py
@@ -7,38 +7,38 @@ Example usage:
python3 rna_cleaner_merge.py out_work.py rna_booleans_work.py
'''
def main():
-
+
def work_line_id(line):
return line[2].split("|")[-1], line[3] # class/from
-
-
+
+
if not (sys.argv[-1].endswith(".py") and sys.argv[-2].endswith(".py")):
print("Only accepts 2 py files as arguments.")
-
+
sys.path.insert(0, ".")
mod_from = __import__(sys.argv[-1][:-3])
mod_to = __import__(sys.argv[-2][:-3])
-
+
mod_to_dict = dict([(work_line_id(line), line) for line in mod_to.rna_api])
mod_from_dict = dict([(work_line_id(line), line) for line in mod_from.rna_api])
-
+
rna_api_new = []
-
+
for key, val_orig in mod_to_dict.items():
try:
val_new = mod_from_dict.pop(key)
except:
# print("not found", key)
val_new = val_orig
-
+
# always take the class from the base
val = list(val_orig)
val[0] = val_new[0] # comment
val[4] = val_new[4] # -> to
val = tuple(val)
rna_api_new.append(val)
-
+
def write_work_file(file_path, rna_api):
rna_api = list(rna_api)
rna_api.sort(key=work_line_id)
@@ -51,7 +51,7 @@ def main():
file_path = sys.argv[-2][:-3] + "_merged.py"
write_work_file(file_path, rna_api_new)
-
+
if mod_from_dict:
file_path = sys.argv[-2][:-3] + "_lost.py"
write_work_file(file_path, list(mod_from_dict.values()))
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index 036954a2774..71022f8a4ab 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -45,6 +45,7 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index f4b39f1eab9..4bcc14236a0 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -431,7 +431,7 @@ static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *
}
static DerivedMesh *fluidsim_read_cache(
- Main *bmain, Object *ob, DerivedMesh *orgdm,
+ Object *ob, DerivedMesh *orgdm,
FluidsimModifierData *fluidmd, int framenr, int useRenderParams)
{
int curFrame = framenr /* - 1 */ /*scene->r.sfra*/; /* start with 0 at start frame */
@@ -466,7 +466,7 @@ static DerivedMesh *fluidsim_read_cache(
/* offset baked frame */
curFrame += fss->frameOffset;
- BLI_path_abs(targetFile, modifier_path_relbase(bmain, ob));
+ BLI_path_abs(targetFile, modifier_path_relbase_from_global(ob));
BLI_path_frame(targetFile, curFrame, 0); // fixed #frame-no
/* assign material + flags to new dm
@@ -552,7 +552,7 @@ DerivedMesh *fluidsimModifier_do(
/* try to read from cache */
/* if the frame is there, fine, otherwise don't do anything */
- if ((result = fluidsim_read_cache(G.main, ob, dm, fluidmd, framenr, useRenderParams)))
+ if ((result = fluidsim_read_cache(ob, dm, fluidmd, framenr, useRenderParams)))
return result;
return dm;
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index ae4eb042444..63b4e950697 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -38,8 +38,8 @@
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_library.h"
-#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_particle.h"
#include "DNA_mesh_types.h"
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 5d8ac9e5638..50765079785 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -152,7 +152,7 @@ static void meshcache_do(
/* would be nice if we could avoid doing this _every_ frame */
BLI_strncpy(filepath, mcmd->filepath, sizeof(filepath));
- BLI_path_abs(filepath, ID_BLEND_PATH(G.main, (ID *)ob));
+ BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL((ID *)ob));
switch (mcmd->type) {
case MOD_MESHCACHE_TYPE_MDD:
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 595b91f25a2..abd84799457 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -31,13 +31,13 @@
#include "DNA_scene_types.h"
#include "BKE_cachefile.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_scene.h"
#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "MOD_modifiertypes.h"
@@ -87,23 +87,23 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
return (mcmd->cache_file == NULL) || (mcmd->object_path[0] == '\0');
}
-static DerivedMesh *applyModifier(
+static Mesh *applyModifier(
ModifierData *md, const ModifierEvalContext *ctx,
- DerivedMesh *dm)
+ Mesh *mesh)
{
#ifdef WITH_ALEMBIC
MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
/* Only used to check whether we are operating on org data or not... */
Mesh *me = (ctx->object->type == OB_MESH) ? ctx->object->data : NULL;
- DerivedMesh *org_dm = dm;
+ Mesh *org_mesh = mesh;
- Scene *scene = md->scene;
- const float frame = BKE_scene_frame_get(scene);
+ Scene *scene = md->scene; /* for FPS macro */
+ const float frame = DEG_get_ctime(ctx->depsgraph);
const float time = BKE_cachefile_time_offset(mcmd->cache_file, frame, FPS);
const char *err_str = NULL;
- CacheFile *cache_file = mcmd->cache_file;
+ CacheFile *cache_file = (CacheFile *)DEG_get_original_id(&mcmd->cache_file->id);
BKE_cachefile_ensure_handle(G.main, cache_file);
@@ -114,39 +114,44 @@ static DerivedMesh *applyModifier(
mcmd->object_path);
if (!mcmd->reader) {
modifier_setError(md, "Could not create Alembic reader for file %s", cache_file->filepath);
- return dm;
+ return mesh;
}
}
if (me != NULL) {
- MVert *mvert = dm->getVertArray(dm);
- MEdge *medge = dm->getEdgeArray(dm);
- MPoly *mpoly = dm->getPolyArray(dm);
+ MVert *mvert = mesh->mvert;
+ MEdge *medge = mesh->medge;
+ MPoly *mpoly = mesh->mpoly;
if ((me->mvert == mvert) || (me->medge == medge) || (me->mpoly == mpoly)) {
/* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */
- dm = CDDM_copy(dm);
+ BKE_id_copy_ex(NULL, &mesh->id, (ID **)&mesh,
+ LIB_ID_CREATE_NO_MAIN |
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG |
+ LIB_ID_COPY_NO_PREVIEW,
+ false);
}
}
- DerivedMesh *result = ABC_read_mesh(mcmd->reader,
- ctx->object,
- dm,
- time,
- &err_str,
- mcmd->read_flag);
+ Mesh *result = ABC_read_mesh(mcmd->reader,
+ ctx->object,
+ mesh,
+ time,
+ &err_str,
+ mcmd->read_flag);
if (err_str) {
modifier_setError(md, "%s", err_str);
}
- if (!ELEM(result, NULL, dm) && (dm != org_dm)) {
- dm->release(dm);
- dm = org_dm;
+ if (!ELEM(result, NULL, mesh) && (mesh != org_mesh)) {
+ BKE_id_free(NULL, mesh);
+ mesh = org_mesh;
}
- return result ? result : dm;
+ return result ? result : mesh;
#else
- return dm;
+ return mesh;
UNUSED_VARS(ctx, md);
#endif
}
@@ -190,14 +195,14 @@ ModifierTypeInfo modifierType_MeshSequenceCache = {
/* deformMatrices_DM */ NULL,
/* deformVertsEM_DM */ NULL,
/* deformMatricesEM_DM*/NULL,
- /* applyModifier_DM */ applyModifier,
+ /* applyModifier_DM */ NULL,
/* applyModifierEM_DM */NULL,
/* deformVerts */ NULL,
/* deformMatrices */ NULL,
/* deformVertsEM */ NULL,
/* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
+ /* applyModifier */ applyModifier,
/* applyModifierEM */ NULL,
/* initData */ initData,
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index 921677ce1b1..af5b537ca52 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -49,9 +49,9 @@
#include "MOD_modifiertypes.h"
#ifdef WITH_OCEANSIM
-static void init_cache_data(Main *bmain, Object *ob, struct OceanModifierData *omd)
+static void init_cache_data(Object *ob, struct OceanModifierData *omd)
{
- const char *relbase = modifier_path_relbase(bmain, ob);
+ const char *relbase = modifier_path_relbase_from_global(ob);
omd->oceancache = BKE_ocean_init_cache(omd->cachepath, relbase,
omd->bakestart, omd->bakeend, omd->wave_scale,
@@ -448,7 +448,7 @@ static DerivedMesh *doOcean(
/* do ocean simulation */
if (omd->cached == true) {
if (!omd->oceancache) {
- init_cache_data(G.main, ob, omd);
+ init_cache_data(ob, omd);
}
BKE_ocean_simulate_cache(omd->oceancache, md->scene->r.cfra);
}
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index eee7f0c5561..0aafcf33202 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -149,7 +149,7 @@ static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *ps
if (p >= psys->totpart) {
ChildParticle *cpa = psys->child + (p - psys->totpart);
- pa = psys->particles + (between? cpa->pa[0]: cpa->parent);
+ pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
}
else {
pa = psys->particles + p;
@@ -173,8 +173,8 @@ static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *ps
/* TODO make randomization optional? */
randp = (int)(psys_frand(psys, 3578 + p) * totpart) % totpart;
- minp = (int)(totpart * pimd->particle_offset) % (totpart+1);
- maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart+1);
+ minp = (int)(totpart * pimd->particle_offset) % (totpart + 1);
+ maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart + 1);
if (maxp > minp) {
return randp < minp || randp >= maxp;
@@ -340,7 +340,7 @@ static Mesh *applyModifier(
for (p = part_start, p_skip = 0; p < part_end; p++) {
float prev_dir[3];
float frame[4]; /* frame orientation quaternion */
- float p_random = psys_frand(psys, 77091 + 283*p);
+ float p_random = psys_frand(psys, 77091 + 283 * p);
/* skip particle? */
if (particle_skip(pimd, psys, p))
@@ -404,7 +404,7 @@ static Mesh *applyModifier(
pa = psys->particles + p;
else {
ChildParticle *cpa = psys->child + (p - psys->totpart);
- pa = psys->particles + (between? cpa->pa[0]: cpa->parent);
+ pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
}
psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat);
copy_m3_m4(mat, hairmat);
@@ -412,7 +412,7 @@ static Mesh *applyModifier(
mat3_to_quat(frame, mat);
if (pimd->rotation > 0.0f || pimd->random_rotation > 0.0f) {
- float angle = 2.0f*M_PI * (pimd->rotation + pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
+ float angle = 2.0f * M_PI * (pimd->rotation + pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
float eul[3] = { 0.0f, 0.0f, angle };
float rot[4];
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index eff343a4906..df607c04164 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -38,6 +38,7 @@
#include "MOD_modifiertypes.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include <assert.h>
#include <stdlib.h>
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index c75f317e3bc..e964da0a8d1 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -9,7 +9,7 @@
#include "BLI_task.h"
#include "BKE_bvhutils.h"
-#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
#include "BKE_editmesh.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index 87b60543853..2c123fdbf7e 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -59,7 +59,7 @@
static void composite_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
{
Scene *scene = CTX_data_scene(C);
-
+
*r_from = NULL;
*r_id = &scene->id;
*r_ntree = scene->nodetree;
@@ -83,7 +83,7 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sock;
-
+
for (sock = node->outputs.first; sock; sock = sock->next) {
if (sock->cache) {
sock->cache = NULL;
@@ -103,15 +103,15 @@ static void localize(bNodeTree *UNUSED(localtree), bNodeTree *ntree)
{
bNode *node;
bNodeSocket *sock;
-
+
for (node = ntree->nodes.first; node; node = node->next) {
/* ensure new user input gets handled ok */
node->need_exec = 0;
node->new_node->original = node;
-
+
/* move over the compbufs */
/* right after ntreeCopyTree() oldsock pointers are valid */
-
+
if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
if (node->id) {
if (node->flag & NODE_DO_OUTPUT)
@@ -120,7 +120,7 @@ static void localize(bNodeTree *UNUSED(localtree), bNodeTree *ntree)
node->new_node->id = NULL;
}
}
-
+
for (sock = node->outputs.first; sock; sock = sock->next) {
sock->new_sock->cache = sock->cache;
sock->cache = NULL;
@@ -138,10 +138,10 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
{
bNode *lnode;
bNodeSocket *lsock;
-
+
/* move over the compbufs and previews */
BKE_node_preview_merge_tree(ntree, localtree, true);
-
+
for (lnode = localtree->nodes.first; lnode; lnode = lnode->next) {
if (ntreeNodeExists(ntree, lnode->new_node)) {
if (ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) {
@@ -161,7 +161,7 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
lnode->new_node->storage = BKE_tracking_distortion_copy(lnode->storage);
}
}
-
+
for (lsock = lnode->outputs.first; lsock; lsock = lsock->next) {
if (ntreeOutputExists(lnode->new_node, lsock->new_sock)) {
lsock->new_sock->cache = lsock->cache;
@@ -176,9 +176,9 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
static void update(bNodeTree *ntree)
{
ntreeSetOutput(ntree);
-
+
ntree_update_reroute_nodes(ntree);
-
+
if (ntree->update & NTREE_UPDATE_NODES) {
/* clean up preview cache, in case nodes have been removed */
BKE_node_preview_remove_unused(ntree);
@@ -187,12 +187,12 @@ static void update(bNodeTree *ntree)
static void composite_node_add_init(bNodeTree *UNUSED(bnodetree), bNode *bnode)
{
- /* Composite node will only show previews for input classes
- * by default, other will be hidden
+ /* Composite node will only show previews for input classes
+ * by default, other will be hidden
* but can be made visible with the show_preview option */
if (bnode->typeinfo->nclass != NODE_CLASS_INPUT) {
bnode->flag &= ~NODE_PREVIEW;
- }
+ }
}
bNodeTreeType *ntreeType_Composite;
@@ -200,13 +200,13 @@ bNodeTreeType *ntreeType_Composite;
void register_node_tree_type_cmp(void)
{
bNodeTreeType *tt = ntreeType_Composite = MEM_callocN(sizeof(bNodeTreeType), "compositor node tree type");
-
+
tt->type = NTREE_COMPOSIT;
strcpy(tt->idname, "CompositorNodeTree");
strcpy(tt->ui_name, "Compositing");
tt->ui_icon = 0; /* defined in drawnode.c */
strcpy(tt->ui_description, "Compositing nodes");
-
+
tt->free_cache = free_cache;
tt->free_node_cache = free_node_cache;
tt->foreach_nodeclass = foreach_nodeclass;
@@ -216,9 +216,9 @@ void register_node_tree_type_cmp(void)
tt->update = update;
tt->get_from_context = composite_get_from_context;
tt->node_add_init = composite_node_add_init;
-
+
tt->ext.srna = &RNA_CompositorNodeTree;
-
+
ntreeTypeAdd(tt);
}
diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c
index faf3d994bf9..022794e8d42 100644
--- a/source/blender/nodes/composite/node_composite_util.c
+++ b/source/blender/nodes/composite/node_composite_util.c
@@ -52,7 +52,7 @@ void cmp_node_update_default(bNodeTree *UNUSED(ntree), bNode *node)
void cmp_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
{
node_type_base(ntype, type, name, nclass, flag);
-
+
ntype->poll = cmp_node_poll_default;
ntype->updatefunc = cmp_node_update_default;
ntype->insert_link = node_insert_link_default;
diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehblur.c b/source/blender/nodes/composite/nodes/node_composite_bokehblur.c
index 503d1ad9a9d..acb5d100b0a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bokehblur.c
+++ b/source/blender/nodes/composite/nodes/node_composite_bokehblur.c
@@ -60,6 +60,6 @@ void register_node_type_cmp_bokehblur(void)
cmp_node_type_base(&ntype, CMP_NODE_BOKEHBLUR, "Bokeh Blur", NODE_CLASS_OP_FILTER, 0);
node_type_socket_templates(&ntype, cmp_node_bokehblur_in, cmp_node_bokehblur_out);
node_type_init(&ntype, node_composit_init_bokehblur);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehimage.c b/source/blender/nodes/composite/nodes/node_composite_bokehimage.c
index 1473212f8e1..04cdd3367e6 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bokehimage.c
+++ b/source/blender/nodes/composite/nodes/node_composite_bokehimage.c
@@ -54,7 +54,7 @@ static void node_composit_init_bokehimage(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_cmp_bokehimage(void)
{
static bNodeType ntype;
-
+
cmp_node_type_base(&ntype, CMP_NODE_BOKEHIMAGE, "Bokeh Image", NODE_CLASS_INPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, NULL, cmp_node_bokehimage_out);
node_type_init(&ntype, node_composit_init_bokehimage);
diff --git a/source/blender/nodes/composite/nodes/node_composite_boxmask.c b/source/blender/nodes/composite/nodes/node_composite_boxmask.c
index 2a47c58c33f..611cf323873 100644
--- a/source/blender/nodes/composite/nodes/node_composite_boxmask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_boxmask.c
@@ -32,7 +32,7 @@
#include "../node_composite_util.h"
-/* **************** SCALAR MATH ******************** */
+/* **************** SCALAR MATH ******************** */
static bNodeSocketTemplate cmp_node_boxmask_in[] = {
{ SOCK_FLOAT, 1, N_("Mask"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Value"), 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
diff --git a/source/blender/nodes/composite/nodes/node_composite_brightness.c b/source/blender/nodes/composite/nodes/node_composite_brightness.c
index 845e9e20c81..d44b8cd63cb 100644
--- a/source/blender/nodes/composite/nodes/node_composite_brightness.c
+++ b/source/blender/nodes/composite/nodes/node_composite_brightness.c
@@ -54,7 +54,7 @@ static void node_composit_init_brightcontrast(bNodeTree *UNUSED(ntree), bNode *n
void register_node_type_cmp_brightcontrast(void)
{
static bNodeType ntype;
-
+
cmp_node_type_base(&ntype, CMP_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, cmp_node_brightcontrast_in, cmp_node_brightcontrast_out);
node_type_init(&ntype, node_composit_init_brightcontrast);
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
index a6a7f3aa5a3..641026c3aad 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c
@@ -57,7 +57,7 @@ static void node_composit_init_color_spill(bNodeTree *UNUSED(ntree), bNode *node
void register_node_type_cmp_color_spill(void)
{
static bNodeType ntype;
-
+
cmp_node_type_base(&ntype, CMP_NODE_COLOR_SPILL, "Color Spill", NODE_CLASS_MATTE, 0);
node_type_socket_templates(&ntype, cmp_node_color_spill_in, cmp_node_color_spill_out);
node_type_init(&ntype, node_composit_init_color_spill);
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
index 8370ace8cb3..f9ad8c0ea5f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
@@ -52,7 +52,7 @@ void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeColorBalance *n = node->storage;
int c;
-
+
for (c = 0; c < 3; ++c) {
n->slope[c] = (2.0f - n->lift[c]) * n->gain[c];
n->offset[c] = (n->lift[c] - 1.0f) * n->gain[c];
@@ -64,7 +64,7 @@ void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeColorBalance *n = node->storage;
int c;
-
+
for (c = 0; c < 3; ++c) {
float d = n->slope[c] + n->offset[c];
n->lift[c] = (d != 0.0f ? n->slope[c] + 2.0f * n->offset[c] / d : 0.0f);
diff --git a/source/blender/nodes/composite/nodes/node_composite_common.c b/source/blender/nodes/composite/nodes/node_composite_common.c
index 57ec0f1c7ad..de97a5beac3 100644
--- a/source/blender/nodes/composite/nodes/node_composite_common.c
+++ b/source/blender/nodes/composite/nodes/node_composite_common.c
@@ -43,7 +43,7 @@
void register_node_type_cmp_group(void)
{
static bNodeType ntype;
-
+
/* NB: cannot use sh_node_type_base for node group, because it would map the node type
* to the shared NODE_GROUP integer type id.
*/
@@ -56,7 +56,7 @@ void register_node_type_cmp_group(void)
ntype.ext.srna = RNA_struct_find("CompositorNodeGroup");
BLI_assert(ntype.ext.srna != NULL);
RNA_struct_blender_type_set(ntype.ext.srna, &ntype);
-
+
node_type_socket_templates(&ntype, NULL, NULL);
node_type_size(&ntype, 140, 60, 400);
node_type_label(&ntype, node_group_label);
diff --git a/source/blender/nodes/composite/nodes/node_composite_dilate.c b/source/blender/nodes/composite/nodes/node_composite_dilate.c
index 4efee112438..72d12e0a643 100644
--- a/source/blender/nodes/composite/nodes/node_composite_dilate.c
+++ b/source/blender/nodes/composite/nodes/node_composite_dilate.c
@@ -54,7 +54,7 @@ static void node_composit_init_dilateerode(bNodeTree *UNUSED(ntree), bNode *node
void register_node_type_cmp_dilateerode(void)
{
static bNodeType ntype;
-
+
cmp_node_type_base(&ntype, CMP_NODE_DILATEERODE, "Dilate/Erode", NODE_CLASS_OP_FILTER, 0);
node_type_socket_templates(&ntype, cmp_node_dilateerode_in, cmp_node_dilateerode_out);
node_type_init(&ntype, node_composit_init_dilateerode);
diff --git a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c
index df8ae4931e5..b72a0fb82ae 100644
--- a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.c
@@ -32,7 +32,7 @@
#include "../node_composite_util.h"
-/* **************** SCALAR MATH ******************** */
+/* **************** SCALAR MATH ******************** */
static bNodeSocketTemplate cmp_node_ellipsemask_in[] = {
{ SOCK_FLOAT, 1, N_("Mask"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Value"), 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
diff --git a/source/blender/nodes/composite/nodes/node_composite_gamma.c b/source/blender/nodes/composite/nodes/node_composite_gamma.c
index 81764c97aac..30d399d3f73 100644
--- a/source/blender/nodes/composite/nodes/node_composite_gamma.c
+++ b/source/blender/nodes/composite/nodes/node_composite_gamma.c
@@ -47,9 +47,9 @@ static bNodeSocketTemplate cmp_node_gamma_out[] = {
void register_node_type_cmp_gamma(void)
{
static bNodeType ntype;
-
+
cmp_node_type_base(&ntype, CMP_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, cmp_node_gamma_in, cmp_node_gamma_out);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_huecorrect.c b/source/blender/nodes/composite/nodes/node_composite_huecorrect.c
index 4ee1bccd726..70c73bcb46a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_huecorrect.c
+++ b/source/blender/nodes/composite/nodes/node_composite_huecorrect.c
@@ -47,14 +47,14 @@ static void node_composit_init_huecorrect(bNodeTree *UNUSED(ntree), bNode *node)
{
CurveMapping *cumapping = node->storage = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
int c;
-
+
cumapping->preset = CURVE_PRESET_MID9;
-
+
for (c = 0; c < 3; c++) {
CurveMap *cuma = &cumapping->cm[c];
curvemap_reset(cuma, &cumapping->clipr, cumapping->preset, CURVEMAP_SLOPE_POSITIVE);
}
-
+
/* default to showing Saturation */
cumapping->cur = 1;
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 6a5458d6045..124b2fa72b9 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -150,10 +150,10 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node, LinkNod
/* make sure ima->type is correct */
ibuf = BKE_image_acquire_ibuf(ima, &load_iuser, NULL);
-
+
if (ima->rr) {
RenderLayer *rl = BLI_findlink(&ima->rr->layers, iuser->layer);
-
+
if (rl) {
RenderPass *rpass;
for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
@@ -251,7 +251,7 @@ static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node, bool rl
bNodeSocket *sock, *sock_next;
LinkNodePair available_sockets = {NULL, NULL};
int sock_index;
-
+
/* XXX make callback */
if (rlayer)
cmp_node_rlayer_create_outputs(ntree, node, &available_sockets);
@@ -307,7 +307,7 @@ static void node_composit_init_image(bNodeTree *ntree, bNode *node)
iuser->fie_ima = 2;
iuser->ok = 1;
iuser->flag |= IMA_ANIM_ALWAYS;
-
+
/* setup initial outputs */
cmp_node_image_verify_outputs(ntree, node, false);
}
@@ -315,20 +315,20 @@ static void node_composit_init_image(bNodeTree *ntree, bNode *node)
static void node_composit_free_image(bNode *node)
{
bNodeSocket *sock;
-
+
/* free extra socket info */
for (sock = node->outputs.first; sock; sock = sock->next)
MEM_freeN(sock->storage);
-
+
MEM_freeN(node->storage);
}
static void node_composit_copy_image(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, bNode *src_node)
{
bNodeSocket *sock;
-
+
dest_node->storage = MEM_dupallocN(src_node->storage);
-
+
/* copy extra socket info */
for (sock = src_node->outputs.first; sock; sock = sock->next)
sock->new_sock->storage = MEM_dupallocN(sock->storage);
@@ -394,7 +394,7 @@ static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree
{
if (STREQ(ntree->idname, "CompositorNodeTree")) {
Scene *scene;
-
+
/* XXX ugly: check if ntree is a local scene node tree.
* Render layers node can only be used in local scene->nodetree,
* since it directly links to the scene.
@@ -402,7 +402,7 @@ static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree
for (scene = G.main->scene.first; scene; scene = scene->id.next)
if (scene->nodetree == ntree)
break;
-
+
return (scene != NULL);
}
return false;
diff --git a/source/blender/nodes/composite/nodes/node_composite_inpaint.c b/source/blender/nodes/composite/nodes/node_composite_inpaint.c
index a0d3531dabf..f97f366d0c4 100644
--- a/source/blender/nodes/composite/nodes/node_composite_inpaint.c
+++ b/source/blender/nodes/composite/nodes/node_composite_inpaint.c
@@ -47,7 +47,7 @@ static bNodeSocketTemplate cmp_node_inpaint_out[] = {
void register_node_type_cmp_inpaint(void)
{
static bNodeType ntype;
-
+
cmp_node_type_base(&ntype, CMP_NODE_INPAINT, "Inpaint", NODE_CLASS_OP_FILTER, 0);
node_type_socket_templates(&ntype, cmp_node_inpaint_in, cmp_node_inpaint_out);
diff --git a/source/blender/nodes/composite/nodes/node_composite_math.c b/source/blender/nodes/composite/nodes/node_composite_math.c
index 276dab27f76..e40621d3210 100644
--- a/source/blender/nodes/composite/nodes/node_composite_math.c
+++ b/source/blender/nodes/composite/nodes/node_composite_math.c
@@ -32,7 +32,7 @@
#include "node_composite_util.h"
-/* **************** SCALAR MATH ******************** */
+/* **************** SCALAR MATH ******************** */
static bNodeSocketTemplate cmp_node_math_in[] = {
{ SOCK_FLOAT, 1, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
{ SOCK_FLOAT, 1, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
index 9c54009d2f1..4149a0eec9d 100644
--- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
+++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
@@ -58,7 +58,7 @@ static void init(const bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
Scene *scene = CTX_data_scene(C);
-
+
node->id = (ID *)scene->clip;
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_normalize.c b/source/blender/nodes/composite/nodes/node_composite_normalize.c
index d93c62f8229..9a5cc84797e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_normalize.c
+++ b/source/blender/nodes/composite/nodes/node_composite_normalize.c
@@ -46,9 +46,9 @@ static bNodeSocketTemplate cmp_node_normalize_out[] = {
void register_node_type_cmp_normalize(void)
{
static bNodeType ntype;
-
+
cmp_node_type_base(&ntype, CMP_NODE_NORMALIZE, "Normalize", NODE_CLASS_OP_VECTOR, 0);
node_type_socket_templates(&ntype, cmp_node_normalize_in, cmp_node_normalize_out);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
index 8b349ea8779..a2a25d5c515 100644
--- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c
+++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
@@ -107,16 +107,16 @@ bNodeSocket *ntreeCompositOutputFileAddSocket(bNodeTree *ntree, bNode *node, con
{
NodeImageMultiFile *nimf = node->storage;
bNodeSocket *sock = nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, NULL, name);
-
+
/* create format data for the input socket */
NodeImageMultiFileSocket *sockdata = MEM_callocN(sizeof(NodeImageMultiFileSocket), "socket image format");
sock->storage = sockdata;
-
+
BLI_strncpy_utf8(sockdata->path, name, sizeof(sockdata->path));
ntreeCompositOutputFileUniquePath(&node->inputs, sock, name, '_');
BLI_strncpy_utf8(sockdata->layer, name, sizeof(sockdata->layer));
ntreeCompositOutputFileUniqueLayer(&node->inputs, sock, name, '_');
-
+
if (im_format) {
sockdata->format = *im_format;
if (BKE_imtype_is_movie(sockdata->format.imtype)) {
@@ -129,7 +129,7 @@ bNodeSocket *ntreeCompositOutputFileAddSocket(bNodeTree *ntree, bNode *node, con
sockdata->use_node_format = true;
nimf->active_input = BLI_findindex(&node->inputs, sock);
-
+
return sock;
}
@@ -138,16 +138,16 @@ int ntreeCompositOutputFileRemoveActiveSocket(bNodeTree *ntree, bNode *node)
NodeImageMultiFile *nimf = node->storage;
bNodeSocket *sock = BLI_findlink(&node->inputs, nimf->active_input);
int totinputs = BLI_listbase_count(&node->inputs);
-
+
if (!sock)
return 0;
-
+
if (nimf->active_input == totinputs - 1)
--nimf->active_input;
-
+
/* free format data */
MEM_freeN(sock->storage);
-
+
nodeRemoveSocket(ntree, node, sock);
return 1;
}
@@ -175,7 +175,7 @@ static void init_output_file(const bContext *C, PointerRNA *ptr)
NodeImageMultiFile *nimf = MEM_callocN(sizeof(NodeImageMultiFile), "node image multi file");
ImageFormatData *format = NULL;
node->storage = nimf;
-
+
if (scene) {
RenderData *rd = &scene->r;
@@ -184,7 +184,7 @@ static void init_output_file(const bContext *C, PointerRNA *ptr)
if (BKE_imtype_is_movie(nimf->format.imtype)) {
nimf->format.imtype = R_IMF_IMTYPE_OPENEXR;
}
-
+
format = &nimf->format;
}
else
@@ -197,21 +197,21 @@ static void init_output_file(const bContext *C, PointerRNA *ptr)
static void free_output_file(bNode *node)
{
bNodeSocket *sock;
-
+
/* free storage data in sockets */
for (sock = node->inputs.first; sock; sock = sock->next) {
MEM_freeN(sock->storage);
}
-
+
MEM_freeN(node->storage);
}
static void copy_output_file(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, bNode *src_node)
{
bNodeSocket *src_sock, *dest_sock;
-
+
dest_node->storage = MEM_dupallocN(src_node->storage);
-
+
/* duplicate storage data in sockets */
for (src_sock = src_node->inputs.first, dest_sock = dest_node->inputs.first; src_sock && dest_sock; src_sock = src_sock->next, dest_sock = dest_sock->next) {
dest_sock->storage = MEM_dupallocN(src_sock->storage);
@@ -222,7 +222,7 @@ static void update_output_file(bNodeTree *ntree, bNode *node)
{
bNodeSocket *sock, *sock_next;
PointerRNA ptr;
-
+
/* XXX fix for #36706: remove invalid sockets added with bpy API.
* This is not ideal, but prevents crashes from missing storage.
* FileOutput node needs a redesign to support this properly.
@@ -237,9 +237,9 @@ static void update_output_file(bNodeTree *ntree, bNode *node)
sock_next = sock->next;
nodeRemoveSocket(ntree, node, sock);
}
-
+
cmp_node_update_default(ntree, node);
-
+
/* automatically update the socket type based on linked input */
for (sock = node->inputs.first; sock; sock = sock->next) {
if (sock->link) {
diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
index 780ec1592bf..dbe47066f66 100644
--- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
@@ -49,7 +49,7 @@ static void node_composit_init_splitviewer(bNodeTree *UNUSED(ntree), bNode *node
iuser->fie_ima = 2;
iuser->ok = 1;
node->custom1 = 50; /* default 50% split */
-
+
node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
index 93ae6b6c4a4..16f5d340ddd 100644
--- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
+++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
@@ -50,9 +50,9 @@ static void init(const bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
Scene *scene = CTX_data_scene(C);
-
+
node->id = (ID *)scene->clip;
-
+
/* default to bilinear, see node_sampler_type_items in rna_nodetree.c */
node->custom1 = 1;
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_valToRgb.c b/source/blender/nodes/composite/nodes/node_composite_valToRgb.c
index 1b62f4e77d4..16fc98a5e85 100644
--- a/source/blender/nodes/composite/nodes/node_composite_valToRgb.c
+++ b/source/blender/nodes/composite/nodes/node_composite_valToRgb.c
@@ -77,10 +77,10 @@ static bNodeSocketTemplate cmp_node_rgbtobw_out[] = {
void register_node_type_cmp_rgbtobw(void)
{
static bNodeType ntype;
-
+
cmp_node_type_base(&ntype, CMP_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, cmp_node_rgbtobw_in, cmp_node_rgbtobw_out);
node_type_size_preset(&ntype, NODE_SIZE_SMALL);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c
index 66f2e2bacbc..a10ba02b38e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_viewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c
@@ -52,7 +52,7 @@ static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode *node)
iuser->ok = 1;
node->custom3 = 0.5f;
node->custom4 = 0.5f;
-
+
node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
}
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index c465f7a9be5..4a47bf7035c 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -98,16 +98,16 @@ int nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree)
{
bNode *node;
int valid = 1;
-
+
/* unspecified node group, generally allowed
* (if anything, should be avoided on operator level)
*/
if (grouptree == NULL)
return 1;
-
+
if (nodetree == grouptree)
return 0;
-
+
for (node = grouptree->nodes.first; node; node = node->next) {
if (node->typeinfo->poll_instance && !node->typeinfo->poll_instance(node, nodetree)) {
valid = 0;
@@ -121,27 +121,27 @@ int nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree)
static bNodeSocket *group_verify_socket(bNodeTree *ntree, bNode *gnode, bNodeSocket *iosock, ListBase *verify_lb, int in_out)
{
bNodeSocket *sock;
-
+
for (sock = verify_lb->first; sock; sock = sock->next) {
if (STREQ(sock->identifier, iosock->identifier))
break;
}
if (sock) {
strcpy(sock->name, iosock->name);
-
+
if (iosock->typeinfo->interface_verify_socket)
iosock->typeinfo->interface_verify_socket(ntree, iosock, gnode, sock, "interface");
}
else {
sock = nodeAddSocket(ntree, gnode, in_out, iosock->idname, iosock->identifier, iosock->name);
-
+
if (iosock->typeinfo->interface_init_socket)
iosock->typeinfo->interface_init_socket(ntree, iosock, gnode, sock, "interface");
}
-
+
/* remove from list temporarily, to distinguish from orphaned sockets */
BLI_remlink(verify_lb, sock);
-
+
return sock;
}
@@ -150,9 +150,9 @@ static void group_verify_socket_list(bNodeTree *ntree, bNode *gnode,
ListBase *iosock_lb, ListBase *verify_lb, int in_out)
{
bNodeSocket *iosock, *sock, *nextsock;
-
+
/* step by step compare */
-
+
iosock = iosock_lb->first;
for (; iosock; iosock = iosock->next) {
/* abusing new_sock pointer for verification here! only used inside this function */
@@ -195,9 +195,9 @@ static void node_frame_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeFrame *data = (NodeFrame *)MEM_callocN(sizeof(NodeFrame), "frame node storage");
node->storage = data;
-
+
data->flag |= NODE_FRAME_SHRINK;
-
+
data->label_size = 20;
}
@@ -211,7 +211,7 @@ void register_node_type_frame(void)
node_type_storage(ntype, "NodeFrame", node_free_standard_storage, node_copy_standard_storage);
node_type_size(ntype, 150, 100, 0);
node_type_compatibility(ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
-
+
ntype->needs_free = 1;
nodeRegisterType(ntype);
}
@@ -251,11 +251,11 @@ void register_node_type_reroute(void)
{
/* frame type is used for all tree types, needs dynamic allocation */
bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "frame node type");
-
+
node_type_base(ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT, 0);
node_type_init(ntype, node_reroute_init);
node_type_internal_links(ntype, node_reroute_update_internal_links);
-
+
ntype->needs_free = 1;
nodeRegisterType(ntype);
}
@@ -267,14 +267,14 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, i
bNodeLink *link;
int type = SOCK_FLOAT;
const char *type_idname = nodeStaticSocketType(type, PROP_NONE);
-
+
/* XXX it would be a little bit more efficient to restrict actual updates
* to rerout nodes connected to an updated node, but there's no reliable flag
* to indicate updated nodes (node->update is not set on linking).
*/
-
+
node->done = 1;
-
+
/* recursive update */
for (link = ntree->links.first; link; link = link->next) {
bNode *fromnode = link->fromnode;
@@ -283,7 +283,7 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, i
continue;
if (nodeLinkIsHidden(link))
continue;
-
+
if (flag & REFINE_FORWARD) {
if (tonode == node && fromnode->type == NODE_REROUTE && !fromnode->done)
node_reroute_inherit_type_recursive(ntree, fromnode, REFINE_FORWARD);
@@ -293,7 +293,7 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, i
node_reroute_inherit_type_recursive(ntree, tonode, REFINE_BACKWARD);
}
}
-
+
/* determine socket type from unambiguous input/output connection if possible */
if (input->limit == 1 && input->link) {
type = input->link->fromsock->type;
@@ -303,7 +303,7 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, i
type = output->link->tosock->type;
type_idname = nodeStaticSocketType(type, PROP_NONE);
}
-
+
if (input->type != type) {
bNodeSocket *ninput = nodeAddSocket(ntree, node, SOCK_IN, type_idname, "input", "Input");
for (link = ntree->links.first; link; link = link->next) {
@@ -314,7 +314,7 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, i
}
nodeRemoveSocket(ntree, node, input);
}
-
+
if (output->type != type) {
bNodeSocket *noutput = nodeAddSocket(ntree, node, SOCK_OUT, type_idname, "output", "Output");
for (link = ntree->links.first; link; link = link->next) {
@@ -324,7 +324,7 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, i
}
nodeRemoveSocket(ntree, node, output);
}
-
+
nodeUpdateInternalLinks(ntree, node);
}
@@ -334,11 +334,11 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, i
void ntree_update_reroute_nodes(bNodeTree *ntree)
{
bNode *node;
-
+
/* clear tags */
for (node = ntree->nodes.first; node; node = node->next)
node->done = 0;
-
+
for (node = ntree->nodes.first; node; node = node->next)
if (node->type == NODE_REROUTE && !node->done)
node_reroute_inherit_type_recursive(ntree, node, REFINE_FORWARD | REFINE_BACKWARD);
@@ -411,7 +411,7 @@ void node_group_input_verify(bNodeTree *ntree, bNode *node, ID *id)
if (id == (ID *)ntree) {
/* value_in_out inverted for interface nodes to get correct socket value_property */
group_verify_socket_list(ntree, node, &ntree->inputs, &node->outputs, SOCK_OUT);
-
+
/* add virtual extension socket */
nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketVirtual", "__extend__", "");
}
@@ -426,23 +426,23 @@ static void node_group_input_update(bNodeTree *ntree, bNode *node)
* so they can be recreated after verification.
*/
ListBase tmplinks;
-
+
/* find links from the extension socket and store them */
BLI_listbase_clear(&tmplinks);
for (link = ntree->links.first; link; link = linknext) {
linknext = link->next;
if (nodeLinkIsHidden(link))
continue;
-
+
if (link->fromsock == extsock) {
bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link");
*tlink = *link;
BLI_addtail(&tmplinks, tlink);
-
+
nodeRemLink(ntree, link);
}
}
-
+
/* find valid link to expose */
exposelink = NULL;
for (link = tmplinks.first; link; link = link->next) {
@@ -456,22 +456,22 @@ static void node_group_input_update(bNodeTree *ntree, bNode *node)
break;
}
}
-
+
if (exposelink) {
bNodeSocket *gsock, *newsock;
-
+
gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock);
-
+
node_group_input_verify(ntree, node, (ID *)ntree);
newsock = node_group_input_find_socket(node, gsock->identifier);
-
+
/* redirect links from the extension socket */
for (link = tmplinks.first; link; link = link->next) {
nodeAddLink(ntree, node, newsock, link->tonode, link->tosock);
}
-
+
}
-
+
BLI_freelistN(&tmplinks);
}
@@ -479,13 +479,13 @@ void register_node_type_group_input(void)
{
/* used for all tree types, needs dynamic allocation */
bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "node type");
-
+
node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE, 0);
node_type_size(ntype, 140, 80, 400);
node_type_init(ntype, node_group_input_init);
node_type_update(ntype, node_group_input_update, node_group_input_verify);
node_type_compatibility(ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
-
+
ntype->needs_free = 1;
nodeRegisterType(ntype);
}
@@ -510,7 +510,7 @@ void node_group_output_verify(bNodeTree *ntree, bNode *node, ID *id)
if (id == (ID *)ntree) {
/* value_in_out inverted for interface nodes to get correct socket value_property */
group_verify_socket_list(ntree, node, &ntree->outputs, &node->inputs, SOCK_IN);
-
+
/* add virtual extension socket */
nodeAddSocket(ntree, node, SOCK_IN, "NodeSocketVirtual", "__extend__", "");
}
@@ -525,23 +525,23 @@ static void node_group_output_update(bNodeTree *ntree, bNode *node)
* so they can be recreated after verification.
*/
ListBase tmplinks;
-
+
/* find links to the extension socket and store them */
BLI_listbase_clear(&tmplinks);
for (link = ntree->links.first; link; link = linknext) {
linknext = link->next;
if (nodeLinkIsHidden(link))
continue;
-
+
if (link->tosock == extsock) {
bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link");
*tlink = *link;
BLI_addtail(&tmplinks, tlink);
-
+
nodeRemLink(ntree, link);
}
}
-
+
/* find valid link to expose */
exposelink = NULL;
for (link = tmplinks.first; link; link = link->next) {
@@ -555,22 +555,22 @@ static void node_group_output_update(bNodeTree *ntree, bNode *node)
break;
}
}
-
+
if (exposelink) {
bNodeSocket *gsock, *newsock;
-
+
/* XXX what if connecting virtual to virtual socket?? */
gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock);
-
+
node_group_output_verify(ntree, node, (ID *)ntree);
newsock = node_group_output_find_socket(node, gsock->identifier);
-
+
/* redirect links to the extension socket */
for (link = tmplinks.first; link; link = link->next) {
nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock);
}
}
-
+
BLI_freelistN(&tmplinks);
}
@@ -578,13 +578,13 @@ void register_node_type_group_output(void)
{
/* used for all tree types, needs dynamic allocation */
bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "node type");
-
+
node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE, 0);
node_type_size(ntype, 140, 80, 400);
node_type_init(ntype, node_group_output_init);
node_type_update(ntype, node_group_output_update, node_group_output_verify);
node_type_compatibility(ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
-
+
ntype->needs_free = 1;
nodeRegisterType(ntype);
}
diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c
index 5b97685fc54..3708a7663ed 100644
--- a/source/blender/nodes/intern/node_exec.c
+++ b/source/blender/nodes/intern/node_exec.c
@@ -61,14 +61,14 @@ bNodeStack *node_get_socket_stack(bNodeStack *stack, bNodeSocket *sock)
void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out)
{
bNodeSocket *sock;
-
+
/* build pointer stack */
if (in) {
for (sock = node->inputs.first; sock; sock = sock->next) {
*(in++) = node_get_socket_stack(stack, sock);
}
}
-
+
if (out) {
for (sock = node->outputs.first; sock; sock = sock->next) {
*(out++) = node_get_socket_stack(stack, sock);
@@ -127,13 +127,13 @@ static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeTree *ntree, bNode
bNodeStack *ns = node_get_socket_stack(stack, sock);
if (!ns)
return NULL;
-
+
/* don't mess with remote socket stacks, these are initialized by other nodes! */
if (sock->link)
return ns;
-
+
ns->sockettype = sock->type;
-
+
switch (sock->type) {
case SOCK_FLOAT:
ns->vec[0] = node_socket_get_float(ntree, node, sock);
@@ -145,7 +145,7 @@ static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeTree *ntree, bNode
node_socket_get_color(ntree, node, sock, ns->vec);
break;
}
-
+
return ns;
}
@@ -161,29 +161,29 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNo
bNode **nodelist;
int totnodes, n;
/* XXX texnodes have threading issues with muting, have to disable it there ... */
-
+
/* ensure all sock->link pointers and node levels are correct */
ntreeUpdateTree(G.main, ntree);
-
+
/* get a dependency-sorted list of nodes */
ntreeGetDependencyList(ntree, &nodelist, &totnodes);
-
+
/* XXX could let callbacks do this for specialized data */
exec = MEM_callocN(sizeof(bNodeTreeExec), "node tree execution data");
/* backpointer to node tree */
exec->nodetree = ntree;
-
+
/* set stack indices */
index = 0;
for (n = 0; n < totnodes; ++n) {
node = nodelist[n];
-
+
node->stack_index = index;
-
+
/* init node socket stack indexes */
for (sock = node->inputs.first; sock; sock = sock->next)
node_init_input_index(sock, &index);
-
+
if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
for (sock = node->outputs.first; sock; sock = sock->next)
node_init_output_index(sock, &index, &node->internal_links);
@@ -193,48 +193,48 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNo
node_init_output_index(sock, &index, NULL);
}
}
-
+
/* allocated exec data pointers for nodes */
exec->totnodes = totnodes;
exec->nodeexec = MEM_callocN(exec->totnodes * sizeof(bNodeExec), "node execution data");
/* allocate data pointer for node stack */
exec->stacksize = index;
exec->stack = MEM_callocN(exec->stacksize * sizeof(bNodeStack), "bNodeStack");
-
+
/* all non-const results are considered inputs */
for (n = 0; n < exec->stacksize; ++n)
exec->stack[n].hasinput = 1;
-
+
/* prepare all nodes for execution */
for (n = 0, nodeexec = exec->nodeexec; n < totnodes; ++n, ++nodeexec) {
node = nodeexec->node = nodelist[n];
nodeexec->freeexecfunc = node->typeinfo->freeexecfunc;
-
+
/* tag inputs */
for (sock = node->inputs.first; sock; sock = sock->next) {
/* disable the node if an input link is invalid */
if (sock->link && !(sock->link->flag & NODE_LINK_VALID))
node->need_exec = 0;
-
+
ns = setup_stack(exec->stack, ntree, node, sock);
if (ns)
ns->hasoutput = 1;
}
-
+
/* tag all outputs */
for (sock = node->outputs.first; sock; sock = sock->next) {
/* ns = */ setup_stack(exec->stack, ntree, node, sock);
}
-
+
nodekey = BKE_node_instance_key(parent_key, ntree, node);
nodeexec->data.preview = context->previews ? BKE_node_instance_hash_lookup(context->previews, nodekey) : NULL;
if (node->typeinfo->initexecfunc)
nodeexec->data.data = node->typeinfo->initexecfunc(context, node, nodekey);
}
-
+
if (nodelist)
MEM_freeN(nodelist);
-
+
return exec;
}
@@ -242,18 +242,18 @@ void ntree_exec_end(bNodeTreeExec *exec)
{
bNodeExec *nodeexec;
int n;
-
+
if (exec->stack)
MEM_freeN(exec->stack);
-
+
for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
if (nodeexec->freeexecfunc)
nodeexec->freeexecfunc(nodeexec->data.data);
}
-
+
if (exec->nodeexec)
MEM_freeN(exec->nodeexec);
-
+
MEM_freeN(exec);
}
@@ -263,14 +263,14 @@ bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread)
{
ListBase *lb = &exec->threadstack[thread];
bNodeThreadStack *nts;
-
+
for (nts = lb->first; nts; nts = nts->next) {
if (!nts->used) {
nts->used = true;
break;
}
}
-
+
if (!nts) {
nts = MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
nts->stack = MEM_dupallocN(exec->stack);
@@ -293,9 +293,9 @@ bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *call
bNodeExec *nodeexec;
bNode *node;
int n;
-
+
/* nodes are presorted, so exec is in order of list */
-
+
for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
node = nodeexec->node;
if (node->need_exec) {
@@ -308,7 +308,7 @@ bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *call
node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout);
}
}
-
+
/* signal to that all went OK, for render */
return true;
}
diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h
index bf4c29bad8e..6771df76bf9 100644
--- a/source/blender/nodes/intern/node_exec.h
+++ b/source/blender/nodes/intern/node_exec.h
@@ -51,17 +51,17 @@ struct bNodeStack;
typedef struct bNodeExec {
struct bNode *node; /* backpointer to node */
bNodeExecData data;
-
+
NodeFreeExecFunction freeexecfunc; /* free function, stored in exec itself to avoid dangling node pointer access */
} bNodeExec;
/* Execution Data for each instance of node tree execution */
typedef struct bNodeTreeExec {
struct bNodeTree *nodetree; /* backpointer to node tree */
-
+
int totnodes; /* total node count */
struct bNodeExec *nodeexec; /* per-node execution data */
-
+
int stacksize;
struct bNodeStack *stack; /* socket data stack */
/* only used by material and texture trees to keep one stack for each thread */
diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c
index e1e1e2f0854..23ba51bbe10 100644
--- a/source/blender/nodes/intern/node_socket.c
+++ b/source/blender/nodes/intern/node_socket.c
@@ -52,9 +52,9 @@ struct Main;
struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp, int in_out)
{
bNodeSocket *sock = nodeAddStaticSocket(ntree, node, in_out, stemp->type, stemp->subtype, stemp->identifier, stemp->name);
-
+
sock->flag |= stemp->flag;
-
+
/* initialize default_value */
switch (stemp->type) {
case SOCK_FLOAT:
@@ -99,14 +99,14 @@ struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree, struc
break;
}
}
-
+
return sock;
}
static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp)
{
bNodeSocket *sock;
-
+
for (sock = socklist->first; sock; sock = sock->next) {
if (STREQLEN(sock->name, stemp->name, NODE_MAXSTR))
break;
@@ -127,7 +127,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in
/* remove the new socket from the node socket list first,
* will be added back after verification. */
BLI_remlink(socklist, sock);
-
+
return sock;
}
@@ -135,7 +135,7 @@ static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_ou
{
bNodeSocket *sock, *nextsock;
bNodeSocketTemplate *stemp;
-
+
/* no inputs anymore? */
if (stemp_first == NULL) {
for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) {
@@ -155,7 +155,7 @@ static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_ou
nextsock = sock->next;
nodeRemoveSocket(ntree, node, sock);
}
-
+
/* and we put back the verified sockets */
stemp = stemp_first;
if (socklist->first) {
@@ -199,10 +199,10 @@ void node_socket_init_default_value(bNodeSocket *sock)
{
int type = sock->typeinfo->type;
int subtype = sock->typeinfo->subtype;
-
+
if (sock->default_value)
return; /* already initialized */
-
+
switch (type) {
case SOCK_FLOAT:
{
@@ -211,7 +211,7 @@ void node_socket_init_default_value(bNodeSocket *sock)
dval->value = 0.0f;
dval->min = -FLT_MAX;
dval->max = FLT_MAX;
-
+
sock->default_value = dval;
break;
}
@@ -222,7 +222,7 @@ void node_socket_init_default_value(bNodeSocket *sock)
dval->value = 0;
dval->min = INT_MIN;
dval->max = INT_MAX;
-
+
sock->default_value = dval;
break;
}
@@ -230,7 +230,7 @@ void node_socket_init_default_value(bNodeSocket *sock)
{
bNodeSocketValueBoolean *dval = MEM_callocN(sizeof(bNodeSocketValueBoolean), "node socket value bool");
dval->value = false;
-
+
sock->default_value = dval;
break;
}
@@ -242,7 +242,7 @@ void node_socket_init_default_value(bNodeSocket *sock)
copy_v3_v3(dval->value, default_value);
dval->min = -FLT_MAX;
dval->max = FLT_MAX;
-
+
sock->default_value = dval;
break;
}
@@ -251,7 +251,7 @@ void node_socket_init_default_value(bNodeSocket *sock)
static float default_value[] = { 0.0f, 0.0f, 0.0f, 1.0f };
bNodeSocketValueRGBA *dval = MEM_callocN(sizeof(bNodeSocketValueRGBA), "node socket value color");
copy_v4_v4(dval->value, default_value);
-
+
sock->default_value = dval;
break;
}
@@ -260,7 +260,7 @@ void node_socket_init_default_value(bNodeSocket *sock)
bNodeSocketValueString *dval = MEM_callocN(sizeof(bNodeSocketValueString), "node socket value string");
dval->subtype = subtype;
dval->value[0] = '\0';
-
+
sock->default_value = dval;
break;
}
@@ -272,12 +272,12 @@ void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from)
/* sanity check */
if (to->type != from->type)
return;
-
+
/* make sure both exist */
if (!from->default_value)
return;
node_socket_init_default_value(to);
-
+
switch (from->typeinfo->type) {
case SOCK_FLOAT:
{
@@ -330,7 +330,7 @@ static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree),
{
/* initialize the type value */
sock->type = sock->typeinfo->type;
-
+
/* XXX socket interface 'type' value is not used really,
* but has to match or the copy function will bail out
*/
@@ -345,12 +345,12 @@ static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree
/* sanity check */
if (sock->type != stemp->typeinfo->type)
return;
-
+
/* make sure both exist */
if (!stemp->default_value)
return;
node_socket_init_default_value(sock);
-
+
switch (stemp->typeinfo->type) {
case SOCK_FLOAT:
{
@@ -389,65 +389,65 @@ static void standard_node_socket_interface_from_socket(bNodeTree *UNUSED(ntree),
static bNodeSocketType *make_standard_socket_type(int type, int subtype)
{
extern void ED_init_standard_node_socket_type(bNodeSocketType *);
-
+
const char *socket_idname = nodeStaticSocketType(type, subtype);
const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype);
bNodeSocketType *stype;
StructRNA *srna;
-
+
stype = MEM_callocN(sizeof(bNodeSocketType), "node socket C type");
BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname));
-
+
/* set the RNA type
* uses the exact same identifier as the socket type idname */
srna = stype->ext_socket.srna = RNA_struct_find(socket_idname);
BLI_assert(srna != NULL);
/* associate the RNA type with the socket type */
RNA_struct_blender_type_set(srna, stype);
-
+
/* set the interface RNA type */
srna = stype->ext_interface.srna = RNA_struct_find(interface_idname);
BLI_assert(srna != NULL);
/* associate the RNA type with the socket type */
RNA_struct_blender_type_set(srna, stype);
-
+
/* extra type info for standard socket types */
stype->type = type;
stype->subtype = subtype;
-
+
/* XXX bad-level call! needed for setting draw callbacks */
ED_init_standard_node_socket_type(stype);
-
+
stype->interface_init_socket = standard_node_socket_interface_init_socket;
stype->interface_from_socket = standard_node_socket_interface_from_socket;
stype->interface_verify_socket = standard_node_socket_interface_verify_socket;
-
+
return stype;
}
static bNodeSocketType *make_socket_type_virtual(void)
{
extern void ED_init_node_socket_type_virtual(bNodeSocketType *);
-
+
const char *socket_idname = "NodeSocketVirtual";
bNodeSocketType *stype;
StructRNA *srna;
-
+
stype = MEM_callocN(sizeof(bNodeSocketType), "node socket C type");
BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname));
-
+
/* set the RNA type
* uses the exact same identifier as the socket type idname */
srna = stype->ext_socket.srna = RNA_struct_find(socket_idname);
BLI_assert(srna != NULL);
/* associate the RNA type with the socket type */
RNA_struct_blender_type_set(srna, stype);
-
+
/* extra type info for standard socket types */
stype->type = SOCK_CUSTOM;
-
+
ED_init_node_socket_type_virtual(stype);
-
+
return stype;
}
@@ -455,21 +455,21 @@ static bNodeSocketType *make_socket_type_virtual(void)
void register_standard_node_socket_types(void)
{
/* draw callbacks are set in drawnode.c to avoid bad-level calls */
-
+
nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_NONE));
nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_UNSIGNED));
nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_PERCENTAGE));
nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_FACTOR));
nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_ANGLE));
nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_TIME));
-
+
nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_NONE));
nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_UNSIGNED));
nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_PERCENTAGE));
nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_FACTOR));
-
+
nodeRegisterSocketType(make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE));
-
+
nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_NONE));
nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_TRANSLATION));
nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_DIRECTION));
@@ -477,12 +477,12 @@ void register_standard_node_socket_types(void)
nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_ACCELERATION));
nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_EULER));
nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_XYZ));
-
+
nodeRegisterSocketType(make_standard_socket_type(SOCK_RGBA, PROP_NONE));
-
+
nodeRegisterSocketType(make_standard_socket_type(SOCK_STRING, PROP_NONE));
-
+
nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE));
-
+
nodeRegisterSocketType(make_socket_type_virtual());
}
diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c
index 45409a2dfad..19529794c7c 100644
--- a/source/blender/nodes/intern/node_util.c
+++ b/source/blender/nodes/intern/node_util.c
@@ -165,10 +165,10 @@ static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
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 */
while (sock != cur) {
if (!nodeSocketIsHidden(sock) && node_link_socket_match(sock, cur)) {
@@ -177,7 +177,7 @@ static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, bNode *node, bNo
if (link_count + 1 <= sock->limit)
return sock; /* found a valid free socket we can swap to */
}
-
+
sock = sock->next ? sock->next : first; /* wrap around the list end */
}
return NULL;
@@ -187,18 +187,18 @@ 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;
-
+
for (tlink = ntree->links.first; tlink; tlink = tlink_next) {
bNodeSocket *new_sock;
tlink_next = tlink->next;
-
+
if (sock != tlink->tosock)
continue;
-
+
new_sock = node_find_linkable_socket(ntree, node, sock);
if (new_sock && new_sock != sock) {
/* redirect existing link */
@@ -287,12 +287,12 @@ static bNodeSocket *select_internal_link_input(bNode *node, bNodeSocket *output)
int i;
int sel_priority = -1;
bool sel_is_linked = false;
-
+
for (input = node->inputs.first, i = 0; input; input = input->next, ++i) {
int priority = node_datatype_priority(input->type, output->type);
bool is_linked = (input->link != NULL);
bool preferred;
-
+
if (nodeSocketIsHidden(input) || /* ignore hidden sockets */
input->flag & SOCK_NO_INTERNAL_LINK || /* ignore if input is not allowed for internal connections */
priority < 0 || /* ignore incompatible types */
@@ -300,18 +300,18 @@ static bNodeSocket *select_internal_link_input(bNode *node, bNodeSocket *output)
{
continue;
}
-
+
/* determine if this input is preferred over the currently selected */
preferred = (priority > sel_priority) || /* prefer higher datatype priority */
(is_linked && !sel_is_linked); /* prefer linked over unlinked */
-
+
if (preferred) {
selected = input;
sel_is_linked = is_linked;
sel_priority = priority;
}
}
-
+
return selected;
}
@@ -319,29 +319,29 @@ void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
{
bNodeLink *link;
bNodeSocket *output, *input;
-
+
/* sanity check */
if (!ntree)
return;
-
+
/* use link pointer as a tag for handled sockets (for outputs is unused anyway) */
for (output = node->outputs.first; output; output = output->next)
output->link = NULL;
-
+
for (link = ntree->links.first; link; link = link->next) {
if (nodeLinkIsHidden(link))
continue;
-
+
output = link->fromsock;
if (link->fromnode != node || output->link)
continue;
if (nodeSocketIsHidden(output) || output->flag & SOCK_NO_INTERNAL_LINK)
continue;
output->link = link; /* not really used, just for tagging handled sockets */
-
+
/* look for suitable input */
input = select_internal_link_input(node, output);
-
+
if (input) {
bNodeLink *ilink = MEM_callocN(sizeof(bNodeLink), "internal node link");
ilink->fromnode = node;
@@ -353,7 +353,7 @@ void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
BLI_addtail(&node->internal_links, ilink);
}
}
-
+
/* clean up */
for (output = node->outputs.first; output; output = output->next)
output->link = NULL;
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index a5d8031f2f3..fcb21982661 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -82,7 +82,7 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
-
+
if (snode->shaderfrom == SNODE_SHADER_OBJECT) {
if (ob) {
*r_from = &ob->id;
@@ -136,11 +136,11 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
{
bNode *node, *node_next;
-
+
/* replace muted nodes and reroute nodes by internal links */
for (node = localtree->nodes.first; node; node = node_next) {
node_next = node->next;
-
+
if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
nodeInternalRelink(localtree, node);
nodeFreeNode(localtree, node);
@@ -161,9 +161,9 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
static void update(bNodeTree *ntree)
{
ntreeSetOutput(ntree);
-
+
ntree_update_reroute_nodes(ntree);
-
+
if (ntree->update & NTREE_UPDATE_NODES) {
/* clean up preview cache, in case nodes have been removed */
BKE_node_preview_remove_unused(ntree);
@@ -175,13 +175,13 @@ bNodeTreeType *ntreeType_Shader;
void register_node_tree_type_sh(void)
{
bNodeTreeType *tt = ntreeType_Shader = MEM_callocN(sizeof(bNodeTreeType), "shader node tree type");
-
+
tt->type = NTREE_SHADER;
strcpy(tt->idname, "ShaderNodeTree");
strcpy(tt->ui_name, "Shader Editor");
tt->ui_icon = 0; /* defined in drawnode.c */
strcpy(tt->ui_description, "Shader nodes");
-
+
tt->foreach_nodeclass = foreach_nodeclass;
tt->localize = localize;
tt->local_sync = local_sync;
@@ -189,9 +189,9 @@ void register_node_tree_type_sh(void)
tt->update = update;
tt->poll = shader_tree_poll;
tt->get_from_context = shader_get_from_context;
-
+
tt->ext.srna = &RNA_ShaderNodeTree;
-
+
ntreeTypeAdd(tt);
}
@@ -622,19 +622,19 @@ bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context, bNod
{
bNodeTreeExec *exec;
bNode *node;
-
+
/* ensures only a single output node is enabled */
ntreeSetOutput(ntree);
-
+
/* common base initialization */
exec = ntree_exec_begin(context, ntree, parent_key);
-
+
/* allocate the thread stack listbase array */
exec->threadstack = MEM_callocN(BLENDER_MAX_THREADS * sizeof(ListBase), "thread stack array");
-
+
for (node = exec->nodetree->nodes.first; node; node = node->next)
node->need_exec = 1;
-
+
return exec;
}
@@ -642,22 +642,22 @@ bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree)
{
bNodeExecContext context;
bNodeTreeExec *exec;
-
+
/* XXX hack: prevent exec data from being generated twice.
* this should be handled by the renderer!
*/
if (ntree->execdata)
return ntree->execdata;
-
+
context.previews = ntree->previews;
-
+
exec = ntreeShaderBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
-
+
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
* which only store the ntree pointer. Should be fixed at some point!
*/
ntree->execdata = exec;
-
+
return exec;
}
@@ -665,18 +665,18 @@ void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
{
bNodeThreadStack *nts;
int a;
-
+
if (exec->threadstack) {
for (a = 0; a < BLENDER_MAX_THREADS; a++) {
for (nts = exec->threadstack[a].first; nts; nts = nts->next)
if (nts->stack) MEM_freeN(nts->stack);
BLI_freelistN(&exec->threadstack[a]);
}
-
+
MEM_freeN(exec->threadstack);
exec->threadstack = NULL;
}
-
+
ntree_exec_end(exec);
}
@@ -686,7 +686,7 @@ void ntreeShaderEndExecTree(bNodeTreeExec *exec)
/* exec may get freed, so assign ntree */
bNodeTree *ntree = exec->nodetree;
ntreeShaderEndExecTree_internal(exec);
-
+
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
ntree->execdata = NULL;
}
@@ -699,7 +699,7 @@ bool ntreeShaderExecTree(bNodeTree *ntree, int thread)
bNodeThreadStack *nts = NULL;
bNodeTreeExec *exec = ntree->execdata;
int compat;
-
+
/* ensure execdata is only initialized once */
if (!exec) {
BLI_thread_lock(LOCK_NODES);
@@ -709,11 +709,11 @@ bool ntreeShaderExecTree(bNodeTree *ntree, int thread)
exec = ntree->execdata;
}
-
+
nts = ntreeGetThreadStack(exec, thread);
compat = ntreeExecThreadNodes(exec, nts, &scd, thread);
ntreeReleaseThreadStack(nts);
-
+
/* if compat is zero, it has been using non-compatible nodes */
return compat;
}
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 43e940d6d0a..a4b2c155675 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -45,7 +45,7 @@ int sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
{
node_type_base(ntype, type, name, nclass, flag);
-
+
ntype->poll = sh_node_poll_default;
ntype->insert_link = node_insert_link_default;
ntype->update_internal_links = node_update_internal_links_default;
@@ -56,11 +56,11 @@ void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, shor
void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
{
const float *from = ns->vec;
-
+
if (type_in == SOCK_FLOAT) {
if (ns->sockettype == SOCK_FLOAT)
*in = *from;
- else
+ else
*in = (from[0] + from[1] + from[2]) / 3.0f;
}
else if (type_in == SOCK_VECTOR) {
@@ -94,7 +94,7 @@ void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
{
memset(gs, 0, sizeof(*gs));
-
+
if (ns == NULL) {
/* node_get_stack() will generate NULL bNodeStack pointers for unknown/unsuported types of sockets... */
zero_v4(gs->vec);
@@ -107,7 +107,7 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
else {
nodestack_get_vec(gs->vec, type, ns);
gs->link = ns->data;
-
+
if (type == SOCK_FLOAT)
gs->type = GPU_FLOAT;
else if (type == SOCK_VECTOR)
@@ -140,10 +140,10 @@ static void gpu_stack_from_data_list(GPUNodeStack *gs, ListBase *sockets, bNodeS
{
bNodeSocket *sock;
int i;
-
+
for (sock = sockets->first, i = 0; sock; sock = sock->next, i++)
node_gpu_stack_from_data(&gs[i], sock->type, ns[i]);
-
+
gs[i].end = true;
}
@@ -192,7 +192,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
if (activetexnode)
return activetexnode;
-
+
if (hasgroup) {
/* node active texture node in this tree, look inside groups */
for (node = ntree->nodes.first; node; node = node->next) {
@@ -203,7 +203,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
}
}
}
-
+
return inactivenode;
}
@@ -222,7 +222,7 @@ void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs, sh
for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
node = nodeexec->node;
-
+
do_it = false;
/* for groups, only execute outputs for edited group */
if (node->typeinfo->nclass == NODE_CLASS_OUTPUT) {
diff --git a/source/blender/nodes/shader/nodes/node_shader_brightness.c b/source/blender/nodes/shader/nodes/node_shader_brightness.c
index d795575c86a..bb95ed2d32c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_brightness.c
+++ b/source/blender/nodes/shader/nodes/node_shader_brightness.c
@@ -50,13 +50,13 @@ static int gpu_shader_brightcontrast(GPUMaterial *mat, bNode *node, bNodeExecDat
void register_node_type_sh_brightcontrast(void)
{
static bNodeType ntype;
-
+
sh_node_type_base(&ntype, SH_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, 0);
node_type_compatibility(&ntype, NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_brightcontrast_in, sh_node_brightcontrast_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, gpu_shader_brightcontrast);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c
index 6098aefc5e1..6274d132bc7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bump.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bump.c
@@ -31,7 +31,7 @@
#include "node_shader_util.h"
-/* **************** BUMP ******************** */
+/* **************** BUMP ******************** */
static bNodeSocketTemplate sh_node_bump_in[] = {
{ SOCK_FLOAT, 1, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_FLOAT, 1, N_("Distance"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
diff --git a/source/blender/nodes/shader/nodes/node_shader_common.c b/source/blender/nodes/shader/nodes/node_shader_common.c
index 134319cb352..24de03dbda4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_common.c
+++ b/source/blender/nodes/shader/nodes/node_shader_common.c
@@ -50,7 +50,7 @@ static void copy_stack(bNodeStack *to, bNodeStack *from)
copy_v4_v4(to->vec, from->vec);
to->data = from->data;
to->datatype = from->datatype;
-
+
/* tag as copy to prevent freeing */
to->is_copy = 1;
}
@@ -63,7 +63,7 @@ static void move_stack(bNodeStack *to, bNodeStack *from)
to->data = from->data;
to->datatype = from->datatype;
to->is_copy = from->is_copy;
-
+
from->data = NULL;
from->is_copy = 0;
}
@@ -75,20 +75,20 @@ static void *group_initexec(bNodeExecContext *context, bNode *node, bNodeInstanc
{
bNodeTree *ngroup = (bNodeTree *)node->id;
bNodeTreeExec *exec;
-
+
if (!ngroup)
return NULL;
-
+
/* initialize the internal node tree execution */
exec = ntreeShaderBeginExecTree_internal(context, ngroup, key);
-
+
return exec;
}
static void group_freeexec(void *nodedata)
{
bNodeTreeExec *gexec = (bNodeTreeExec *)nodedata;
-
+
if (gexec)
ntreeShaderEndExecTree_internal(gexec);
}
@@ -102,7 +102,7 @@ static void group_copy_inputs(bNode *gnode, bNodeStack **in, bNodeStack *gstack)
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_INPUT) {
for (sock = node->outputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -123,7 +123,7 @@ static void group_move_outputs(bNode *gnode, bNodeStack **out, bNodeStack *gstac
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT)) {
for (sock = node->inputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -140,10 +140,10 @@ static void group_execute(void *data, int thread, struct bNode *node, bNodeExecD
{
bNodeTreeExec *exec = execdata->data;
bNodeThreadStack *nts;
-
+
if (!exec)
return;
-
+
/* XXX same behavior as trunk: all nodes inside group are executed.
* it's stupid, but just makes it work. compo redesign will do this better.
*/
@@ -152,13 +152,13 @@ static void group_execute(void *data, int thread, struct bNode *node, bNodeExecD
for (inode = exec->nodetree->nodes.first; inode; inode = inode->next)
inode->need_exec = 1;
}
-
+
nts = ntreeGetThreadStack(exec, thread);
-
+
group_copy_inputs(node, in, nts->stack);
ntreeExecThreadNodes(exec, nts, data, thread);
group_move_outputs(node, out, nts->stack);
-
+
ntreeReleaseThreadStack(nts);
}
@@ -169,7 +169,7 @@ static void group_gpu_copy_inputs(bNode *gnode, GPUNodeStack *in, bNodeStack *gs
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_INPUT) {
for (sock = node->outputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -192,7 +192,7 @@ static void group_gpu_move_outputs(bNode *gnode, GPUNodeStack *out, bNodeStack *
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT)) {
for (sock = node->inputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -210,10 +210,10 @@ static void group_gpu_move_outputs(bNode *gnode, GPUNodeStack *out, bNodeStack *
static int gpu_group_execute(GPUMaterial *mat, bNode *node, bNodeExecData *execdata, GPUNodeStack *in, GPUNodeStack *out)
{
bNodeTreeExec *exec = execdata->data;
-
+
if (!node->id)
return 0;
-
+
group_gpu_copy_inputs(node, in, exec->stack);
#if 0 /* XXX NODE_GROUP_EDIT is deprecated, depends on node space */
ntreeExecGPUNodes(exec, mat, (node->flag & NODE_GROUP_EDIT));
@@ -221,14 +221,14 @@ static int gpu_group_execute(GPUMaterial *mat, bNode *node, bNodeExecData *execd
ntreeExecGPUNodes(exec, mat, 0, NODE_NEW_SHADING | NODE_OLD_SHADING);
#endif
group_gpu_move_outputs(node, out, exec->stack);
-
+
return 1;
}
void register_node_type_sh_group(void)
{
static bNodeType ntype;
-
+
/* NB: cannot use sh_node_type_base for node group, because it would map the node type
* to the shared NODE_GROUP integer type id.
*/
@@ -241,7 +241,7 @@ void register_node_type_sh_group(void)
ntype.ext.srna = RNA_struct_find("ShaderNodeGroup");
BLI_assert(ntype.ext.srna != NULL);
RNA_struct_blender_type_set(ntype.ext.srna, &ntype);
-
+
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, NULL, NULL);
node_type_size(&ntype, 140, 60, 400);
@@ -249,6 +249,6 @@ void register_node_type_sh_group(void)
node_type_update(&ntype, NULL, node_group_verify);
node_type_exec(&ntype, group_initexec, group_freeexec, group_execute);
node_type_gpu(&ntype, gpu_group_execute);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 5dfeb883915..4f3dc92ad02 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -48,7 +48,7 @@ static bNodeSocketTemplate sh_node_curve_vec_out[] = {
static void node_shader_exec_curve_vec(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float vec[3];
-
+
/* stack order input: vec */
/* stack order output: vec */
nodestack_get_vec(vec, SOCK_VECTOR, in[1]);
@@ -102,7 +102,7 @@ static void node_shader_exec_curve_rgb(void *UNUSED(data), int UNUSED(thread), b
{
float vec[3];
float fac;
-
+
/* stack order input: vec */
/* stack order output: vec */
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.c
index 599d0533c27..072abed6c16 100644
--- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c
+++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.c
@@ -47,7 +47,7 @@ static int node_shader_gpu_fresnel(GPUMaterial *mat, bNode *node, bNodeExecData
else {
GPU_link(mat, "direction_transform_m4v3", in[1].link, GPU_builtin(GPU_VIEW_MATRIX), &in[1].link);
}
-
+
return GPU_stack_link(mat, node, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_POSITION));
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.c b/source/blender/nodes/shader/nodes/node_shader_gamma.c
index 2aedba58f2c..e536d198ed0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_gamma.c
+++ b/source/blender/nodes/shader/nodes/node_shader_gamma.c
@@ -60,7 +60,7 @@ static int node_shader_gpu_gamma(GPUMaterial *mat, bNode *node, bNodeExecData *U
void register_node_type_sh_gamma(void)
{
static bNodeType ntype;
-
+
sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_gamma_in, sh_node_gamma_out);
@@ -68,6 +68,6 @@ void register_node_type_sh_gamma(void)
node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_gamma);
node_type_gpu(&ntype, node_shader_gpu_gamma);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c
new file mode 100644
index 00000000000..0a51ee8dc68
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_geom.c
@@ -0,0 +1,163 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_geom.c
+ * \ingroup shdnodes
+ */
+
+
+#include "node_shader_util.h"
+
+#include "DNA_customdata_types.h"
+
+/* **************** GEOMETRY ******************** */
+
+/* output socket type definition */
+static bNodeSocketTemplate sh_node_geom_out[] = {
+ { SOCK_VECTOR, 0, N_("Global")},
+ { SOCK_VECTOR, 0, N_("Local")},
+ { SOCK_VECTOR, 0, N_("View")},
+ { SOCK_VECTOR, 0, N_("Orco")},
+ { SOCK_VECTOR, 0, N_("UV")},
+ { SOCK_VECTOR, 0, N_("Normal")},
+ { SOCK_RGBA, 0, N_("Vertex Color")},
+ { SOCK_FLOAT, 0, N_("Vertex Alpha")},
+ { SOCK_FLOAT, 0, N_("Front/Back")},
+ { -1, 0, "" }
+};
+
+/* node execute callback */
+static void node_shader_exec_geom(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out)
+{
+ if (data) {
+ ShadeInput *shi = ((ShaderCallData *)data)->shi;
+ NodeGeometry *ngeo = (NodeGeometry *)node->storage;
+ ShadeInputUV *suv = &shi->uv[shi->actuv];
+ static float defaultvcol[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ int i;
+
+ if (ngeo->uvname[0]) {
+ /* find uv map by name */
+ for (i = 0; i < shi->totuv; i++) {
+ if (STREQ(shi->uv[i].name, ngeo->uvname)) {
+ suv = &shi->uv[i];
+ break;
+ }
+ }
+ }
+
+ /* out: global, local, view, orco, uv, normal, vertex color */
+ copy_v3_v3(out[GEOM_OUT_GLOB]->vec, shi->gl);
+ copy_v3_v3(out[GEOM_OUT_LOCAL]->vec, shi->co);
+ copy_v3_v3(out[GEOM_OUT_VIEW]->vec, shi->view);
+ copy_v3_v3(out[GEOM_OUT_ORCO]->vec, shi->lo);
+ copy_v3_v3(out[GEOM_OUT_UV]->vec, suv->uv);
+ copy_v3_v3(out[GEOM_OUT_NORMAL]->vec, shi->vno);
+
+ if (shi->use_world_space_shading) {
+ negate_v3(out[GEOM_OUT_NORMAL]->vec);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[GEOM_OUT_NORMAL]->vec);
+ }
+ if (shi->totcol) {
+ /* find vertex color layer by name */
+ ShadeInputCol *scol = &shi->col[0];
+
+ if (ngeo->colname[0]) {
+ for (i = 0; i < shi->totcol; i++) {
+ if (STREQ(shi->col[i].name, ngeo->colname)) {
+ scol = &shi->col[i];
+ break;
+ }
+ }
+ }
+
+ srgb_to_linearrgb_v3_v3(out[GEOM_OUT_VCOL]->vec, scol->col);
+ out[GEOM_OUT_VCOL]->vec[3] = scol->col[3];
+ out[GEOM_OUT_VCOL_ALPHA]->vec[0] = scol->col[3];
+ }
+ else {
+ memcpy(out[GEOM_OUT_VCOL]->vec, defaultvcol, sizeof(defaultvcol));
+ out[GEOM_OUT_VCOL_ALPHA]->vec[0] = 1.0f;
+ }
+
+ if (shi->osatex) {
+ out[GEOM_OUT_GLOB]->data = shi->dxgl;
+ out[GEOM_OUT_GLOB]->datatype = NS_OSA_VECTORS;
+ out[GEOM_OUT_LOCAL]->data = shi->dxco;
+ out[GEOM_OUT_LOCAL]->datatype = NS_OSA_VECTORS;
+ out[GEOM_OUT_VIEW]->data = &shi->dxview;
+ out[GEOM_OUT_VIEW]->datatype = NS_OSA_VALUES;
+ out[GEOM_OUT_ORCO]->data = shi->dxlo;
+ out[GEOM_OUT_ORCO]->datatype = NS_OSA_VECTORS;
+ out[GEOM_OUT_UV]->data = suv->dxuv;
+ out[GEOM_OUT_UV]->datatype = NS_OSA_VECTORS;
+ out[GEOM_OUT_NORMAL]->data = shi->dxno;
+ out[GEOM_OUT_NORMAL]->datatype = NS_OSA_VECTORS;
+ }
+
+ /* front/back, normal flipping was stored */
+ out[GEOM_OUT_FRONTBACK]->vec[0] = (shi->flippednor) ? 0.0f : 1.0f;
+ }
+}
+
+static void node_shader_init_geometry(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->storage = MEM_callocN(sizeof(NodeGeometry), "NodeGeometry");
+}
+
+static int gpu_shader_geom(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ NodeGeometry *ngeo = (NodeGeometry *)node->storage;
+ GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
+ GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, ngeo->uvname);
+ GPUNodeLink *mcol = GPU_attribute(CD_MCOL, ngeo->colname);
+
+ bool ret = GPU_stack_link(mat, "geom", in, out,
+ GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), orco, mtface, mcol);
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", out[5].link, &out[5].link);
+ ret &= GPU_link(mat, "direction_transform_m4v3", out[5].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[5].link);
+ }
+ return ret;
+}
+
+/* node type definition */
+void register_node_type_sh_geom(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_GEOMETRY, "Geometry", NODE_CLASS_INPUT, 0);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, NULL, sh_node_geom_out);
+ node_type_init(&ntype, node_shader_init_geometry);
+ node_type_storage(&ntype, "NodeGeometry", node_free_standard_storage, node_copy_standard_storage);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_geom);
+ node_type_gpu(&ntype, gpu_shader_geom);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
index 0e82c962f53..07f1e9e3233 100644
--- a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
+++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
@@ -52,7 +52,7 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat
{
if (fac != 0.0f && (hue != 0.5f || sat != 1.0f || val != 1.0f)) {
float col[3], hsv[3], mfac = 1.0f - fac;
-
+
rgb_to_hsv(in[0], in[1], in[2], hsv, hsv + 1, hsv + 2);
hsv[0] += (hue - 0.5f);
if (hsv[0] > 1.0f) hsv[0] -= 1.0f; else if (hsv[0] < 0.0f) hsv[0] += 1.0f;
diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.c b/source/blender/nodes/shader/nodes/node_shader_invert.c
index c5765ae492b..b1805946f65 100644
--- a/source/blender/nodes/shader/nodes/node_shader_invert.c
+++ b/source/blender/nodes/shader/nodes/node_shader_invert.c
@@ -34,7 +34,7 @@
-/* **************** INVERT ******************** */
+/* **************** INVERT ******************** */
static bNodeSocketTemplate sh_node_invert_in[] = {
{ SOCK_FLOAT, 1, N_("Fac"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
@@ -46,18 +46,18 @@ static bNodeSocketTemplate sh_node_invert_out[] = {
{ -1, 0, "" }
};
-static void node_shader_exec_invert(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in,
+static void node_shader_exec_invert(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in,
bNodeStack **out)
{
float col[3], icol[3], fac;
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
nodestack_get_vec(col, SOCK_VECTOR, in[1]);
-
+
icol[0] = 1.0f - col[0];
icol[1] = 1.0f - col[1];
icol[2] = 1.0f - col[2];
-
+
/* if fac, blend result against original input */
if (fac < 1.0f)
interp_v3_v3v3(out[0]->vec, col, icol, fac);
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
index 42d957977e3..fdbf23618ef 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c
@@ -56,7 +56,7 @@ static void node_shader_exec_mapping(void *UNUSED(data), int UNUSED(thread), bNo
{
TexMapping *texmap = node->storage;
float *vec = out[0]->vec;
-
+
/* stack order input: vector */
/* stack order output: vector */
nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
@@ -105,7 +105,7 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS
void register_node_type_sh_mapping(void)
{
static bNodeType ntype;
-
+
sh_node_type_base(&ntype, SH_NODE_MAPPING, "Mapping", NODE_CLASS_OP_VECTOR, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_mapping_in, sh_node_mapping_out);
@@ -114,6 +114,6 @@ void register_node_type_sh_mapping(void)
node_type_storage(&ntype, "TexMapping", node_free_standard_storage, node_copy_standard_storage);
node_type_exec(&ntype, node_shader_initexec_mapping, NULL, node_shader_exec_mapping);
node_type_gpu(&ntype, gpu_shader_mapping);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c
new file mode 100644
index 00000000000..8a73ddc1194
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_material.c
@@ -0,0 +1,374 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_material.c
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.h"
+
+/* **************** MATERIAL ******************** */
+
+static bNodeSocketTemplate sh_node_material_in[] = {
+ { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, N_("Spec"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("DiffuseIntensity"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_material_out[] = {
+ { SOCK_RGBA, 0, N_("Color")},
+ { SOCK_FLOAT, 0, N_("Alpha")},
+ { SOCK_VECTOR, 0, N_("Normal")},
+ { -1, 0, "" }
+};
+
+/* **************** EXTENDED MATERIAL ******************** */
+
+static bNodeSocketTemplate sh_node_material_ext_in[] = {
+ { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, N_("Spec"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("DiffuseIntensity"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION},
+ { SOCK_RGBA, 1, N_("Mirror"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Ambient"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("Emit"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
+ { SOCK_FLOAT, 1, N_("SpecTra"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("Reflectivity"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("Alpha"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
+ { SOCK_FLOAT, 1, N_("Translucency"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_material_ext_out[] = {
+ { SOCK_RGBA, 0, N_("Color")},
+ { SOCK_FLOAT, 0, N_("Alpha")},
+ { SOCK_VECTOR, 0, N_("Normal")},
+ { SOCK_RGBA, 0, N_("Diffuse")},
+ { SOCK_RGBA, 0, N_("Spec")},
+ { SOCK_RGBA, 0, N_("AO")},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_material(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+{
+ if (data && node->id) {
+ ShadeResult shrnode;
+ ShadeInput *shi;
+ ShaderCallData *shcd = data;
+ float col[4];
+ bNodeSocket *sock;
+ char hasinput[NUM_MAT_IN] = {'\0'};
+ int i, mode;
+
+ /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily
+ * the constant input stack values (e.g. in case material node is inside a group).
+ * we just want to know if a node input uses external data or the material setting.
+ * this is an ugly hack, but so is this node as a whole.
+ */
+ for (sock = node->inputs.first, i = 0; sock; sock = sock->next, ++i)
+ hasinput[i] = (sock->link != NULL);
+
+ shi = shcd->shi;
+ shi->mat = (Material *)node->id;
+
+ /* copy all relevant material vars, note, keep this synced with render_types.h */
+ memcpy(&shi->r, &shi->mat->r, 23 * sizeof(float));
+ shi->har = shi->mat->har;
+
+ /* write values */
+ if (hasinput[MAT_IN_COLOR])
+ nodestack_get_vec(&shi->r, SOCK_VECTOR, in[MAT_IN_COLOR]);
+
+ if (hasinput[MAT_IN_SPEC])
+ nodestack_get_vec(&shi->specr, SOCK_VECTOR, in[MAT_IN_SPEC]);
+
+ if (hasinput[MAT_IN_REFL])
+ nodestack_get_vec(&shi->refl, SOCK_FLOAT, in[MAT_IN_REFL]);
+
+ /* retrieve normal */
+ if (hasinput[MAT_IN_NORMAL]) {
+ nodestack_get_vec(shi->vn, SOCK_VECTOR, in[MAT_IN_NORMAL]);
+ if (shi->use_world_space_shading) {
+ negate_v3(shi->vn);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), shi->vn);
+ }
+ normalize_v3(shi->vn);
+ }
+ else
+ copy_v3_v3(shi->vn, shi->vno);
+
+ /* custom option to flip normal */
+ if (node->custom1 & SH_NODE_MAT_NEG) {
+ negate_v3(shi->vn);
+ }
+
+ if (node->type == SH_NODE_MATERIAL_EXT) {
+ if (hasinput[MAT_IN_MIR])
+ nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]);
+ if (hasinput[MAT_IN_AMB])
+ nodestack_get_vec(&shi->amb, SOCK_FLOAT, in[MAT_IN_AMB]);
+ if (hasinput[MAT_IN_EMIT])
+ nodestack_get_vec(&shi->emit, SOCK_FLOAT, in[MAT_IN_EMIT]);
+ if (hasinput[MAT_IN_SPECTRA])
+ nodestack_get_vec(&shi->spectra, SOCK_FLOAT, in[MAT_IN_SPECTRA]);
+ if (hasinput[MAT_IN_RAY_MIRROR])
+ nodestack_get_vec(&shi->ray_mirror, SOCK_FLOAT, in[MAT_IN_RAY_MIRROR]);
+ if (hasinput[MAT_IN_ALPHA])
+ nodestack_get_vec(&shi->alpha, SOCK_FLOAT, in[MAT_IN_ALPHA]);
+ if (hasinput[MAT_IN_TRANSLUCENCY])
+ nodestack_get_vec(&shi->translucency, SOCK_FLOAT, in[MAT_IN_TRANSLUCENCY]);
+ }
+
+ /* make alpha output give results even if transparency is only enabled on
+ * the material linked in this not and not on the parent material */
+ mode = shi->mode;
+ if (shi->mat->mode & MA_TRANSP)
+ shi->mode |= MA_TRANSP;
+
+ shi->nodes = 1; /* temp hack to prevent trashadow recursion */
+ node_shader_lamp_loop(shi, &shrnode); /* clears shrnode */
+ shi->nodes = 0;
+
+ shi->mode = mode;
+
+ /* write to outputs */
+ if (node->custom1 & SH_NODE_MAT_DIFF) {
+ copy_v3_v3(col, shrnode.combined);
+ if (!(node->custom1 & SH_NODE_MAT_SPEC)) {
+ sub_v3_v3(col, shrnode.spec);
+ }
+ }
+ else if (node->custom1 & SH_NODE_MAT_SPEC) {
+ copy_v3_v3(col, shrnode.spec);
+ }
+ else
+ col[0] = col[1] = col[2] = 0.0f;
+
+ col[3] = shrnode.alpha;
+
+ if (shi->do_preview)
+ BKE_node_preview_set_pixel(execdata->preview, col, shi->xs, shi->ys, shi->do_manage);
+
+ copy_v3_v3(out[MAT_OUT_COLOR]->vec, col);
+ out[MAT_OUT_ALPHA]->vec[0] = shrnode.alpha;
+
+ if (node->custom1 & SH_NODE_MAT_NEG) {
+ shi->vn[0] = -shi->vn[0];
+ shi->vn[1] = -shi->vn[1];
+ shi->vn[2] = -shi->vn[2];
+ }
+
+ copy_v3_v3(out[MAT_OUT_NORMAL]->vec, shi->vn);
+
+ if (shi->use_world_space_shading) {
+ negate_v3(out[MAT_OUT_NORMAL]->vec);
+ mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), out[MAT_OUT_NORMAL]->vec);
+ }
+ /* Extended material options */
+ if (node->type == SH_NODE_MATERIAL_EXT) {
+ /* Shadow, Reflect, Refract, Radiosity, Speed seem to cause problems inside
+ * a node tree :( */
+ copy_v3_v3(out[MAT_OUT_DIFFUSE]->vec, shrnode.diffshad);
+ copy_v3_v3(out[MAT_OUT_SPEC]->vec, shrnode.spec);
+ copy_v3_v3(out[MAT_OUT_AO]->vec, shrnode.ao);
+ }
+
+ /* copy passes, now just active node */
+ if (node->flag & NODE_ACTIVE_ID) {
+ float combined[4], alpha;
+
+ copy_v4_v4(combined, shcd->shr->combined);
+ alpha = shcd->shr->alpha;
+
+ *(shcd->shr) = shrnode;
+
+ copy_v4_v4(shcd->shr->combined, combined);
+ shcd->shr->alpha = alpha;
+ }
+ }
+}
+
+
+static void node_shader_init_material(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SH_NODE_MAT_DIFF | SH_NODE_MAT_SPEC;
+}
+
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUMaterial *mat, GPUNodeStack *in)
+{
+ if (in->link) {
+ return in->link;
+ }
+ else {
+ GPUNodeLink *result = NULL;
+
+ /* note GPU_uniform() is only intended to be used as a parameter to
+ * GPU_link(), returning it directly results in leaks or double frees */
+ if (in->type == GPU_FLOAT)
+ GPU_link(mat, "set_value", GPU_uniform(in->vec), &result);
+ else if (in->type == GPU_VEC3)
+ GPU_link(mat, "set_rgb", GPU_uniform(in->vec), &result);
+ else if (in->type == GPU_VEC4)
+ GPU_link(mat, "set_rgba", GPU_uniform(in->vec), &result);
+ else
+ BLI_assert(0);
+
+ return result;
+ }
+}
+
+static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ if (node->id) {
+ GPUShadeInput shi;
+ GPUShadeResult shr;
+ bNodeSocket *sock;
+ char hasinput[NUM_MAT_IN] = {'\0'};
+ int i;
+
+ /* note: cannot use the in[]->hasinput flags directly, as these are not necessarily
+ * the constant input stack values (e.g. in case material node is inside a group).
+ * we just want to know if a node input uses external data or the material setting.
+ */
+ for (sock = node->inputs.first, i = 0; sock; sock = sock->next, ++i)
+ hasinput[i] = (sock->link != NULL);
+
+ GPU_shadeinput_set(mat, (Material *)node->id, &shi);
+
+ /* write values */
+ if (hasinput[MAT_IN_COLOR])
+ shi.rgb = gpu_get_input_link(mat, &in[MAT_IN_COLOR]);
+
+ if (hasinput[MAT_IN_SPEC])
+ shi.specrgb = gpu_get_input_link(mat, &in[MAT_IN_SPEC]);
+
+ if (hasinput[MAT_IN_REFL])
+ shi.refl = gpu_get_input_link(mat, &in[MAT_IN_REFL]);
+
+ /* retrieve normal */
+ if (hasinput[MAT_IN_NORMAL]) {
+ GPUNodeLink *tmp;
+ shi.vn = gpu_get_input_link(mat, &in[MAT_IN_NORMAL]);
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
+ GPU_link(mat, "direction_transform_m4v3", shi.vn, GPU_builtin(GPU_VIEW_MATRIX), &shi.vn);
+ }
+ GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp);
+ }
+
+ /* custom option to flip normal */
+ if (node->custom1 & SH_NODE_MAT_NEG)
+ GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
+
+ if (node->type == SH_NODE_MATERIAL_EXT) {
+ if (hasinput[MAT_IN_MIR])
+ shi.mir = gpu_get_input_link(mat, &in[MAT_IN_MIR]);
+ if (hasinput[MAT_IN_AMB])
+ shi.amb = gpu_get_input_link(mat, &in[MAT_IN_AMB]);
+ if (hasinput[MAT_IN_EMIT])
+ shi.emit = gpu_get_input_link(mat, &in[MAT_IN_EMIT]);
+ if (hasinput[MAT_IN_SPECTRA])
+ shi.spectra = gpu_get_input_link(mat, &in[MAT_IN_SPECTRA]);
+ if (hasinput[MAT_IN_ALPHA])
+ shi.alpha = gpu_get_input_link(mat, &in[MAT_IN_ALPHA]);
+ }
+
+ GPU_shaderesult_set(&shi, &shr); /* clears shr */
+
+ /* write to outputs */
+ if (node->custom1 & SH_NODE_MAT_DIFF) {
+ out[MAT_OUT_COLOR].link = shr.combined;
+
+ if (!(node->custom1 & SH_NODE_MAT_SPEC)) {
+ GPUNodeLink *link;
+ GPU_link(mat, "vec_math_sub", shr.combined, shr.spec, &out[MAT_OUT_COLOR].link, &link);
+ }
+ }
+ else if (node->custom1 & SH_NODE_MAT_SPEC) {
+ out[MAT_OUT_COLOR].link = shr.spec;
+ }
+ else
+ GPU_link(mat, "set_rgb_zero", &out[MAT_OUT_COLOR].link);
+
+ GPU_link(mat, "mtex_alpha_to_col", out[MAT_OUT_COLOR].link, shr.alpha, &out[MAT_OUT_COLOR].link);
+
+ out[MAT_OUT_ALPHA].link = shr.alpha; //
+
+ if (node->custom1 & SH_NODE_MAT_NEG)
+ GPU_link(mat, "vec_math_negate", shi.vn, &shi.vn);
+ out[MAT_OUT_NORMAL].link = shi.vn;
+ if (GPU_material_use_world_space_shading(mat)) {
+ GPU_link(mat, "vec_math_negate", out[MAT_OUT_NORMAL].link, &out[MAT_OUT_NORMAL].link);
+ GPU_link(mat, "direction_transform_m4v3", out[MAT_OUT_NORMAL].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[MAT_OUT_NORMAL].link);
+ }
+
+ if (node->type == SH_NODE_MATERIAL_EXT) {
+ out[MAT_OUT_DIFFUSE].link = shr.diff;
+ out[MAT_OUT_SPEC].link = shr.spec;
+ GPU_link(mat, "set_rgb_one", &out[MAT_OUT_AO].link);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void register_node_type_sh_material(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_MATERIAL, "Material", NODE_CLASS_INPUT, NODE_PREVIEW);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, sh_node_material_in, sh_node_material_out);
+ node_type_init(&ntype, node_shader_init_material);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_material);
+ node_type_gpu(&ntype, gpu_shader_material);
+
+ nodeRegisterType(&ntype);
+}
+
+
+void register_node_type_sh_material_ext(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_MATERIAL_EXT, "Extended Material", NODE_CLASS_INPUT, NODE_PREVIEW);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, sh_node_material_ext_in, sh_node_material_ext_out);
+ node_type_init(&ntype, node_shader_init_material);
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_material);
+ node_type_gpu(&ntype, gpu_shader_material);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index 2be70b66b36..bf594325119 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -33,7 +33,7 @@
#include "node_shader_util.h"
-/* **************** SCALAR MATH ******************** */
+/* **************** SCALAR MATH ******************** */
static bNodeSocketTemplate sh_node_math_in[] = {
{ SOCK_FLOAT, 1, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
{ SOCK_FLOAT, 1, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
@@ -45,15 +45,15 @@ static bNodeSocketTemplate sh_node_math_out[] = {
{ -1, 0, "" }
};
-static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
+static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float a, b, r = 0.0f;
-
+
nodestack_get_vec(&a, SOCK_FLOAT, in[0]);
nodestack_get_vec(&b, SOCK_FLOAT, in[1]);
-
+
switch (node->custom1) {
-
+
case NODE_MATH_ADD:
r = a + b;
break;
@@ -147,7 +147,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
}
else {
float y_mod_1 = fabsf(fmodf(b, 1.0f));
-
+
/* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */
if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
r = powf(a, floorf(b + 0.5f));
diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
index 37ec4d46226..054b02b220d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
@@ -54,7 +54,7 @@ static void node_shader_exec_mix_rgb(void *UNUSED(data), int UNUSED(thread), bNo
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
CLAMP(fac, 0.0f, 1.0f);
-
+
nodestack_get_vec(col, SOCK_VECTOR, in[1]);
nodestack_get_vec(vec, SOCK_VECTOR, in[2]);
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.c
index 4bca5add106..265f6ac6fab 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal.c
@@ -48,12 +48,12 @@ static bNodeSocketTemplate sh_node_normal_out[] = {
static void node_shader_exec_normal(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float vec[3];
-
+
/* stack order input: normal */
/* stack order output: normal, value */
-
+
nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
-
+
/* render normals point inside... the widget points outside */
out[1]->vec[0] = -dot_v3v3(vec, out[0]->vec);
}
@@ -67,12 +67,12 @@ static int gpu_shader_normal(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSE
void register_node_type_sh_normal(void)
{
static bNodeType ntype;
-
+
sh_node_type_base(&ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, 0);
node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_normal_in, sh_node_normal_out);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_normal);
node_type_gpu(&ntype, gpu_shader_normal);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output.c b/source/blender/nodes/shader/nodes/node_shader_output.c
new file mode 100644
index 00000000000..5b1a68b4bf9
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_output.c
@@ -0,0 +1,97 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_output.c
+ * \ingroup shdnodes
+ */
+
+
+#include "node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+static bNodeSocketTemplate sh_node_output_in[] = {
+ { SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_output(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **UNUSED(out))
+{
+ if (data) {
+ ShadeInput *shi = ((ShaderCallData *)data)->shi;
+ float col[4];
+
+ /* stack order input sockets: col, alpha, normal */
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
+ nodestack_get_vec(col + 3, SOCK_FLOAT, in[1]);
+
+ if (shi->do_preview) {
+ BKE_node_preview_set_pixel(execdata->preview, col, shi->xs, shi->ys, shi->do_manage);
+ node->lasty = shi->ys;
+ }
+
+ if (node->flag & NODE_DO_OUTPUT) {
+ ShadeResult *shr = ((ShaderCallData *)data)->shr;
+
+ copy_v4_v4(shr->combined, col);
+ shr->alpha = col[3];
+
+ // copy_v3_v3(shr->nor, in[3]->vec);
+ }
+ }
+}
+
+static int gpu_shader_output(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ GPUNodeLink *outlink;
+
+#if 0
+ if (in[1].hasinput)
+ GPU_material_enable_alpha(mat);
+#endif
+
+ GPU_stack_link(mat, "output_node", in, out, &outlink);
+ GPU_material_output_link(mat, outlink);
+
+ return 1;
+}
+
+void register_node_type_sh_output(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, sh_node_output_in, NULL);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_output);
+ node_type_gpu(&ntype, gpu_shader_output);
+
+ /* Do not allow muting output node. */
+ node_type_internal_links(&ntype, NULL);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_world.c b/source/blender/nodes/shader/nodes/node_shader_output_world.c
index 17b4bfb6de6..2c115bdda20 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_world.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_world.c
@@ -56,7 +56,7 @@ void register_node_type_sh_output_world(void)
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, node_shader_gpu_output_world);
-
+
/* Do not allow muting output node. */
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
index 19f31f77989..148f8e99c8f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
@@ -48,7 +48,7 @@ static void node_shader_exec_sephsv(void *UNUSED(data), int UNUSED(thread), bNod
{
float col[3];
nodestack_get_vec(col, SOCK_VECTOR, in[0]);
-
+
rgb_to_hsv(col[0], col[1], col[2],
&out[0]->vec[0], &out[1]->vec[0], &out[2]->vec[0]);
}
@@ -90,7 +90,7 @@ static void node_shader_exec_combhsv(void *UNUSED(data), int UNUSED(thread), bNo
nodestack_get_vec(&h, SOCK_FLOAT, in[0]);
nodestack_get_vec(&s, SOCK_FLOAT, in[1]);
nodestack_get_vec(&v, SOCK_FLOAT, in[2]);
-
+
hsv_to_rgb(h, s, v, &out[0]->vec[0], &out[0]->vec[1], &out[0]->vec[2]);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
index 3f866af5de4..bd914399a28 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
@@ -48,7 +48,7 @@ static void node_shader_exec_seprgb(void *UNUSED(data), int UNUSED(thread), bNod
{
float col[3];
nodestack_get_vec(col, SOCK_VECTOR, in[0]);
-
+
out[0]->vec[0] = col[0];
out[1]->vec[0] = col[1];
out[2]->vec[0] = col[2];
@@ -92,7 +92,7 @@ static void node_shader_exec_combrgb(void *UNUSED(data), int UNUSED(thread), bNo
nodestack_get_vec(&r, SOCK_FLOAT, in[0]);
nodestack_get_vec(&g, SOCK_FLOAT, in[1]);
nodestack_get_vec(&b, SOCK_FLOAT, in[2]);
-
+
out[0]->vec[0] = r;
out[0]->vec[1] = g;
out[0]->vec[2] = b;
diff --git a/source/blender/nodes/shader/nodes/node_shader_squeeze.c b/source/blender/nodes/shader/nodes/node_shader_squeeze.c
index 2175a7c564f..e46494efd34 100644
--- a/source/blender/nodes/shader/nodes/node_shader_squeeze.c
+++ b/source/blender/nodes/shader/nodes/node_shader_squeeze.c
@@ -32,7 +32,7 @@
#include "node_shader_util.h"
-/* **************** VALUE SQUEEZE ******************** */
+/* **************** VALUE SQUEEZE ******************** */
static bNodeSocketTemplate sh_node_squeeze_in[] = {
{ SOCK_FLOAT, 1, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
{ SOCK_FLOAT, 1, N_("Width"), 1.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE},
@@ -48,7 +48,7 @@ static bNodeSocketTemplate sh_node_squeeze_out[] = {
static void node_shader_exec_squeeze(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
{
float vec[3];
-
+
nodestack_get_vec(vec, SOCK_FLOAT, in[0]);
nodestack_get_vec(vec + 1, SOCK_FLOAT, in[1]);
nodestack_get_vec(vec + 2, SOCK_FLOAT, in[2]);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
index c919f8efa4e..67fe6d08ffd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
@@ -54,7 +54,7 @@ static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
NodeTexBrick *tex = MEM_callocN(sizeof(NodeTexBrick), "NodeTexBrick");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
-
+
tex->offset = 0.5f;
tex->squash = 1.0f;
tex->offset_freq = 2;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index 111a9cbfbc0..360b28d768a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -49,7 +49,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *node, bNodeExecDat
GPUMatType type = GPU_Material_get_type(mat);
GPU_link(mat, "generated_from_orco", orco, &orco);
-
+
if (type == GPU_MATERIAL_TYPE_WORLD) {
return GPU_stack_link(mat, node, "node_tex_coord_background", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
@@ -59,7 +59,7 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *node, bNodeExecDat
else {
return GPU_stack_link(mat, node, "node_tex_coord", in, out,
GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 378da163f64..d441a674838 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -66,20 +66,20 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE
if (!in[0].link) {
GPUMatType type = GPU_Material_get_type(mat);
-
+
if (type == GPU_MATERIAL_TYPE_MESH)
in[0].link = GPU_builtin(GPU_VIEW_POSITION);
else
GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
}
-
+
node_shader_gpu_tex_mapping(mat, node, in, out);
if (tex->projection == SHD_PROJ_EQUIRECTANGULAR)
GPU_stack_link(mat, node, "node_tex_environment_equirectangular", in, out, GPU_image(ima, iuser, isdata));
else
GPU_stack_link(mat, node, "node_tex_environment_mirror_ball", in, out, GPU_image(ima, iuser, isdata));
-
+
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
GPU_material_do_color_management(mat))
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
new file mode 100644
index 00000000000..737ec7d1c4b
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -0,0 +1,166 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_texture.c
+ * \ingroup shdnodes
+ */
+
+#include "DNA_texture_types.h"
+
+#include "node_shader_util.h"
+
+#include "GPU_material.h"
+
+/* **************** TEXTURE ******************** */
+static bNodeSocketTemplate sh_node_texture_in[] = {
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, /* no limit */
+ { -1, 0, "" }
+};
+static bNodeSocketTemplate sh_node_texture_out[] = {
+ { SOCK_FLOAT, 0, N_("Value"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_RGBA, 0, N_("Color"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { SOCK_VECTOR, 0, N_("Normal"), 0, 0, 0, 0, 0, 0, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_texture(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+{
+ if (data && node->id) {
+ ShadeInput *shi = ((ShaderCallData *)data)->shi;
+ TexResult texres;
+ bNodeSocket *sock_vector = node->inputs.first;
+ float vec[3], nor[3] = {0.0f, 0.0f, 0.0f};
+ int retval;
+ short which_output = node->custom1;
+
+ short thread = shi->thread;
+
+ /* out: value, color, normal */
+
+ /* we should find out if a normal as output is needed, for now we do all */
+ texres.nor = nor;
+ texres.tr = texres.tg = texres.tb = 0.0f;
+
+ /* don't use in[0]->hasinput, see material node for explanation */
+ if (sock_vector->link) {
+ nodestack_get_vec(vec, SOCK_VECTOR, in[0]);
+
+ if (in[0]->datatype == NS_OSA_VECTORS) {
+ float *fp = in[0]->data;
+ retval = multitex_nodes((Tex *)node->id, vec, fp, fp + 3, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
+ }
+ else if (in[0]->datatype == NS_OSA_VALUES) {
+ const float *fp = in[0]->data;
+ float dxt[3], dyt[3];
+
+ dxt[0] = fp[0]; dxt[1] = dxt[2] = 0.0f;
+ dyt[0] = fp[1]; dyt[1] = dyt[2] = 0.0f;
+ retval = multitex_nodes((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL);
+ }
+ else
+ retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL);
+ }
+ else {
+ copy_v3_v3(vec, shi->lo);
+ retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL);
+ }
+
+ /* stupid exception */
+ if ( ((Tex *)node->id)->type == TEX_STUCCI) {
+ texres.tin = 0.5f + 0.7f * texres.nor[0];
+ CLAMP(texres.tin, 0.0f, 1.0f);
+ }
+
+ /* intensity and color need some handling */
+ if (texres.talpha)
+ out[0]->vec[0] = texres.ta;
+ else
+ out[0]->vec[0] = texres.tin;
+
+ if ((retval & TEX_RGB) == 0) {
+ copy_v3_fl(out[1]->vec, out[0]->vec[0]);
+ out[1]->vec[3] = 1.0f;
+ }
+ else {
+ copy_v3_v3(out[1]->vec, &texres.tr);
+ out[1]->vec[3] = 1.0f;
+ }
+
+ copy_v3_v3(out[2]->vec, nor);
+
+ if (shi->do_preview) {
+ BKE_node_preview_set_pixel(execdata->preview, out[1]->vec, shi->xs, shi->ys, shi->do_manage);
+ }
+
+ }
+}
+
+static int gpu_shader_texture(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ Tex *tex = (Tex *)node->id;
+
+ if (tex && tex->ima && (tex->type == TEX_IMAGE || tex->type == TEX_ENVMAP)) {
+ if (tex->type == TEX_IMAGE) {
+ GPUNodeLink *texlink = GPU_image(tex->ima, &tex->iuser, false);
+ GPU_stack_link(mat, "texture_image", in, out, texlink);
+ }
+ else { /* TEX_ENVMAP */
+ if (!in[0].link)
+ in[0].link = GPU_uniform(in[0].vec);
+ if (!GPU_material_use_world_space_shading(mat))
+ GPU_link(mat, "direction_transform_m4v3", in[0].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[0].link);
+ GPU_link(mat, "mtex_cube_map_refl_from_refldir",
+ GPU_cube_map(tex->ima, &tex->iuser, false), in[0].link, &out[0].link, &out[1].link);
+ GPU_link(mat, "color_to_normal", out[1].link, &out[2].link);
+ }
+
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
+ if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
+ GPU_material_do_color_management(mat))
+ {
+ GPU_link(mat, "srgb_to_linearrgb", out[1].link, &out[1].link);
+ }
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
+
+ return true;
+ }
+
+ return false;
+}
+
+void register_node_type_sh_texture(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_PREVIEW);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING);
+ node_type_socket_templates(&ntype, sh_node_texture_in, sh_node_texture_out);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_texture);
+ node_type_gpu(&ntype, gpu_shader_texture);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
index 5041741beb1..a1879df3a18 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
@@ -48,7 +48,7 @@ static void node_shader_exec_valtorgb(void *UNUSED(data), int UNUSED(thread), bN
{
/* stack order in: fac */
/* stack order out: col, alpha */
-
+
if (node->storage) {
float fac;
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectMath.c b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
index 2b060806819..ca5291e6041 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectMath.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
@@ -31,7 +31,7 @@
#include "node_shader_util.h"
-/* **************** VECTOR MATH ******************** */
+/* **************** VECTOR MATH ******************** */
static bNodeSocketTemplate sh_node_vect_math_in[] = {
{ SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
{ SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
@@ -44,32 +44,32 @@ static bNodeSocketTemplate sh_node_vect_math_out[] = {
{ -1, 0, "" }
};
-static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
-{
+static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
+{
float vec1[3], vec2[3];
-
+
nodestack_get_vec(vec1, SOCK_VECTOR, in[0]);
nodestack_get_vec(vec2, SOCK_VECTOR, in[1]);
-
+
if (node->custom1 == 0) { /* Add */
out[0]->vec[0] = vec1[0] + vec2[0];
out[0]->vec[1] = vec1[1] + vec2[1];
out[0]->vec[2] = vec1[2] + vec2[2];
-
+
out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[1]) + fabsf(out[0]->vec[2])) / 3.0f;
}
else if (node->custom1 == 1) { /* Subtract */
out[0]->vec[0] = vec1[0] - vec2[0];
out[0]->vec[1] = vec1[1] - vec2[1];
out[0]->vec[2] = vec1[2] - vec2[2];
-
+
out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[1]) + fabsf(out[0]->vec[2])) / 3.0f;
}
else if (node->custom1 == 2) { /* Average */
out[0]->vec[0] = vec1[0] + vec2[0];
out[0]->vec[1] = vec1[1] + vec2[1];
out[0]->vec[2] = vec1[2] + vec2[2];
-
+
out[1]->vec[0] = normalize_v3(out[0]->vec);
}
else if (node->custom1 == 3) { /* Dot product */
@@ -79,7 +79,7 @@ static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), b
out[0]->vec[0] = (vec1[1] * vec2[2]) - (vec1[2] * vec2[1]);
out[0]->vec[1] = (vec1[2] * vec2[0]) - (vec1[0] * vec2[2]);
out[0]->vec[2] = (vec1[0] * vec2[1]) - (vec1[1] * vec2[0]);
-
+
out[1]->vec[0] = normalize_v3(out[0]->vec);
}
else if (node->custom1 == 5) { /* Normalize */
@@ -93,10 +93,10 @@ static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), b
out[0]->vec[1] = vec2[1];
out[0]->vec[2] = vec2[2];
}
-
+
out[1]->vec[0] = normalize_v3(out[0]->vec);
}
-
+
}
static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
@@ -132,7 +132,7 @@ static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, bNodeExecData *UN
default:
return false;
}
-
+
return true;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
index 8183b6c45cb..d0b16dd5886 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
@@ -28,10 +28,10 @@
/** \file blender/nodes/shader/nodes/node_shader_vectTransform.c
* \ingroup shdnodes
*/
-
+
#include "../node_shader_util.h"
-/* **************** Vector Transform ******************** */
+/* **************** Vector Transform ******************** */
static bNodeSocketTemplate sh_node_vect_transform_in[] = {
{ SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
{ -1, 0, "" }
@@ -45,10 +45,10 @@ static bNodeSocketTemplate sh_node_vect_transform_out[] = {
static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeShaderVectTransform *vect = MEM_callocN(sizeof(NodeShaderVectTransform), "NodeShaderVectTransform");
-
+
/* Convert World into Object Space per default */
vect->convert_to = 1;
-
+
node->storage = vect;
}
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 0d3d3f261de..5dbcece0a84 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -70,7 +70,7 @@ static void texture_get_from_context(
if (snode->texfrom == SNODE_TEX_BRUSH) {
struct Brush *brush = NULL;
-
+
if (ob && (ob->mode & OB_MODE_SCULPT))
brush = BKE_paint_brush(&scene->toolsettings->sculpt->paint);
else
@@ -119,11 +119,11 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
{
bNode *node, *node_next;
-
+
/* replace muted nodes and reroute nodes by internal links */
for (node = localtree->nodes.first; node; node = node_next) {
node_next = node->next;
-
+
if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
nodeInternalRelink(localtree, node);
nodeFreeNode(localtree, node);
@@ -149,7 +149,7 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree)
static void update(bNodeTree *ntree)
{
ntree_update_reroute_nodes(ntree);
-
+
if (ntree->update & NTREE_UPDATE_NODES) {
/* clean up preview cache, in case nodes have been removed */
BKE_node_preview_remove_unused(ntree);
@@ -161,31 +161,31 @@ bNodeTreeType *ntreeType_Texture;
void register_node_tree_type_tex(void)
{
bNodeTreeType *tt = ntreeType_Texture = MEM_callocN(sizeof(bNodeTreeType), "texture node tree type");
-
+
tt->type = NTREE_TEXTURE;
strcpy(tt->idname, "TextureNodeTree");
strcpy(tt->ui_name, "Texture Editor");
tt->ui_icon = 0; /* defined in drawnode.c */
strcpy(tt->ui_description, "Texture nodes");
-
+
tt->foreach_nodeclass = foreach_nodeclass;
tt->update = update;
tt->localize = localize;
tt->local_sync = local_sync;
tt->local_merge = local_merge;
tt->get_from_context = texture_get_from_context;
-
+
tt->ext.srna = &RNA_TextureNodeTree;
-
+
ntreeTypeAdd(tt);
}
int ntreeTexTagAnimated(bNodeTree *ntree)
{
bNode *node;
-
+
if (ntree == NULL) return 0;
-
+
for (node = ntree->nodes.first; node; node = node->next) {
if (node->type == TEX_NODE_CURVE_TIME) {
nodeUpdate(ntree, node);
@@ -197,7 +197,7 @@ int ntreeTexTagAnimated(bNodeTree *ntree)
}
}
}
-
+
return 0;
}
@@ -205,16 +205,16 @@ bNodeTreeExec *ntreeTexBeginExecTree_internal(bNodeExecContext *context, bNodeTr
{
bNodeTreeExec *exec;
bNode *node;
-
+
/* common base initialization */
exec = ntree_exec_begin(context, ntree, parent_key);
-
+
/* allocate the thread stack listbase array */
exec->threadstack = MEM_callocN(BLENDER_MAX_THREADS * sizeof(ListBase), "thread stack array");
-
+
for (node = exec->nodetree->nodes.first; node; node = node->next)
node->need_exec = 1;
-
+
return exec;
}
@@ -222,22 +222,22 @@ bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree)
{
bNodeExecContext context;
bNodeTreeExec *exec;
-
+
/* XXX hack: prevent exec data from being generated twice.
* this should be handled by the renderer!
*/
if (ntree->execdata)
return ntree->execdata;
-
+
context.previews = ntree->previews;
-
+
exec = ntreeTexBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
-
+
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
* which only store the ntree pointer. Should be fixed at some point!
*/
ntree->execdata = exec;
-
+
return exec;
}
@@ -247,7 +247,7 @@ static void tex_free_delegates(bNodeTreeExec *exec)
bNodeThreadStack *nts;
bNodeStack *ns;
int th, a;
-
+
for (th = 0; th < BLENDER_MAX_THREADS; th++)
for (nts = exec->threadstack[th].first; nts; nts = nts->next)
for (ns = nts->stack, a = 0; a < exec->stacksize; a++, ns++)
@@ -259,20 +259,20 @@ void ntreeTexEndExecTree_internal(bNodeTreeExec *exec)
{
bNodeThreadStack *nts;
int a;
-
+
if (exec->threadstack) {
tex_free_delegates(exec);
-
+
for (a = 0; a < BLENDER_MAX_THREADS; a++) {
for (nts = exec->threadstack[a].first; nts; nts = nts->next)
if (nts->stack) MEM_freeN(nts->stack);
BLI_freelistN(&exec->threadstack[a]);
}
-
+
MEM_freeN(exec->threadstack);
exec->threadstack = NULL;
}
-
+
ntree_exec_end(exec);
}
@@ -282,7 +282,7 @@ void ntreeTexEndExecTree(bNodeTreeExec *exec)
/* exec may get freed, so assign ntree */
bNodeTree *ntree = exec->nodetree;
ntreeTexEndExecTree_internal(exec);
-
+
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
ntree->execdata = NULL;
}
@@ -318,7 +318,7 @@ int ntreeTexExecTree(
data.which_output = which_output;
data.cfra = cfra;
data.mtex = mtex;
-
+
/* ensure execdata is only initialized once */
if (!exec) {
BLI_thread_lock(LOCK_NODES);
@@ -328,7 +328,7 @@ int ntreeTexExecTree(
exec = nodes->execdata;
}
-
+
nts = ntreeGetThreadStack(exec, thread);
ntreeExecThreadNodes(exec, nts, &data, thread);
ntreeReleaseThreadStack(nts);
diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c
index 8cb61478c41..a6b0d060d93 100644
--- a/source/blender/nodes/texture/node_texture_util.c
+++ b/source/blender/nodes/texture/node_texture_util.c
@@ -58,7 +58,7 @@ int tex_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
{
node_type_base(ntype, type, name, nclass, flag);
-
+
ntype->poll = tex_node_poll_default;
ntype->insert_link = node_insert_link_default;
ntype->update_internal_links = node_update_internal_links_default;
@@ -80,7 +80,7 @@ static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, sho
TexDelegate *dg = in->data;
if (dg) {
tex_call_delegate(dg, in->vec, params, thread);
-
+
if (in->hasoutput && in->sockettype == SOCK_FLOAT)
in->vec[1] = in->vec[2] = in->vec[0];
}
@@ -95,12 +95,12 @@ void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread)
void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
{
tex_input(out, 4, in, params, thread);
-
+
if (in->hasoutput && in->sockettype == SOCK_FLOAT) {
out[1] = out[2] = out[0];
out[3] = 1;
}
-
+
if (in->hasoutput && in->sockettype == SOCK_VECTOR) {
out[0] = out[0] * 0.5f + 0.5f;
out[1] = out[1] * 0.5f + 0.5f;
@@ -132,7 +132,7 @@ void tex_do_preview(bNodePreview *preview, const float coord[2], const float col
if (preview) {
int xs = ((coord[0] + 1.0f) * 0.5f) * preview->xsize;
int ys = ((coord[1] + 1.0f) * 0.5f) * preview->ysize;
-
+
BKE_node_preview_set_pixel(preview, col, xs, ys, do_manage);
}
}
@@ -140,7 +140,7 @@ void tex_do_preview(bNodePreview *preview, const float coord[2], const float col
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata)
{
TexDelegate *dg;
-
+
if (node->flag & NODE_MUTED) {
/* do not add a delegate if the node is muted */
return;
@@ -175,9 +175,9 @@ void ntreeTexCheckCyclics(struct bNodeTree *ntree)
}
else {
Tex *tex = (Tex *)node->id;
-
+
node->custom2 = 0;
-
+
node->custom1 = 1;
if (tex->use_nodes && tex->nodetree) {
ntreeTexCheckCyclics(tex->nodetree);
diff --git a/source/blender/nodes/texture/nodes/node_texture_at.c b/source/blender/nodes/texture/nodes/node_texture_at.c
index bd37a73c776..690d87b42a9 100644
--- a/source/blender/nodes/texture/nodes/node_texture_at.c
+++ b/source/blender/nodes/texture/nodes/node_texture_at.c
@@ -48,7 +48,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
TexParams np = *p;
float new_co[3];
np.co = new_co;
-
+
tex_input_vec(new_co, in[1], p, thread);
tex_input_rgba(out, in[0], &np, thread);
}
@@ -61,11 +61,11 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_at(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_AT, "At", NODE_CLASS_DISTORT, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size(&ntype, 140, 100, 320);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.c b/source/blender/nodes/texture/nodes/node_texture_bricks.c
index 802cfb97533..43af02acdf2 100644
--- a/source/blender/nodes/texture/nodes/node_texture_bricks.c
+++ b/source/blender/nodes/texture/nodes/node_texture_bricks.c
@@ -67,43 +67,43 @@ static float noise(int n) /* fast integer noise */
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
{
const float *co = p->co;
-
+
float x = co[0];
float y = co[1];
-
+
int bricknum, rownum;
float offset = 0;
float ins_x, ins_y;
float tint;
-
+
float bricks1[4];
float bricks2[4];
float mortar[4];
-
+
float mortar_thickness = tex_input_value(in[3], p, thread);
float bias = tex_input_value(in[4], p, thread);
float brick_width = tex_input_value(in[5], p, thread);
float row_height = tex_input_value(in[6], p, thread);
-
+
tex_input_rgba(bricks1, in[0], p, thread);
tex_input_rgba(bricks2, in[1], p, thread);
tex_input_rgba(mortar, in[2], p, thread);
-
+
rownum = (int)floor(y / row_height);
-
+
if (node->custom1 && node->custom2) {
brick_width *= ((int)(rownum) % node->custom2) ? 1.0f : node->custom4; /* squash */
offset = ((int)(rownum) % node->custom1) ? 0 : (brick_width * node->custom3); /* offset */
}
-
+
bricknum = (int)floor((x + offset) / brick_width);
-
+
ins_x = (x + offset) - brick_width * bricknum;
ins_y = y - row_height * rownum;
-
+
tint = noise((rownum << 16) + (bricknum & 0xFFFF)) + bias;
CLAMP(tint, 0.0f, 1.0f);
-
+
if (ins_x < mortar_thickness || ins_y < mortar_thickness ||
ins_x > (brick_width - mortar_thickness) ||
ins_y > (row_height - mortar_thickness))
@@ -124,12 +124,12 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_bricks(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_BRICKS, "Bricks", NODE_CLASS_PATTERN, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_init(&ntype, init);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_checker.c b/source/blender/nodes/texture/nodes/node_texture_checker.c
index b38c883e3b8..d7ad642d474 100644
--- a/source/blender/nodes/texture/nodes/node_texture_checker.c
+++ b/source/blender/nodes/texture/nodes/node_texture_checker.c
@@ -51,12 +51,12 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
float y = p->co[1];
float z = p->co[2];
float sz = tex_input_value(in[2], p, thread);
-
+
/* 0.00001 because of unit sized stuff */
int xi = (int)fabs(floor(0.00001f + x / sz));
int yi = (int)fabs(floor(0.00001f + y / sz));
int zi = (int)fabs(floor(0.00001f + z / sz));
-
+
if ( (xi % 2 == yi % 2) == (zi % 2) ) {
tex_input_rgba(out, in[0], p, thread);
}
@@ -73,10 +73,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_checker(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_CHECKER, "Checker", NODE_CLASS_PATTERN, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_common.c b/source/blender/nodes/texture/nodes/node_texture_common.c
index 6f9a39d7524..20b1815e436 100644
--- a/source/blender/nodes/texture/nodes/node_texture_common.c
+++ b/source/blender/nodes/texture/nodes/node_texture_common.c
@@ -50,7 +50,7 @@ static void copy_stack(bNodeStack *to, bNodeStack *from)
copy_v4_v4(to->vec, from->vec);
to->data = from->data;
to->datatype = from->datatype;
-
+
/* tag as copy to prevent freeing */
to->is_copy = 1;
}
@@ -62,20 +62,20 @@ static void *group_initexec(bNodeExecContext *context, bNode *node, bNodeInstanc
{
bNodeTree *ngroup = (bNodeTree *)node->id;
void *exec;
-
+
if (!ngroup)
return NULL;
-
+
/* initialize the internal node tree execution */
exec = ntreeTexBeginExecTree_internal(context, ngroup, key);
-
+
return exec;
}
static void group_freeexec(void *nodedata)
{
bNodeTreeExec *gexec = (bNodeTreeExec *)nodedata;
-
+
ntreeTexEndExecTree_internal(gexec);
}
@@ -89,7 +89,7 @@ static void group_copy_inputs(bNode *gnode, bNodeStack **in, bNodeStack *gstack)
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_INPUT) {
for (sock = node->outputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -113,7 +113,7 @@ static void group_copy_outputs(bNode *gnode, bNodeStack **out, bNodeStack *gstac
bNodeSocket *sock;
bNodeStack *ns;
int a;
-
+
for (node = ngroup->nodes.first; node; node = node->next) {
if (node->type == NODE_GROUP_OUTPUT && (node->flag & NODE_DO_OUTPUT)) {
for (sock = node->inputs.first, a = 0; sock; sock = sock->next, ++a) {
@@ -133,10 +133,10 @@ static void group_execute(void *data, int thread, struct bNode *node, bNodeExecD
{
bNodeTreeExec *exec = execdata->data;
bNodeThreadStack *nts;
-
+
if (!exec)
return;
-
+
/* XXX same behavior as trunk: all nodes inside group are executed.
* it's stupid, but just makes it work. compo redesign will do this better.
*/
@@ -145,13 +145,13 @@ static void group_execute(void *data, int thread, struct bNode *node, bNodeExecD
for (inode = exec->nodetree->nodes.first; inode; inode = inode->next)
inode->need_exec = 1;
}
-
+
nts = ntreeGetThreadStack(exec, thread);
-
+
group_copy_inputs(node, in, nts->stack);
ntreeExecThreadNodes(exec, nts, data, thread);
group_copy_outputs(node, out, nts->stack);
-
+
ntreeReleaseThreadStack(nts);
}
@@ -171,12 +171,12 @@ void register_node_type_tex_group(void)
ntype.ext.srna = RNA_struct_find("TextureNodeGroup");
BLI_assert(ntype.ext.srna != NULL);
RNA_struct_blender_type_set(ntype.ext.srna, &ntype);
-
+
node_type_socket_templates(&ntype, NULL, NULL);
node_type_size(&ntype, 140, 60, 400);
node_type_label(&ntype, node_group_label);
node_type_update(&ntype, NULL, node_group_verify);
node_type_exec(&ntype, group_initexec, group_freeexec, group_execute);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_compose.c b/source/blender/nodes/texture/nodes/node_texture_compose.c
index 092bf919a67..002da4428cc 100644
--- a/source/blender/nodes/texture/nodes/node_texture_compose.c
+++ b/source/blender/nodes/texture/nodes/node_texture_compose.c
@@ -30,7 +30,7 @@
*/
-#include "node_texture_util.h"
+#include "node_texture_util.h"
#include "NOD_texture.h"
static bNodeSocketTemplate inputs[] = {
@@ -60,10 +60,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_compose(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_COMPOSE, "Combine RGBA", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_coord.c b/source/blender/nodes/texture/nodes/node_texture_coord.c
index e76987da61b..e698ffd0a54 100644
--- a/source/blender/nodes/texture/nodes/node_texture_coord.c
+++ b/source/blender/nodes/texture/nodes/node_texture_coord.c
@@ -51,11 +51,11 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_coord(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_COORD, "Coordinates", NODE_CLASS_INPUT, 0);
node_type_socket_templates(&ntype, NULL, outputs);
node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.c b/source/blender/nodes/texture/nodes/node_texture_curves.c
index c25c312626e..cc734df9586 100644
--- a/source/blender/nodes/texture/nodes/node_texture_curves.c
+++ b/source/blender/nodes/texture/nodes/node_texture_curves.c
@@ -45,10 +45,10 @@ static void time_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNU
{
/* stack order output: fac */
float fac = 0.0f;
-
+
if (node->custom1 < node->custom2)
fac = (p->cfra - node->custom1) / (float)(node->custom2 - node->custom1);
-
+
curvemapping_initialize(node->storage);
fac = curvemapping_evaluateF(node->storage, 0, fac);
out[0] = CLAMPIS(fac, 0.0f, 1.0f);
@@ -70,14 +70,14 @@ static void time_init(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_tex_curve_time(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_CURVE_TIME, "Time", NODE_CLASS_INPUT, 0);
node_type_socket_templates(&ntype, NULL, time_outputs);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_init(&ntype, time_init);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
node_type_exec(&ntype, node_initexec_curves, NULL, time_exec);
-
+
nodeRegisterType(&ntype);
}
@@ -96,7 +96,7 @@ static void rgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in,
{
float cin[4];
tex_input_rgba(cin, in[0], p, thread);
-
+
curvemapping_evaluateRGBF(node->storage, out, cin);
out[3] = cin[3];
}
@@ -114,13 +114,13 @@ static void rgb_init(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_tex_curve_rgb(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, rgb_inputs, rgb_outputs);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_init(&ntype, rgb_init);
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
node_type_exec(&ntype, node_initexec_curves, NULL, rgb_exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_decompose.c b/source/blender/nodes/texture/nodes/node_texture_decompose.c
index 16938bee8e4..392cff970e7 100644
--- a/source/blender/nodes/texture/nodes/node_texture_decompose.c
+++ b/source/blender/nodes/texture/nodes/node_texture_decompose.c
@@ -30,7 +30,7 @@
*/
-#include "node_texture_util.h"
+#include "node_texture_util.h"
#include "NOD_texture.h"
#include <math.h>
@@ -81,10 +81,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_decompose(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_DECOMPOSE, "Separate RGBA", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_distance.c b/source/blender/nodes/texture/nodes/node_texture_distance.c
index 3fdcbe870a9..7cd032f7d59 100644
--- a/source/blender/nodes/texture/nodes/node_texture_distance.c
+++ b/source/blender/nodes/texture/nodes/node_texture_distance.c
@@ -64,11 +64,11 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_distance(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_DISTANCE, "Distance", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_storage(&ntype, "", NULL, NULL);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c
index 9c86f2d0a4c..8316579af93 100644
--- a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c
+++ b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c
@@ -51,7 +51,7 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat
{
if (fac != 0 && (hue != 0.5f || sat != 1 || val != 1)) {
float col[3], hsv[3], mfac = 1.0f - fac;
-
+
rgb_to_hsv(in[0], in[1], in[2], hsv, hsv + 1, hsv + 2);
hsv[0] += (hue - 0.5f);
if (hsv[0] > 1.0f) hsv[0] -= 1.0f; else if (hsv[0] < 0.0f) hsv[0] += 1.0f;
@@ -71,19 +71,19 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat
}
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
-{
+{
float hue = tex_input_value(in[0], p, thread);
float sat = tex_input_value(in[1], p, thread);
float val = tex_input_value(in[2], p, thread);
float fac = tex_input_value(in[3], p, thread);
-
+
float col[4];
tex_input_rgba(col, in[4], p, thread);
-
+
hue += 0.5f; /* [-0.5, 0.5] -> [0, 1] */
-
+
do_hue_sat_fac(node, out, hue, sat, val, col, fac);
-
+
out[3] = col[3];
}
@@ -95,11 +95,11 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_hue_sat(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c
index e36df01f489..0d70eff15e3 100644
--- a/source/blender/nodes/texture/nodes/node_texture_image.c
+++ b/source/blender/nodes/texture/nodes/node_texture_image.c
@@ -44,37 +44,37 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i
float y = p->co[1];
Image *ima = (Image *)node->id;
ImageUser *iuser = (ImageUser *)node->storage;
-
+
if (ima) {
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf) {
float xsize, ysize;
float xoff, yoff;
int px, py;
-
+
const float *result;
xsize = ibuf->x / 2;
ysize = ibuf->y / 2;
xoff = yoff = -1;
-
+
px = (int)( (x - xoff) * xsize);
py = (int)( (y - yoff) * ysize);
-
+
if ( (!xsize) || (!ysize) ) return;
-
+
if (!ibuf->rect_float) {
BLI_thread_lock(LOCK_IMAGE);
if (!ibuf->rect_float)
IMB_float_from_rect(ibuf);
BLI_thread_unlock(LOCK_IMAGE);
}
-
+
while (px < 0) px += ibuf->x;
while (py < 0) py += ibuf->y;
while (px >= ibuf->x) px -= ibuf->x;
while (py >= ibuf->y) py -= ibuf->y;
-
+
result = ibuf->rect_float + py * ibuf->x * 4 + px * 4;
copy_v4_v4(out, result);
@@ -101,7 +101,7 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_tex_image(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, NULL, outputs);
node_type_init(&ntype, init);
diff --git a/source/blender/nodes/texture/nodes/node_texture_invert.c b/source/blender/nodes/texture/nodes/node_texture_invert.c
index 35f5072d8a2..8ef7a7a6ad2 100644
--- a/source/blender/nodes/texture/nodes/node_texture_invert.c
+++ b/source/blender/nodes/texture/nodes/node_texture_invert.c
@@ -33,7 +33,7 @@
#include "node_texture_util.h"
#include "NOD_texture.h"
-/* **************** INVERT ******************** */
+/* **************** INVERT ******************** */
static bNodeSocketTemplate inputs[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
@@ -47,13 +47,13 @@ static bNodeSocketTemplate outputs[] = {
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
{
float col[4];
-
+
tex_input_rgba(col, in[0], p, thread);
col[0] = 1.0f - col[0];
col[1] = 1.0f - col[1];
col[2] = 1.0f - col[2];
-
+
copy_v3_v3(out, col);
out[3] = col[3];
}
@@ -66,10 +66,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_invert(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_mixRgb.c b/source/blender/nodes/texture/nodes/node_texture_mixRgb.c
index 835a49c24d4..9fb8332c61a 100644
--- a/source/blender/nodes/texture/nodes/node_texture_mixRgb.c
+++ b/source/blender/nodes/texture/nodes/node_texture_mixRgb.c
@@ -49,16 +49,16 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
{
float fac = tex_input_value(in[0], p, thread);
float col1[4], col2[4];
-
+
tex_input_rgba(col1, in[1], p, thread);
tex_input_rgba(col2, in[2], p, thread);
/* use alpha */
if (node->custom2 & 1)
fac *= col2[3];
-
+
CLAMP(fac, 0.0f, 1.0f);
-
+
copy_v4_v4(out, col1);
ramp_blend(node->custom1, out, fac, col2);
}
@@ -71,11 +71,11 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_mix_rgb(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_label(&ntype, node_blend_label);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c
index 664b7e4f507..412e3ffb56c 100644
--- a/source/blender/nodes/texture/nodes/node_texture_output.c
+++ b/source/blender/nodes/texture/nodes/node_texture_output.c
@@ -45,7 +45,7 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
{
TexCallData *cdata = (TexCallData *)data;
TexResult *target = cdata->target;
-
+
if (cdata->do_preview) {
TexParams params;
params_from_cdata(&params, cdata);
@@ -61,12 +61,12 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
if (cdata->which_output == node->custom1 || (cdata->which_output == 0 && node->custom1 == 1)) {
TexParams params;
params_from_cdata(&params, cdata);
-
+
tex_input_rgba(&target->tr, in[0], &params, cdata->thread);
-
+
target->tin = (target->tr + target->tg + target->tb) / 3.0f;
target->talpha = true;
-
+
if (target->nor) {
if (in[1] && in[1]->hasinput)
tex_input_vec(target->nor, in[1], &params, cdata->thread);
@@ -85,7 +85,7 @@ static void unique_name(bNode *node)
int suffix;
bNode *i;
const char *name = tno->name;
-
+
new_name[0] = '\0';
i = node;
while (i->prev) i = i->prev;
@@ -114,7 +114,7 @@ static void unique_name(bNode *node)
}
sprintf(new_name + new_len - 4, ".%03d", ++suffix);
}
-
+
if (new_name[0] != '\0') {
BLI_strncpy(tno->name, new_name, sizeof(tno->name));
}
@@ -124,11 +124,11 @@ static void assign_index(struct bNode *node)
{
bNode *tnode;
int index = 1;
-
+
tnode = node;
while (tnode->prev)
tnode = tnode->prev;
-
+
check_index:
for (; tnode; tnode = tnode->next)
if (tnode->type == TEX_NODE_OUTPUT && tnode != node)
@@ -136,7 +136,7 @@ check_index:
index++;
goto check_index;
}
-
+
node->custom1 = index;
}
@@ -144,7 +144,7 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
{
TexNodeOutput *tno = MEM_callocN(sizeof(TexNodeOutput), "TEX_output");
node->storage = tno;
-
+
strcpy(tno->name, "Default");
unique_name(node);
assign_index(node);
@@ -160,16 +160,16 @@ static void copy(bNodeTree *dest_ntree, bNode *dest_node, bNode *src_node)
void register_node_type_tex_output(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, NULL);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_init(&ntype, init);
node_type_storage(&ntype, "TexNodeOutput", node_free_standard_storage, copy);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
/* Do not allow muting output. */
node_type_internal_links(&ntype, NULL);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c
index 2461a53ca2a..47f4683549f 100644
--- a/source/blender/nodes/texture/nodes/node_texture_proc.c
+++ b/source/blender/nodes/texture/nodes/node_texture_proc.c
@@ -35,7 +35,7 @@
#include "RE_shader_ext.h"
-/*
+/*
* In this file: wrappers to use procedural textures as nodes
*/
@@ -61,19 +61,19 @@ static void do_proc(float *result, TexParams *p, const float col1[4], const floa
{
TexResult texres;
int textype;
-
+
if (is_normal) {
texres.nor = result;
}
else
texres.nor = NULL;
-
+
textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex,
&texres, thread, 0, p->mtex, NULL);
-
+
if (is_normal)
return;
-
+
if (textype & TEX_RGB) {
copy_v4_v4(result, &texres.tr);
}
@@ -86,11 +86,11 @@ static void do_proc(float *result, TexParams *p, const float col1[4], const floa
typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, const short thread);
static void texfn(
- float *result,
+ float *result,
TexParams *p,
- bNode *node,
+ bNode *node,
bNodeStack **in,
- char is_normal,
+ char is_normal,
MapFn map_inputs,
short thread)
{
@@ -98,9 +98,9 @@ static void texfn(
float col1[4], col2[4];
tex_input_rgba(col1, in[0], p, thread);
tex_input_rgba(col2, in[1], p, thread);
-
+
map_inputs(&tex, in, p, thread);
-
+
do_proc(result, p, col1, col2, is_normal, &tex, thread);
}
@@ -144,10 +144,10 @@ static bNodeSocketTemplate voronoi_inputs[] = {
{ SOCK_FLOAT, 1, N_("W2"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
{ SOCK_FLOAT, 1, N_("W3"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
{ SOCK_FLOAT, 1, N_("W4"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
-
+
{ SOCK_FLOAT, 1, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f, PROP_UNSIGNED },
-
+
{ -1, 0, "" }
};
static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
@@ -156,7 +156,7 @@ static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short th
tex->vn_w2 = tex_input_value(in[I + 1], p, thread);
tex->vn_w3 = tex_input_value(in[I + 2], p, thread);
tex->vn_w4 = tex_input_value(in[I + 3], p, thread);
-
+
tex->ns_outscale = tex_input_value(in[I + 4], p, thread);
tex->noisesize = tex_input_value(in[I + 5], p, thread);
}
@@ -242,7 +242,7 @@ static bNodeSocketTemplate musgrave_inputs[] = {
{ SOCK_FLOAT, 1, N_("H"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("Lacunarity"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("Octaves"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, PROP_UNSIGNED },
-
+
{ SOCK_FLOAT, 1, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f, PROP_UNSIGNED },
{ SOCK_FLOAT, 1, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED },
{ -1, 0, "" }
@@ -285,13 +285,13 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
{
Tex *tex = MEM_callocN(sizeof(Tex), "Tex");
node->storage = tex;
-
+
BKE_texture_default(tex);
tex->type = node->type - TEX_NODE_PROC;
-
+
if (tex->type == TEX_WOOD)
tex->stype = TEX_BANDNOISE;
-
+
}
/* Node type definitions */
@@ -309,10 +309,10 @@ void register_node_type_tex_proc_##name(void) \
\
nodeRegisterType(&ntype); \
}
-
+
#define C outputs_color_only
#define CV outputs_both
-
+
TexDef(TEX_VORONOI, CV, voronoi, "Voronoi" )
TexDef(TEX_BLEND, C, blend, "Blend" )
TexDef(TEX_MAGIC, C, magic, "Magic" )
diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.c b/source/blender/nodes/texture/nodes/node_texture_rotate.c
index 99648ec323f..bc4e56ea81d 100644
--- a/source/blender/nodes/texture/nodes/node_texture_rotate.c
+++ b/source/blender/nodes/texture/nodes/node_texture_rotate.c
@@ -52,18 +52,18 @@ static void rotate(float new_co[3], float a, float ax[3], const float co[3])
float para[3];
float perp[3];
float cp[3];
-
+
float cos_a = cosf(a * (float)(2 * M_PI));
float sin_a = sinf(a * (float)(2 * M_PI));
-
+
// x' = xcosa + n(n.x)(1-cosa) + (x*n)sina
-
+
mul_v3_v3fl(perp, co, cos_a);
mul_v3_v3fl(para, ax, dot_v3v3(co, ax) * (1 - cos_a));
-
+
cross_v3_v3v3(cp, ax, co);
mul_v3_fl(cp, sin_a);
-
+
new_co[0] = para[0] + perp[0] + cp[0];
new_co[1] = para[1] + perp[1] + cp[1];
new_co[2] = para[2] + perp[2] + cp[2];
@@ -72,7 +72,7 @@ static void rotate(float new_co[3], float a, float ax[3], const float co[3])
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
{
float new_co[3], new_dxt[3], new_dyt[3], a, ax[3];
-
+
a = tex_input_value(in[1], p, thread);
tex_input_vec(ax, in[2], p, thread);
@@ -81,7 +81,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
rotate(new_dxt, a, ax, p->dxt);
rotate(new_dyt, a, ax, p->dyt);
}
-
+
{
TexParams np = *p;
np.co = new_co;
@@ -90,7 +90,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
tex_input_rgba(out, in[0], &np, thread);
}
}
-static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
}
@@ -98,10 +98,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_rotate(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_ROTATE, "Rotate", NODE_CLASS_DISTORT, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_scale.c b/source/blender/nodes/texture/nodes/node_texture_scale.c
index d623e8e159a..94ccfd01357 100644
--- a/source/blender/nodes/texture/nodes/node_texture_scale.c
+++ b/source/blender/nodes/texture/nodes/node_texture_scale.c
@@ -52,7 +52,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
np.co = new_co;
np.dxt = new_dxt;
np.dyt = new_dyt;
-
+
tex_input_vec(scale, in[1], p, thread);
mul_v3_v3v3(new_co, p->co, scale);
@@ -60,10 +60,10 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
mul_v3_v3v3(new_dxt, p->dxt, scale);
mul_v3_v3v3(new_dyt, p->dyt, scale);
}
-
+
tex_input_rgba(out, in[0], &np, thread);
}
-static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
}
@@ -71,10 +71,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_scale(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_SCALE, "Scale", NODE_CLASS_DISTORT, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c
index f77234ae1ae..ff405cc9f3e 100644
--- a/source/blender/nodes/texture/nodes/node_texture_texture.c
+++ b/source/blender/nodes/texture/nodes/node_texture_texture.c
@@ -52,7 +52,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
static float red[] = {1, 0, 0, 1};
static float white[] = {1, 1, 1, 1};
float co[3], dxt[3], dyt[3];
-
+
copy_v3_v3(co, p->co);
if (p->osatex) {
copy_v3_v3(dxt, p->dxt);
@@ -62,7 +62,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
zero_v3(dxt);
zero_v3(dyt);
}
-
+
if (node->custom2 || node->need_exec == 0) {
/* this node refers to its own texture tree! */
copy_v4_v4(out, (fabsf(co[0] - co[1]) < 0.01f) ? white : red);
@@ -72,14 +72,14 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
int textype;
float nor[] = {0, 0, 0};
float col1[4], col2[4];
-
+
tex_input_rgba(col1, in[0], p, thread);
tex_input_rgba(col2, in[1], p, thread);
-
+
texres.nor = nor;
textype = multitex_nodes(nodetex, co, dxt, dyt, p->osatex,
&texres, thread, 0, p->mtex, NULL);
-
+
if (textype & TEX_RGB) {
copy_v4_v4(out, &texres.tr);
}
@@ -98,10 +98,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_texture(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_translate.c b/source/blender/nodes/texture/nodes/node_texture_translate.c
index ec90029c0bf..fa8319d077b 100644
--- a/source/blender/nodes/texture/nodes/node_texture_translate.c
+++ b/source/blender/nodes/texture/nodes/node_texture_translate.c
@@ -50,16 +50,16 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
float offset[3], new_co[3];
TexParams np = *p;
np.co = new_co;
-
+
tex_input_vec(offset, in[1], p, thread);
-
+
new_co[0] = p->co[0] + offset[0];
new_co[1] = p->co[1] + offset[1];
new_co[2] = p->co[2] + offset[2];
-
+
tex_input_rgba(out, in[0], &np, thread);
}
-static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
}
@@ -67,10 +67,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_translate(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_TRANSLATE, "Translate", NODE_CLASS_DISTORT, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_valToNor.c b/source/blender/nodes/texture/nodes/node_texture_valToNor.c
index 995fb6c1782..b7d57b4d4cf 100644
--- a/source/blender/nodes/texture/nodes/node_texture_valToNor.c
+++ b/source/blender/nodes/texture/nodes/node_texture_valToNor.c
@@ -52,7 +52,7 @@ static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack *
float nabla = tex_input_value(in[1], p, thread);
float val;
float nor[3];
-
+
TexParams np = *p;
np.co = new_co;
@@ -66,7 +66,7 @@ static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack *
new_co[0] = co[0];
new_co[1] = co[1] + nabla;
nor[1] = tex_input_value(in[0], &np, thread);
-
+
new_co[1] = co[1];
new_co[2] = co[2] + nabla;
nor[2] = tex_input_value(in[0], &np, thread);
@@ -75,7 +75,7 @@ static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack *
out[1] = val - nor[1];
out[2] = val - nor[2];
}
-static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &normalfn, data);
}
@@ -83,10 +83,10 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
void register_node_type_tex_valtonor(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_VALTONOR, "Value to Normal", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_valToRgb.c b/source/blender/nodes/texture/nodes/node_texture_valToRgb.c
index 4041d666811..ad3c4344f34 100644
--- a/source/blender/nodes/texture/nodes/node_texture_valToRgb.c
+++ b/source/blender/nodes/texture/nodes/node_texture_valToRgb.c
@@ -53,7 +53,7 @@ static void valtorgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack *
}
}
-static void valtorgb_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
+static void valtorgb_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &valtorgb_colorfn, data);
}
@@ -66,14 +66,14 @@ static void valtorgb_init(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_tex_valtorgb(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, valtorgb_in, valtorgb_out);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
node_type_init(&ntype, valtorgb_init);
node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
node_type_exec(&ntype, NULL, NULL, valtorgb_exec);
-
+
nodeRegisterType(&ntype);
}
@@ -103,10 +103,10 @@ static void rgbtobw_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecD
void register_node_type_tex_rgbtobw(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, rgbtobw_in, rgbtobw_out);
node_type_exec(&ntype, NULL, NULL, rgbtobw_exec);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_viewer.c b/source/blender/nodes/texture/nodes/node_texture_viewer.c
index fefa06b0078..69f4d3ca086 100644
--- a/source/blender/nodes/texture/nodes/node_texture_viewer.c
+++ b/source/blender/nodes/texture/nodes/node_texture_viewer.c
@@ -59,13 +59,13 @@ static void exec(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecD
void register_node_type_tex_viewer(void)
{
static bNodeType ntype;
-
+
tex_node_type_base(&ntype, TEX_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
-
+
/* Do not allow muting viewer node. */
node_type_internal_links(&ntype, NULL);
-
+
nodeRegisterType(&ntype);
}
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index e5724c97bbc..c8932045c52 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -60,7 +60,7 @@ static int cloth_count_nondiag_blocks(Cloth *cloth)
{
LinkNode *link;
int nondiag = 0;
-
+
for (link = cloth->springs; link; link = link->next) {
ClothSpring *spring = (ClothSpring *)link->link;
switch (spring->type) {
@@ -68,14 +68,14 @@ static int cloth_count_nondiag_blocks(Cloth *cloth)
/* angular bending combines 3 vertices */
nondiag += 3;
break;
-
+
default:
/* all other springs depend on 2 vertices only */
nondiag += 1;
break;
}
}
-
+
return nondiag;
}
@@ -86,25 +86,25 @@ int BPH_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
const float ZERO[3] = {0.0f, 0.0f, 0.0f};
Implicit_Data *id;
unsigned int i, nondiag;
-
+
nondiag = cloth_count_nondiag_blocks(cloth);
cloth->implicit = id = BPH_mass_spring_solver_create(cloth->mvert_num, nondiag);
-
+
for (i = 0; i < cloth->mvert_num; i++) {
BPH_mass_spring_set_vertex_mass(id, i, verts[i].mass);
}
-
+
for (i = 0; i < cloth->mvert_num; i++) {
BPH_mass_spring_set_motion_state(id, i, verts[i].x, ZERO);
}
-
+
return 1;
}
void BPH_cloth_solver_free(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
-
+
if (cloth->implicit) {
BPH_mass_spring_solver_free(cloth->implicit);
cloth->implicit = NULL;
@@ -118,7 +118,7 @@ void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
unsigned int mvert_num = cloth->mvert_num, i;
ClothHairData *cloth_hairdata = clmd->hairdata;
Implicit_Data *id = cloth->implicit;
-
+
for (i = 0; i < mvert_num; i++) {
if (cloth_hairdata) {
ClothHairData *root = &cloth_hairdata[i];
@@ -126,7 +126,7 @@ void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
}
else
BPH_mass_spring_set_rest_transform(id, i, I3);
-
+
BPH_mass_spring_set_motion_state(id, i, verts[i].x, verts[i].v);
}
}
@@ -136,22 +136,22 @@ static bool collision_response(ClothModifierData *clmd, CollisionModifierData *c
Cloth *cloth = clmd->clothObject;
int index = collpair->ap1;
bool result = false;
-
+
float v1[3], v2_old[3], v2_new[3], v_rel_old[3], v_rel_new[3];
float epsilon2 = BLI_bvhtree_get_epsilon(collmd->bvhtree);
float margin_distance = (float)collpair->distance - epsilon2;
float mag_v_rel;
-
+
zero_v3(r_impulse);
-
+
if (margin_distance > 0.0f)
return false; /* XXX tested before already? */
-
+
/* only handle static collisions here */
if ( collpair->flag & COLLISION_IN_FUTURE )
return false;
-
+
/* velocity */
copy_v3_v3(v1, cloth->verts[index].v);
collision_get_collider_velocity(v2_old, v2_new, collmd, collpair);
@@ -160,32 +160,32 @@ static bool collision_response(ClothModifierData *clmd, CollisionModifierData *c
sub_v3_v3v3(v_rel_new, v1, v2_new);
/* normal component of the relative velocity */
mag_v_rel = dot_v3v3(v_rel_old, collpair->normal);
-
+
/* only valid when moving toward the collider */
if (mag_v_rel < -ALMOST_ZERO) {
float v_nor_old, v_nor_new;
float v_tan_old[3], v_tan_new[3];
float bounce, repulse;
-
+
/* Collision response based on
* "Simulating Complex Hair with Robust Collision Handling" (Choe, Choi, Ko, ACM SIGGRAPH 2005)
* http://graphics.snu.ac.kr/publications/2005-choe-HairSim/Choe_2005_SCA.pdf
*/
-
+
v_nor_old = mag_v_rel;
v_nor_new = dot_v3v3(v_rel_new, collpair->normal);
-
+
madd_v3_v3v3fl(v_tan_old, v_rel_old, collpair->normal, -v_nor_old);
madd_v3_v3v3fl(v_tan_new, v_rel_new, collpair->normal, -v_nor_new);
-
+
bounce = -v_nor_old * restitution;
-
+
repulse = -margin_distance / dt; /* base repulsion velocity in normal direction */
/* XXX this clamping factor is quite arbitrary ...
* not sure if there is a more scientific approach, but seems to give good results
*/
CLAMP(repulse, 0.0f, 4.0f * bounce);
-
+
if (margin_distance < -epsilon2) {
mul_v3_v3fl(r_impulse, collpair->normal, max_ff(repulse, bounce) - v_nor_new);
}
@@ -193,10 +193,10 @@ static bool collision_response(ClothModifierData *clmd, CollisionModifierData *c
bounce = 0.0f;
mul_v3_v3fl(r_impulse, collpair->normal, repulse - v_nor_new);
}
-
+
result = true;
}
-
+
return result;
}
@@ -211,17 +211,17 @@ static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts *c
ClothVertex *verts = cloth->verts;
int mvert_num = cloth->mvert_num;
int i, j, v;
-
+
const float ZERO[3] = {0.0f, 0.0f, 0.0f};
-
+
BPH_mass_spring_clear_constraints(data);
-
+
for (v = 0; v < mvert_num; v++) {
if (verts[v].flags & CLOTH_VERT_FLAG_PINNED) {
/* pinned vertex constraints */
BPH_mass_spring_add_constraint_ndof0(data, v, ZERO); /* velocity is defined externally */
}
-
+
verts[v].impulse_count = 0;
}
@@ -233,21 +233,21 @@ static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts *c
float restitution = 0.0f;
int v = collpair->face1;
float impulse[3];
-
+
/* pinned verts handled separately */
if (verts[v].flags & CLOTH_VERT_FLAG_PINNED)
continue;
-
+
/* XXX cheap way of avoiding instability from multiple collisions in the same step
* this should eventually be supported ...
*/
if (verts[v].impulse_count > 0)
continue;
-
+
/* calculate collision response */
if (!collision_response(clmd, ct->collmd, collpair, dt, restitution, impulse))
continue;
-
+
BPH_mass_spring_add_constraint_ndof2(data, v, collpair->normal, impulse);
++verts[v].impulse_count;
}
@@ -267,11 +267,11 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothMo
ClothSpring *spring;
ClothVertex *cv;
int i, steps;
-
+
cv = cloth->verts;
for (i = 0; i < cloth->mvert_num; i++, cv++) {
copy_v3_v3(cos[i], cv->tx);
-
+
if (cv->goal == 1.0f || len_squared_v3v3(initial_cos[i], cv->tx) != 0.0f) {
masses[i] = 1e+10;
}
@@ -279,57 +279,57 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothMo
masses[i] = cv->mass;
}
}
-
+
steps = 55;
for (i=0; i<steps; i++) {
for (node=cloth->springs; node; node=node->next) {
/* ClothVertex *cv1, *cv2; */ /* UNUSED */
int v1, v2;
float len, c, l, vec[3];
-
+
spring = (ClothSpring *)node->link;
- if (spring->type != CLOTH_SPRING_TYPE_STRUCTURAL && spring->type != CLOTH_SPRING_TYPE_SHEAR)
+ if (spring->type != CLOTH_SPRING_TYPE_STRUCTURAL && spring->type != CLOTH_SPRING_TYPE_SHEAR)
continue;
-
+
v1 = spring->ij; v2 = spring->kl;
/* cv1 = cloth->verts + v1; */ /* UNUSED */
/* cv2 = cloth->verts + v2; */ /* UNUSED */
len = len_v3v3(cos[v1], cos[v2]);
-
+
sub_v3_v3v3(vec, cos[v1], cos[v2]);
normalize_v3(vec);
-
+
c = (len - spring->restlen);
if (c == 0.0f)
continue;
-
+
l = c / ((1.0f / masses[v1]) + (1.0f / masses[v2]));
-
+
mul_v3_fl(vec, -(1.0f / masses[v1]) * l);
add_v3_v3(cos[v1], vec);
-
+
sub_v3_v3v3(vec, cos[v2], cos[v1]);
normalize_v3(vec);
-
+
mul_v3_fl(vec, -(1.0f / masses[v2]) * l);
add_v3_v3(cos[v2], vec);
}
}
-
+
cv = cloth->verts;
for (i = 0; i < cloth->mvert_num; i++, cv++) {
float vec[3];
-
+
/*compute forces*/
sub_v3_v3v3(vec, cos[i], cv->tx);
mul_v3_fl(vec, cv->mass*dt*20.0f);
add_v3_v3(cv->tv, vec);
//copy_v3_v3(cv->tx, cos[i]);
}
-
+
MEM_freeN(cos);
MEM_freeN(masses);
-
+
return 1;
}
@@ -338,21 +338,21 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
Cloth *cloth = clmd->clothObject;
ClothSimSettings *parms = clmd->sim_parms;
Implicit_Data *data = cloth->implicit;
-
+
bool no_compress = parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
-
+
s->flags &= ~CLOTH_SPRING_FLAG_NEEDED;
-
+
// calculate force of structural + shear springs
if ((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR) || (s->type & CLOTH_SPRING_TYPE_SEWING) ) {
#ifdef CLOTH_FORCE_SPRING_STRUCTURAL
float k, scaling;
-
+
s->flags |= CLOTH_SPRING_FLAG_NEEDED;
-
+
scaling = parms->structural + s->stiffness * fabsf(parms->max_struct - parms->structural);
k = scaling / (parms->avg_spring_len + FLT_EPSILON);
-
+
if (s->type & CLOTH_SPRING_TYPE_SEWING) {
// TODO: verify, half verified (couldn't see error)
// sewing springs usually have a large distance at first so clamp the force so we don't get tunnelling through colission objects
@@ -366,50 +366,50 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
else if (s->type & CLOTH_SPRING_TYPE_BENDING) { /* calculate force of bending springs */
#ifdef CLOTH_FORCE_SPRING_BEND
float kb, cb, scaling;
-
+
s->flags |= CLOTH_SPRING_FLAG_NEEDED;
-
+
scaling = parms->bending + s->stiffness * fabsf(parms->max_bend - parms->bending);
kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
-
+
// Fix for [#45084] for cloth stiffness must have cb proportional to kb
cb = kb * parms->bending_damping;
-
+
BPH_mass_spring_force_spring_bending(data, s->ij, s->kl, s->restlen, kb, cb);
#endif
}
else if (s->type & CLOTH_SPRING_TYPE_BENDING_ANG) {
#ifdef CLOTH_FORCE_SPRING_BEND
float kb, cb, scaling;
-
+
s->flags |= CLOTH_SPRING_FLAG_NEEDED;
-
+
/* XXX WARNING: angular bending springs for hair apply stiffness factor as an overall factor, unlike cloth springs!
* this is crap, but needed due to cloth/hair mixing ...
* max_bend factor is not even used for hair, so ...
*/
scaling = s->stiffness * parms->bending;
kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
-
+
// Fix for [#45084] for cloth stiffness must have cb proportional to kb
cb = kb * parms->bending_damping;
-
+
/* XXX assuming same restlen for ij and jk segments here, this can be done correctly for hair later */
BPH_mass_spring_force_spring_bending_angular(data, s->ij, s->kl, s->mn, s->target, kb, cb);
-
+
#if 0
{
float x_kl[3], x_mn[3], v[3], d[3];
-
+
BPH_mass_spring_get_motion_state(data, s->kl, x_kl, v);
BPH_mass_spring_get_motion_state(data, s->mn, x_mn, v);
-
+
BKE_sim_debug_data_add_dot(clmd->debug_data, x_kl, 0.9, 0.9, 0.9, "target", 7980, s->kl);
BKE_sim_debug_data_add_line(clmd->debug_data, x_kl, x_mn, 0.8, 0.8, 0.8, "target", 7981, s->kl);
-
+
copy_v3_v3(d, s->target);
BKE_sim_debug_data_add_vector(clmd->debug_data, x_kl, d, 0.8, 0.8, 0.2, "target", 7982, s->kl);
-
+
// copy_v3_v3(d, s->target_ij);
// BKE_sim_debug_data_add_vector(clmd->debug_data, x, d, 1, 0.4, 0.4, "target", 7983, s->kl);
}
@@ -424,7 +424,7 @@ static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax
Implicit_Data *data = cloth->implicit;
unsigned int mvert_num = cloth->mvert_num;
int i;
-
+
INIT_MINMAX(gmin, gmax);
for (i = 0; i < mvert_num; i++) {
float x[3];
@@ -444,7 +444,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
const MVertTri *tri = cloth->tri;
unsigned int mvert_num = cloth->mvert_num;
ClothVertex *vert;
-
+
#ifdef CLOTH_FORCE_GRAVITY
/* global acceleration (gravitation) */
if (clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
@@ -477,7 +477,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
#ifdef CLOTH_FORCE_DRAG
BPH_mass_spring_force_drag(data, drag);
#endif
-
+
/* handle external forces like wind */
if (effectors) {
/* cache per-vertex forces to avoid redundant calculation */
@@ -485,12 +485,12 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
for (i = 0; i < cloth->mvert_num; i++) {
float x[3], v[3];
EffectedPoint epoint;
-
+
BPH_mass_spring_get_motion_state(data, i, x, v);
pd_point_from_loc(clmd->scene, x, v, i, &epoint);
pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);
}
-
+
for (i = 0; i < cloth->tri_num; i++) {
const MVertTri *vt = &tri[i];
BPH_mass_spring_force_face_wind(data, vt->tri[0], vt->tri[1], vt->tri[2], winvec);
@@ -501,7 +501,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
#if 0
ClothHairData *hairdata = clmd->hairdata;
ClothHairData *hair_ij, *hair_kl;
-
+
for (LinkNode *link = cloth->springs; link; link = link->next) {
ClothSpring *spring = (ClothSpring *)link->link;
if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
@@ -516,7 +516,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
}
#else
ClothHairData *hairdata = clmd->hairdata;
-
+
vert = cloth->verts;
for (i = 0; i < cloth->mvert_num; i++, vert++) {
if (hairdata) {
@@ -531,7 +531,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
MEM_freeN(winvec);
}
-
+
// calculate spring forces
for (LinkNode *link = cloth->springs; link; link = link->next) {
ClothSpring *spring = (ClothSpring *)link->link;
@@ -548,7 +548,7 @@ BLI_INLINE void cloth_get_grid_location(Implicit_Data *data, float cell_scale, c
{
BPH_mass_spring_get_position(data, index, x);
BPH_mass_spring_get_new_velocity(data, index, v);
-
+
mul_v3_fl(x, cell_scale);
add_v3_v3(x, cell_offset);
}
@@ -582,41 +582,41 @@ static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid, const float c
// ClothVertex *vert3, *vert4;
float x1[3], v1[3], x2[3], v2[3], x3[3], v3[3], x4[3], v4[3];
float dir1[3], dir2[3], dir3[3];
-
+
spring1 = NULL;
spring2 = NULL;
spring3 = (ClothSpring *)spring_link->link;
-
+
zero_v3(x1); zero_v3(v1);
zero_v3(dir1);
zero_v3(x2); zero_v3(v2);
zero_v3(dir2);
-
+
// vert3 = &verts[spring3->kl];
cloth_get_grid_location(data, cell_scale, cell_offset, spring3->kl, x3, v3);
// vert4 = &verts[spring3->ij];
cloth_get_grid_location(data, cell_scale, cell_offset, spring3->ij, x4, v4);
sub_v3_v3v3(dir3, x4, x3);
normalize_v3(dir3);
-
+
while (spring_link) {
/* move on */
spring1 = spring2;
spring2 = spring3;
-
+
// vert3 = vert4;
-
+
copy_v3_v3(x1, x2); copy_v3_v3(v1, v2);
copy_v3_v3(x2, x3); copy_v3_v3(v2, v3);
copy_v3_v3(x3, x4); copy_v3_v3(v3, v4);
-
+
copy_v3_v3(dir1, dir2);
copy_v3_v3(dir2, dir3);
-
+
/* read next segment */
next_spring_link = spring_link->next;
spring_link = hair_spring_next(spring_link);
-
+
if (spring_link) {
spring3 = (ClothSpring *)spring_link->link;
// vert4 = &verts[spring3->ij];
@@ -630,13 +630,13 @@ static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid, const float c
zero_v3(x4); zero_v3(v4);
zero_v3(dir3);
}
-
+
BPH_hair_volume_add_segment(grid, x1, v1, x2, v2, x3, v3, x4, v4,
spring1 ? dir1 : NULL,
dir2,
spring3 ? dir3 : NULL);
}
-
+
return next_spring_link;
}
@@ -647,17 +647,17 @@ static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
int mvert_num = cloth->mvert_num;
ClothVertex *vert;
int i;
-
+
for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {
float x[3], v[3];
-
+
cloth_get_vertex_motion_state(data, vert, x, v);
BPH_hair_volume_add_vertex(grid, x, v);
}
#else
LinkNode *link;
float cellsize, gmin[3], cell_scale, cell_offset[3];
-
+
/* scale and offset for transforming vertex locations into grid space
* (cell size is 0..1, gmin becomes origin)
*/
@@ -665,7 +665,7 @@ static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
cell_scale = cellsize > 0.0f ? 1.0f / cellsize : 0.0f;
mul_v3_v3fl(cell_offset, gmin, cell_scale);
negate_v3(cell_offset);
-
+
link = cloth->springs;
while (link) {
ClothSpring *spring = (ClothSpring *)link->link;
@@ -685,7 +685,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
Implicit_Data *data = cloth->implicit;
int mvert_num = cloth->mvert_num;
ClothVertex *vert;
-
+
const float fluid_factor = 0.95f; /* blend between PIC and FLIP methods */
float smoothfac = parms->velocity_smooth;
/* XXX FIXME arbitrary factor!!! this should be based on some intuitive value instead,
@@ -695,42 +695,42 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
float density_strength = parms->density_strength;
float gmin[3], gmax[3];
int i;
-
+
/* clear grid info */
zero_v3_int(clmd->hair_grid_res);
zero_v3(clmd->hair_grid_min);
zero_v3(clmd->hair_grid_max);
clmd->hair_grid_cellsize = 0.0f;
-
+
hair_get_boundbox(clmd, gmin, gmax);
-
+
/* gather velocities & density */
if (smoothfac > 0.0f || density_strength > 0.0f) {
HairGrid *grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax);
-
+
cloth_continuum_fill_grid(grid, cloth);
-
+
/* main hair continuum solver */
BPH_hair_volume_solve_divergence(grid, dt, density_target, density_strength);
-
+
for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {
float x[3], v[3], nv[3];
-
+
/* calculate volumetric velocity influence */
BPH_mass_spring_get_position(data, i, x);
BPH_mass_spring_get_new_velocity(data, i, v);
-
+
BPH_hair_volume_grid_velocity(grid, x, v, fluid_factor, nv);
-
+
interp_v3_v3v3(nv, v, nv, smoothfac);
-
+
/* apply on hair data */
BPH_mass_spring_set_new_velocity(data, i, nv);
}
-
+
/* store basic grid info in the modifier data */
BPH_hair_volume_grid_geometry(grid, &clmd->hair_grid_cellsize, clmd->hair_grid_res, clmd->hair_grid_min, clmd->hair_grid_max);
-
+
#if 0 /* DEBUG hair velocity vector field */
{
const int size = 64;
@@ -738,26 +738,26 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
float offset[3], a[3], b[3];
const int axis = 0;
const float shift = 0.0f;
-
+
copy_v3_v3(offset, clmd->hair_grid_min);
zero_v3(a);
zero_v3(b);
-
+
offset[axis] = shift * clmd->hair_grid_cellsize;
a[(axis+1) % 3] = clmd->hair_grid_max[(axis+1) % 3] - clmd->hair_grid_min[(axis+1) % 3];
b[(axis+2) % 3] = clmd->hair_grid_max[(axis+2) % 3] - clmd->hair_grid_min[(axis+2) % 3];
-
+
BKE_sim_debug_data_clear_category(clmd->debug_data, "grid velocity");
for (j = 0; j < size; ++j) {
for (i = 0; i < size; ++i) {
float x[3], v[3], gvel[3], gvel_smooth[3], gdensity;
-
+
madd_v3_v3v3fl(x, offset, a, (float)i / (float)(size-1));
madd_v3_v3fl(x, b, (float)j / (float)(size-1));
zero_v3(v);
-
+
BPH_hair_volume_grid_interpolate(grid, x, &gdensity, gvel, gvel_smooth, NULL, NULL);
-
+
// BKE_sim_debug_data_add_circle(clmd->debug_data, x, gdensity, 0.7, 0.3, 1, "grid density", i, j, 3111);
if (!is_zero_v3(gvel) || !is_zero_v3(gvel_smooth)) {
float dvel[3];
@@ -770,7 +770,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
float col0[3] = {0.0, 0.0, 0.0};
float col1[3] = {0.0, 1.0, 0.0};
float col[3];
-
+
interp_v3_v3v3(col, col0, col1, CLAMPIS(gdensity * clmd->sim_parms->density_strength, 0.0, 1.0));
// BKE_sim_debug_data_add_circle(clmd->debug_data, x, gdensity * clmd->sim_parms->density_strength, 0, 1, 0.4, "grid velocity", i, j, 3115);
// BKE_sim_debug_data_add_dot(clmd->debug_data, x, col[0], col[1], col[2], "grid velocity", i, j, 3115);
@@ -782,7 +782,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
}
}
#endif
-
+
BPH_hair_volume_free_vertex_grid(grid);
}
}
@@ -795,7 +795,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
Implicit_Data *data = cloth->implicit;
int mvert_num = cloth->mvert_num;
ClothVertex *vert;
-
+
/* 2.0f is an experimental value that seems to give good results */
float smoothfac = 2.0f * parms->velocity_smooth;
float collfac = 2.0f * parms->collider_friction;
@@ -803,17 +803,17 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
float minpress = parms->pressure_threshold;
float gmin[3], gmax[3];
int i;
-
+
hair_get_boundbox(clmd, gmin, gmax);
-
+
/* gather velocities & density */
if (smoothfac > 0.0f || pressfac > 0.0f) {
HairVertexGrid *vertex_grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_res, gmin, gmax);
-
+
vert = cloth->verts;
for (i = 0; i < mvert_num; i++, vert++) {
float x[3], v[3];
-
+
if (vert->solver_index < 0) {
copy_v3_v3(x, vert->x);
copy_v3_v3(v, vert->v);
@@ -824,21 +824,21 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
BPH_hair_volume_add_vertex(vertex_grid, x, v);
}
BPH_hair_volume_normalize_vertex_grid(vertex_grid);
-
+
vert = cloth->verts;
for (i = 0; i < mvert_num; i++, vert++) {
float x[3], v[3], f[3], dfdx[3][3], dfdv[3][3];
-
+
if (vert->solver_index < 0)
continue;
-
+
/* calculate volumetric forces */
BPH_mass_spring_get_motion_state(data, vert->solver_index, x, v);
BPH_hair_volume_vertex_grid_forces(vertex_grid, x, v, smoothfac, pressfac, minpress, f, dfdx, dfdv);
/* apply on hair data */
BPH_mass_spring_force_extern(data, vert->solver_index, f, dfdx, dfdv);
}
-
+
BPH_hair_volume_free_vertex_grid(vertex_grid);
}
}
@@ -854,33 +854,33 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
ClothVertex *verts = cloth->verts;
int mvert_num = cloth->mvert_num;
const float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
-
+
bool do_extra_solve;
int i;
-
+
if (!(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED))
return;
if (!clmd->clothObject->bvhtree)
return;
-
+
// update verts to current positions
for (i = 0; i < mvert_num; i++) {
BPH_mass_spring_get_new_position(id, i, verts[i].tx);
-
+
sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
copy_v3_v3(verts[i].v, verts[i].tv);
}
-
+
#if 0 /* unused */
for (i=0, cv=cloth->verts; i<cloth->mvert_num; i++, cv++) {
copy_v3_v3(initial_cos[i], cv->tx);
}
#endif
-
+
// call collision function
// TODO: check if "step" or "step+dt" is correct - dg
do_extra_solve = cloth_bvh_objcollision(ob, clmd, step / clmd->sim_parms->timescale, dt / clmd->sim_parms->timescale);
-
+
// copy corrected positions back to simulation
for (i = 0; i < mvert_num; i++) {
float curx[3];
@@ -888,41 +888,41 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
// correct velocity again, just to be sure we had to change it due to adaptive collisions
sub_v3_v3v3(verts[i].tv, verts[i].tx, curx);
}
-
+
if (do_extra_solve) {
// cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
-
+
for (i = 0; i < mvert_num; i++) {
-
+
float newv[3];
-
+
if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
continue;
-
+
BPH_mass_spring_set_new_position(id, i, verts[i].tx);
mul_v3_v3fl(newv, verts[i].tv, spf);
BPH_mass_spring_set_new_velocity(id, i, newv);
}
}
-
+
// X = Xnew;
BPH_mass_spring_apply_result(id);
-
+
if (do_extra_solve) {
ImplicitSolverResult result;
-
+
/* initialize forces to zero */
BPH_mass_spring_clear_forces(id);
-
+
// calculate forces
cloth_calc_force(clmd, frame, effectors, step);
-
+
// calculate new velocity and position
BPH_mass_spring_solve_velocities(id, dt, &result);
// cloth_record_result(clmd, &result, clmd->sim_parms->stepsPerFrame);
-
+
/* note: positions are advanced only once in the main solver step! */
-
+
BPH_mass_spring_apply_result(id);
}
}
@@ -930,7 +930,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
static void cloth_clear_result(ClothModifierData *clmd)
{
ClothSolverResult *sres = clmd->solver_result;
-
+
sres->status = 0;
sres->max_error = sres->min_error = sres->avg_error = 0.0f;
sres->max_iterations = sres->min_iterations = 0;
@@ -940,7 +940,7 @@ static void cloth_clear_result(ClothModifierData *clmd)
static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *result, int steps)
{
ClothSolverResult *sres = clmd->solver_result;
-
+
if (sres->status) { /* already initialized ? */
/* error only makes sense for successful iterations */
if (result->status == BPH_SOLVER_SUCCESS) {
@@ -948,7 +948,7 @@ static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *r
sres->max_error = max_ff(sres->max_error, result->error);
sres->avg_error += result->error / (float)steps;
}
-
+
sres->min_iterations = min_ii(sres->min_iterations, result->iterations);
sres->max_iterations = max_ii(sres->max_iterations, result->iterations);
sres->avg_iterations += (float)result->iterations / (float)steps;
@@ -959,11 +959,11 @@ static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *r
sres->min_error = sres->max_error = result->error;
sres->avg_error += result->error / (float)steps;
}
-
+
sres->min_iterations = sres->max_iterations = result->iterations;
sres->avg_iterations += (float)result->iterations / (float)steps;
}
-
+
sres->status |= result->status;
}
@@ -974,7 +974,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
* Bad design, TODO
*/
const bool is_hair = (clmd->hairdata != NULL);
-
+
unsigned int i=0;
float step=0.0f, tf=clmd->sim_parms->timescale;
Cloth *cloth = clmd->clothObject;
@@ -984,13 +984,13 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
Implicit_Data *id = cloth->implicit;
ColliderContacts *contacts = NULL;
int totcolliders = 0;
-
+
BKE_sim_debug_data_clear_category("collision");
-
+
if (!clmd->solver_result)
clmd->solver_result = (ClothSolverResult *)MEM_callocN(sizeof(ClothSolverResult), "cloth solver result");
cloth_clear_result(clmd);
-
+
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { /* do goal stuff */
for (i = 0; i < mvert_num; i++) {
// update velocities with constrained velocities from pinned verts
@@ -1004,22 +1004,22 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
}
}
}
-
+
while (step < tf) {
ImplicitSolverResult result;
-
+
/* copy velocities for collision */
for (i = 0; i < mvert_num; i++) {
BPH_mass_spring_get_motion_state(id, i, NULL, verts[i].tv);
copy_v3_v3(verts[i].v, verts[i].tv);
}
-
+
if (is_hair) {
/* determine contact points */
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) {
cloth_find_point_contacts(ob, clmd, 0.0f, tf, &contacts, &totcolliders);
}
-
+
/* setup vertex constraints for pinned vertices and contacts */
cloth_setup_constraints(clmd, contacts, totcolliders, dt);
}
@@ -1027,10 +1027,10 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
/* setup vertex constraints for pinned vertices */
cloth_setup_constraints(clmd, NULL, 0, dt);
}
-
+
/* initialize forces to zero */
BPH_mass_spring_clear_forces(id);
-
+
// damping velocity for artistic reasons
// this is a bad way to do it, should be removed imo - lukas_t
if (clmd->sim_parms->vel_damping != 1.0f) {
@@ -1041,26 +1041,26 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
BPH_mass_spring_set_velocity(id, i, v);
}
}
-
+
// calculate forces
cloth_calc_force(clmd, frame, effectors, step);
-
+
// calculate new velocity and position
BPH_mass_spring_solve_velocities(id, dt, &result);
cloth_record_result(clmd, &result, clmd->sim_parms->stepsPerFrame);
-
+
if (is_hair) {
cloth_continuum_step(clmd, dt);
}
-
+
BPH_mass_spring_solve_positions(id, dt);
-
+
if (!is_hair) {
cloth_collision_solve_extra(ob, clmd, effectors, frame, step, dt);
}
-
+
BPH_mass_spring_apply_result(id);
-
+
/* move pinned verts to correct position */
for (i = 0; i < mvert_num; i++) {
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
@@ -1071,23 +1071,23 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
BPH_mass_spring_set_position(id, i, x);
}
}
-
+
BPH_mass_spring_get_motion_state(id, i, verts[i].txold, NULL);
}
-
+
/* free contact points */
if (contacts) {
cloth_free_contacts(contacts, totcolliders);
}
-
+
step += dt;
}
-
+
/* copy results back to cloth data */
for (i = 0; i < mvert_num; i++) {
BPH_mass_spring_get_motion_state(id, i, verts[i].x, verts[i].v);
copy_v3_v3(verts[i].txold, verts[i].x);
}
-
+
return 1;
}
diff --git a/source/blender/physics/intern/ConstrainedConjugateGradient.h b/source/blender/physics/intern/ConstrainedConjugateGradient.h
index f9c6931fe8c..2d5fb41cc73 100644
--- a/source/blender/physics/intern/ConstrainedConjugateGradient.h
+++ b/source/blender/physics/intern/ConstrainedConjugateGradient.h
@@ -4,7 +4,7 @@
#include <Eigen/Core>
-namespace Eigen {
+namespace Eigen {
namespace internal {
@@ -29,16 +29,16 @@ void constrained_conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest&
typedef typename Dest::RealScalar RealScalar;
typedef typename Dest::Scalar Scalar;
typedef Matrix<Scalar,Dynamic,1> VectorType;
-
+
RealScalar tol = tol_error;
int maxIters = iters;
-
+
int n = mat.cols();
VectorType residual = filter * (rhs - mat * x); //initial residual
RealScalar rhsNorm2 = (filter * rhs).squaredNorm();
- if(rhsNorm2 == 0)
+ if(rhsNorm2 == 0)
{
/* XXX TODO set constrained result here */
x.setZero();
@@ -54,7 +54,7 @@ void constrained_conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest&
tol_error = sqrt(residualNorm2 / rhsNorm2);
return;
}
-
+
VectorType p(n);
p = filter * precond.solve(residual); //initial search direction
@@ -68,11 +68,11 @@ void constrained_conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest&
Scalar alpha = absNew / p.dot(tmp); // the amount we travel on dir
x += alpha * p; // update solution
residual -= alpha * tmp; // update residue
-
+
residualNorm2 = residual.squaredNorm();
if(residualNorm2 < threshold)
break;
-
+
z = precond.solve(residual); // approximately solve for "A z = residual"
RealScalar absOld = absNew;
@@ -95,20 +95,20 @@ struct MatrixFilter
m_cmat(NULL)
{
}
-
+
MatrixFilter(const MatrixType &cmat) :
m_cmat(&cmat)
{
}
-
+
void setMatrix(const MatrixType &cmat) { m_cmat = &cmat; }
-
+
template <typename VectorType>
void apply(VectorType v) const
{
v = (*m_cmat) * v;
}
-
+
protected:
const MatrixType *m_cmat;
};
@@ -145,7 +145,7 @@ struct traits<ConstrainedConjugateGradient<_MatrixType,_UpLo,_FilterMatrixType,_
* The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
* and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
* and NumTraits<Scalar>::epsilon() for the tolerance.
- *
+ *
* This class can be used as the direct solver classes. Here is a typical usage example:
* \code
* int n = 10000;
@@ -160,7 +160,7 @@ struct traits<ConstrainedConjugateGradient<_MatrixType,_UpLo,_FilterMatrixType,_
* // update b, and solve again
* x = cg.solve(b);
* \endcode
- *
+ *
* By default the iterations start with x=0 as an initial guess of the solution.
* One can control the start using the solveWithGuess() method. Here is a step by
* step execution example starting with a random guess and printing the evolution
@@ -176,7 +176,7 @@ struct traits<ConstrainedConjugateGradient<_MatrixType,_UpLo,_FilterMatrixType,_
* } while (cg.info()!=Success && i<100);
* \endcode
* Note that such a step by step excution is slightly slower.
- *
+ *
* \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner
*/
template< typename _MatrixType, int _UpLo, typename _FilterMatrixType, typename _Preconditioner>
@@ -206,10 +206,10 @@ public:
ConstrainedConjugateGradient() : Base() {}
/** Initialize the solver with matrix \a A for further \c Ax=b solving.
- *
+ *
* This constructor is a shortcut for the default constructor followed
* by a call to compute().
- *
+ *
* \warning this class stores a reference to the matrix A as well as some
* precomputed values that depend on it. Therefore, if \a A is changed
* this class becomes invalid. Call compute() to update it with the new
@@ -258,7 +258,7 @@ public:
m_isInitialized = true;
m_info = m_error <= Base::m_tolerance ? Success : NoConvergence;
}
-
+
/** \internal */
template<typename Rhs,typename Dest>
void _solve(const Rhs& b, Dest& x) const
diff --git a/source/blender/physics/intern/eigen_utils.h b/source/blender/physics/intern/eigen_utils.h
index 8a5a9dbf5e9..4598d3ad3a7 100644
--- a/source/blender/physics/intern/eigen_utils.h
+++ b/source/blender/physics/intern/eigen_utils.h
@@ -56,24 +56,24 @@ typedef float Scalar;
class Vector3 : public Eigen::Vector3f {
public:
typedef float *ctype;
-
+
Vector3()
{
}
-
+
Vector3(const ctype &v)
{
for (int k = 0; k < 3; ++k)
coeffRef(k) = v[k];
}
-
+
Vector3& operator = (const ctype &v)
{
for (int k = 0; k < 3; ++k)
coeffRef(k) = v[k];
return *this;
}
-
+
operator ctype()
{
return data();
@@ -86,18 +86,18 @@ public:
class Matrix3 : public Eigen::Matrix3f {
public:
typedef float (*ctype)[3];
-
+
Matrix3()
{
}
-
+
Matrix3(const ctype &v)
{
for (int k = 0; k < 3; ++k)
for (int l = 0; l < 3; ++l)
coeffRef(l, k) = v[k][l];
}
-
+
Matrix3& operator = (const ctype &v)
{
for (int k = 0; k < 3; ++k)
@@ -105,7 +105,7 @@ public:
coeffRef(l, k) = v[k][l];
return *this;
}
-
+
operator ctype()
{
return (ctype)data();
@@ -120,23 +120,23 @@ typedef Eigen::VectorXf lVector;
class lVector3f : public Eigen::VectorXf {
public:
typedef Eigen::VectorXf base_t;
-
+
lVector3f()
{
}
-
+
template <typename T>
lVector3f& operator = (T rhs)
{
base_t::operator=(rhs);
return *this;
}
-
+
float* v3(int vertex)
{
return &coeffRef(3 * vertex);
}
-
+
const float* v3(int vertex) const
{
return &coeffRef(3 * vertex);
@@ -157,18 +157,18 @@ struct lMatrix3fCtor {
lMatrix3fCtor()
{
}
-
+
void reset()
{
m_trips.clear();
}
-
+
void reserve(int numverts)
{
/* reserve for diagonal entries */
m_trips.reserve(numverts * 9);
}
-
+
void add(int i, int j, const Matrix3 &m)
{
i *= 3;
@@ -177,7 +177,7 @@ struct lMatrix3fCtor {
for (int l = 0; l < 3; ++l)
m_trips.push_back(Triplet(i + k, j + l, m.coeff(l, k)));
}
-
+
void sub(int i, int j, const Matrix3 &m)
{
i *= 3;
@@ -186,13 +186,13 @@ struct lMatrix3fCtor {
for (int l = 0; l < 3; ++l)
m_trips.push_back(Triplet(i + k, j + l, -m.coeff(l, k)));
}
-
+
inline void construct(lMatrix &m)
{
m.setFromTriplets(m_trips.begin(), m_trips.end());
m_trips.clear();
}
-
+
private:
TripletList m_trips;
};
@@ -206,7 +206,7 @@ BLI_INLINE void print_lvector(const lVector3f &v)
for (int i = 0; i < v.rows(); ++i) {
if (i > 0 && i % 3 == 0)
printf("\n");
-
+
printf("%f,\n", v[i]);
}
}
@@ -216,11 +216,11 @@ BLI_INLINE void print_lmatrix(const lMatrix &m)
for (int j = 0; j < m.rows(); ++j) {
if (j > 0 && j % 3 == 0)
printf("\n");
-
+
for (int i = 0; i < m.cols(); ++i) {
if (i > 0 && i % 3 == 0)
printf(" ");
-
+
implicit_print_matrix_elem(m.coeff(j, i));
}
printf("\n");
diff --git a/source/blender/physics/intern/hair_volume.cpp b/source/blender/physics/intern/hair_volume.cpp
index 6ab69a0050c..b59ac46abbc 100644
--- a/source/blender/physics/intern/hair_volume.cpp
+++ b/source/blender/physics/intern/hair_volume.cpp
@@ -82,7 +82,7 @@ typedef struct HairGridVert {
int samples;
float velocity[3];
float density;
-
+
float velocity_smooth[3];
} HairGridVert;
@@ -107,20 +107,20 @@ BLI_INLINE int hair_grid_offset(const float vec[3], const int res[3], const floa
BLI_INLINE int hair_grid_interp_weights(const int res[3], const float gmin[3], float scale, const float vec[3], float uvw[3])
{
int i, j, k, offset;
-
+
i = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 0);
j = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 1);
k = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 2);
offset = i + (j + k*res[1])*res[0];
-
+
uvw[0] = (vec[0] - gmin[0]) * scale - (float)i;
uvw[1] = (vec[1] - gmin[1]) * scale - (float)j;
uvw[2] = (vec[2] - gmin[2]) * scale - (float)k;
-
+
// BLI_assert(0.0f <= uvw[0] && uvw[0] <= 1.0001f);
// BLI_assert(0.0f <= uvw[1] && uvw[1] <= 1.0001f);
// BLI_assert(0.0f <= uvw[2] && uvw[2] <= 1.0001f);
-
+
return offset;
}
@@ -131,12 +131,12 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3]
float uvw[3], muvw[3];
int res2 = res[1] * res[0];
int offset;
-
+
offset = hair_grid_interp_weights(res, gmin, scale, vec, uvw);
muvw[0] = 1.0f - uvw[0];
muvw[1] = 1.0f - uvw[1];
muvw[2] = 1.0f - uvw[2];
-
+
data[0] = grid[offset ];
data[1] = grid[offset +1];
data[2] = grid[offset +res[0] ];
@@ -145,14 +145,14 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3]
data[5] = grid[offset+res2 +1];
data[6] = grid[offset+res2+res[0] ];
data[7] = grid[offset+res2+res[0]+1];
-
+
if (density) {
*density = muvw[2]*( muvw[1]*( muvw[0]*data[0].density + uvw[0]*data[1].density ) +
uvw[1]*( muvw[0]*data[2].density + uvw[0]*data[3].density ) ) +
uvw[2]*( muvw[1]*( muvw[0]*data[4].density + uvw[0]*data[5].density ) +
uvw[1]*( muvw[0]*data[6].density + uvw[0]*data[7].density ) );
}
-
+
if (velocity) {
int k;
for (k = 0; k < 3; ++k) {
@@ -162,7 +162,7 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3]
uvw[1]*( muvw[0]*data[6].velocity[k] + uvw[0]*data[7].velocity[k] ) );
}
}
-
+
if (vel_smooth) {
int k;
for (k = 0; k < 3; ++k) {
@@ -172,24 +172,24 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3]
uvw[1]*( muvw[0]*data[6].velocity_smooth[k] + uvw[0]*data[7].velocity_smooth[k] ) );
}
}
-
+
if (density_gradient) {
density_gradient[0] = muvw[1] * muvw[2] * ( data[0].density - data[1].density ) +
uvw[1] * muvw[2] * ( data[2].density - data[3].density ) +
muvw[1] * uvw[2] * ( data[4].density - data[5].density ) +
uvw[1] * uvw[2] * ( data[6].density - data[7].density );
-
+
density_gradient[1] = muvw[2] * muvw[0] * ( data[0].density - data[2].density ) +
uvw[2] * muvw[0] * ( data[4].density - data[6].density ) +
muvw[2] * uvw[0] * ( data[1].density - data[3].density ) +
uvw[2] * uvw[0] * ( data[5].density - data[7].density );
-
+
density_gradient[2] = muvw[2] * muvw[0] * ( data[0].density - data[4].density ) +
uvw[2] * muvw[0] * ( data[1].density - data[5].density ) +
muvw[2] * uvw[0] * ( data[2].density - data[6].density ) +
uvw[2] * uvw[0] * ( data[3].density - data[7].density );
}
-
+
if (velocity_gradient) {
/* XXX TODO */
zero_m3(velocity_gradient);
@@ -201,21 +201,21 @@ void BPH_hair_volume_vertex_grid_forces(HairGrid *grid, const float x[3], const
float f[3], float dfdx[3][3], float dfdv[3][3])
{
float gdensity, gvelocity[3], ggrad[3], gvelgrad[3][3], gradlen;
-
+
hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, &gdensity, gvelocity, NULL, ggrad, gvelgrad);
-
+
zero_v3(f);
sub_v3_v3(gvelocity, v);
mul_v3_v3fl(f, gvelocity, smoothfac);
-
+
gradlen = normalize_v3(ggrad) - minpressure;
if (gradlen > 0.0f) {
mul_v3_fl(ggrad, gradlen);
madd_v3_v3fl(f, ggrad, pressurefac);
}
-
+
zero_m3(dfdx);
-
+
sub_m3_m3m3(dfdv, gvelgrad, I);
mul_m3_fl(dfdv, smoothfac);
}
@@ -232,16 +232,16 @@ void BPH_hair_volume_grid_velocity(HairGrid *grid, const float x[3], const float
{
float gdensity, gvelocity[3], gvel_smooth[3], ggrad[3], gvelgrad[3][3];
float v_pic[3], v_flip[3];
-
+
hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, &gdensity, gvelocity, gvel_smooth, ggrad, gvelgrad);
-
+
/* velocity according to PIC method (Particle-in-Cell) */
copy_v3_v3(v_pic, gvel_smooth);
-
+
/* velocity according to FLIP method (Fluid-Implicit-Particle) */
sub_v3_v3v3(v_flip, gvel_smooth, gvelocity);
add_v3_v3(v_flip, v);
-
+
interp_v3_v3v3(r_v, v_pic, v_flip, fluid_factor);
}
@@ -283,16 +283,16 @@ BLI_INLINE int hair_grid_weights(const int res[3], const float gmin[3], float sc
{
int i, j, k, offset;
float uvw[3];
-
+
i = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 0);
j = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 1);
k = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 2);
offset = i + (j + k*res[1])*res[0];
-
+
uvw[0] = (vec[0] - gmin[0]) * scale;
uvw[1] = (vec[1] - gmin[1]) * scale;
uvw[2] = (vec[2] - gmin[2]) * scale;
-
+
weights[0] = dist_tent_v3f3(uvw, (float)i , (float)j , (float)k );
weights[1] = dist_tent_v3f3(uvw, (float)(i+1), (float)j , (float)k );
weights[2] = dist_tent_v3f3(uvw, (float)i , (float)(j+1), (float)k );
@@ -301,9 +301,9 @@ BLI_INLINE int hair_grid_weights(const int res[3], const float gmin[3], float sc
weights[5] = dist_tent_v3f3(uvw, (float)(i+1), (float)j , (float)(k+1));
weights[6] = dist_tent_v3f3(uvw, (float)i , (float)(j+1), (float)(k+1));
weights[7] = dist_tent_v3f3(uvw, (float)(i+1), (float)(j+1), (float)(k+1));
-
+
// BLI_assert(fabsf(weights_sum(weights) - 1.0f) < 0.0001f);
-
+
return offset;
}
@@ -320,18 +320,18 @@ void BPH_hair_volume_add_vertex(HairGrid *grid, const float x[3], const float v[
float weights[8];
int di, dj, dk;
int offset;
-
+
if (!hair_grid_point_valid(x, grid->gmin, grid->gmax))
return;
-
+
offset = hair_grid_weights(res, grid->gmin, grid->inv_cellsize, x, weights);
-
+
for (di = 0; di < 2; ++di) {
for (dj = 0; dj < 2; ++dj) {
for (dk = 0; dk < 2; ++dk) {
int voffset = offset + di + (dj + dk*res[1])*res[0];
int iw = di + dj*2 + dk*4;
-
+
grid->verts[voffset].density += weights[iw];
madd_v3_v3fl(grid->verts[voffset].velocity, v, weights[iw]);
}
@@ -344,15 +344,15 @@ BLI_INLINE void hair_volume_eval_grid_vertex(HairGridVert *vert, const float loc
const float x2[3], const float v2[3], const float x3[3], const float v3[3])
{
float closest[3], lambda, dist, weight;
-
+
lambda = closest_to_line_v3(closest, loc, x2, x3);
dist = len_v3v3(closest, loc);
-
+
weight = (radius - dist) * dist_scale;
-
+
if (weight > 0.0f) {
float vel[3];
-
+
interp_v3_v3v3(vel, v2, v3, lambda);
madd_v3_v3fl(vert->velocity, vel, weight);
vert->density += weight;
@@ -378,37 +378,37 @@ BLI_INLINE void hair_volume_add_segment_2D(HairGrid *grid,
{
const float radius = 1.5f;
const float dist_scale = grid->inv_cellsize;
-
+
int j, k;
-
+
/* boundary checks to be safe */
CLAMP_MIN(jmin, 0);
CLAMP_MAX(jmax, resj-1);
CLAMP_MIN(kmin, 0);
CLAMP_MAX(kmax, resk-1);
-
+
HairGridVert *vert_j = vert + jmin * stride_j;
float loc_j[3] = { loc[0], loc[1], loc[2] };
loc_j[axis_j] += (float)jmin;
for (j = jmin; j <= jmax; ++j, vert_j += stride_j, loc_j[axis_j] += 1.0f) {
-
+
HairGridVert *vert_k = vert_j + kmin * stride_k;
float loc_k[3] = { loc_j[0], loc_j[1], loc_j[2] };
loc_k[axis_k] += (float)kmin;
for (k = kmin; k <= kmax; ++k, vert_k += stride_k, loc_k[axis_k] += 1.0f) {
-
+
hair_volume_eval_grid_vertex(vert_k, loc_k, radius, dist_scale, x2, v2, x3, v3);
-
+
#if 0
{
float wloc[3], x2w[3], x3w[3];
grid_to_world(grid, wloc, loc_k);
grid_to_world(grid, x2w, x2);
grid_to_world(grid, x3w, x3);
-
+
if (vert_k->samples > 0)
BKE_sim_debug_data_add_circle(wloc, 0.01f, 1.0, 1.0, 0.3, "grid", 2525, debug_i, j, k);
-
+
if (grid->debug_value) {
BKE_sim_debug_data_add_dot(wloc, 1, 0, 0, "grid", 93, debug_i, j, k);
BKE_sim_debug_data_add_dot(x2w, 0.1, 0.1, 0.7, "grid", 649, debug_i, j, k);
@@ -435,55 +435,55 @@ void BPH_hair_volume_add_segment(HairGrid *grid,
const float dir1[3], const float dir2[3], const float dir3[3])
{
const int res[3] = { grid->res[0], grid->res[1], grid->res[2] };
-
+
/* find the primary direction from the major axis of the direction vector */
const int axis0 = major_axis_v3(dir2);
const int axis1 = (axis0 + 1) % 3;
const int axis2 = (axis0 + 2) % 3;
-
+
/* vertex buffer offset factors along cardinal axes */
const int strides[3] = { 1, res[0], res[0] * res[1] };
const int stride0 = strides[axis0];
const int stride1 = strides[axis1];
const int stride2 = strides[axis2];
-
+
/* increment of secondary directions per step in the primary direction
* note: we always go in the positive direction along axis0, so the sign can be inverted
*/
const float inc1 = dir2[axis1] / dir2[axis0];
const float inc2 = dir2[axis2] / dir2[axis0];
-
+
/* start/end points, so increment along axis0 is always positive */
const float *start = x2[axis0] < x3[axis0] ? x2 : x3;
const float *end = x2[axis0] < x3[axis0] ? x3 : x2;
const float start0 = start[axis0], start1 = start[axis1], start2 = start[axis2];
const float end0 = end[axis0];
-
+
/* range along primary direction */
const int imin = max_ii(floor_int(start[axis0]) - 1, 0);
const int imax = min_ii(floor_int(end[axis0]) + 2, res[axis0]-1);
-
+
float h = 0.0f;
HairGridVert *vert0;
float loc0[3];
int j0, k0, j0_prev, k0_prev;
int i;
-
+
for (i = imin; i <= imax; ++i) {
float shift1, shift2; /* fraction of a full cell shift [0.0, 1.0) */
int jmin, jmax, kmin, kmax;
-
+
h = CLAMPIS((float)i, start0, end0);
-
+
shift1 = start1 + (h - start0) * inc1;
shift2 = start2 + (h - start0) * inc2;
-
+
j0_prev = j0;
j0 = floor_int(shift1);
-
+
k0_prev = k0;
k0 = floor_int(shift2);
-
+
if (i > imin) {
jmin = min_ii(j0, j0_prev);
jmax = max_ii(j0, j0_prev);
@@ -494,12 +494,12 @@ void BPH_hair_volume_add_segment(HairGrid *grid,
jmin = jmax = j0;
kmin = kmax = k0;
}
-
+
vert0 = grid->verts + i * stride0;
loc0[axis0] = (float)i;
loc0[axis1] = 0.0f;
loc0[axis2] = 0.0f;
-
+
hair_volume_add_segment_2D(grid, x1, v1, x2, v2, x3, v3, x4, v4, dir1, dir2, dir3,
res[axis1], res[axis2], jmin-1, jmax+2, kmin-1, kmax+2,
vert0, stride1, stride2, loc0, axis1, axis2,
@@ -511,11 +511,11 @@ BLI_INLINE void hair_volume_eval_grid_vertex_sample(HairGridVert *vert, const fl
const float x[3], const float v[3])
{
float dist, weight;
-
+
dist = len_v3v3(x, loc);
-
+
weight = (radius - dist) * dist_scale;
-
+
if (weight > 0.0f) {
madd_v3_v3fl(vert->velocity, v, weight);
vert->density += weight;
@@ -533,34 +533,34 @@ void BPH_hair_volume_add_segment(HairGrid *grid,
{
const float radius = 1.5f;
const float dist_scale = grid->inv_cellsize;
-
+
const int res[3] = { grid->res[0], grid->res[1], grid->res[2] };
const int stride[3] = { 1, res[0], res[0] * res[1] };
const int num_samples = 10;
-
+
int s;
-
+
for (s = 0; s < num_samples; ++s) {
float x[3], v[3];
int i, j, k;
-
+
float f = (float)s / (float)(num_samples-1);
interp_v3_v3v3(x, x2, x3, f);
interp_v3_v3v3(v, v2, v3, f);
-
+
int imin = max_ii(floor_int(x[0]) - 2, 0);
int imax = min_ii(floor_int(x[0]) + 2, res[0]-1);
int jmin = max_ii(floor_int(x[1]) - 2, 0);
int jmax = min_ii(floor_int(x[1]) + 2, res[1]-1);
int kmin = max_ii(floor_int(x[2]) - 2, 0);
int kmax = min_ii(floor_int(x[2]) + 2, res[2]-1);
-
+
for (k = kmin; k <= kmax; ++k) {
for (j = jmin; j <= jmax; ++j) {
for (i = imin; i <= imax; ++i) {
float loc[3] = { (float)i, (float)j, (float)k };
HairGridVert *vert = grid->verts + i * stride[0] + j * stride[1] + k * stride[2];
-
+
hair_volume_eval_grid_vertex_sample(vert, loc, radius, dist_scale, x, v);
}
}
@@ -598,25 +598,25 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
{
const float flowfac = grid->cellsize;
const float inv_flowfac = 1.0f / grid->cellsize;
-
+
/*const int num_cells = hair_grid_size(grid->res);*/
const int res[3] = { grid->res[0], grid->res[1], grid->res[2] };
const int resA[3] = { grid->res[0] + 2, grid->res[1] + 2, grid->res[2] + 2 };
-
+
const int stride0 = 1;
const int stride1 = grid->res[0];
const int stride2 = grid->res[1] * grid->res[0];
const int strideA0 = 1;
const int strideA1 = grid->res[0] + 2;
const int strideA2 = (grid->res[1] + 2) * (grid->res[0] + 2);
-
+
const int num_cells = res[0] * res[1] * res[2];
const int num_cellsA = (res[0] + 2) * (res[1] + 2) * (res[2] + 2);
-
+
HairGridVert *vert_start = grid->verts - (stride0 + stride1 + stride2);
HairGridVert *vert;
int i, j, k;
-
+
#define MARGIN_i0 (i < 1)
#define MARGIN_j0 (j < 1)
#define MARGIN_k0 (k < 1)
@@ -630,9 +630,9 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
#define NEIGHBOR_MARGIN_i1 (i >= resA[0]-2)
#define NEIGHBOR_MARGIN_j1 (j >= resA[1]-2)
#define NEIGHBOR_MARGIN_k1 (k >= resA[2]-2)
-
+
BLI_assert(num_cells >= 1);
-
+
/* Calculate divergence */
lVector B(num_cellsA);
for (k = 0; k < resA[2]; ++k) {
@@ -640,14 +640,14 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
for (i = 0; i < resA[0]; ++i) {
int u = i * strideA0 + j * strideA1 + k * strideA2;
bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1;
-
+
if (is_margin) {
B[u] = 0.0f;
continue;
}
-
+
vert = vert_start + i * stride0 + j * stride1 + k * stride2;
-
+
const float *v0 = vert->velocity;
float dx = 0.0f, dy = 0.0f, dz = 0.0f;
if (!NEIGHBOR_MARGIN_i0)
@@ -662,19 +662,19 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
dz += v0[2] - (vert - stride2)->velocity[2];
if (!NEIGHBOR_MARGIN_k1)
dz += (vert + stride2)->velocity[2] - v0[2];
-
+
float divergence = -0.5f * flowfac * (dx + dy + dz);
-
+
/* adjustment term for target density */
float target = hair_volume_density_divergence(vert->density, target_density, target_strength);
-
+
/* B vector contains the finite difference approximation of the velocity divergence.
* Note: according to the discretized Navier-Stokes equation the rhs vector
* and resulting pressure gradient should be multiplied by the (inverse) density;
* however, this is already included in the weighting of hair velocities on the grid!
*/
B[u] = divergence - target;
-
+
#if 0
{
float wloc[3], loc[3];
@@ -683,12 +683,12 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
float coln[3] = {1.0, 0.0, 1.0};
float col[3];
float fac;
-
+
loc[0] = (float)(i - 1);
loc[1] = (float)(j - 1);
loc[2] = (float)(k - 1);
grid_to_world(grid, wloc, loc);
-
+
if (divergence > 0.0f) {
fac = CLAMPIS(divergence * target_strength, 0.0, 1.0);
interp_v3_v3v3(col, col0, colp, fac);
@@ -704,11 +704,11 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
}
}
}
-
+
/* Main Poisson equation system:
* This is derived from the discretezation of the Poisson equation
* div(grad(p)) = div(v)
- *
+ *
* The finite difference approximation yields the linear equation system described here:
* https://en.wikipedia.org/wiki/Discrete_Poisson_equation
*/
@@ -718,13 +718,13 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
* and up to 6 factors -1 on other places.
*/
A.reserve(Eigen::VectorXi::Constant(num_cellsA, 7));
-
+
for (k = 0; k < resA[2]; ++k) {
for (j = 0; j < resA[1]; ++j) {
for (i = 0; i < resA[0]; ++i) {
int u = i * strideA0 + j * strideA1 + k * strideA2;
bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1;
-
+
vert = vert_start + i * stride0 + j * stride1 + k * stride2;
if (!is_margin && vert->density > density_threshold) {
int neighbors_lo = 0;
@@ -733,7 +733,7 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
int neighbor_lo_index[3];
int neighbor_hi_index[3];
int n;
-
+
/* check for upper bounds in advance
* to get the correct number of neighbors,
* needed for the diagonal element
@@ -750,10 +750,10 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
neighbor_hi_index[neighbors_hi++] = u + strideA1;
if (!NEIGHBOR_MARGIN_k1 && (vert + stride2)->density > density_threshold)
neighbor_hi_index[neighbors_hi++] = u + strideA2;
-
+
/*int liquid_neighbors = neighbors_lo + neighbors_hi;*/
non_solid_neighbors = 6;
-
+
for (n = 0; n < neighbors_lo; ++n)
A.insert(neighbor_lo_index[n], u) = -1.0f;
A.insert(u, u) = (float)non_solid_neighbors;
@@ -766,15 +766,15 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
}
}
}
-
+
ConjugateGradient cg;
cg.setMaxIterations(100);
cg.setTolerance(0.01f);
-
+
cg.compute(A);
-
+
lVector p = cg.solve(B);
-
+
if (cg.info() == Eigen::Success) {
/* Calculate velocity = grad(p) */
for (k = 0; k < resA[2]; ++k) {
@@ -784,7 +784,7 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1;
if (is_margin)
continue;
-
+
vert = vert_start + i * stride0 + j * stride1 + k * stride2;
if (vert->density > density_threshold) {
float p_left = p[u - strideA0];
@@ -793,14 +793,14 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
float p_up = p[u + strideA1];
float p_bottom = p[u - strideA2];
float p_top = p[u + strideA2];
-
+
/* finite difference estimate of pressure gradient */
float dvel[3];
dvel[0] = p_right - p_left;
dvel[1] = p_up - p_down;
dvel[2] = p_top - p_bottom;
mul_v3_fl(dvel, -0.5f * inv_flowfac);
-
+
/* pressure gradient describes velocity delta */
add_v3_v3v3(vert->velocity_smooth, vert->velocity, dvel);
}
@@ -810,14 +810,14 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
}
}
}
-
+
#if 0
{
int axis = 0;
float offset = 0.0f;
-
+
int slice = (offset - grid->gmin[axis]) / grid->cellsize;
-
+
for (k = 0; k < resA[2]; ++k) {
for (j = 0; j < resA[1]; ++j) {
for (i = 0; i < resA[0]; ++i) {
@@ -825,21 +825,21 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1;
if (i != slice)
continue;
-
+
vert = vert_start + i * stride0 + j * stride1 + k * stride2;
-
+
float wloc[3], loc[3];
float col0[3] = {0.0, 0.0, 0.0};
float colp[3] = {0.0, 1.0, 1.0};
float coln[3] = {1.0, 0.0, 1.0};
float col[3];
float fac;
-
+
loc[0] = (float)(i - 1);
loc[1] = (float)(j - 1);
loc[2] = (float)(k - 1);
grid_to_world(grid, wloc, loc);
-
+
float pressure = p[u];
if (pressure > 0.0f) {
fac = CLAMPIS(pressure * grid->debug1, 0.0, 1.0);
@@ -851,19 +851,19 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
}
if (fac > 0.05f)
BKE_sim_debug_data_add_circle(grid->debug_data, wloc, 0.01f, col[0], col[1], col[2], "grid", 5533, i, j, k);
-
+
if (!is_margin) {
float dvel[3];
sub_v3_v3v3(dvel, vert->velocity_smooth, vert->velocity);
// BKE_sim_debug_data_add_vector(grid->debug_data, wloc, dvel, 1, 1, 1, "grid", 5566, i, j, k);
}
-
+
if (!is_margin) {
float d = CLAMPIS(vert->density * grid->debug2, 0.0f, 1.0f);
float col0[3] = {0.3, 0.3, 0.3};
float colp[3] = {0.0, 0.0, 1.0};
float col[3];
-
+
interp_v3_v3v3(col, col0, colp, d);
// if (d > 0.05f)
// BKE_sim_debug_data_add_dot(grid->debug_data, wloc, col[0], col[1], col[2], "grid", 5544, i, j, k);
@@ -873,7 +873,7 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
}
}
#endif
-
+
return true;
}
else {
@@ -881,7 +881,7 @@ bool BPH_hair_volume_solve_divergence(HairGrid *grid, float /*dt*/, float target
for (i = 0, vert = grid->verts; i < num_cells; ++i, ++vert) {
zero_v3(vert->velocity_smooth);
}
-
+
return false;
}
}
@@ -901,20 +901,20 @@ BLI_INLINE void hair_volume_filter_box_convolute(HairVertexGrid *grid, float inv
int offset, kernel_offset, kernel_dq, kernel_dr;
HairGridVert *verts;
float *vel_smooth;
-
+
offset = i + (j + k*res)*res;
verts = grid->verts;
vel_smooth = verts[offset].velocity_smooth;
-
+
kernel_offset = minp + (minq + minr*res)*res;
kernel_dq = res;
kernel_dr = res * res;
for (r = minr; r <= maxr; ++r) {
for (q = minq; q <= maxq; ++q) {
for (p = minp; p <= maxp; ++p) {
-
+
madd_v3_v3fl(vel_smooth, verts[kernel_offset].velocity, invD);
-
+
kernel_offset += 1;
}
kernel_offset += kernel_dq;
@@ -930,18 +930,18 @@ void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_siz
int tot;
float invD;
int i, j, k;
-
+
if (kernel_size <= 0)
return;
-
+
tot = kernel_size * 2 + 1;
invD = 1.0f / (float)(tot*tot*tot);
-
+
/* clear values for convolution */
for (i = 0; i < size; ++i) {
zero_v3(grid->verts[i].velocity_smooth);
}
-
+
for (i = 0; i < grid->res; ++i) {
for (j = 0; j < grid->res; ++j) {
for (k = 0; k < grid->res; ++k) {
@@ -949,7 +949,7 @@ void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_siz
}
}
}
-
+
/* apply as new velocity */
for (i = 0; i < size; ++i) {
copy_v3_v3(grid->verts[i].velocity, grid->verts[i].velocity_smooth);
@@ -966,21 +966,21 @@ HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize, const float gmin[3]
int size;
HairGrid *grid;
int i;
-
+
/* sanity check */
if (cellsize <= 0.0f)
cellsize = 1.0f;
scale = 1.0f / cellsize;
-
+
sub_v3_v3v3(extent, gmax, gmin);
for (i = 0; i < 3; ++i) {
resmin[i] = floor_int(gmin[i] * scale);
resmax[i] = floor_int(gmax[i] * scale) + 1;
-
+
/* add margin of 1 cell */
resmin[i] -= 1;
resmax[i] += 1;
-
+
res[i] = resmax[i] - resmin[i] + 1;
/* sanity check: avoid null-sized grid */
if (res[i] < 4) {
@@ -992,12 +992,12 @@ HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize, const float gmin[3]
res[i] = MAX_HAIR_GRID_RES;
resmax[i] = resmin[i] + MAX_HAIR_GRID_RES;
}
-
+
gmin_margin[i] = (float)resmin[i] * cellsize;
gmax_margin[i] = (float)resmax[i] * cellsize;
}
size = hair_grid_size(res);
-
+
grid = (HairGrid *)MEM_callocN(sizeof(HairGrid), "hair grid");
grid->res[0] = res[0];
grid->res[1] = res[1];
@@ -1062,23 +1062,23 @@ static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd,
float vel[3];
float weights[8];
int di, dj, dk;
-
+
for (v=0; v < col->collmd->numverts; v++, loc0++, loc1++) {
int offset;
-
+
if (!hair_grid_point_valid(loc1->co, gmin, gmax))
continue;
-
+
offset = hair_grid_weights(res, gmin, scale, lX[v], weights);
-
+
sub_v3_v3v3(vel, loc1->co, loc0->co);
-
+
for (di = 0; di < 2; ++di) {
for (dj = 0; dj < 2; ++dj) {
for (dk = 0; dk < 2; ++dk) {
int voffset = offset + di + (dj + dk*res)*res;
int iw = di + dj*2 + dk*4;
-
+
collgrid[voffset].density += weights[iw];
madd_v3_v3fl(collgrid[voffset].velocity, vel, weights[iw]);
}
@@ -1095,7 +1095,7 @@ static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd,
if (density > 0.0f)
mul_v3_fl(collgrid[i].velocity, 1.0f/density);
}
-
+
return collgrid;
}
#endif
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
index d6bf5c6b7bf..2eadd3171b0 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -62,7 +62,7 @@ struct Implicit_Data;
typedef struct ImplicitSolverResult {
int status;
-
+
int iterations;
float error;
} ImplicitSolverResult;
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c
index 49798081cff..5fd9c6b50de 100644
--- a/source/blender/physics/intern/implicit_blender.c
+++ b/source/blender/physics/intern/implicit_blender.c
@@ -71,9 +71,9 @@ static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
/*
#define C99
#ifdef C99
-#defineDO_INLINE inline
-#else
-#defineDO_INLINE static
+#defineDO_INLINE inline
+#else
+#defineDO_INLINE static
#endif
*/
struct Cloth;
@@ -90,7 +90,7 @@ typedef struct fmatrix3x3 {
/* int pinned; // is this vertex allowed to move? */
float n1, n2, n3; /* three normal vectors for collision constrains */
unsigned int vcount; /* vertex count */
- unsigned int scount; /* spring count */
+ unsigned int scount; /* spring count */
} fmatrix3x3;
///////////////////////////
@@ -115,9 +115,9 @@ DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vect
/* simple v^T * v product with scalar ("outer product") */
/* STATUS: HAS TO BE verified (*should* work) */
DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS)
-{
+{
mul_fvectorT_fvector(to, vectorA, vectorB);
-
+
mul_fvector_S(to[0], to[0], aS);
mul_fvector_S(to[1], to[1], aS);
mul_fvector_S(to[2], to[2], aS);
@@ -288,7 +288,7 @@ static void print_lvector(lfVector *v, int numverts)
for (i = 0; i < numverts; ++i) {
if (i > 0)
printf("\n");
-
+
printf("%f,\n", v[i][0]);
printf("%f,\n", v[i][1]);
printf("%f,\n", v[i][2]);
@@ -303,11 +303,11 @@ static void print_bfmatrix(fmatrix3x3 *m)
int size = m[0].vcount * 3;
float *t = MEM_callocN(sizeof(float) * size*size, "bfmatrix");
int q, i, j;
-
+
for (q = 0; q < tot; ++q) {
int k = 3 * m[q].r;
int l = 3 * m[q].c;
-
+
for (j = 0; j < 3; ++j) {
for (i = 0; i < 3; ++i) {
// if (t[k + i + (l + j) * size] != 0.0f) {
@@ -323,20 +323,20 @@ static void print_bfmatrix(fmatrix3x3 *m)
}
}
}
-
+
for (j = 0; j < size; ++j) {
if (j > 0 && j % 3 == 0)
printf("\n");
-
+
for (i = 0; i < size; ++i) {
if (i > 0 && i % 3 == 0)
printf(" ");
-
+
implicit_print_matrix_elem(t[i + j * size]);
}
printf("\n");
}
-
+
MEM_freeN(t);
}
#endif
@@ -354,7 +354,7 @@ DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])
DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS)
{
cp_fmatrix(to, ZERO);
-
+
to[0][0] = aS;
to[1][1] = aS;
to[2][2] = aS;
@@ -532,15 +532,15 @@ DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
// TODO: check if memory allocation was successful */
fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN(sizeof(fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix");
int i;
-
+
temp[0].vcount = verts;
temp[0].scount = springs;
-
+
/* vertex part of the matrix is diagonal blocks */
for (i = 0; i < verts; ++i) {
init_fmatrix(temp + i, i, i);
}
-
+
return temp;
}
/* delete big matrix */
@@ -565,7 +565,7 @@ DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
unsigned int i;
for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- cp_fmatrix(matrix[i].m, m3);
+ cp_fmatrix(matrix[i].m, m3);
}
}
@@ -577,10 +577,10 @@ DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
float tmatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
for (i = 0; i < matrix[0].vcount; i++) {
- cp_fmatrix(matrix[i].m, m3);
+ cp_fmatrix(matrix[i].m, m3);
}
for (j = matrix[0].vcount; j < matrix[0].vcount+matrix[0].scount; j++) {
- cp_fmatrix(matrix[j].m, tmatrix);
+ cp_fmatrix(matrix[j].m, tmatrix);
}
}
@@ -591,7 +591,7 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector
unsigned int i = 0;
unsigned int vcount = from[0].vcount;
lfVector *temp = create_lfvector(vcount);
-
+
zero_lfvector(to, vcount);
#pragma omp parallel sections private(i) if (vcount > CLOTH_OPENMP_LIMIT)
@@ -610,10 +610,10 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector
}
}
add_lfvector_lfvector(to, to, temp, from[0].vcount);
-
+
del_lfvector(temp);
-
-
+
+
}
/* SPARSE SYMMETRIC sub big matrix with big matrix*/
@@ -642,15 +642,15 @@ typedef struct Implicit_Data {
lfVector *F; /* forces */
fmatrix3x3 *dFdV, *dFdX; /* force jacobians */
int num_blocks; /* number of off-diagonal blocks (springs) */
-
+
/* motion state data */
lfVector *X, *Xnew; /* positions */
lfVector *V, *Vnew; /* velocities */
-
+
/* internal solver data */
lfVector *B; /* B for A*dV = B */
fmatrix3x3 *A; /* A for A*dV = B */
-
+
lfVector *dV; /* velocity change (solution of A*dV = B) */
lfVector *z; /* target velocity in constrained directions */
fmatrix3x3 *S; /* filtering matrix for constraints */
@@ -660,7 +660,7 @@ typedef struct Implicit_Data {
Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings)
{
Implicit_Data *id = (Implicit_Data *)MEM_callocN(sizeof(Implicit_Data), "implicit vecmat");
-
+
/* process diagonal elements */
id->tfm = create_bfmatrix(numverts, 0);
id->A = create_bfmatrix(numverts, numsprings);
@@ -696,7 +696,7 @@ void BPH_mass_spring_solver_free(Implicit_Data *id)
del_bfmatrix(id->Pinv);
del_bfmatrix(id->bigI);
del_bfmatrix(id->M);
-
+
del_lfvector(id->X);
del_lfvector(id->Xnew);
del_lfvector(id->V);
@@ -705,7 +705,7 @@ void BPH_mass_spring_solver_free(Implicit_Data *id)
del_lfvector(id->B);
del_lfvector(id->dV);
del_lfvector(id->z);
-
+
MEM_freeN(id);
}
@@ -752,7 +752,7 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z
// Solves for unknown X in equation AX=B
unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
float conjgrad_epsilon=0.0001f /* , conjgrad_lasterror=0 */ /* UNUSED */;
- lfVector *q, *d, *tmp, *r;
+ lfVector *q, *d, *tmp, *r;
float s, starget, a, s_prev;
unsigned int numverts = lA[0].vcount;
q = create_lfvector(numverts);
@@ -818,7 +818,7 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z,
// Solves for unknown X in equation AX=B
unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
float conjgrad_epsilon=0.01f;
-
+
unsigned int numverts = lA[0].vcount;
lfVector *fB = create_lfvector(numverts);
lfVector *AdV = create_lfvector(numverts);
@@ -827,27 +827,27 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z,
lfVector *q = create_lfvector(numverts);
lfVector *s = create_lfvector(numverts);
float bnorm2, delta_new, delta_old, delta_target, alpha;
-
+
cp_lfvector(ldV, z, numverts);
-
+
/* d0 = filter(B)^T * P * filter(B) */
cp_lfvector(fB, lB, numverts);
filter(fB, S);
bnorm2 = dot_lfvector(fB, fB, numverts);
delta_target = conjgrad_epsilon*conjgrad_epsilon * bnorm2;
-
+
/* r = filter(B - A * dV) */
mul_bfmatrix_lfvector(AdV, lA, ldV);
sub_lfvector_lfvector(r, lB, AdV, numverts);
filter(r, S);
-
+
/* c = filter(P^-1 * r) */
cp_lfvector(c, r, numverts);
filter(c, S);
-
+
/* delta = r^T * c */
delta_new = dot_lfvector(r, c, numverts);
-
+
#ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
printf("==== A ====\n");
print_bfmatrix(lA);
@@ -858,25 +858,25 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z,
printf("==== S ====\n");
print_bfmatrix(S);
#endif
-
+
while (delta_new > delta_target && conjgrad_loopcount < conjgrad_looplimit) {
mul_bfmatrix_lfvector(q, lA, c);
filter(q, S);
-
+
alpha = delta_new / dot_lfvector(c, q, numverts);
-
+
add_lfvector_lfvectorS(ldV, ldV, c, alpha, numverts);
-
+
add_lfvector_lfvectorS(r, r, q, -alpha, numverts);
-
+
/* s = P^-1 * r */
cp_lfvector(s, r, numverts);
delta_old = delta_new;
delta_new = dot_lfvector(r, s, numverts);
-
+
add_lfvector_lfvectorS(c, s, c, delta_new / delta_old, numverts);
filter(c, S);
-
+
conjgrad_loopcount++;
}
@@ -885,7 +885,7 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z,
print_lvector(ldV, numverts);
printf("========\n");
#endif
-
+
del_lfvector(fB);
del_lfvector(AdV);
del_lfvector(r);
@@ -906,14 +906,14 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z,
DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
{
unsigned int i = 0;
-
+
// Take only the diagonal blocks of A
// #pragma omp parallel for private(i) if (lA[0].vcount > CLOTH_OPENMP_LIMIT)
for (i = 0; i<lA[0].vcount; i++) {
// block diagonalizer
cp_fmatrix(P[i].m, lA[i].m);
inverse_fmatrix(Pinv[i].m, P[i].m);
-
+
}
}
/*
@@ -927,65 +927,65 @@ static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector
lfVector *p = create_lfvector(numverts);
lfVector *s = create_lfvector(numverts);
lfVector *h = create_lfvector(numverts);
-
+
BuildPPinv(lA, P, Pinv);
-
+
filter(dv, S);
add_lfvector_lfvector(dv, dv, z, numverts);
-
+
mul_bfmatrix_lfvector(r, lA, dv);
sub_lfvector_lfvector(r, lB, r, numverts);
filter(r, S);
-
+
mul_prevfmatrix_lfvector(p, Pinv, r);
filter(p, S);
-
+
deltaNew = dot_lfvector(r, p, numverts);
-
+
delta0 = deltaNew * sqrt(conjgrad_epsilon);
-
+
#ifdef DEBUG_TIME
double start = PIL_check_seconds_timer();
#endif
-
+
while ((deltaNew > delta0) && (iterations < conjgrad_looplimit))
{
iterations++;
-
+
mul_bfmatrix_lfvector(s, lA, p);
filter(s, S);
-
+
alpha = deltaNew / dot_lfvector(p, s, numverts);
-
+
add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
-
+
add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
-
+
mul_prevfmatrix_lfvector(h, Pinv, r);
filter(h, S);
-
+
deltaOld = deltaNew;
-
+
deltaNew = dot_lfvector(r, h, numverts);
-
+
add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
-
+
filter(p, S);
-
+
}
#ifdef DEBUG_TIME
double end = PIL_check_seconds_timer();
printf("cg_filtered_pre time: %f\n", (float)(end - start));
#endif
-
+
del_lfvector(h);
del_lfvector(s);
del_lfvector(p);
del_lfvector(r);
-
+
printf("iterations: %d\n", iterations);
-
+
return iterations<conjgrad_looplimit;
}
*/
@@ -1000,83 +1000,83 @@ static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector
lfVector *h = create_lfvector(numverts);
lfVector *bhat = create_lfvector(numverts);
lfVector *btemp = create_lfvector(numverts);
-
+
BuildPPinv(lA, P, Pinv);
-
+
initdiag_bfmatrix(bigI, I);
sub_bfmatrix_Smatrix(bigI, bigI, S);
-
+
// x = Sx_0+(I-S)z
filter(dv, S);
add_lfvector_lfvector(dv, dv, z, numverts);
-
+
// b_hat = S(b-A(I-S)z)
mul_bfmatrix_lfvector(r, lA, z);
mul_bfmatrix_lfvector(bhat, bigI, r);
sub_lfvector_lfvector(bhat, lB, bhat, numverts);
-
+
// r = S(b-Ax)
mul_bfmatrix_lfvector(r, lA, dv);
sub_lfvector_lfvector(r, lB, r, numverts);
filter(r, S);
-
+
// p = SP^-1r
mul_prevfmatrix_lfvector(p, Pinv, r);
filter(p, S);
-
+
// delta0 = bhat^TP^-1bhat
mul_prevfmatrix_lfvector(btemp, Pinv, bhat);
delta0 = dot_lfvector(bhat, btemp, numverts);
-
+
// deltaNew = r^TP
deltaNew = dot_lfvector(r, p, numverts);
-
+
/*
filter(dv, S);
add_lfvector_lfvector(dv, dv, z, numverts);
-
+
mul_bfmatrix_lfvector(r, lA, dv);
sub_lfvector_lfvector(r, lB, r, numverts);
filter(r, S);
-
+
mul_prevfmatrix_lfvector(p, Pinv, r);
filter(p, S);
-
+
deltaNew = dot_lfvector(r, p, numverts);
-
+
delta0 = deltaNew * sqrt(conjgrad_epsilon);
*/
#ifdef DEBUG_TIME
double start = PIL_check_seconds_timer();
#endif
-
+
tol = (0.01*0.2);
-
+
while ((deltaNew > delta0*tol*tol) && (iterations < conjgrad_looplimit))
{
iterations++;
-
+
mul_bfmatrix_lfvector(s, lA, p);
filter(s, S);
-
+
alpha = deltaNew / dot_lfvector(p, s, numverts);
-
+
add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
-
+
add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
-
+
mul_prevfmatrix_lfvector(h, Pinv, r);
filter(h, S);
-
+
deltaOld = deltaNew;
-
+
deltaNew = dot_lfvector(r, h, numverts);
-
+
add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
-
+
filter(p, S);
-
+
}
#ifdef DEBUG_TIME
@@ -1090,9 +1090,9 @@ static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector
del_lfvector(s);
del_lfvector(p);
del_lfvector(r);
-
+
// printf("iterations: %d\n", iterations);
-
+
return iterations<conjgrad_looplimit;
}
#endif
@@ -1128,17 +1128,17 @@ bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSol
add_lfvector_lfvector(data->Vnew, data->V, data->dV, numverts);
del_lfvector(dFdXmV);
-
+
return result->status == BPH_SOLVER_SUCCESS;
}
bool BPH_mass_spring_solve_positions(Implicit_Data *data, float dt)
{
int numverts = data->M[0].vcount;
-
+
// advance positions
add_lfvector_lfvectorS(data->Xnew, data->X, data->Vnew, dt, numverts);
-
+
return true;
}
@@ -1219,7 +1219,7 @@ static int BPH_mass_spring_add_block(Implicit_Data *data, int v1, int v2)
int s = data->M[0].vcount + data->num_blocks; /* index from array start */
BLI_assert(s < data->M[0].vcount + data->M[0].scount);
++data->num_blocks;
-
+
/* tfm and S don't have spring entries (diagonal blocks only) */
init_fmatrix(data->bigI + s, v1, v2);
init_fmatrix(data->M + s, v1, v2);
@@ -1228,7 +1228,7 @@ static int BPH_mass_spring_add_block(Implicit_Data *data, int v1, int v2)
init_fmatrix(data->A + s, v1, v2);
init_fmatrix(data->P + s, v1, v2);
init_fmatrix(data->Pinv + s, v1, v2);
-
+
return s;
}
@@ -1244,26 +1244,26 @@ void BPH_mass_spring_clear_constraints(Implicit_Data *data)
void BPH_mass_spring_add_constraint_ndof0(Implicit_Data *data, int index, const float dV[3])
{
zero_m3(data->S[index].m);
-
+
world_to_root_v3(data, index, data->z[index], dV);
}
void BPH_mass_spring_add_constraint_ndof1(Implicit_Data *data, int index, const float c1[3], const float c2[3], const float dV[3])
{
float m[3][3], p[3], q[3], u[3], cmat[3][3];
-
+
world_to_root_v3(data, index, p, c1);
mul_fvectorT_fvector(cmat, p, p);
sub_m3_m3m3(m, I, cmat);
-
+
world_to_root_v3(data, index, q, c2);
mul_fvectorT_fvector(cmat, q, q);
sub_m3_m3m3(m, m, cmat);
-
+
/* XXX not sure but multiplication should work here */
copy_m3_m3(data->S[index].m, m);
// mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
-
+
world_to_root_v3(data, index, u, dV);
add_v3_v3(data->z[index], u);
}
@@ -1271,14 +1271,14 @@ void BPH_mass_spring_add_constraint_ndof1(Implicit_Data *data, int index, const
void BPH_mass_spring_add_constraint_ndof2(Implicit_Data *data, int index, const float c1[3], const float dV[3])
{
float m[3][3], p[3], u[3], cmat[3][3];
-
+
world_to_root_v3(data, index, p, c1);
mul_fvectorT_fvector(cmat, p, p);
sub_m3_m3m3(m, I, cmat);
-
+
copy_m3_m3(data->S[index].m, m);
// mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
-
+
world_to_root_v3(data, index, u, dV);
add_v3_v3(data->z[index], u);
}
@@ -1289,7 +1289,7 @@ void BPH_mass_spring_clear_forces(Implicit_Data *data)
zero_lfvector(data->F, numverts);
init_bfmatrix(data->dFdX, ZERO);
init_bfmatrix(data->dFdV, ZERO);
-
+
data->num_blocks = 0;
}
@@ -1300,37 +1300,37 @@ void BPH_mass_spring_force_reference_frame(Implicit_Data *data, int index, const
float f[3], dfdx[3][3], dfdv[3][3];
float euler[3], coriolis[3], centrifugal[3], rotvel[3];
float deuler[3][3], dcoriolis[3][3], dcentrifugal[3][3], drotvel[3][3];
-
+
world_to_root_v3(data, index, acc, acceleration);
world_to_root_v3(data, index, w, omega);
world_to_root_v3(data, index, dwdt, domega_dt);
-
+
cross_v3_v3v3(euler, dwdt, data->X[index]);
cross_v3_v3v3(coriolis, w, data->V[index]);
mul_v3_fl(coriolis, 2.0f);
cross_v3_v3v3(rotvel, w, data->X[index]);
cross_v3_v3v3(centrifugal, w, rotvel);
-
+
sub_v3_v3v3(f, acc, euler);
sub_v3_v3(f, coriolis);
sub_v3_v3(f, centrifugal);
-
+
mul_v3_fl(f, mass); /* F = m * a */
-
+
cross_v3_identity(deuler, dwdt);
cross_v3_identity(dcoriolis, w);
mul_m3_fl(dcoriolis, 2.0f);
cross_v3_identity(drotvel, w);
cross_m3_v3m3(dcentrifugal, w, drotvel);
-
+
add_m3_m3m3(dfdx, deuler, dcentrifugal);
negate_m3(dfdx);
mul_m3_fl(dfdx, mass);
-
+
copy_m3_m3(dfdv, dcoriolis);
negate_m3(dfdv);
mul_m3_fl(dfdv, mass);
-
+
add_v3_v3(data->F[index], f);
add_m3_m3m3(data->dFdX[index].m, data->dFdX[index].m, dfdx);
add_m3_m3m3(data->dFdV[index].m, data->dFdV[index].m, dfdv);
@@ -1349,7 +1349,7 @@ void BPH_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, c
float f[3];
world_to_root_v3(data, index, f, g);
mul_v3_fl(f, mass);
-
+
add_v3_v3(data->F[index], f);
}
@@ -1358,10 +1358,10 @@ void BPH_mass_spring_force_drag(Implicit_Data *data, float drag)
int i, numverts = data->M[0].vcount;
for (i = 0; i < numverts; i++) {
float tmp[3][3];
-
+
/* NB: uses root space velocity, no need to transform */
madd_v3_v3fl(data->F[i], data->V[i], -drag);
-
+
copy_m3_m3(tmp, I);
mul_m3_fl(tmp, -drag);
add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, tmp);
@@ -1374,7 +1374,7 @@ void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float
world_to_root_v3(data, i, tf, f);
world_to_root_m3(data, i, tdfdx, dfdx);
world_to_root_m3(data, i, tdfdv, dfdv);
-
+
add_v3_v3(data->F[i], tf);
add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, tdfdx);
add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, tdfdv);
@@ -1383,10 +1383,10 @@ void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float
static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3], const float v3[3])
{
float n1[3], n2[3];
-
+
sub_v3_v3v3(n1, v1, v2);
sub_v3_v3v3(n2, v2, v3);
-
+
cross_v3_v3v3(nor, n1, n2);
return normalize_v3(nor);
}
@@ -1397,17 +1397,17 @@ void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3
const float effector_scale = 0.02f;
float win[3], nor[3], area;
float factor;
-
+
/* calculate face normal and area */
area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
factor = effector_scale * area / 3.0f;
-
+
world_to_root_v3(data, v1, win, winvec[v1]);
madd_v3_v3fl(data->F[v1], nor, factor * dot_v3v3(win, nor));
-
+
world_to_root_v3(data, v2, win, winvec[v2]);
madd_v3_v3fl(data->F[v2], nor, factor * dot_v3v3(win, nor));
-
+
world_to_root_v3(data, v3, win, winvec[v3]);
madd_v3_v3fl(data->F[v3], nor, factor * dot_v3v3(win, nor));
}
@@ -1417,17 +1417,17 @@ static void edge_wind_vertex(const float dir[3], float length, float radius, con
const float density = 0.01f; /* XXX arbitrary value, corresponds to effect of air density */
float cos_alpha, sin_alpha, cross_section;
float windlen = len_v3(wind);
-
+
if (windlen == 0.0f) {
zero_v3(f);
return;
}
-
+
/* angle of wind direction to edge */
cos_alpha = dot_v3v3(wind, dir) / windlen;
sin_alpha = sqrtf(1.0f - cos_alpha * cos_alpha);
cross_section = radius * ((float)M_PI * radius * sin_alpha + length * cos_alpha);
-
+
mul_v3_v3fl(f, wind, density * cross_section);
}
@@ -1435,14 +1435,14 @@ void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, float
{
float win[3], dir[3], length;
float f[3], dfdx[3][3], dfdv[3][3];
-
+
sub_v3_v3v3(dir, data->X[v1], data->X[v2]);
length = normalize_v3(dir);
-
+
world_to_root_v3(data, v1, win, winvec[v1]);
edge_wind_vertex(dir, length, radius1, win, f, dfdx, dfdv);
add_v3_v3(data->F[v1], f);
-
+
world_to_root_v3(data, v2, win, winvec[v2]);
edge_wind_vertex(dir, length, radius2, win, f, dfdx, dfdv);
add_v3_v3(data->F[v2], f);
@@ -1451,10 +1451,10 @@ void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, float
void BPH_mass_spring_force_vertex_wind(Implicit_Data *data, int v, float UNUSED(radius), const float (*winvec)[3])
{
const float density = 0.01f; /* XXX arbitrary value, corresponds to effect of air density */
-
+
float wind[3];
float f[3];
-
+
world_to_root_v3(data, v, wind, winvec[v]);
mul_v3_v3fl(f, wind, density);
add_v3_v3(data->F[v], f);
@@ -1466,8 +1466,8 @@ BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, fl
//return ( (I-outerprod(dir, dir))*Min(1.0f, rest/length) - I) * -k;
outerproduct(to, dir, dir);
sub_m3_m3m3(to, I, to);
-
- mul_m3_fl(to, (L/length));
+
+ mul_m3_fl(to, (L/length));
sub_m3_m3m3(to, to, I);
mul_m3_fl(to, k);
}
@@ -1476,7 +1476,7 @@ BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, fl
#if 0
BLI_INLINE void dfdx_damp(float to[3][3], const float dir[3], float length, const float vel[3], float rest, float damping)
{
- // inner spring damping vel is the relative velocity of the endpoints.
+ // inner spring damping vel is the relative velocity of the endpoints.
// return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest)));
mul_fvectorT_fvector(to, dir, dir);
sub_fmatrix_fmatrix(to, I, to);
@@ -1512,7 +1512,7 @@ BLI_INLINE float fbstar(float length, float L, float kb, float cb)
{
float tempfb_fl = kb * fb(length, L);
float fbstar_fl = cb * (length - L);
-
+
if (tempfb_fl < fbstar_fl)
return fbstar_fl;
else
@@ -1539,7 +1539,7 @@ BLI_INLINE bool spring_length(Implicit_Data *data, int i, int j, float r_extent[
sub_v3_v3v3(r_extent, data->X[j], data->X[i]);
sub_v3_v3v3(r_vel, data->V[j], data->V[i]);
*r_length = len_v3(r_extent);
-
+
if (*r_length > ALMOST_ZERO) {
/*
if (length>L) {
@@ -1557,21 +1557,21 @@ BLI_INLINE bool spring_length(Implicit_Data *data, int i, int j, float r_extent[
else {
zero_v3(r_dir);
}
-
+
return true;
}
BLI_INLINE void apply_spring(Implicit_Data *data, int i, int j, const float f[3], float dfdx[3][3], float dfdv[3][3])
{
int block_ij = BPH_mass_spring_add_block(data, i, j);
-
+
add_v3_v3(data->F[i], f);
sub_v3_v3(data->F[j], f);
-
+
add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfdx);
add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfdx);
sub_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfdx);
-
+
add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, dfdv);
add_m3_m3m3(data->dFdV[j].m, data->dFdV[j].m, dfdv);
sub_m3_m3m3(data->dFdV[block_ij].m, data->dFdV[block_ij].m, dfdv);
@@ -1581,7 +1581,7 @@ bool BPH_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, floa
float stiffness, float damping, bool no_compress, float clamp_force)
{
float extent[3], length, dir[3], vel[3];
-
+
// calculate elonglation
spring_length(data, i, j, extent, dir, &length, vel);
@@ -1590,22 +1590,22 @@ bool BPH_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, floa
Thus length > restlen makes cloth unconstrained at the start of simulation. */
if ((length >= restlen && length > 0) || no_compress) {
float stretch_force, f[3], dfdx[3][3], dfdv[3][3];
-
+
stretch_force = stiffness * (length - restlen);
if (clamp_force > 0.0f && stretch_force > clamp_force) {
stretch_force = clamp_force;
}
mul_v3_v3fl(f, dir, stretch_force);
-
+
// Ascher & Boxman, p.21: Damping only during elonglation
// something wrong with it...
madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
-
+
dfdx_spring(dfdx, dir, length, restlen, stiffness);
dfdv_damp(dfdv, dir, damping);
-
+
apply_spring(data, i, j, f, dfdx, dfdv);
-
+
return true;
}
else {
@@ -1617,23 +1617,23 @@ bool BPH_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, floa
bool BPH_mass_spring_force_spring_bending(Implicit_Data *data, int i, int j, float restlen, float kb, float cb)
{
float extent[3], length, dir[3], vel[3];
-
+
// calculate elonglation
spring_length(data, i, j, extent, dir, &length, vel);
-
+
if (length < restlen) {
float f[3], dfdx[3][3], dfdv[3][3];
-
+
mul_v3_v3fl(f, dir, fbstar(length, restlen, kb, cb));
-
+
outerproduct(dfdx, dir, dir);
mul_m3_fl(dfdx, fbstar_jacobi(length, restlen, kb, cb));
-
+
/* XXX damping not supported */
zero_m3(dfdv);
-
+
apply_spring(data, i, j, f, dfdx, dfdv);
-
+
return true;
}
else {
@@ -1650,10 +1650,10 @@ bool BPH_mass_spring_force_spring_bending(Implicit_Data *data, int i, int j, flo
BLI_INLINE void spring_grad_dir(Implicit_Data *data, int i, int j, float edge[3], float dir[3], float grad_dir[3][3])
{
float length;
-
+
sub_v3_v3v3(edge, data->X[j], data->X[i]);
length = normalize_v3_v3(dir, edge);
-
+
if (length > ALMOST_ZERO) {
outerproduct(grad_dir, dir, dir);
sub_m3_m3m3(grad_dir, I, grad_dir);
@@ -1676,39 +1676,39 @@ BLI_INLINE void spring_angbend_forces(Implicit_Data *data, int i, int j, int k,
float f_bend[3], f_damp[3];
float fk[3];
float dist[3];
-
+
zero_v3(fk);
-
+
sub_v3_v3v3(edge_ij, data->X[j], data->X[i]);
if (q == i) sub_v3_v3(edge_ij, dx);
if (q == j) add_v3_v3(edge_ij, dx);
normalize_v3_v3(dir_ij, edge_ij);
-
+
sub_v3_v3v3(edge_jk, data->X[k], data->X[j]);
if (q == j) sub_v3_v3(edge_jk, dx);
if (q == k) add_v3_v3(edge_jk, dx);
normalize_v3_v3(dir_jk, edge_jk);
-
+
sub_v3_v3v3(vel_ij, data->V[j], data->V[i]);
if (q == i) sub_v3_v3(vel_ij, dv);
if (q == j) add_v3_v3(vel_ij, dv);
-
+
sub_v3_v3v3(vel_jk, data->V[k], data->V[j]);
if (q == j) sub_v3_v3(vel_jk, dv);
if (q == k) add_v3_v3(vel_jk, dv);
-
+
/* bending force */
sub_v3_v3v3(dist, goal, edge_jk);
mul_v3_v3fl(f_bend, dist, stiffness);
-
+
add_v3_v3(fk, f_bend);
-
+
/* damping force */
madd_v3_v3v3fl(vel_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
mul_v3_v3fl(f_damp, vel_ortho, damping);
-
+
sub_v3_v3(fk, f_damp);
-
+
copy_v3_v3(r_f, fk);
}
@@ -1722,24 +1722,24 @@ BLI_INLINE void spring_angbend_estimate_dfdx(Implicit_Data *data, int i, int j,
float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
float f[3];
int a, b;
-
+
zero_m3(dvec_null);
unit_m3(dvec_pos);
mul_m3_fl(dvec_pos, delta * 0.5f);
copy_m3_m3(dvec_neg, dvec_pos);
negate_m3(dvec_neg);
-
+
/* XXX TODO offset targets to account for position dependency */
-
+
for (a = 0; a < 3; ++a) {
spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
q, dvec_pos[a], dvec_null[a], f);
copy_v3_v3(dfdx[a], f);
-
+
spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
q, dvec_neg[a], dvec_null[a], f);
sub_v3_v3(dfdx[a], f);
-
+
for (b = 0; b < 3; ++b) {
dfdx[a][b] /= delta;
}
@@ -1756,24 +1756,24 @@ BLI_INLINE void spring_angbend_estimate_dfdv(Implicit_Data *data, int i, int j,
float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
float f[3];
int a, b;
-
+
zero_m3(dvec_null);
unit_m3(dvec_pos);
mul_m3_fl(dvec_pos, delta * 0.5f);
copy_m3_m3(dvec_neg, dvec_pos);
negate_m3(dvec_neg);
-
+
/* XXX TODO offset targets to account for position dependency */
-
+
for (a = 0; a < 3; ++a) {
spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
q, dvec_null[a], dvec_pos[a], f);
copy_v3_v3(dfdv[a], f);
-
+
spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
q, dvec_null[a], dvec_neg[a], f);
sub_v3_v3(dfdv[a], f);
-
+
for (b = 0; b < 3; ++b) {
dfdv[a][b] /= delta;
}
@@ -1790,45 +1790,45 @@ bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data, int i, in
float fj[3], fk[3];
float dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
float dfj_dvi[3][3], dfj_dvj[3][3], dfk_dvi[3][3], dfk_dvj[3][3], dfk_dvk[3][3];
-
+
const float vecnull[3] = {0.0f, 0.0f, 0.0f};
-
+
int block_ij = BPH_mass_spring_add_block(data, i, j);
int block_jk = BPH_mass_spring_add_block(data, j, k);
int block_ik = BPH_mass_spring_add_block(data, i, k);
-
+
world_to_root_v3(data, j, goal, target);
-
+
spring_angbend_forces(data, i, j, k, goal, stiffness, damping, k, vecnull, vecnull, fk);
negate_v3_v3(fj, fk); /* counterforce */
-
+
spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, i, dfk_dxi);
spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, j, dfk_dxj);
spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, k, dfk_dxk);
copy_m3_m3(dfj_dxi, dfk_dxi); negate_m3(dfj_dxi);
copy_m3_m3(dfj_dxj, dfk_dxj); negate_m3(dfj_dxj);
-
+
spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, i, dfk_dvi);
spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, j, dfk_dvj);
spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, k, dfk_dvk);
copy_m3_m3(dfj_dvi, dfk_dvi); negate_m3(dfj_dvi);
copy_m3_m3(dfj_dvj, dfk_dvj); negate_m3(dfj_dvj);
-
+
/* add forces and jacobians to the solver data */
-
+
add_v3_v3(data->F[j], fj);
add_v3_v3(data->F[k], fk);
-
+
add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfj_dxj);
add_m3_m3m3(data->dFdX[k].m, data->dFdX[k].m, dfk_dxk);
-
+
add_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfj_dxi);
add_m3_m3m3(data->dFdX[block_jk].m, data->dFdX[block_jk].m, dfk_dxj);
add_m3_m3m3(data->dFdX[block_ik].m, data->dFdX[block_ik].m, dfk_dxi);
-
+
add_m3_m3m3(data->dFdV[j].m, data->dFdV[j].m, dfj_dvj);
add_m3_m3m3(data->dFdV[k].m, data->dFdV[k].m, dfk_dvk);
-
+
add_m3_m3m3(data->dFdV[block_ij].m, data->dFdV[block_ij].m, dfj_dvi);
add_m3_m3m3(data->dFdV[block_jk].m, data->dFdV[block_jk].m, dfk_dvj);
add_m3_m3m3(data->dFdV[block_ik].m, data->dFdV[block_ik].m, dfk_dvi);
@@ -1847,10 +1847,10 @@ bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data, int i, in
float fi[3], fj[3], fk[3];
float dfi_dxi[3][3], dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
float dfdvi[3][3];
-
+
// TESTING
damping = 0.0f;
-
+
zero_v3(fi);
zero_v3(fj);
zero_v3(fk);
@@ -1859,68 +1859,68 @@ bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data, int i, in
zero_m3(dfk_dxi);
zero_m3(dfk_dxj);
zero_m3(dfk_dxk);
-
+
/* jacobian of direction vectors */
spring_grad_dir(data, i, j, edge_ij, dir_ij, grad_dir_ij);
spring_grad_dir(data, j, k, edge_jk, dir_jk, grad_dir_jk);
-
+
sub_v3_v3v3(vel_jk, data->V[k], data->V[j]);
-
+
/* bending force */
mul_v3_v3fl(target, dir_ij, restlen);
sub_v3_v3v3(dist, target, edge_jk);
mul_v3_v3fl(fk, dist, stiffness);
-
+
/* damping force */
madd_v3_v3v3fl(vel_jk_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
madd_v3_v3fl(fk, vel_jk_ortho, damping);
-
+
/* XXX this only holds true as long as we assume straight rest shape!
* eventually will become a bit more involved since the opposite segment
* gets its own target, under condition of having equal torque on both sides.
*/
copy_v3_v3(fi, fk);
-
+
/* counterforce on the middle point */
sub_v3_v3(fj, fi);
sub_v3_v3(fj, fk);
-
+
/* === derivatives === */
-
+
madd_m3_m3fl(dfk_dxi, grad_dir_ij, stiffness * restlen);
-
+
madd_m3_m3fl(dfk_dxj, grad_dir_ij, -stiffness * restlen);
madd_m3_m3fl(dfk_dxj, I, stiffness);
-
+
madd_m3_m3fl(dfk_dxk, I, -stiffness);
-
+
copy_m3_m3(dfi_dxi, dfk_dxk);
negate_m3(dfi_dxi);
-
+
/* dfj_dfi == dfi_dfj due to symmetry,
* dfi_dfj == dfk_dfj due to fi == fk
* XXX see comment above on future bent rest shapes
*/
copy_m3_m3(dfj_dxi, dfk_dxj);
-
+
/* dfj_dxj == -(dfi_dxj + dfk_dxj) due to fj == -(fi + fk) */
sub_m3_m3m3(dfj_dxj, dfj_dxj, dfj_dxi);
sub_m3_m3m3(dfj_dxj, dfj_dxj, dfk_dxj);
-
+
/* add forces and jacobians to the solver data */
add_v3_v3(data->F[i], fi);
add_v3_v3(data->F[j], fj);
add_v3_v3(data->F[k], fk);
-
+
add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfi_dxi);
add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfj_dxj);
add_m3_m3m3(data->dFdX[k].m, data->dFdX[k].m, dfk_dxk);
-
+
add_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfj_dxi);
add_m3_m3m3(data->dFdX[block_jk].m, data->dFdX[block_jk].m, dfk_dxj);
add_m3_m3m3(data->dFdX[block_ik].m, data->dFdX[block_ik].m, dfk_dxi);
#endif
-
+
return true;
}
@@ -1929,29 +1929,29 @@ bool BPH_mass_spring_force_spring_goal(Implicit_Data *data, int i, const float g
{
float root_goal_x[3], root_goal_v[3], extent[3], length, dir[3], vel[3];
float f[3], dfdx[3][3], dfdv[3][3];
-
+
/* goal is in world space */
world_to_root_v3(data, i, root_goal_x, goal_x);
world_to_root_v3(data, i, root_goal_v, goal_v);
-
+
sub_v3_v3v3(extent, root_goal_x, data->X[i]);
sub_v3_v3v3(vel, root_goal_v, data->V[i]);
length = normalize_v3_v3(dir, extent);
-
+
if (length > ALMOST_ZERO) {
mul_v3_v3fl(f, dir, stiffness * length);
-
+
// Ascher & Boxman, p.21: Damping only during elonglation
// something wrong with it...
madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
-
+
dfdx_spring(dfdx, dir, length, 0.0f, stiffness);
dfdv_damp(dfdv, dir, damping);
-
+
add_v3_v3(data->F[i], f);
add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfdx);
add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, dfdv);
-
+
return true;
}
else {
diff --git a/source/blender/physics/intern/implicit_eigen.cpp b/source/blender/physics/intern/implicit_eigen.cpp
index d56525f2e93..eaac63893a6 100644
--- a/source/blender/physics/intern/implicit_eigen.cpp
+++ b/source/blender/physics/intern/implicit_eigen.cpp
@@ -99,24 +99,24 @@ static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
class fVector : public Eigen::Vector3f {
public:
typedef float *ctype;
-
+
fVector()
{
}
-
+
fVector(const ctype &v)
{
for (int k = 0; k < 3; ++k)
coeffRef(k) = v[k];
}
-
+
fVector& operator = (const ctype &v)
{
for (int k = 0; k < 3; ++k)
coeffRef(k) = v[k];
return *this;
}
-
+
operator ctype()
{
return data();
@@ -129,18 +129,18 @@ public:
class fMatrix : public Eigen::Matrix3f {
public:
typedef float (*ctype)[3];
-
+
fMatrix()
{
}
-
+
fMatrix(const ctype &v)
{
for (int k = 0; k < 3; ++k)
for (int l = 0; l < 3; ++l)
coeffRef(l, k) = v[k][l];
}
-
+
fMatrix& operator = (const ctype &v)
{
for (int k = 0; k < 3; ++k)
@@ -148,7 +148,7 @@ public:
coeffRef(l, k) = v[k][l];
return *this;
}
-
+
operator ctype()
{
return (ctype)data();
@@ -161,23 +161,23 @@ public:
class lVector : public Eigen::VectorXf {
public:
typedef Eigen::VectorXf base_t;
-
+
lVector()
{
}
-
+
template <typename T>
lVector& operator = (T rhs)
{
base_t::operator=(rhs);
return *this;
}
-
+
float* v3(int vertex)
{
return &coeffRef(3 * vertex);
}
-
+
const float* v3(int vertex) const
{
return &coeffRef(3 * vertex);
@@ -198,18 +198,18 @@ struct lMatrixCtor {
lMatrixCtor()
{
}
-
+
void reset()
{
m_trips.clear();
}
-
+
void reserve(int numverts)
{
/* reserve for diagonal entries */
m_trips.reserve(numverts * 9);
}
-
+
void add(int i, int j, const fMatrix &m)
{
i *= 3;
@@ -218,7 +218,7 @@ struct lMatrixCtor {
for (int l = 0; l < 3; ++l)
m_trips.push_back(Triplet(i + k, j + l, m.coeff(l, k)));
}
-
+
void sub(int i, int j, const fMatrix &m)
{
i *= 3;
@@ -227,13 +227,13 @@ struct lMatrixCtor {
for (int l = 0; l < 3; ++l)
m_trips.push_back(Triplet(i + k, j + l, -m.coeff(l, k)));
}
-
+
inline void construct(lMatrix &m)
{
m.setFromTriplets(m_trips.begin(), m_trips.end());
m_trips.clear();
}
-
+
private:
TripletList m_trips;
};
@@ -253,7 +253,7 @@ static void print_lvector(const lVector &v)
for (int i = 0; i < v.rows(); ++i) {
if (i > 0 && i % 3 == 0)
printf("\n");
-
+
printf("%f,\n", v[i]);
}
}
@@ -263,11 +263,11 @@ static void print_lmatrix(const lMatrix &m)
for (int j = 0; j < m.rows(); ++j) {
if (j > 0 && j % 3 == 0)
printf("\n");
-
+
for (int i = 0; i < m.cols(); ++i) {
if (i > 0 && i % 3 == 0)
printf(" ");
-
+
implicit_print_matrix_elem(m.coeff(j, i));
}
printf("\n");
@@ -383,63 +383,63 @@ BLI_INLINE void madd_m3_m3m3fl(float r[3][3], float a[3][3], float b[3][3], floa
struct Implicit_Data {
typedef std::vector<fMatrix> fMatrixVector;
-
+
Implicit_Data(int numverts)
{
resize(numverts);
}
-
+
void resize(int numverts)
{
this->numverts = numverts;
int tot = 3 * numverts;
-
+
M.resize(tot, tot);
F.resize(tot);
dFdX.resize(tot, tot);
dFdV.resize(tot, tot);
-
+
tfm.resize(numverts, I);
-
+
X.resize(tot);
Xnew.resize(tot);
V.resize(tot);
Vnew.resize(tot);
-
+
A.resize(tot, tot);
B.resize(tot);
-
+
dV.resize(tot);
z.resize(tot);
S.resize(tot, tot);
-
+
iM.reserve(numverts);
idFdX.reserve(numverts);
idFdV.reserve(numverts);
iS.reserve(numverts);
}
-
+
int numverts;
-
+
/* inputs */
lMatrix M; /* masses */
lVector F; /* forces */
lMatrix dFdX, dFdV; /* force jacobians */
-
+
fMatrixVector tfm; /* local coordinate transform */
-
+
/* motion state data */
lVector X, Xnew; /* positions */
lVector V, Vnew; /* velocities */
-
+
/* internal solver data */
lVector B; /* B for A*dV = B */
lMatrix A; /* A for A*dV = B */
-
+
lVector dV; /* velocity change (solution of A*dV = B) */
lVector z; /* target velocity in constrained directions */
lMatrix S; /* filtering matrix for constraints */
-
+
/* temporary constructors */
lMatrixCtor iM; /* masses */
lMatrixCtor idFdX, idFdV; /* force jacobians */
@@ -502,25 +502,25 @@ bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSol
#ifdef USE_EIGEN_CONSTRAINED_CG
typedef ConstraintConjGrad solver_t;
#endif
-
+
data->iM.construct(data->M);
data->idFdX.construct(data->dFdX);
data->idFdV.construct(data->dFdV);
data->iS.construct(data->S);
-
+
solver_t cg;
cg.setMaxIterations(100);
cg.setTolerance(0.01f);
-
+
#ifdef USE_EIGEN_CONSTRAINED_CG
cg.filter() = data->S;
#endif
-
+
data->A = data->M - dt * data->dFdV - dt*dt * data->dFdX;
cg.compute(data->A);
-
+
data->B = dt * data->F + dt*dt * data->dFdX * data->V;
-
+
#ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
printf("==== A ====\n");
print_lmatrix(id->A);
@@ -531,22 +531,22 @@ bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSol
printf("==== S ====\n");
print_lmatrix(id->S);
#endif
-
+
#ifdef USE_EIGEN_CORE
data->dV = cg.solve(data->B);
#endif
#ifdef USE_EIGEN_CONSTRAINED_CG
data->dV = cg.solveWithGuess(data->B, data->z);
#endif
-
+
#ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
printf("==== dV ====\n");
print_lvector(id->dV);
printf("========\n");
#endif
-
+
data->Vnew = data->V + data->dV;
-
+
switch (cg.info()) {
case Eigen::Success: result->status = BPH_SOLVER_SUCCESS; break;
case Eigen::NoConvergence: result->status = BPH_SOLVER_NO_CONVERGENCE; break;
@@ -556,7 +556,7 @@ bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSol
result->iterations = cg.iterations();
result->error = cg.error();
-
+
return cg.info() == Eigen::Success;
}
@@ -641,26 +641,26 @@ void BPH_mass_spring_clear_constraints(Implicit_Data *data)
void BPH_mass_spring_add_constraint_ndof0(Implicit_Data *data, int index, const float dV[3])
{
data->iS.sub(index, index, I);
-
+
world_to_root_v3(data, index, data->z.v3(index), dV);
}
void BPH_mass_spring_add_constraint_ndof1(Implicit_Data *data, int index, const float c1[3], const float c2[3], const float dV[3])
{
float m[3][3], p[3], q[3], u[3], cmat[3][3];
-
+
world_to_root_v3(data, index, p, c1);
outerproduct(cmat, p, p);
copy_m3_m3(m, cmat);
-
+
world_to_root_v3(data, index, q, c2);
outerproduct(cmat, q, q);
add_m3_m3m3(m, m, cmat);
-
+
/* XXX not sure but multiplication should work here */
data->iS.sub(index, index, m);
// mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
-
+
world_to_root_v3(data, index, u, dV);
add_v3_v3(data->z.v3(index), u);
}
@@ -668,14 +668,14 @@ void BPH_mass_spring_add_constraint_ndof1(Implicit_Data *data, int index, const
void BPH_mass_spring_add_constraint_ndof2(Implicit_Data *data, int index, const float c1[3], const float dV[3])
{
float m[3][3], p[3], u[3], cmat[3][3];
-
+
world_to_root_v3(data, index, p, c1);
outerproduct(cmat, p, p);
copy_m3_m3(m, cmat);
-
+
data->iS.sub(index, index, m);
// mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
-
+
world_to_root_v3(data, index, u, dV);
add_v3_v3(data->z.v3(index), u);
}
@@ -694,37 +694,37 @@ void BPH_mass_spring_force_reference_frame(Implicit_Data *data, int index, const
float f[3], dfdx[3][3], dfdv[3][3];
float euler[3], coriolis[3], centrifugal[3], rotvel[3];
float deuler[3][3], dcoriolis[3][3], dcentrifugal[3][3], drotvel[3][3];
-
+
world_to_root_v3(data, index, acc, acceleration);
world_to_root_v3(data, index, w, omega);
world_to_root_v3(data, index, dwdt, domega_dt);
-
+
cross_v3_v3v3(euler, dwdt, data->X.v3(index));
cross_v3_v3v3(coriolis, w, data->V.v3(index));
mul_v3_fl(coriolis, 2.0f);
cross_v3_v3v3(rotvel, w, data->X.v3(index));
cross_v3_v3v3(centrifugal, w, rotvel);
-
+
sub_v3_v3v3(f, acc, euler);
sub_v3_v3(f, coriolis);
sub_v3_v3(f, centrifugal);
-
+
mul_v3_fl(f, mass); /* F = m * a */
-
+
cross_v3_identity(deuler, dwdt);
cross_v3_identity(dcoriolis, w);
mul_m3_fl(dcoriolis, 2.0f);
cross_v3_identity(drotvel, w);
cross_m3_v3m3(dcentrifugal, w, drotvel);
-
+
add_m3_m3m3(dfdx, deuler, dcentrifugal);
negate_m3(dfdx);
mul_m3_fl(dfdx, mass);
-
+
copy_m3_m3(dfdv, dcoriolis);
negate_m3(dfdv);
mul_m3_fl(dfdv, mass);
-
+
add_v3_v3(data->F.v3(index), f);
data->idFdX.add(index, index, dfdx);
data->idFdV.add(index, index, dfdv);
@@ -743,7 +743,7 @@ void BPH_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, c
float f[3];
world_to_root_v3(data, index, f, g);
mul_v3_fl(f, mass);
-
+
add_v3_v3(data->F.v3(index), f);
}
@@ -752,10 +752,10 @@ void BPH_mass_spring_force_drag(Implicit_Data *data, float drag)
int numverts = data->numverts;
for (int i = 0; i < numverts; i++) {
float tmp[3][3];
-
+
/* NB: uses root space velocity, no need to transform */
madd_v3_v3fl(data->F.v3(i), data->V.v3(i), -drag);
-
+
copy_m3_m3(tmp, I);
mul_m3_fl(tmp, -drag);
data->idFdV.add(i, i, tmp);
@@ -768,7 +768,7 @@ void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float
world_to_root_v3(data, i, tf, f);
world_to_root_m3(data, i, tdfdx, dfdx);
world_to_root_m3(data, i, tdfdv, dfdv);
-
+
add_v3_v3(data->F.v3(i), tf);
data->idFdX.add(i, i, tdfdx);
data->idFdV.add(i, i, tdfdv);
@@ -777,10 +777,10 @@ void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float
static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3], const float v3[3])
{
float n1[3], n2[3];
-
+
sub_v3_v3v3(n1, v1, v2);
sub_v3_v3v3(n2, v2, v3);
-
+
cross_v3_v3v3(nor, n1, n2);
return normalize_v3(nor);
}
@@ -791,17 +791,17 @@ void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3
const float effector_scale = 0.02f;
float win[3], nor[3], area;
float factor;
-
+
// calculate face normal and area
area = calc_nor_area_tri(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3));
factor = effector_scale * area / 3.0f;
-
+
world_to_root_v3(data, v1, win, winvec[v1]);
madd_v3_v3fl(data->F.v3(v1), nor, factor * dot_v3v3(win, nor));
-
+
world_to_root_v3(data, v2, win, winvec[v2]);
madd_v3_v3fl(data->F.v3(v2), nor, factor * dot_v3v3(win, nor));
-
+
world_to_root_v3(data, v3, win, winvec[v3]);
madd_v3_v3fl(data->F.v3(v3), nor, factor * dot_v3v3(win, nor));
}
@@ -810,14 +810,14 @@ void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, const
{
const float effector_scale = 0.01;
float win[3], dir[3], nor[3], length;
-
+
sub_v3_v3v3(dir, data->X.v3(v1), data->X.v3(v2));
length = normalize_v3(dir);
-
+
world_to_root_v3(data, v1, win, winvec[v1]);
madd_v3_v3v3fl(nor, win, dir, -dot_v3v3(win, dir));
madd_v3_v3fl(data->F.v3(v1), nor, effector_scale * length);
-
+
world_to_root_v3(data, v2, win, winvec[v2]);
madd_v3_v3v3fl(nor, win, dir, -dot_v3v3(win, dir));
madd_v3_v3fl(data->F.v3(v2), nor, effector_scale * length);
@@ -829,8 +829,8 @@ BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, fl
//return ( (I-outerprod(dir, dir))*Min(1.0f, rest/length) - I) * -k;
outerproduct(to, dir, dir);
sub_m3_m3m3(to, I, to);
-
- mul_m3_fl(to, (L/length));
+
+ mul_m3_fl(to, (L/length));
sub_m3_m3m3(to, to, I);
mul_m3_fl(to, k);
}
@@ -839,7 +839,7 @@ BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, fl
#if 0
BLI_INLINE void dfdx_damp(float to[3][3], const float dir[3], float length, const float vel[3], float rest, float damping)
{
- // inner spring damping vel is the relative velocity of the endpoints.
+ // inner spring damping vel is the relative velocity of the endpoints.
// return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest)));
mul_fvectorT_fvector(to, dir, dir);
sub_fmatrix_fmatrix(to, I, to);
@@ -871,7 +871,7 @@ BLI_INLINE float fbstar(float length, float L, float kb, float cb)
{
float tempfb_fl = kb * fb(length, L);
float fbstar_fl = cb * (length - L);
-
+
if (tempfb_fl < fbstar_fl)
return fbstar_fl;
else
@@ -898,7 +898,7 @@ BLI_INLINE bool spring_length(Implicit_Data *data, int i, int j, float r_extent[
sub_v3_v3v3(r_extent, data->X.v3(j), data->X.v3(i));
sub_v3_v3v3(r_vel, data->V.v3(j), data->V.v3(i));
*r_length = len_v3(r_extent);
-
+
if (*r_length > ALMOST_ZERO) {
/*
if (length>L) {
@@ -916,7 +916,7 @@ BLI_INLINE bool spring_length(Implicit_Data *data, int i, int j, float r_extent[
else {
zero_v3(r_dir);
}
-
+
return true;
}
@@ -924,12 +924,12 @@ BLI_INLINE void apply_spring(Implicit_Data *data, int i, int j, const float f[3]
{
add_v3_v3(data->F.v3(i), f);
sub_v3_v3(data->F.v3(j), f);
-
+
data->idFdX.add(i, i, dfdx);
data->idFdX.add(j, j, dfdx);
data->idFdX.sub(i, j, dfdx);
data->idFdX.sub(j, i, dfdx);
-
+
data->idFdV.add(i, i, dfdv);
data->idFdV.add(j, j, dfdv);
data->idFdV.sub(i, j, dfdv);
@@ -941,39 +941,39 @@ bool BPH_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, floa
float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3])
{
float extent[3], length, dir[3], vel[3];
-
+
// calculate elonglation
spring_length(data, i, j, extent, dir, &length, vel);
-
+
if (length > restlen || no_compress) {
float stretch_force, f[3], dfdx[3][3], dfdv[3][3];
-
+
stretch_force = stiffness * (length - restlen);
if (clamp_force > 0.0f && stretch_force > clamp_force) {
stretch_force = clamp_force;
}
mul_v3_v3fl(f, dir, stretch_force);
-
+
// Ascher & Boxman, p.21: Damping only during elonglation
// something wrong with it...
madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
-
+
dfdx_spring(dfdx, dir, length, restlen, stiffness);
dfdv_damp(dfdv, dir, damping);
-
+
apply_spring(data, i, j, f, dfdx, dfdv);
-
+
if (r_f) copy_v3_v3(r_f, f);
if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
-
+
return true;
}
else {
if (r_f) zero_v3(r_f);
if (r_dfdx) zero_m3(r_dfdx);
if (r_dfdv) zero_m3(r_dfdv);
-
+
return false;
}
}
@@ -984,34 +984,34 @@ bool BPH_mass_spring_force_spring_bending(Implicit_Data *data, int i, int j, flo
float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3])
{
float extent[3], length, dir[3], vel[3];
-
+
// calculate elonglation
spring_length(data, i, j, extent, dir, &length, vel);
-
+
if (length < restlen) {
float f[3], dfdx[3][3], dfdv[3][3];
-
+
mul_v3_v3fl(f, dir, fbstar(length, restlen, kb, cb));
-
+
outerproduct(dfdx, dir, dir);
mul_m3_fl(dfdx, fbstar_jacobi(length, restlen, kb, cb));
-
+
/* XXX damping not supported */
zero_m3(dfdv);
-
+
apply_spring(data, i, j, f, dfdx, dfdv);
-
+
if (r_f) copy_v3_v3(r_f, f);
if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
-
+
return true;
}
else {
if (r_f) zero_v3(r_f);
if (r_dfdx) zero_m3(r_dfdx);
if (r_dfdv) zero_m3(r_dfdv);
-
+
return false;
}
}
@@ -1025,10 +1025,10 @@ bool BPH_mass_spring_force_spring_bending(Implicit_Data *data, int i, int j, flo
BLI_INLINE void spring_grad_dir(Implicit_Data *data, int i, int j, float edge[3], float dir[3], float grad_dir[3][3])
{
float length;
-
+
sub_v3_v3v3(edge, data->X.v3(j), data->X.v3(i));
length = normalize_v3_v3(dir, edge);
-
+
if (length > ALMOST_ZERO) {
outerproduct(grad_dir, dir, dir);
sub_m3_m3m3(grad_dir, I, grad_dir);
@@ -1051,39 +1051,39 @@ BLI_INLINE void spring_angbend_forces(Implicit_Data *data, int i, int j, int k,
float f_bend[3], f_damp[3];
float fk[3];
float dist[3];
-
+
zero_v3(fk);
-
+
sub_v3_v3v3(edge_ij, data->X.v3(j), data->X.v3(i));
if (q == i) sub_v3_v3(edge_ij, dx);
if (q == j) add_v3_v3(edge_ij, dx);
normalize_v3_v3(dir_ij, edge_ij);
-
+
sub_v3_v3v3(edge_jk, data->X.v3(k), data->X.v3(j));
if (q == j) sub_v3_v3(edge_jk, dx);
if (q == k) add_v3_v3(edge_jk, dx);
normalize_v3_v3(dir_jk, edge_jk);
-
+
sub_v3_v3v3(vel_ij, data->V.v3(j), data->V.v3(i));
if (q == i) sub_v3_v3(vel_ij, dv);
if (q == j) add_v3_v3(vel_ij, dv);
-
+
sub_v3_v3v3(vel_jk, data->V.v3(k), data->V.v3(j));
if (q == j) sub_v3_v3(vel_jk, dv);
if (q == k) add_v3_v3(vel_jk, dv);
-
+
/* bending force */
sub_v3_v3v3(dist, goal, edge_jk);
mul_v3_v3fl(f_bend, dist, stiffness);
-
+
add_v3_v3(fk, f_bend);
-
+
/* damping force */
madd_v3_v3v3fl(vel_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
mul_v3_v3fl(f_damp, vel_ortho, damping);
-
+
sub_v3_v3(fk, f_damp);
-
+
copy_v3_v3(r_f, fk);
}
@@ -1097,24 +1097,24 @@ BLI_INLINE void spring_angbend_estimate_dfdx(Implicit_Data *data, int i, int j,
float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
float f[3];
int a, b;
-
+
zero_m3(dvec_null);
unit_m3(dvec_pos);
mul_m3_fl(dvec_pos, delta * 0.5f);
copy_m3_m3(dvec_neg, dvec_pos);
negate_m3(dvec_neg);
-
+
/* XXX TODO offset targets to account for position dependency */
-
+
for (a = 0; a < 3; ++a) {
spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
q, dvec_pos[a], dvec_null[a], f);
copy_v3_v3(dfdx[a], f);
-
+
spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
q, dvec_neg[a], dvec_null[a], f);
sub_v3_v3(dfdx[a], f);
-
+
for (b = 0; b < 3; ++b) {
dfdx[a][b] /= delta;
}
@@ -1131,24 +1131,24 @@ BLI_INLINE void spring_angbend_estimate_dfdv(Implicit_Data *data, int i, int j,
float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
float f[3];
int a, b;
-
+
zero_m3(dvec_null);
unit_m3(dvec_pos);
mul_m3_fl(dvec_pos, delta * 0.5f);
copy_m3_m3(dvec_neg, dvec_pos);
negate_m3(dvec_neg);
-
+
/* XXX TODO offset targets to account for position dependency */
-
+
for (a = 0; a < 3; ++a) {
spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
q, dvec_null[a], dvec_pos[a], f);
copy_v3_v3(dfdv[a], f);
-
+
spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
q, dvec_null[a], dvec_neg[a], f);
sub_v3_v3(dfdv[a], f);
-
+
for (b = 0; b < 3; ++b) {
dfdv[a][b] /= delta;
}
@@ -1165,44 +1165,44 @@ bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data, int i, in
float fj[3], fk[3];
float dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
float dfj_dvi[3][3], dfj_dvj[3][3], dfk_dvi[3][3], dfk_dvj[3][3], dfk_dvk[3][3];
-
+
const float vecnull[3] = {0.0f, 0.0f, 0.0f};
-
+
world_to_root_v3(data, j, goal, target);
-
+
spring_angbend_forces(data, i, j, k, goal, stiffness, damping, k, vecnull, vecnull, fk);
negate_v3_v3(fj, fk); /* counterforce */
-
+
spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, i, dfk_dxi);
spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, j, dfk_dxj);
spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, k, dfk_dxk);
copy_m3_m3(dfj_dxi, dfk_dxi); negate_m3(dfj_dxi);
copy_m3_m3(dfj_dxj, dfk_dxj); negate_m3(dfj_dxj);
-
+
spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, i, dfk_dvi);
spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, j, dfk_dvj);
spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, k, dfk_dvk);
copy_m3_m3(dfj_dvi, dfk_dvi); negate_m3(dfj_dvi);
copy_m3_m3(dfj_dvj, dfk_dvj); negate_m3(dfj_dvj);
-
+
/* add forces and jacobians to the solver data */
-
+
add_v3_v3(data->F.v3(j), fj);
add_v3_v3(data->F.v3(k), fk);
-
+
data->idFdX.add(j, j, dfj_dxj);
data->idFdX.add(k, k, dfk_dxk);
-
+
data->idFdX.add(i, j, dfj_dxi);
data->idFdX.add(j, i, dfj_dxi);
data->idFdX.add(j, k, dfk_dxj);
data->idFdX.add(k, j, dfk_dxj);
data->idFdX.add(i, k, dfk_dxi);
data->idFdX.add(k, i, dfk_dxi);
-
+
data->idFdV.add(j, j, dfj_dvj);
data->idFdV.add(k, k, dfk_dvk);
-
+
data->idFdV.add(i, j, dfj_dvi);
data->idFdV.add(j, i, dfj_dvi);
data->idFdV.add(j, k, dfk_dvj);
@@ -1223,10 +1223,10 @@ bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data, int i, in
float fi[3], fj[3], fk[3];
float dfi_dxi[3][3], dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
float dfdvi[3][3];
-
+
// TESTING
damping = 0.0f;
-
+
zero_v3(fi);
zero_v3(fj);
zero_v3(fk);
@@ -1235,68 +1235,68 @@ bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data, int i, in
zero_m3(dfk_dxi);
zero_m3(dfk_dxj);
zero_m3(dfk_dxk);
-
+
/* jacobian of direction vectors */
spring_grad_dir(data, i, j, edge_ij, dir_ij, grad_dir_ij);
spring_grad_dir(data, j, k, edge_jk, dir_jk, grad_dir_jk);
-
+
sub_v3_v3v3(vel_jk, data->V[k], data->V[j]);
-
+
/* bending force */
mul_v3_v3fl(target, dir_ij, restlen);
sub_v3_v3v3(dist, target, edge_jk);
mul_v3_v3fl(fk, dist, stiffness);
-
+
/* damping force */
madd_v3_v3v3fl(vel_jk_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
madd_v3_v3fl(fk, vel_jk_ortho, damping);
-
+
/* XXX this only holds true as long as we assume straight rest shape!
* eventually will become a bit more involved since the opposite segment
* gets its own target, under condition of having equal torque on both sides.
*/
copy_v3_v3(fi, fk);
-
+
/* counterforce on the middle point */
sub_v3_v3(fj, fi);
sub_v3_v3(fj, fk);
-
+
/* === derivatives === */
-
+
madd_m3_m3fl(dfk_dxi, grad_dir_ij, stiffness * restlen);
-
+
madd_m3_m3fl(dfk_dxj, grad_dir_ij, -stiffness * restlen);
madd_m3_m3fl(dfk_dxj, I, stiffness);
-
+
madd_m3_m3fl(dfk_dxk, I, -stiffness);
-
+
copy_m3_m3(dfi_dxi, dfk_dxk);
negate_m3(dfi_dxi);
-
+
/* dfj_dfi == dfi_dfj due to symmetry,
* dfi_dfj == dfk_dfj due to fi == fk
* XXX see comment above on future bent rest shapes
*/
copy_m3_m3(dfj_dxi, dfk_dxj);
-
+
/* dfj_dxj == -(dfi_dxj + dfk_dxj) due to fj == -(fi + fk) */
sub_m3_m3m3(dfj_dxj, dfj_dxj, dfj_dxi);
sub_m3_m3m3(dfj_dxj, dfj_dxj, dfk_dxj);
-
+
/* add forces and jacobians to the solver data */
add_v3_v3(data->F[i], fi);
add_v3_v3(data->F[j], fj);
add_v3_v3(data->F[k], fk);
-
+
add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfi_dxi);
add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfj_dxj);
add_m3_m3m3(data->dFdX[k].m, data->dFdX[k].m, dfk_dxk);
-
+
add_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfj_dxi);
add_m3_m3m3(data->dFdX[block_jk].m, data->dFdX[block_jk].m, dfk_dxj);
add_m3_m3m3(data->dFdX[block_ik].m, data->dFdX[block_ik].m, dfk_dxi);
#endif
-
+
return true;
}
@@ -1306,40 +1306,40 @@ bool BPH_mass_spring_force_spring_goal(Implicit_Data *data, int i, const float g
{
float root_goal_x[3], root_goal_v[3], extent[3], length, dir[3], vel[3];
float f[3], dfdx[3][3], dfdv[3][3];
-
+
/* goal is in world space */
world_to_root_v3(data, i, root_goal_x, goal_x);
world_to_root_v3(data, i, root_goal_v, goal_v);
-
+
sub_v3_v3v3(extent, root_goal_x, data->X.v3(i));
sub_v3_v3v3(vel, root_goal_v, data->V.v3(i));
length = normalize_v3_v3(dir, extent);
-
+
if (length > ALMOST_ZERO) {
mul_v3_v3fl(f, dir, stiffness * length);
-
+
// Ascher & Boxman, p.21: Damping only during elonglation
// something wrong with it...
madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
-
+
dfdx_spring(dfdx, dir, length, 0.0f, stiffness);
dfdv_damp(dfdv, dir, damping);
-
+
add_v3_v3(data->F.v3(i), f);
data->idFdX.add(i, i, dfdx);
data->idFdV.add(i, i, dfdv);
-
+
if (r_f) copy_v3_v3(r_f, f);
if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
-
+
return true;
}
else {
if (r_f) zero_v3(r_f);
if (r_dfdx) zero_m3(r_dfdx);
if (r_dfdv) zero_m3(r_dfdv);
-
+
return false;
}
}
diff --git a/source/blender/python/bmesh/CMakeLists.txt b/source/blender/python/bmesh/CMakeLists.txt
index 4d3230fa3e9..48213b7eed5 100644
--- a/source/blender/python/bmesh/CMakeLists.txt
+++ b/source/blender/python/bmesh/CMakeLists.txt
@@ -18,7 +18,7 @@
#
# ***** END GPL LICENSE BLOCK *****
-set(INC
+set(INC
.
../../bmesh
../../blenkernel
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index a6ed92d139c..c6a67a1b2dd 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -2153,7 +2153,7 @@ static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args)
if (vert_array == NULL) {
return NULL;
}
-
+
if (BM_edge_exists(vert_array[0], vert_array[1])) {
PyErr_SetString(PyExc_ValueError,
"edges.new(): this edge exists");
diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt
index df611e00d00..9a5a3fddff0 100644
--- a/source/blender/python/generic/CMakeLists.txt
+++ b/source/blender/python/generic/CMakeLists.txt
@@ -18,7 +18,7 @@
#
# ***** END GPL LICENSE BLOCK *****
-set(INC
+set(INC
.
../../blenkernel
../../blenlib
@@ -39,12 +39,14 @@ set(SRC
bpy_internal_import.c
bpy_threads.c
idprop_py_api.c
+ imbuf_py_api.c
py_capi_utils.c
bgl.h
blf_py_api.h
bpy_internal_import.h
idprop_py_api.h
+ imbuf_py_api.h
py_capi_utils.h
# header-only
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 1e2837799e3..8f9475822bf 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -866,7 +866,7 @@ static PyObject *Buffer_slice(Buffer *self, int begin, int end)
{
PyObject *list;
int count;
-
+
if (begin < 0) begin = 0;
if (end > self->dimensions[0]) end = self->dimensions[0];
if (begin > end) begin = end;
@@ -914,11 +914,11 @@ static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq)
{
PyObject *item;
int count, err = 0;
-
+
if (begin < 0) begin = 0;
if (end > self->dimensions[0]) end = self->dimensions[0];
if (begin > end) begin = end;
-
+
if (!PySequence_Check(seq)) {
PyErr_Format(PyExc_TypeError,
"buffer[:] = value, invalid assignment. "
@@ -934,7 +934,7 @@ static int Buffer_ass_slice(Buffer *self, int begin, int end, PyObject *seq)
"Expected: %d (given: %d)", count, end - begin);
return -1;
}
-
+
for (count = begin; count < end; count++) {
item = PySequence_GetItem(seq, count - begin);
if (item) {
diff --git a/source/blender/python/generic/bgl.h b/source/blender/python/generic/bgl.h
index b27a4d6a0a4..1373c81046b 100644
--- a/source/blender/python/generic/bgl.h
+++ b/source/blender/python/generic/bgl.h
@@ -39,7 +39,7 @@ int BGL_typeSize(int type);
* For Python access to OpenGL functions requiring a pointer.
*/
typedef struct _Buffer {
- PyObject_VAR_HEAD
+ PyObject_VAR_HEAD
PyObject *parent;
int type; /* GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT */
diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c
index 02bd1fdbe39..2305d448e04 100644
--- a/source/blender/python/generic/blf_py_api.c
+++ b/source/blender/python/generic/blf_py_api.c
@@ -307,7 +307,7 @@ static PyObject *py_blf_rotation(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "if:blf.rotation", &fontid, &angle))
return NULL;
-
+
BLF_rotation(fontid, angle);
Py_RETURN_NONE;
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index 750d0c20301..0211e7bd880 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -177,7 +177,7 @@ PyObject *bpy_text_import_name(const char *name, int *found)
int namelen = strlen(name);
//XXX Main *maggie = bpy_import_main ? bpy_import_main:G.main;
Main *maggie = bpy_import_main;
-
+
*found = 0;
if (!maggie) {
@@ -210,7 +210,7 @@ PyObject *bpy_text_import_name(const char *name, int *found)
return NULL;
else
*found = 1;
-
+
return bpy_text_import(text);
}
@@ -226,14 +226,14 @@ PyObject *bpy_text_reimport(PyObject *module, int *found)
const char *filepath;
//XXX Main *maggie = bpy_import_main ? bpy_import_main:G.main;
Main *maggie = bpy_import_main;
-
+
if (!maggie) {
printf("ERROR: bpy_import_main_set() was not called before running python. this is a bug.\n");
return NULL;
}
-
+
*found = 0;
-
+
/* get name, filename from the module itself */
if ((name = PyModule_GetName(module)) == NULL)
return NULL;
@@ -288,15 +288,15 @@ static PyObject *blender_import(PyObject *UNUSED(self), PyObject *args, PyObject
/* import existing builtin modules or modules that have been imported already */
newmodule = PyImport_ImportModuleLevel(name, globals, locals, fromlist, level);
-
+
if (newmodule)
return newmodule;
-
+
PyErr_Fetch(&exception, &err, &tb); /* get the python error in case we cant import as blender text either */
-
+
/* importing from existing modules failed, see if we have this module as blender text */
newmodule = bpy_text_import_name(name, &found);
-
+
if (newmodule) { /* found module as blender text, ignore above exception */
PyErr_Clear();
Py_XDECREF(exception);
diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h
index f11571fb933..8de1436ed48 100644
--- a/source/blender/python/generic/bpy_internal_import.h
+++ b/source/blender/python/generic/bpy_internal_import.h
@@ -1,4 +1,4 @@
-/*
+/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -47,7 +47,7 @@ bool bpy_text_compile(struct Text *text);
PyObject *bpy_text_import(struct Text *text);
PyObject *bpy_text_import_name(const char *name, int *found);
PyObject *bpy_text_reimport(PyObject *module, int *found);
-/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
+/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text);
diff --git a/source/blender/python/generic/imbuf_py_api.c b/source/blender/python/generic/imbuf_py_api.c
new file mode 100644
index 00000000000..2e32829bf6c
--- /dev/null
+++ b/source/blender/python/generic/imbuf_py_api.c
@@ -0,0 +1,447 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/generic/imbuf_py_api.c
+ * \ingroup pygen
+ *
+ * This file defines the 'imbuf' image manipulation module.
+ */
+
+#include <Python.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+
+#include "py_capi_utils.h"
+
+#include "python_utildefines.h"
+
+#include "imbuf_py_api.h" /* own include */
+
+#include "../../imbuf/IMB_imbuf.h"
+#include "../../imbuf/IMB_imbuf_types.h"
+
+/* File IO */
+#include <fcntl.h>
+#include <errno.h>
+#include "BLI_fileops.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Type & Utilities
+ * \{ */
+
+typedef struct Py_ImBuf {
+ PyObject_VAR_HEAD
+ /* can be NULL */
+ ImBuf *ibuf;
+} Py_ImBuf;
+
+static int py_imbuf_valid_check(Py_ImBuf *self)
+{
+ if (LIKELY(self->ibuf)) {
+ return 0;
+ }
+ else {
+ PyErr_Format(PyExc_ReferenceError,
+ "ImBuf data of type %.200s has been freed",
+ Py_TYPE(self)->tp_name);
+ return -1;
+ }
+}
+
+#define PY_IMBUF_CHECK_OBJ(obj) \
+ if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { return NULL; } ((void)0)
+#define PY_IMBUF_CHECK_INT(obj) \
+ if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { return -1; } ((void)0)
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Methods
+ * \{ */
+
+PyDoc_STRVAR(py_imbuf_resize_doc,
+".. method:: resize(size, method='FAST')\n"
+"\n"
+" Resize the image.\n"
+"\n"
+" :arg size: New size.\n"
+" :type size: pair of ints\n"
+" :arg method: Method of resizing (TODO)\n"
+" :type method: str\n"
+);
+static PyObject *py_imbuf_resize(Py_ImBuf *self, PyObject *args, PyObject *kw)
+{
+ PY_IMBUF_CHECK_OBJ(self);
+
+ uint size[2];
+ char *method = NULL;
+
+ static const char *_keywords[] = {"size", "method", NULL};
+ static _PyArg_Parser _parser = {"(II)|s:resize", _keywords, 0};
+ if (!_PyArg_ParseTupleAndKeywordsFast(
+ args, kw, &_parser,
+ &size[0], &size[1],
+ &method))
+ {
+ return NULL;
+ }
+ IMB_scaleImBuf(self->ibuf, UNPACK2(size));
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(py_imbuf_free_doc,
+".. method:: free()\n"
+"\n"
+" Clear image data immediately (causing an error on re-use).\n"
+);
+static PyObject *py_imbuf_free(Py_ImBuf *self)
+{
+ if (self->ibuf) {
+ IMB_freeImBuf(self->ibuf);
+ self->ibuf = NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static struct PyMethodDef Py_ImBuf_methods[] = {
+ {"resize", (PyCFunction)py_imbuf_resize, METH_VARARGS | METH_KEYWORDS, (char *)py_imbuf_resize_doc},
+ {"free", (PyCFunction)py_imbuf_free, METH_NOARGS, (char *)py_imbuf_free_doc},
+ {NULL, NULL, 0, NULL}
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Attributes
+ * \{ */
+
+PyDoc_STRVAR(py_imbuf_size_doc,
+"size of the image in pixels.\n\n:type: pair of ints"
+);
+static PyObject *py_imbuf_size_get(Py_ImBuf *self, void *UNUSED(closure))
+{
+ PY_IMBUF_CHECK_OBJ(self);
+ ImBuf *ibuf = self->ibuf;
+ return PyC_Tuple_Pack_I32(ibuf->x, ibuf->y);
+}
+
+PyDoc_STRVAR(py_imbuf_ppm_doc,
+"pixels per meter.\n\n:type: pair of floats"
+);
+static PyObject *py_imbuf_ppm_get(Py_ImBuf *self, void *UNUSED(closure))
+{
+ PY_IMBUF_CHECK_OBJ(self);
+ ImBuf *ibuf = self->ibuf;
+ return PyC_Tuple_Pack_F64(ibuf->ppm[0], ibuf->ppm[1]);
+}
+
+static int py_imbuf_ppm_set(Py_ImBuf *self, PyObject *value, void *UNUSED(closure))
+{
+ PY_IMBUF_CHECK_INT(self);
+ double ppm[2];
+
+ if (PyC_AsArray(ppm, value, 2, &PyFloat_Type, true, "ppm") == -1) {
+ return -1;
+ }
+
+ if (ppm[0] <= 0.0 || ppm[1] <= 0.0) {
+ PyErr_SetString(PyExc_ValueError, "invalid ppm value");
+ return -1;
+ }
+
+ ImBuf *ibuf = self->ibuf;
+ ibuf->ppm[0] = ppm[0];
+ ibuf->ppm[1] = ppm[1];
+ return 0;
+}
+
+static PyGetSetDef Py_ImBuf_getseters[] = {
+ {(char *)"size", (getter)py_imbuf_size_get, (setter)NULL, (char *)py_imbuf_size_doc, NULL},
+ {(char *)"ppm", (getter)py_imbuf_ppm_get, (setter)py_imbuf_ppm_set, (char *)py_imbuf_ppm_doc, NULL},
+ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Type & Implementation
+ * \{ */
+
+static void py_imbuf_dealloc(Py_ImBuf *self)
+{
+ ImBuf *ibuf = self->ibuf;
+ if (ibuf != NULL) {
+ IMB_freeImBuf(self->ibuf);
+ self->ibuf = NULL;
+ }
+ PyObject_DEL(self);
+}
+
+static PyObject *py_imbuf_repr(Py_ImBuf *self)
+{
+ const ImBuf *ibuf = self->ibuf;
+ if (ibuf != NULL) {
+ return PyUnicode_FromFormat(
+ "<imbuf: address=%p, filename='%s', size=(%d, %d)>",
+ ibuf, ibuf->name, ibuf->x, ibuf->y);
+ }
+ else {
+ return PyUnicode_FromString(
+ "<imbuf: address=0x0>");
+ }
+}
+
+static Py_hash_t py_imbuf_hash(Py_ImBuf *self)
+{
+ return _Py_HashPointer(self->ibuf);
+}
+
+PyTypeObject Py_ImBuf_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /* For printing, in format "<module>.<name>" */
+ "ImBuf", /* tp_name */
+ sizeof(Py_ImBuf), /* int tp_basicsize; */
+ 0, /* tp_itemsize; For allocation */
+
+ /* Methods to implement standard operations */
+
+ (destructor)py_imbuf_dealloc, /* destructor tp_dealloc; */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* cmpfunc tp_compare; */
+ (reprfunc)py_imbuf_repr, /* reprfunc tp_repr; */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ (hashfunc)py_imbuf_hash, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ NULL, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+ /*** Attribute descriptor and subclassing stuff ***/
+ Py_ImBuf_methods, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ Py_ImBuf_getseters, /* struct PyGetSetDef *tp_getset; */
+};
+
+static PyObject *Py_ImBuf_CreatePyObject(ImBuf *ibuf)
+{
+ Py_ImBuf *self = PyObject_New(Py_ImBuf, &Py_ImBuf_Type);
+ self->ibuf = ibuf;
+ return (PyObject *)self;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Module Functions
+ * \{ */
+
+PyDoc_STRVAR(M_imbuf_new_doc,
+".. function:: new(size)\n"
+"\n"
+" Load a new image.\n"
+"\n"
+" :arg size: The size of the image in pixels.\n"
+" :type size: pair of ints\n"
+" :return: the newly loaded image.\n"
+" :rtype: :class:`ImBuf`\n"
+);
+static PyObject *M_imbuf_new(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ int size[2];
+ static const char *_keywords[] = {"size", NULL};
+ static _PyArg_Parser _parser = {"(ii)|i:new", _keywords, 0};
+ if (!_PyArg_ParseTupleAndKeywordsFast(
+ args, kw, &_parser,
+ &size[0], &size[1]))
+ {
+ return NULL;
+ }
+
+ /* TODO, make options */
+ uchar planes = 4;
+ uint flags = IB_rect;
+
+ ImBuf *ibuf = IMB_allocImBuf(UNPACK2(size), planes, flags);
+ if (ibuf == NULL) {
+ PyErr_Format(PyExc_ValueError, "new: Unable to create image (%d, %d)", UNPACK2(size));
+ return NULL;
+ }
+ return Py_ImBuf_CreatePyObject(ibuf);
+}
+
+PyDoc_STRVAR(M_imbuf_load_doc,
+".. function:: load(filename)\n"
+"\n"
+" Load an image from a file.\n"
+"\n"
+" :arg filename: the filename of the image.\n"
+" :type filename: string\n"
+" :return: the newly loaded image.\n"
+" :rtype: :class:`ImBuf`\n"
+);
+static PyObject *M_imbuf_load(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ const char *filename;
+
+ static const char *_keywords[] = {"filename", NULL};
+ static _PyArg_Parser _parser = {"s:load", _keywords, 0};
+ if (!_PyArg_ParseTupleAndKeywordsFast(
+ args, kw, &_parser,
+ &filename))
+ {
+ return NULL;
+ }
+
+ const int file = BLI_open(filename, O_BINARY | O_RDONLY, 0);
+ if (file == -1) {
+ PyErr_Format(PyExc_IOError, "load: %s, failed to open file '%s'", strerror(errno));
+ return NULL;
+ }
+
+ ImBuf *ibuf = IMB_loadifffile(file, filename, IB_rect, NULL, filename);
+
+ close(file);
+
+ if (ibuf == NULL) {
+ PyErr_Format(PyExc_ValueError, "load: Unable to recognize image format for file '%s'", filename);
+ return NULL;
+ }
+
+ BLI_strncpy(ibuf->name, filename, sizeof(ibuf->name));
+
+ return Py_ImBuf_CreatePyObject(ibuf);
+}
+
+PyDoc_STRVAR(M_imbuf_write_doc,
+".. function:: write(image, filename)\n"
+"\n"
+" Write an image.\n"
+"\n"
+" :arg image: the image to write.\n"
+" :type image: :class:`ImBuf`\n"
+" :arg filename: the filename of the image.\n"
+" :type filename: string\n"
+);
+static PyObject *M_imbuf_write(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ Py_ImBuf *py_imb;
+ const char *filename = NULL;
+
+ static const char *_keywords[] = {"image", "filename", NULL};
+ static _PyArg_Parser _parser = {"O!|s:write", _keywords, 0};
+ if (!_PyArg_ParseTupleAndKeywordsFast(
+ args, kw, &_parser,
+ &Py_ImBuf_Type, &py_imb,
+ &filename))
+ {
+ return NULL;
+ }
+
+ if (filename == NULL) {
+ filename = py_imb->ibuf->name;
+ }
+
+ bool ok = IMB_saveiff(py_imb->ibuf, filename, IB_rect);
+ if (ok == false) {
+ PyErr_Format(PyExc_IOError, "write: Unable to write image file (%s) '%s'", strerror(errno), filename);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Module Definition
+ * \{ */
+
+static PyMethodDef IMB_methods[] = {
+ {"new", (PyCFunction) M_imbuf_new, METH_VARARGS | METH_KEYWORDS, M_imbuf_new_doc},
+ {"load", (PyCFunction) M_imbuf_load, METH_VARARGS | METH_KEYWORDS, M_imbuf_load_doc},
+ {"write", (PyCFunction) M_imbuf_write, METH_VARARGS | METH_KEYWORDS, M_imbuf_write_doc},
+ {NULL, NULL, 0, NULL}
+};
+
+PyDoc_STRVAR(IMB_doc,
+"This module provides access to Blender's image manipulation API."
+);
+static struct PyModuleDef IMB_module_def = {
+ PyModuleDef_HEAD_INIT,
+ "imbuf", /* m_name */
+ IMB_doc, /* m_doc */
+ 0, /* m_size */
+ IMB_methods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyObject *BPyInit_imbuf(void)
+{
+ PyObject *submodule;
+
+ submodule = PyModule_Create(&IMB_module_def);
+
+ PyType_Ready(&Py_ImBuf_Type);
+
+ return submodule;
+}
+
+/** \} */
diff --git a/source/blender/python/generic/imbuf_py_api.h b/source/blender/python/generic/imbuf_py_api.h
new file mode 100644
index 00000000000..92c1732a9c9
--- /dev/null
+++ b/source/blender/python/generic/imbuf_py_api.h
@@ -0,0 +1,30 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __IMBUF_PY_API_H__
+#define __IMBUF_PY_API_H__
+
+/** \file blender/python/generic/imbuf_py_api.h
+ * \ingroup pygen
+ */
+
+PyObject *BPyInit_imbuf(void);
+
+#endif /* __IMBUF_PY_API_H__ */
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 6f265b2ae87..22646462163 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -295,7 +295,7 @@ void PyC_LineSpit(void)
PyErr_Clear();
PyC_FileAndNum(&filename, &lineno);
-
+
fprintf(stderr, "%s:%d\n", filename, lineno);
}
@@ -317,7 +317,7 @@ void PyC_StackSpit(void)
void PyC_FileAndNum(const char **filename, int *lineno)
{
PyFrameObject *frame;
-
+
if (filename) *filename = NULL;
if (lineno) *lineno = -1;
@@ -375,22 +375,22 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
Py_ssize_t i;
PyObject *item = o;
const char *attr;
-
+
va_list vargs;
va_start(vargs, n);
for (i = 0; i < n; i++) {
attr = va_arg(vargs, char *);
item = PyObject_GetAttrString(item, attr);
-
- if (item)
+
+ if (item)
Py_DECREF(item);
else /* python will set the error value here */
break;
-
+
}
va_end(vargs);
-
+
Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
return item;
}
@@ -839,7 +839,7 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
}
}
va_end(vargs);
-
+
/* set the value so we can access it */
PyDict_SetItemString(py_dict, "values", values);
Py_DECREF(values);
@@ -865,7 +865,7 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
for (i = 0; i * 2 < n; i++) {
const char *format = va_arg(vargs, char *);
void *ptr = va_arg(vargs, void *);
-
+
PyObject *item;
PyObject *item_new;
/* prepend the string formatting and remake the tuple */
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index e07fa46424c..a0461ed945d 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -171,7 +171,7 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
return NULL;
}
-
+
/* same logic as BKE_appdir_folder_id_create(), but best leave it up to the script author to create */
path = BKE_appdir_folder_id(folder_id, subdir);
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index f6e89ef38a5..03662102bbc 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -253,10 +253,10 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *clos
PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False");
return -1;
}
-
+
if (param) G.debug |= flag;
else G.debug &= ~flag;
-
+
return 0;
}
@@ -307,7 +307,7 @@ static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void
PyErr_SetString(PyExc_TypeError, "bpy.app.debug_value can only be set to a whole number");
return -1;
}
-
+
G.debug_value = param;
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -406,7 +406,7 @@ static void py_struct_seq_getset_init(void)
PyObject *BPY_app_struct(void)
{
PyObject *ret;
-
+
PyStructSequence_InitType(&BlenderAppType, &app_info_desc);
ret = make_app_info();
diff --git a/source/blender/python/intern/bpy_capi_utils.c b/source/blender/python/intern/bpy_capi_utils.c
index 7232e4ea821..f873a8a762b 100644
--- a/source/blender/python/intern/bpy_capi_utils.c
+++ b/source/blender/python/intern/bpy_capi_utils.c
@@ -88,21 +88,21 @@ bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const boo
if (!PyErr_Occurred())
return 1;
-
+
/* less hassle if we allow NULL */
if (reports == NULL) {
PyErr_Print();
PyErr_Clear();
return 1;
}
-
+
if (use_full) {
pystring = PyC_ExceptionBuffer();
}
else {
pystring = PyC_ExceptionBuffer_Simple();
}
-
+
if (pystring == NULL) {
BKE_report(reports, RPT_ERROR, "Unknown py-exception, could not convert");
return 0;
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index c8ce7b2f770..215a64a4449 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -285,7 +285,7 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna, ChannelDriver *driver, c
for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) {
PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
}
-
+
driver->flag &= ~DRIVER_FLAG_RENAMEVAR;
}
else {
@@ -342,7 +342,7 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna, ChannelDriver *driver, c
fprintf(stderr, "\nBPY_driver_eval() - Error while evaluating PyDriver:\n");
targets_ok = 0;
}
-
+
fprintf(stderr, "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->name);
// BPy_errors_to_report(NULL); // TODO - reports
PyErr_Print();
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 7156bed0c2b..5f51f2ac152 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -74,6 +74,7 @@
#include "../generic/bgl.h"
#include "../generic/blf_py_api.h"
#include "../generic/idprop_py_api.h"
+#include "../generic/imbuf_py_api.h"
#include "../gawain/gwn_py_api.h"
#include "../bmesh/bmesh_py_api.h"
#include "../mathutils/mathutils.h"
@@ -221,6 +222,7 @@ static struct _inittab bpy_internal_modules[] = {
{"_gawain", BPyInit_gawain},
{"bgl", BPyInit_bgl},
{"blf", BPyInit_blf},
+ {"imbuf", BPyInit_imbuf},
{"bmesh", BPyInit_bmesh},
#if 0
{"bmesh.types", BPyInit_bmesh_types},
@@ -291,7 +293,7 @@ void BPY_python_start(int argc, const char **argv)
PySys_SetObject("argv", py_argv);
Py_DECREF(py_argv);
}
-
+
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads();
#else
@@ -330,7 +332,7 @@ void BPY_python_start(int argc, const char **argv)
BPy_init_modules();
bpy_import_init(PyEval_GetBuiltins());
-
+
pyrna_alloc_types();
#ifndef WITH_PYTHON_MODULE
@@ -349,7 +351,7 @@ void BPY_python_end(void)
/* finalizing, no need to grab the state, except when we are a module */
gilstate = PyGILState_Ensure();
-
+
/* free other python data. */
pyrna_free_types();
@@ -696,7 +698,7 @@ bool BPY_execute_string_ex(bContext *C, const char *expr, bool use_eval)
PyC_MainModule_Restore(main_mod);
bpy_context_clear(C, &gilstate);
-
+
return ok;
}
@@ -730,7 +732,7 @@ void BPY_modules_load_user(bContext *C)
G.f |= G_SCRIPT_AUTOEXEC_FAIL;
BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Text '%s'", text->id.name + 2);
- printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name + 2);
+ printf("scripts disabled for \"%s\", skipping '%s'\n", BKE_main_blendfile_path(bmain), text->id.name + 2);
}
}
else {
@@ -880,7 +882,7 @@ static void bpy_module_delay_init(PyObject *bpy_proxy)
argv[0] = filename_abs;
argv[1] = NULL;
-
+
// printf("module found %s\n", argv[0]);
main_python_enter(argc, argv);
@@ -909,14 +911,14 @@ PyMODINIT_FUNC
PyInit_bpy(void)
{
PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def);
-
+
/* Problem:
* 1) this init function is expected to have a private member defined - 'md_def'
* but this is only set for C defined modules (not py packages)
* so we cant return 'bpy_package_py' as is.
*
* 2) there is a 'bpy' C module for python to load which is basically all of blender,
- * and there is scripts/bpy/__init__.py,
+ * and there is scripts/bpy/__init__.py,
* we may end up having to rename this module so there is no naming conflict here eg:
* 'from blender import bpy'
*
@@ -926,13 +928,13 @@ PyInit_bpy(void)
/* assign an object which is freed after __file__ is assigned */
dealloc_obj *dob;
-
+
/* assign dummy type */
dealloc_obj_Type.tp_name = "dealloc_obj";
dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj);
dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc;
dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT;
-
+
if (PyType_Ready(&dealloc_obj_Type) < 0)
return NULL;
diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c
index 0ca46f9b20e..d60c44e702a 100644
--- a/source/blender/python/intern/bpy_library_load.c
+++ b/source/blender/python/intern/bpy_library_load.c
@@ -205,7 +205,7 @@ static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *
BLI_strncpy(ret->relpath, filename, sizeof(ret->relpath));
BLI_strncpy(ret->abspath, filename, sizeof(ret->abspath));
- BLI_path_abs(ret->abspath, bmain->name);
+ BLI_path_abs(ret->abspath, BKE_main_blendfile_path(bmain));
ret->blo_handle = NULL;
ret->flag = ((is_link ? FILE_LINK : 0) |
diff --git a/source/blender/python/intern/bpy_library_write.c b/source/blender/python/intern/bpy_library_write.c
index 9ca6092eab3..ead10efb212 100644
--- a/source/blender/python/intern/bpy_library_write.c
+++ b/source/blender/python/intern/bpy_library_write.c
@@ -107,7 +107,7 @@ static PyObject *bpy_lib_write(PyObject *UNUSED(self), PyObject *args, PyObject
}
BLI_strncpy(filepath_abs, filepath, FILE_MAX);
- BLI_path_abs(filepath_abs, G.main->name);
+ BLI_path_abs(filepath_abs, BKE_main_blendfile_path_from_global());
BKE_blendfile_write_partial_begin(bmain_src);
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 0cadbc30a9f..4652da2018c 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -79,7 +79,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
/* XXX Todo, work out a better solution for passing on context,
* could make a tuple from self and pack the name and Context into it... */
bContext *C = (bContext *)BPy_GetContext();
-
+
if (C == NULL) {
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
return NULL;
@@ -87,7 +87,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str))
return NULL;
-
+
ot = WM_operatortype_find(opname, true);
if (ot == NULL) {
@@ -108,7 +108,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
return NULL;
}
}
-
+
if (context_dict == NULL || context_dict == Py_None) {
context_dict = NULL;
}
@@ -123,10 +123,10 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
context_dict_back = CTX_py_dict_get(C);
CTX_py_dict_set(C, (void *)context_dict);
Py_XINCREF(context_dict); /* so we done loose it */
-
+
/* main purpose of thsi function */
ret = WM_operator_poll_context((bContext *)C, ot, context) ? Py_True : Py_False;
-
+
/* restore with original context dict, probably NULL but need this for nested operator calls */
Py_XDECREF(context_dict);
CTX_py_dict_set(C, (void *)context_dict_back);
@@ -154,12 +154,12 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
/* XXX Todo, work out a better solution for passing on context,
* could make a tuple from self and pack the name and Context into it... */
bContext *C = (bContext *)BPy_GetContext();
-
+
if (C == NULL) {
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
return NULL;
}
-
+
if (!PyArg_ParseTuple(args, "sO|O!si:_bpy.ops.call",
&opname, &context_dict, &PyDict_Type, &kw, &context_str, &is_undo))
{
@@ -174,7 +174,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
"could not be found", opname);
return NULL;
}
-
+
if (!pyrna_write_check()) {
PyErr_Format(PyExc_RuntimeError,
"Calling operator \"bpy.ops.%s\" error, "
@@ -259,7 +259,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
PySys_WriteStdout("%s: %s\n", report->typestr, report->message);
}
}
-
+
BKE_reports_clear(reports);
if ((reports->flag & RPT_FREE) == 0) {
MEM_freeN(reports);
@@ -330,7 +330,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
PyErr_SetString(PyExc_RuntimeError, "Context is None, cant get the string representation of this object.");
return NULL;
}
-
+
if (!PyArg_ParseTuple(
args, "s|O!O&O&:_bpy.ops.as_string",
&opname, &PyDict_Type, &kw,
@@ -400,7 +400,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
PointerRNA ptr;
const char *opname = _PyUnicode_AsString(value);
BPy_StructRNA *pyrna = NULL;
-
+
if (opname == NULL) {
PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument");
return NULL;
@@ -410,7 +410,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname);
return NULL;
}
-
+
/* type */
//RNA_pointer_create(NULL, &RNA_Struct, ot->srna, &ptr);
@@ -418,7 +418,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
WM_operator_properties_create_ptr(&ptr, ot);
WM_operator_properties_sanitize(&ptr, 0);
-
+
pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
pyrna->freeptr = true;
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index d3eddff4b9a..d0b0331430d 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -366,7 +366,7 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *
Py_DECREF(ret);
}
-
+
if (use_gil)
PyGILState_Release(gilstate);
@@ -1329,7 +1329,7 @@ static int icon_id_from_name(const char *name)
}
}
}
-
+
return 0;
}
@@ -1631,7 +1631,7 @@ static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject
{
BooleanPropertyGetFunc rna_get_cb = NULL;
BooleanPropertySetFunc rna_set_cb = NULL;
-
+
if (get_cb && get_cb != Py_None) {
PyObject **py_data = bpy_prop_py_data_get(prop);
@@ -1653,7 +1653,7 @@ static void bpy_prop_callback_assign_boolean_array(struct PropertyRNA *prop, PyO
{
BooleanArrayPropertyGetFunc rna_get_cb = NULL;
BooleanArrayPropertySetFunc rna_set_cb = NULL;
-
+
if (get_cb && get_cb != Py_None) {
PyObject **py_data = bpy_prop_py_data_get(prop);
@@ -1675,7 +1675,7 @@ static void bpy_prop_callback_assign_int(struct PropertyRNA *prop, PyObject *get
{
IntPropertyGetFunc rna_get_cb = NULL;
IntPropertySetFunc rna_set_cb = NULL;
-
+
if (get_cb && get_cb != Py_None) {
PyObject **py_data = bpy_prop_py_data_get(prop);
@@ -1697,7 +1697,7 @@ static void bpy_prop_callback_assign_int_array(struct PropertyRNA *prop, PyObjec
{
IntArrayPropertyGetFunc rna_get_cb = NULL;
IntArrayPropertySetFunc rna_set_cb = NULL;
-
+
if (get_cb && get_cb != Py_None) {
PyObject **py_data = bpy_prop_py_data_get(prop);
@@ -1719,7 +1719,7 @@ static void bpy_prop_callback_assign_float(struct PropertyRNA *prop, PyObject *g
{
FloatPropertyGetFunc rna_get_cb = NULL;
FloatPropertySetFunc rna_set_cb = NULL;
-
+
if (get_cb && get_cb != Py_None) {
PyObject **py_data = bpy_prop_py_data_get(prop);
@@ -1741,7 +1741,7 @@ static void bpy_prop_callback_assign_float_array(struct PropertyRNA *prop, PyObj
{
FloatArrayPropertyGetFunc rna_get_cb = NULL;
FloatArrayPropertySetFunc rna_set_cb = NULL;
-
+
if (get_cb && get_cb != Py_None) {
PyObject **py_data = bpy_prop_py_data_get(prop);
@@ -1764,7 +1764,7 @@ static void bpy_prop_callback_assign_string(struct PropertyRNA *prop, PyObject *
StringPropertyGetFunc rna_get_cb = NULL;
StringPropertyLengthFunc rna_length_cb = NULL;
StringPropertySetFunc rna_set_cb = NULL;
-
+
if (get_cb && get_cb != Py_None) {
PyObject **py_data = bpy_prop_py_data_get(prop);
@@ -1788,7 +1788,7 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *ge
EnumPropertyGetFunc rna_get_cb = NULL;
EnumPropertyItemFunc rna_itemf_cb = NULL;
EnumPropertySetFunc rna_set_cb = NULL;
-
+
if (get_cb && get_cb != Py_None) {
PyObject **py_data = bpy_prop_py_data_get(prop);
@@ -1815,7 +1815,7 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *ge
RNA_def_property_enum_funcs_runtime(prop, rna_get_cb, rna_set_cb, rna_itemf_cb);
}
-/* this define runs at the start of each function and deals with
+/* this define runs at the start of each function and deals with
* returning a deferred property (to be registered later) */
#define BPY_PROPDEF_HEAD(_func) \
if (PyTuple_GET_SIZE(args) == 1) { \
@@ -2166,7 +2166,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
-
+
Py_RETURN_NONE;
}
@@ -2801,7 +2801,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
StructRNA *srna;
BPY_PROPDEF_HEAD(EnumProperty);
-
+
if (srna) {
const char *id = NULL, *name = NULL, *description = "";
PyObject *def = NULL;
@@ -3195,7 +3195,7 @@ PyObject *BPY_rna_props(void)
{
PyObject *submodule;
PyObject *submodule_dict;
-
+
submodule = PyModule_Create(&props_module);
PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule);
@@ -3203,7 +3203,7 @@ PyObject *BPY_rna_props(void)
* module with a new ref like PyDict_New, since they are passed to
* PyModule_AddObject which steals a ref */
Py_INCREF(submodule);
-
+
/* api needs the PyObjects internally */
submodule_dict = PyModule_GetDict(submodule);
@@ -3220,6 +3220,6 @@ PyObject *BPY_rna_props(void)
ASSIGN_STATIC(PointerProperty);
ASSIGN_STATIC(CollectionProperty);
ASSIGN_STATIC(RemoveProperty);
-
+
return submodule;
}
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 3bbeaea2674..7903f92265b 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -40,11 +40,12 @@
#include "ED_keyframing.h"
#include "ED_keyframes_edit.h"
-#include "BKE_report.h"
-#include "BKE_context.h"
#include "BKE_animsys.h"
+#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_global.h"
#include "BKE_idcode.h"
+#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -234,13 +235,13 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
struct Depsgraph *depsgraph = CTX_data_depsgraph(BPy_GetContext());
ReportList reports;
short result = 0;
-
+
PointerRNA ptr = self->ptr;
PropertyRNA *prop = NULL;
const char *prop_name;
-
+
BKE_reports_init(&reports, RPT_STORE);
-
+
/* Retrieve the property identifier from the full path, since we can't get it any other way */
prop_name = strrchr(path_full, '.');
if ((prop_name >= path_full) &&
@@ -248,21 +249,21 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
{
prop = RNA_struct_find_property(&ptr, prop_name + 1);
}
-
+
if (prop) {
NlaStrip *strip = (NlaStrip *)ptr.data;
FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
-
+
result = insert_keyframe_direct(depsgraph, &reports, ptr, prop, fcu, cfra, keytype, options);
}
else {
BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full);
}
MEM_freeN((void *)path_full);
-
+
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
-
+
return PyBool_FromLong(result);
}
else {
@@ -272,7 +273,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
BKE_reports_init(&reports, RPT_STORE);
- result = insert_keyframe(depsgraph, &reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, keytype, options);
+ result = insert_keyframe(G.main, depsgraph, &reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, keytype, options);
MEM_freeN((void *)path_full);
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
@@ -322,13 +323,13 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
*/
ReportList reports;
short result = 0;
-
+
PointerRNA ptr = self->ptr;
PropertyRNA *prop = NULL;
const char *prop_name;
-
+
BKE_reports_init(&reports, RPT_STORE);
-
+
/* Retrieve the property identifier from the full path, since we can't get it any other way */
prop_name = strrchr(path_full, '.');
if ((prop_name >= path_full) &&
@@ -336,14 +337,14 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
{
prop = RNA_struct_find_property(&ptr, prop_name + 1);
}
-
+
if (prop) {
ID *id = ptr.id.data;
NlaStrip *strip = (NlaStrip *)ptr.data;
FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
-
+
BLI_assert(fcu != NULL); /* NOTE: This should be true, or else we wouldn't be able to get here */
-
+
if (BKE_fcurve_is_protected(fcu)) {
BKE_reportf(&reports, RPT_WARNING,
"Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
@@ -356,7 +357,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
*/
bool found = false;
int i;
-
+
/* try to find index of beztriple to get rid of */
i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
if (found) {
@@ -370,10 +371,10 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full);
}
MEM_freeN((void *)path_full);
-
+
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
-
+
return PyBool_FromLong(result);
}
else {
@@ -425,7 +426,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
BKE_reports_init(&reports, RPT_STORE);
- result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index,
+ result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index,
CREATEDRIVER_WITH_FMODIFIER, DRIVER_TYPE_PYTHON);
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
@@ -451,7 +452,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
ret = pyrna_struct_CreatePyObject(&tptr);
}
-
+
WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
}
else {
@@ -504,7 +505,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
return NULL;
-
+
WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
return PyBool_FromLong(result);
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index ed9d1e9c0e5..571ee0edea2 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -277,10 +277,10 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA
* dimsize[1] = 4
* dimsize[2] = 5
* lvalue_dim = 0, totdim = 3
- *
+ *
* arr[2][3] = x
* lvalue_dim = 1
- *
+ *
* arr[2][3][4] = x
* lvalue_dim = 2 */
for (i = lvalue_dim; i < totdim; i++)
@@ -805,7 +805,7 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr,
*
* x = arr[2]
* index = 0 + 2 * 4 * 5
- *
+ *
* x = arr[2][3]
* index = offset + 3 * 5 */
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
index 6b8684c7acd..45d556d68e9 100644
--- a/source/blender/python/intern/bpy_rna_callback.c
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -93,7 +93,7 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
if (!PyArg_ParseTuple(args, "OO!|s:bpy_struct.callback_add", &cb_func, &PyTuple_Type, &cb_args, &cb_event_str))
return NULL;
-
+
if (!PyCallable_Check(cb_func)) {
PyErr_SetString(PyExc_TypeError, "callback_add(): first argument isn't callable");
return NULL;
diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c
index a8ec828c13f..a65469ea739 100644
--- a/source/blender/python/intern/gpu_offscreen.c
+++ b/source/blender/python/intern/gpu_offscreen.c
@@ -35,6 +35,8 @@
#include "WM_types.h"
+#include "BKE_global.h"
+
#include "ED_screen.h"
#include "GPU_framebuffer.h"
diff --git a/source/blender/python/mathutils/CMakeLists.txt b/source/blender/python/mathutils/CMakeLists.txt
index f70f893aeac..adf7c85d7c9 100644
--- a/source/blender/python/mathutils/CMakeLists.txt
+++ b/source/blender/python/mathutils/CMakeLists.txt
@@ -18,7 +18,7 @@
#
# ***** END GPL LICENSE BLOCK *****
-set(INC
+set(INC
.
../../blenlib
../../blenkernel
diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h
index d2fbe6a04d5..f7c8d7eebeb 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.h
+++ b/source/blender/python/mathutils/mathutils_Matrix.h
@@ -1,4 +1,4 @@
-/*
+/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
diff --git a/source/blender/python/mathutils/mathutils_interpolate.c b/source/blender/python/mathutils/mathutils_interpolate.c
index c8cb71874db..720fac7c276 100644
--- a/source/blender/python/mathutils/mathutils_interpolate.c
+++ b/source/blender/python/mathutils/mathutils_interpolate.c
@@ -60,10 +60,10 @@ static PyObject *M_Interpolate_poly_3d_calc(PyObject *UNUSED(self), PyObject *ar
float fp[3];
float (*vecs)[3];
Py_ssize_t len;
-
+
PyObject *point, *veclist, *ret;
int i;
-
+
if (!PyArg_ParseTuple(
args, "OO!:poly_3d_calc",
&veclist,
@@ -71,27 +71,27 @@ static PyObject *M_Interpolate_poly_3d_calc(PyObject *UNUSED(self), PyObject *ar
{
return NULL;
}
-
+
if (BaseMath_ReadCallback((VectorObject *)point) == -1)
return NULL;
-
+
fp[0] = ((VectorObject *)point)->vec[0];
fp[1] = ((VectorObject *)point)->vec[1];
if (((VectorObject *)point)->size > 2)
fp[2] = ((VectorObject *)point)->vec[2];
else
fp[2] = 0.0f; /* if its a 2d vector then set the z to be zero */
-
+
len = mathutils_array_parse_alloc_v(((float **)&vecs), 3, veclist, __func__);
if (len == -1) {
return NULL;
}
-
+
if (len) {
float *weights = MEM_mallocN(sizeof(float) * len, __func__);
-
+
interp_weights_poly_v3(weights, vecs, len, fp);
-
+
ret = PyList_New(len);
for (i = 0; i < len; i++) {
PyList_SET_ITEM(ret, i, PyFloat_FromDouble(weights[i]));
diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c
index 88c89b90dc8..839d1ffc588 100644
--- a/source/blender/python/mathutils/mathutils_noise.c
+++ b/source/blender/python/mathutils/mathutils_noise.c
@@ -671,7 +671,7 @@ static PyObject *M_Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject *
if (mathutils_array_parse(vec, 3, 3, value, "hybrid_multi_fractal: invalid 'position' arg") == -1)
return NULL;
-
+
return PyFloat_FromDouble(mg_HybridMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, nb));
}
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 0f0060c7578..359369228f8 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -24,7 +24,7 @@
# ***** END GPL LICENSE BLOCK *****
-set(INC
+set(INC
extern/include
intern/include
../blenkernel
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 1b0707bafc0..660e81eb022 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -103,11 +103,11 @@ typedef struct RenderPass {
/* after render, the Combined pass is in combined, for renderlayers read from files it is a real pass */
typedef struct RenderLayer {
struct RenderLayer *next, *prev;
-
+
/* copy of RenderData */
char name[RE_MAXNAME];
int layflag, passflag, pass_xor;
-
+
/* MULTIVIEW_TODO: acolrect and scolrect are not supported by multiview at the moment.
* If they are really required they should be in RenderView instead */
@@ -121,16 +121,16 @@ typedef struct RenderLayer {
void *exrhandle;
ListBase passes;
-
+
} RenderLayer;
typedef struct RenderResult {
struct RenderResult *next, *prev;
-
+
/* target image size */
int rectx, recty;
short crop, sample_nr;
-
+
/* the following rect32, rectf and rectz buffers are for temporary storage only, for RenderResult structs
* created in #RE_AcquireResultImage - which do not have RenderView */
@@ -140,25 +140,25 @@ typedef struct RenderResult {
float *rectf;
/* if this exists, a copy of one of layers, or result of composited layers */
float *rectz;
-
+
/* coordinates within final image (after cropping) */
rcti tilerect;
/* offset to apply to get a border render in full image */
int xof, yof;
-
+
/* the main buffers */
ListBase layers;
-
+
/* multiView maps to a StringVector in OpenEXR */
ListBase views; /* RenderView */
/* allowing live updates: */
volatile rcti renrect;
volatile RenderLayer *renlay;
-
+
/* optional saved endresult on disk */
int do_exr_tile;
-
+
/* for render results in Image, verify validity for sequences */
int framenr;
diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h
new file mode 100644
index 00000000000..c66427ae788
--- /dev/null
+++ b/source/blender/render/intern/include/envmap.h
@@ -0,0 +1,54 @@
+/*
+ * envmap_ext.h
+ *
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/envmap.h
+ * \ingroup render
+ */
+
+
+#ifndef __ENVMAP_H__
+#define __ENVMAP_H__
+
+/**
+ * Make environment maps for all objects in the scene that have an
+ * environment map as texture.
+ * (initrender.c)
+ */
+
+struct Render;
+struct TexResult;
+struct ImagePool;
+
+void make_envmaps(struct Render *re);
+int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, const bool skip_image_load);
+void env_rotate_scene(struct Render *re, float mat[4][4], int do_rotate);
+
+#endif /* __ENVMAP_H__ */
+
diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h
index e7ff3c7097c..b8732e7cc5c 100644
--- a/source/blender/render/intern/include/initrender.h
+++ b/source/blender/render/intern/include/initrender.h
@@ -31,7 +31,7 @@
#ifndef __INITRENDER_H__
-#define __INITRENDER_H__
+#define __INITRENDER_H__
/* Functions */
diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h
new file mode 100644
index 00000000000..022510c7132
--- /dev/null
+++ b/source/blender/render/intern/include/pixelblending.h
@@ -0,0 +1,65 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): 2004-2006 Blender Foundation, full recode
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/pixelblending.h
+ * \ingroup render
+ */
+
+
+#ifndef __PIXELBLENDING_H__
+#define __PIXELBLENDING_H__
+
+
+/**
+ * add 1 pixel to into filtered three lines
+ * (float vecs to float vec)
+ */
+void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w);
+void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize);
+void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_stride, int x, int y, rcti *mask);
+void mask_array(unsigned int mask, float filt[3][3]);
+
+/**
+ * Alpha-over blending for floats.
+ */
+void addAlphaOverFloat(float dest[4], const float source[4]);
+
+/**
+ * Alpha-under blending for floats.
+ */
+void addAlphaUnderFloat(float dest[4], const float source[4]);
+
+
+/**
+ * Same for floats
+ */
+void addalphaAddfacFloat(float dest[4], const float source[4], char addfac);
+
+/**
+ * dest = dest + source
+ */
+void addalphaAddFloat(float dest[4], const float source[4]);
+
+#endif /* __PIXELBLENDING_H__ */
diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h
new file mode 100644
index 00000000000..0e630eda475
--- /dev/null
+++ b/source/blender/render/intern/include/pixelshading.h
@@ -0,0 +1,62 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): 2004-2006, Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/pixelshading.h
+ * \ingroup render
+ *
+ * These functions determine what actual color a pixel will have.
+ */
+
+#ifndef __PIXELSHADING_H__
+#define __PIXELSHADING_H__
+
+
+/**
+ * Render the pixel at (x,y) for object ap. Apply the jitter mask.
+ * Output is given in float collector[4]. The type vector:
+ * t[0] - min. distance
+ * t[1] - face/halo index
+ * t[2] - jitter mask
+ * t[3] - type ZB_POLY or ZB_HALO
+ * t[4] - max. distance
+ * mask is pixel coverage in bits
+ * \return pointer to the object
+ */
+int shadeHaloFloat(HaloRen *har,
+ float *col, int zz,
+ float dist, float xn,
+ float yn, short flarec);
+
+/**
+ * Render the sky at pixel (x, y).
+ */
+void shadeSkyPixel(float collector[4], float fx, float fy, short thread);
+void shadeSkyView(float col_r[3], const float rco[3], const float view[3], const float dxyview[2], short thread);
+void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance);
+void shadeSunView(float col_r[3], const float view[3]);
+/* ------------------------------------------------------------------------- */
+
+#endif
+
diff --git a/source/blender/render/intern/include/pointdensity.h b/source/blender/render/intern/include/pointdensity.h
new file mode 100644
index 00000000000..eadf714c1ba
--- /dev/null
+++ b/source/blender/render/intern/include/pointdensity.h
@@ -0,0 +1,51 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Matt Ebb
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/pointdensity.h
+ * \ingroup render
+ */
+
+
+#ifndef __POINTDENSITY_H__
+#define __POINTDENSITY_H__
+
+/**
+ * Make point density kd-trees for all point density textures in the scene
+ */
+
+struct PointDensity;
+struct Render;
+struct TexResult;
+
+void free_pointdensity(struct PointDensity *pd);
+void cache_pointdensity(struct Render *re, struct PointDensity *pd);
+void make_pointdensities(struct Render *re);
+void free_pointdensities(struct Render *re);
+int pointdensitytex(struct Tex *tex, const float texvec[3], struct TexResult *texres);
+
+#endif /* __POINTDENSITY_H__ */
+
diff --git a/source/blender/render/intern/include/raycounter.h b/source/blender/render/intern/include/raycounter.h
new file mode 100644
index 00000000000..e16c6e13c7e
--- /dev/null
+++ b/source/blender/render/intern/include/raycounter.h
@@ -0,0 +1,74 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/raycounter.h
+ * \ingroup render
+ */
+
+
+#ifndef __RAYCOUNTER_H__
+#define __RAYCOUNTER_H__
+
+//#define RE_RAYCOUNTER /* enable counters per ray, useful for measuring raytrace structures performance */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef RE_RAYCOUNTER
+
+/* ray counter functions */
+
+typedef struct RayCounter {
+ struct {
+ unsigned long long test, hit;
+ } faces, bb, simd_bb, raycast, raytrace_hint, rayshadow_last_hit;
+} RayCounter;
+
+#define RE_RC_INIT(isec, shi) (isec).raycounter = &((shi).shading.raycounter)
+void RE_RC_INFO(RayCounter *rc);
+void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp);
+#define RE_RC_COUNT(var) (var)++
+
+extern RayCounter re_rc_counter[];
+
+#else
+
+/* ray counter stubs */
+
+#define RE_RC_INIT(isec,shi)
+#define RE_RC_INFO(rc)
+#define RE_RC_MERGE(dest,src)
+#define RE_RC_COUNT(var)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/blender/render/intern/include/rayintersection.h b/source/blender/render/intern/include/rayintersection.h
new file mode 100644
index 00000000000..a303301ad3b
--- /dev/null
+++ b/source/blender/render/intern/include/rayintersection.h
@@ -0,0 +1,136 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * RE_raytrace.h: ray tracing api, can be used independently from the renderer.
+ */
+
+/** \file blender/render/intern/include/rayintersection.h
+ * \ingroup render
+ */
+
+
+#ifndef __RAYINTERSECTION_H__
+#define __RAYINTERSECTION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "BLI_math_geom.h"
+
+struct RayObject;
+
+/* Ray Hints */
+
+#define RE_RAY_LCTS_MAX_SIZE 256
+#define RT_USE_LAST_HIT /* last shadow hit is reused before raycasting on whole tree */
+//#define RT_USE_HINT /* last hit object is reused before raycasting on whole tree */
+
+typedef struct LCTSHint {
+ int size;
+ struct RayObject *stack[RE_RAY_LCTS_MAX_SIZE];
+} LCTSHint;
+
+typedef struct RayHint {
+ union { LCTSHint lcts; } data;
+} RayHint;
+
+/* Ray Intersection */
+
+typedef struct Isect {
+ /* ray start, direction (normalized vector), and max distance. on hit,
+ * the distance is modified to be the distance to the hit point. */
+ float start[3];
+ float dir[3];
+ float dist;
+
+ /* for envmap and incremental view update renders */
+ float origstart[3];
+ float origdir[3];
+
+ /* precomputed values to accelerate bounding box intersection */
+ int bv_index[6];
+ float idot_axis[3];
+
+ /* intersection options */
+ int mode; /* RE_RAY_SHADOW, RE_RAY_MIRROR, RE_RAY_SHADOW_TRA */
+ int lay; /* -1 default, set for layer lamps */
+ int skip; /* skip flags */
+ int check; /* check flags */
+ void *userdata; /* used by bake check */
+
+ /* hit information */
+ float u, v;
+ int isect; /* which half of quad */
+
+ struct {
+ void *ob;
+ void *face;
+ } hit, orig;
+
+ /* last hit optimization */
+ struct RayObject *last_hit;
+
+ /* hints */
+#ifdef RT_USE_HINT
+ RayTraceHint *hint, *hit_hint;
+#endif
+ RayHint *hint;
+
+ /* ray counter */
+#ifdef RE_RAYCOUNTER
+ RayCounter *raycounter;
+#endif
+
+ /* Precalculated coefficients for watertight intersection check. */
+ struct IsectRayPrecalc isect_precalc;
+} Isect;
+
+/* ray types */
+#define RE_RAY_SHADOW 0
+#define RE_RAY_MIRROR 1
+#define RE_RAY_SHADOW_TRA 2
+
+/* skip options */
+#define RE_SKIP_CULLFACE (1 << 0)
+/* if using this flag then *face should be a pointer to a VlakRen */
+#define RE_SKIP_VLR_NEIGHBOUR (1 << 1)
+
+/* check options */
+#define RE_CHECK_VLR_NONE 0
+#define RE_CHECK_VLR_RENDER 1
+#define RE_CHECK_VLR_NON_SOLID_MATERIAL 2
+#define RE_CHECK_VLR_BAKE 3
+
+/* arbitrary, but can't use e.g. FLT_MAX because of precision issues */
+#define RE_RAYTRACE_MAXDIST 1e15f
+#define RE_RAYTRACE_EPSILON 0.0f
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RAYINTERSECTION_H__ */
+
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 8308b5e76e4..fd24f4eb053 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -52,10 +52,10 @@ struct Main;
/* this is handed over to threaded hiding/passes/shading engine */
typedef struct RenderPart {
struct RenderPart *next, *prev;
-
+
RenderResult *result; /* result of part rendering */
ListBase fullresult; /* optional full sample buffers */
-
+
rcti disprect; /* part coordinates within total picture */
int rectx, recty; /* the size */
int nr; /* nr is partnr */
@@ -74,10 +74,10 @@ struct Render {
struct Render *next, *prev;
char name[RE_MAXNAME];
int slot;
-
+
/* state settings */
short flag, ok, result_ok;
-
+
/* result of rendering */
RenderResult *result;
/* if render with single-layer option, other rendered layers are stored here */
@@ -88,29 +88,29 @@ struct Render {
* write lock, all external code must use a read lock. internal code is assumed
* to not conflict with writes, so no lock used for that */
ThreadRWMutex resultmutex;
-
+
/* window size, display rect, viewplane */
int winx, winy; /* buffer width and height with percentage applied
* without border & crop. convert to long before multiplying together to avoid overflow. */
rcti disprect; /* part within winx winy */
rctf viewplane; /* mapped on winx winy */
-
+
/* final picture width and height (within disprect) */
int rectx, recty;
-
- /* real maximum size of parts after correction for minimum
+
+ /* real maximum size of parts after correction for minimum
* partx*xparts can be larger than rectx, in that case last part is smaller */
int partx, party;
-
+
/* Camera transform, only used by Freestyle. */
float viewmat[4][4], viewinv[4][4];
float viewmat_orig[4][4]; /* for incremental render */
float winmat[4][4];
-
+
/* clippping */
float clipsta;
float clipend;
-
+
/* main, scene, and its full copy of renderdata and world */
struct Main *main;
Scene *scene;
@@ -119,13 +119,13 @@ struct Render {
int active_view_layer;
struct Object *camera_override;
unsigned int lay, layer_override;
-
+
ThreadRWMutex partsmutex;
ListBase parts;
-
+
/* render engine */
struct RenderEngine *engine;
-
+
#ifdef WITH_FREESTYLE
struct Main *freestyle_bmain;
ListBase freestyle_renders;
@@ -140,17 +140,17 @@ struct Render {
void *duh;
void (*current_scene_update)(void *handle, struct Scene *scene);
void *suh;
-
+
void (*stats_draw)(void *handle, RenderStats *ri);
void *sdh;
void (*progress)(void *handle, float i);
void *prh;
-
+
void (*draw_lock)(void *handle, int i);
void *dlh;
int (*test_break)(void *handle);
void *tbh;
-
+
RenderStats i;
struct ReportList *reports;
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
new file mode 100644
index 00000000000..aa3efca9e5b
--- /dev/null
+++ b/source/blender/render/intern/include/rendercore.h
@@ -0,0 +1,105 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __RENDERCORE_H__
+#define __RENDERCORE_H__
+
+/** \file blender/render/intern/include/rendercore.h
+ * \ingroup render
+ */
+
+#include "render_types.h"
+
+#include "RE_engine.h"
+
+#include "DNA_node_types.h"
+
+#include "NOD_composite.h"
+
+struct ShadeInput;
+struct ShadeResult;
+struct World;
+struct RenderPart;
+struct RenderLayer;
+struct RayObject;
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct PixStr {
+ struct PixStr *next;
+ int obi, facenr, z, maskz;
+ unsigned short mask;
+ short shadfac;
+} PixStr;
+
+typedef struct PixStrMain {
+ struct PixStrMain *next, *prev;
+ struct PixStr *ps;
+ int counter;
+} PixStrMain;
+
+/* ------------------------------------------------------------------------- */
+
+
+void calc_view_vector(float view[3], float x, float y);
+float mistfactor(float zcor, const float co[3]); /* dist and height, return alpha */
+
+void renderspothalo(struct ShadeInput *shi, float col[4], float alpha);
+void add_halo_flare(Render *re);
+
+void calc_renderco_zbuf(float co[3], const float view[3], int z);
+void calc_renderco_ortho(float co[3], float x, float y, int z);
+
+int count_mask(unsigned short mask);
+
+void zbufshade_tile(struct RenderPart *pa);
+void zbufshadeDA_tile(struct RenderPart *pa);
+
+void zbufshade_sss_tile(struct RenderPart *pa);
+
+int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct RenderLayer **rlpp);
+
+void render_internal_update_passes(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl);
+
+
+/* -------- ray.c ------- */
+
+struct RayObject *RE_rayobject_create(int type, int size, int octree_resolution);
+
+extern void freeraytree(Render *re);
+extern void makeraytree(Render *re);
+struct RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi);
+
+extern void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]);
+extern void ray_trace(ShadeInput *shi, ShadeResult *);
+extern void ray_ao(ShadeInput *shi, float ao[3], float env[3]);
+extern void init_jitter_plane(LampRen *lar);
+extern void init_ao_sphere(Render *re, struct World *wrld);
+extern void init_render_qmcsampler(Render *re);
+extern void free_render_qmcsampler(Render *re);
+
+#endif /* __RENDERCORE_H__ */
diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h
new file mode 100644
index 00000000000..e306c3c075c
--- /dev/null
+++ b/source/blender/render/intern/include/shading.h
@@ -0,0 +1,105 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/shading.h
+ * \ingroup render
+ */
+
+
+struct ShadeInput;
+struct ShadeResult;
+struct RenderPart;
+struct RenderLayer;
+struct PixStr;
+struct LampRen;
+struct VlakRen;
+struct StrandPoint;
+struct ObjectInstanceRen;
+struct Isect;
+
+/* shadeinput.c */
+
+#define RE_MAX_OSA 16
+
+/* needed to calculate shadow and AO for an entire pixel */
+typedef struct ShadeSample {
+ int tot; /* amount of shi in use, can be 1 for not FULL_OSA */
+
+ RenderLayer *rlpp[RE_MAX_OSA]; /* fast lookup from sample to renderlayer (fullsample buf) */
+
+ /* could be malloced once */
+ ShadeInput shi[RE_MAX_OSA];
+ ShadeResult shr[RE_MAX_OSA];
+} ShadeSample;
+
+
+ /* also the node shader callback */
+void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
+
+void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3);
+void shade_input_set_triangle(struct ShadeInput *shi, int obi, int facenr, int normal_flip);
+void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from);
+void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3]);
+void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float sx, float sy, float z);
+void shade_input_set_uv(struct ShadeInput *shi);
+void shade_input_set_normals(struct ShadeInput *shi);
+void shade_input_set_vertex_normals(struct ShadeInput *shi);
+void shade_input_flip_normals(struct ShadeInput *shi);
+void shade_input_set_shade_texco(struct ShadeInput *shi);
+void shade_input_set_strand(struct ShadeInput *shi, struct StrandRen *strand, struct StrandPoint *spoint);
+void shade_input_set_strand_texco(struct ShadeInput *shi, struct StrandRen *strand, struct StrandVert *svert, struct StrandPoint *spoint);
+void shade_input_do_shade(struct ShadeInput *shi, struct ShadeResult *shr);
+
+void shade_input_init_material(struct ShadeInput *shi);
+void shade_input_initialize(struct ShadeInput *shi, struct RenderPart *pa, struct RenderLayer *rl, int sample);
+
+void shade_sample_initialize(struct ShadeSample *ssamp, struct RenderPart *pa, struct RenderLayer *rl);
+void shade_samples_do_AO(struct ShadeSample *ssamp);
+void shade_samples_fill_with_ps(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y);
+int shade_samples(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y);
+
+void vlr_set_uv_indices(struct VlakRen *vlr, int *i1, int *i2, int *i3);
+
+void calc_R_ref(struct ShadeInput *shi);
+
+void barycentric_differentials_from_position(
+ const float co[3], const float v1[3], const float v2[3], const float v3[3],
+ const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials,
+ float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v);
+
+/* shadeoutput. */
+void shade_lamp_loop(struct ShadeInput *shi, struct ShadeResult *shr);
+
+void shade_color(struct ShadeInput *shi, ShadeResult *shr);
+
+void ambient_occlusion(struct ShadeInput *shi);
+void environment_lighting_apply(struct ShadeInput *shi, struct ShadeResult *shr);
+
+ListBase *get_lights(struct ShadeInput *shi);
+float lamp_get_visibility(struct LampRen *lar, const float co[3], float lv[3], float *dist);
+void lamp_get_shadow(struct LampRen *lar, ShadeInput *shi, float inp, float shadfac[4], int do_real);
+
+float fresnel_fac(const float view[3], const float vn[3], float fresnel, float fac);
+
+/* rayshade.c */
+extern void shade_ray(struct Isect *is, struct ShadeInput *shi, struct ShadeResult *shr);
diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h
new file mode 100644
index 00000000000..f4e22c78b42
--- /dev/null
+++ b/source/blender/render/intern/include/strand.h
@@ -0,0 +1,99 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/strand.h
+ * \ingroup render
+ */
+
+
+#ifndef __STRAND_H__
+#define __STRAND_H__
+
+struct StrandVert;
+struct StrandRen;
+struct StrandBuffer;
+struct ShadeSample;
+struct StrandPart;
+struct Render;
+struct ZSpan;
+struct ObjectInstanceRen;
+struct StrandSurface;
+struct DerivedMesh;
+struct ObjectRen;
+
+typedef struct StrandPoint {
+ /* position within segment */
+ float t;
+
+ /* camera space */
+ float co[3];
+ float nor[3];
+ float tan[3];
+ float strandco;
+ float width;
+
+ /* derivatives */
+ float dtco[3], dsco[3];
+ float dtstrandco;
+
+ /* outer points */
+ float co1[3], co2[3];
+ float hoco1[4], hoco2[4];
+ float zco1[3], zco2[3];
+ int clip1, clip2;
+
+ /* screen space */
+ float hoco[4];
+ float x, y;
+
+ /* simplification */
+ float alpha;
+} StrandPoint;
+
+typedef struct StrandSegment {
+ struct StrandVert *v[4];
+ struct StrandRen *strand;
+ struct StrandBuffer *buffer;
+ struct ObjectInstanceRen *obi;
+ float sqadaptcos;
+
+ StrandPoint point1, point2;
+ int shaded;
+} StrandSegment;
+
+struct StrandShadeCache;
+typedef struct StrandShadeCache StrandShadeCache;
+
+void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
+void render_strand_segment(struct Render *re, float winmat[4][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
+void strand_minmax(struct StrandRen *strand, float min[3], float max[3], const float width);
+
+struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[4][4], int timeoffset);
+void free_strand_surface(struct Render *re);
+
+struct StrandShadeCache *strand_shade_cache_create(void);
+void strand_shade_cache_free(struct StrandShadeCache *cache);
+void strand_shade_segment(struct Render *re, struct StrandShadeCache *cache, struct StrandSegment *sseg, struct ShadeSample *ssamp, float t, float s, int addpassflag);
+void strand_shade_unref(struct StrandShadeCache *cache, struct ObjectInstanceRen *obi, struct StrandVert *svert);
+
+#endif
+
diff --git a/source/blender/render/intern/include/sunsky.h b/source/blender/render/intern/include/sunsky.h
new file mode 100644
index 00000000000..c608f9fc48c
--- /dev/null
+++ b/source/blender/render/intern/include/sunsky.h
@@ -0,0 +1,81 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): zaghaghi
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/sunsky.h
+ * \ingroup render
+ */
+
+#ifndef __SUNSKY_H__
+#define __SUNSKY_H__
+
+// #define SPECTRUM_MAX_COMPONENTS 100
+
+typedef struct SunSky {
+ short effect_type, skyblendtype, sky_colorspace;
+ float turbidity;
+ float theta, phi;
+
+ float toSun[3];
+
+ /*float sunSpectralRaddata[SPECTRUM_MAX_COMPONENTS];*/
+ float sunSolidAngle;
+
+ float zenith_Y, zenith_x, zenith_y;
+
+ float perez_Y[5], perez_x[5], perez_y[5];
+
+ /* suggested by glome in patch [#8063] */
+ float horizon_brightness;
+ float spread;
+ float sun_brightness;
+ float sun_size;
+ float backscattered_light;
+ float skyblendfac;
+ float sky_exposure;
+
+ float atm_HGg;
+
+ float atm_SunIntensity;
+ float atm_InscatteringMultiplier;
+ float atm_ExtinctionMultiplier;
+ float atm_BetaRayMultiplier;
+ float atm_BetaMieMultiplier;
+ float atm_DistanceMultiplier;
+
+ float atm_BetaRay[3];
+ float atm_BetaDashRay[3];
+ float atm_BetaMie[3];
+ float atm_BetaDashMie[3];
+ float atm_BetaRM[3];
+} SunSky;
+
+void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness,
+ float spread, float sun_brightness, float sun_size, float back_scatter,
+ float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace);
+
+void GetSkyXYZRadiance(struct SunSky *sunsky, float theta, float phi, float color_out[3]);
+void GetSkyXYZRadiancef(struct SunSky *sunsky, const float varg[3], float color_out[3]);
+void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float rayf, float inscattf, float extincf, float disf);
+void AtmospherePixleShader(struct SunSky *sunSky, float view[3], float s, float rgb[3]);
+void ClipColor(float c[3]);
+
+#endif /*__SUNSKY_H__*/
diff --git a/source/blender/render/intern/include/texture_ocean.h b/source/blender/render/intern/include/texture_ocean.h
new file mode 100644
index 00000000000..6d7bc6fe7b0
--- /dev/null
+++ b/source/blender/render/intern/include/texture_ocean.h
@@ -0,0 +1,35 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributors: Matt Ebb
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __TEXTURE_OCEAN_H__
+#define __TEXTURE_OCEAN_H__
+
+/** \file blender/render/intern/include/texture_ocean.h
+ * \ingroup render
+ */
+
+int ocean_texture(struct Tex *tex, const float texvec[2], struct TexResult *texres);
+
+#endif /* __TEXTURE_OCEAN_H__ */
diff --git a/source/blender/render/intern/include/voxeldata.h b/source/blender/render/intern/include/voxeldata.h
new file mode 100644
index 00000000000..041ca78a799
--- /dev/null
+++ b/source/blender/render/intern/include/voxeldata.h
@@ -0,0 +1,47 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Raul Fernandez Hernandez (Farsthary), Matt Ebb.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/voxeldata.h
+ * \ingroup render
+ */
+
+#ifndef __VOXELDATA_H__
+#define __VOXELDATA_H__
+
+struct Render;
+struct TexResult;
+
+typedef struct VoxelDataHeader {
+ int resolX, resolY, resolZ;
+ int frames;
+} VoxelDataHeader;
+
+void cache_voxeldata(Tex *tex, int scene_frame);
+void make_voxeldata(struct Render *re);
+int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres);
+
+#endif /* __VOXELDATA_H__ */
diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index 3dfcbc355c4..0654a4f8df6 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -36,7 +36,7 @@
/* span fill in method, is also used to localize data for zbuffering */
typedef struct ZSpan {
int rectx, recty; /* range for clipping */
-
+
int miny1, maxy1, miny2, maxy2; /* actual filled in range */
const float *minp1, *maxp1, *minp2, *maxp2; /* vertex pointers detect min/max range in */
float *span1, *span2;
diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h
new file mode 100644
index 00000000000..0f9a506762b
--- /dev/null
+++ b/source/blender/render/intern/raytrace/bvh.h
@@ -0,0 +1,407 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/bvh.h
+ * \ingroup render
+ */
+
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "raycounter.h"
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "rayobject_hint.h"
+#include "rayobject_rtbuild.h"
+
+#include <assert.h>
+
+#ifdef __SSE__
+#include <xmmintrin.h>
+#endif
+
+#ifndef __BVH_H__
+#define __BVH_H__
+
+#ifdef __SSE__
+inline int test_bb_group4(__m128 *bb_group, const Isect *isec)
+{
+ const __m128 tmin0 = _mm_setzero_ps();
+ const __m128 tmax0 = _mm_set_ps1(isec->dist);
+
+ float start[3], idot_axis[3];
+ copy_v3_v3(start, isec->start);
+ copy_v3_v3(idot_axis, isec->idot_axis);
+
+ const __m128 tmin1 = _mm_max_ps(tmin0, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[0]], _mm_set_ps1(start[0]) ), _mm_set_ps1(idot_axis[0])) );
+ const __m128 tmax1 = _mm_min_ps(tmax0, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[1]], _mm_set_ps1(start[0]) ), _mm_set_ps1(idot_axis[0])) );
+ const __m128 tmin2 = _mm_max_ps(tmin1, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[2]], _mm_set_ps1(start[1]) ), _mm_set_ps1(idot_axis[1])) );
+ const __m128 tmax2 = _mm_min_ps(tmax1, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[3]], _mm_set_ps1(start[1]) ), _mm_set_ps1(idot_axis[1])) );
+ const __m128 tmin3 = _mm_max_ps(tmin2, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[4]], _mm_set_ps1(start[2]) ), _mm_set_ps1(idot_axis[2])) );
+ const __m128 tmax3 = _mm_min_ps(tmax2, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[5]], _mm_set_ps1(start[2]) ), _mm_set_ps1(idot_axis[2])) );
+
+ return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3));
+}
+#endif
+
+/*
+ * Determines the distance that the ray must travel to hit the bounding volume of the given node
+ * Based on Tactical Optimization of Ray/Box Intersection, by Graham Fyffe
+ * [http://tog.acm.org/resources/RTNews/html/rtnv21n1.html#art9]
+ */
+static inline int rayobject_bb_intersect_test(const Isect *isec, const float *_bb)
+{
+ const float *bb = _bb;
+
+ float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0];
+ float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0];
+ float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1];
+ float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1];
+ float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2];
+ float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2];
+
+ RE_RC_COUNT(isec->raycounter->bb.test);
+
+ if (t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0;
+ if (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) return 0;
+ if (t1x > isec->dist || t1y > isec->dist || t1z > isec->dist) return 0;
+ RE_RC_COUNT(isec->raycounter->bb.hit);
+
+ return 1;
+}
+
+/* bvh tree generics */
+template<class Tree> static void bvh_add(Tree *obj, RayObject *ob)
+{
+ rtbuild_add(obj->builder, ob);
+}
+
+template<class Node>
+inline bool is_leaf(Node *node)
+{
+ return !RE_rayobject_isAligned(node);
+}
+
+template<class Tree> static void bvh_done(Tree *obj);
+
+template<class Tree>
+static void bvh_free(Tree *obj)
+{
+ if (obj->builder)
+ rtbuild_free(obj->builder);
+
+ if (obj->node_arena)
+ BLI_memarena_free(obj->node_arena);
+
+ MEM_freeN(obj);
+}
+
+template<class Tree>
+static void bvh_bb(Tree *obj, float *min, float *max)
+{
+ if (obj->root)
+ bvh_node_merge_bb(obj->root, min, max);
+}
+
+
+template<class Tree>
+static float bvh_cost(Tree *obj)
+{
+ assert(obj->cost >= 0.0f);
+ return obj->cost;
+}
+
+
+
+/* bvh tree nodes generics */
+template<class Node> static inline int bvh_node_hit_test(Node *node, Isect *isec)
+{
+ return rayobject_bb_intersect_test(isec, (const float *)node->bb);
+}
+
+
+template<class Node>
+static inline void bvh_node_merge_bb(Node *node, float min[3], float max[3])
+{
+ if (is_leaf(node)) {
+ RE_rayobject_merge_bb((RayObject *)node, min, max);
+ }
+ else {
+ DO_MIN(node->bb, min);
+ DO_MAX(node->bb + 3, max);
+ }
+}
+
+
+
+/*
+ * recursively transverse a BVH looking for a rayhit using a local stack
+ */
+template<class Node> static inline void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos);
+
+template<class Node, int MAX_STACK_SIZE, bool TEST_ROOT, bool SHADOW>
+static int bvh_node_stack_raycast(Node *root, Isect *isec)
+{
+ Node *stack[MAX_STACK_SIZE];
+ int hit = 0, stack_pos = 0;
+
+ if (!TEST_ROOT && !is_leaf(root))
+ bvh_node_push_childs(root, isec, stack, stack_pos);
+ else
+ stack[stack_pos++] = root;
+
+ while (stack_pos) {
+ Node *node = stack[--stack_pos];
+ if (!is_leaf(node)) {
+ if (bvh_node_hit_test(node, isec)) {
+ bvh_node_push_childs(node, isec, stack, stack_pos);
+ assert(stack_pos <= MAX_STACK_SIZE);
+ }
+ }
+ else {
+ hit |= RE_rayobject_intersect( (RayObject *)node, isec);
+ if (SHADOW && hit) return hit;
+ }
+ }
+ return hit;
+}
+
+
+#ifdef __SSE__
+/*
+ * Generic SIMD bvh recursion
+ * this was created to be able to use any simd (with the cost of some memmoves)
+ * it can take advantage of any SIMD width and doens't needs any special tree care
+ */
+template<class Node, int MAX_STACK_SIZE, bool TEST_ROOT>
+static int bvh_node_stack_raycast_simd(Node *root, Isect *isec)
+{
+ Node *stack[MAX_STACK_SIZE];
+
+ int hit = 0, stack_pos = 0;
+
+ if (!TEST_ROOT) {
+ if (!is_leaf(root)) {
+ if (!is_leaf(root->child))
+ bvh_node_push_childs(root, isec, stack, stack_pos);
+ else
+ return RE_rayobject_intersect( (RayObject *)root->child, isec);
+ }
+ else
+ return RE_rayobject_intersect( (RayObject *)root, isec);
+ }
+ else {
+ if (!is_leaf(root))
+ stack[stack_pos++] = root;
+ else
+ return RE_rayobject_intersect( (RayObject *)root, isec);
+ }
+
+ while (true) {
+ //Use SIMD 4
+ if (stack_pos >= 4) {
+ __m128 t_bb[6];
+ Node *t_node[4];
+
+ stack_pos -= 4;
+
+ /* prepare the 4BB for SIMD */
+ t_node[0] = stack[stack_pos + 0]->child;
+ t_node[1] = stack[stack_pos + 1]->child;
+ t_node[2] = stack[stack_pos + 2]->child;
+ t_node[3] = stack[stack_pos + 3]->child;
+
+ const float *bb0 = stack[stack_pos + 0]->bb;
+ const float *bb1 = stack[stack_pos + 1]->bb;
+ const float *bb2 = stack[stack_pos + 2]->bb;
+ const float *bb3 = stack[stack_pos + 3]->bb;
+
+ const __m128 x0y0x1y1 = _mm_shuffle_ps(_mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(1, 0, 1, 0) );
+ const __m128 x2y2x3y3 = _mm_shuffle_ps(_mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(1, 0, 1, 0) );
+ t_bb[0] = _mm_shuffle_ps(x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2, 0, 2, 0) );
+ t_bb[1] = _mm_shuffle_ps(x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3, 1, 3, 1) );
+
+ const __m128 z0X0z1X1 = _mm_shuffle_ps(_mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(3, 2, 3, 2) );
+ const __m128 z2X2z3X3 = _mm_shuffle_ps(_mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(3, 2, 3, 2) );
+ t_bb[2] = _mm_shuffle_ps(z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2, 0, 2, 0) );
+ t_bb[3] = _mm_shuffle_ps(z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3, 1, 3, 1) );
+
+ const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps(_mm_load_ps(bb0 + 4), _mm_load_ps(bb1 + 4), _MM_SHUFFLE(1, 0, 1, 0) );
+ const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps(_mm_load_ps(bb2 + 4), _mm_load_ps(bb3 + 4), _MM_SHUFFLE(1, 0, 1, 0) );
+ t_bb[4] = _mm_shuffle_ps(Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2, 0, 2, 0) );
+ t_bb[5] = _mm_shuffle_ps(Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3, 1, 3, 1) );
+#if 0
+ for (int i = 0; i < 4; i++)
+ {
+ Node *t = stack[stack_pos + i];
+ assert(!is_leaf(t));
+
+ float *bb = ((float *)t_bb) + i;
+ bb[4 * 0] = t->bb[0];
+ bb[4 * 1] = t->bb[1];
+ bb[4 * 2] = t->bb[2];
+ bb[4 * 3] = t->bb[3];
+ bb[4 * 4] = t->bb[4];
+ bb[4 * 5] = t->bb[5];
+ t_node[i] = t->child;
+ }
+#endif
+ RE_RC_COUNT(isec->raycounter->simd_bb.test);
+ int res = test_bb_group4(t_bb, isec);
+
+ for (int i = 0; i < 4; i++)
+ if (res & (1 << i)) {
+ RE_RC_COUNT(isec->raycounter->simd_bb.hit);
+ if (!is_leaf(t_node[i])) {
+ for (Node *t = t_node[i]; t; t = t->sibling) {
+ assert(stack_pos < MAX_STACK_SIZE);
+ stack[stack_pos++] = t;
+ }
+ }
+ else {
+ hit |= RE_rayobject_intersect( (RayObject *)t_node[i], isec);
+ if (hit && isec->mode == RE_RAY_SHADOW) return hit;
+ }
+ }
+ }
+ else if (stack_pos > 0) {
+ Node *node = stack[--stack_pos];
+ assert(!is_leaf(node));
+
+ if (bvh_node_hit_test(node, isec)) {
+ if (!is_leaf(node->child)) {
+ bvh_node_push_childs(node, isec, stack, stack_pos);
+ assert(stack_pos <= MAX_STACK_SIZE);
+ }
+ else {
+ hit |= RE_rayobject_intersect( (RayObject *)node->child, isec);
+ if (hit && isec->mode == RE_RAY_SHADOW) return hit;
+ }
+ }
+ }
+ else break;
+ }
+ return hit;
+}
+#endif
+
+/*
+ * recursively transverse a BVH looking for a rayhit using system stack
+ */
+#if 0
+template<class Node>
+static int bvh_node_raycast(Node *node, Isect *isec)
+{
+ int hit = 0;
+ if (bvh_test_node(node, isec))
+ {
+ if (isec->idot_axis[node->split_axis] > 0.0f)
+ {
+ int i;
+ for (i = 0; i < BVH_NCHILDS; i++)
+ if (!is_leaf(node->child[i]))
+ {
+ if (node->child[i] == 0) break;
+
+ hit |= bvh_node_raycast(node->child[i], isec);
+ if (hit && isec->mode == RE_RAY_SHADOW) return hit;
+ }
+ else {
+ hit |= RE_rayobject_intersect( (RayObject *)node->child[i], isec);
+ if (hit && isec->mode == RE_RAY_SHADOW) return hit;
+ }
+ }
+ else {
+ int i;
+ for (i = BVH_NCHILDS - 1; i >= 0; i--)
+ if (!is_leaf(node->child[i]))
+ {
+ if (node->child[i])
+ {
+ hit |= dfs_raycast(node->child[i], isec);
+ if (hit && isec->mode == RE_RAY_SHADOW) return hit;
+ }
+ }
+ else {
+ hit |= RE_rayobject_intersect( (RayObject *)node->child[i], isec);
+ if (hit && isec->mode == RE_RAY_SHADOW) return hit;
+ }
+ }
+ }
+ return hit;
+}
+#endif
+
+template<class Node, class HintObject>
+static void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject *hintObject)
+{
+ assert(hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE);
+
+ if (is_leaf(node)) {
+ hint->stack[hint->size++] = (RayObject *)node;
+ }
+ else {
+ int childs = count_childs(node);
+ if (hint->size + reserve_space + childs <= RE_RAY_LCTS_MAX_SIZE) {
+ int result = hint_test_bb(hintObject, node->bb, node->bb + 3);
+ if (result == HINT_RECURSE) {
+ /* We are 100% sure the ray will be pass inside this node */
+ bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, hintObject);
+ }
+ else if (result == HINT_ACCEPT) {
+ hint->stack[hint->size++] = (RayObject *)node;
+ }
+ }
+ else {
+ hint->stack[hint->size++] = (RayObject *)node;
+ }
+ }
+}
+
+
+template<class Tree>
+static RayObjectAPI *bvh_get_api(int maxstacksize);
+
+
+template<class Tree, int DFS_STACK_SIZE>
+static inline RayObject *bvh_create_tree(int size)
+{
+ Tree *obj = (Tree *)MEM_callocN(sizeof(Tree), "BVHTree");
+ assert(RE_rayobject_isAligned(obj)); /* RayObject API assumes real data to be 4-byte aligned */
+
+ obj->rayobj.api = bvh_get_api<Tree>(DFS_STACK_SIZE);
+ obj->root = NULL;
+
+ obj->node_arena = NULL;
+ obj->builder = rtbuild_create(size);
+
+ return RE_rayobject_unalignRayAPI((RayObject *) obj);
+}
+
+#endif
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
new file mode 100644
index 00000000000..fee877b311d
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -0,0 +1,534 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject.cpp
+ * \ingroup render
+ */
+
+
+#include <assert.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_material_types.h"
+
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "raycounter.h"
+#include "render_types.h"
+#include "renderdatabase.h"
+
+/* RayFace
+ *
+ * note we force always inline here, because compiler refuses to otherwise
+ * because function is too long. Since this is code that is called billions
+ * of times we really do want to inline. */
+
+MALWAYS_INLINE RayObject *rayface_from_coords(RayFace *rayface, void *ob, void *face,
+ float *v1, float *v2, float *v3, float *v4)
+{
+ rayface->ob = ob;
+ rayface->face = face;
+
+ copy_v3_v3(rayface->v1, v1);
+ copy_v3_v3(rayface->v2, v2);
+ copy_v3_v3(rayface->v3, v3);
+
+ if (v4) {
+ copy_v3_v3(rayface->v4, v4);
+ rayface->quad = 1;
+ }
+ else {
+ rayface->quad = 0;
+ }
+
+ return RE_rayobject_unalignRayFace(rayface);
+}
+
+MALWAYS_INLINE void rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
+{
+ rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL);
+
+ if (obi->transform_primitives) {
+ mul_m4_v3(obi->mat, rayface->v1);
+ mul_m4_v3(obi->mat, rayface->v2);
+ mul_m4_v3(obi->mat, rayface->v3);
+
+ if (RE_rayface_isQuad(rayface))
+ mul_m4_v3(obi->mat, rayface->v4);
+ }
+}
+
+RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
+{
+ return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL);
+}
+
+RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
+{
+ return rayface_from_coords(rayface, ob, face, v1, v2, v3, v4);
+}
+
+/* VlakPrimitive */
+
+RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
+{
+ face->ob = obi;
+ face->face = vlr;
+
+ return RE_rayobject_unalignVlakPrimitive(face);
+}
+
+/* Checks for ignoring faces or materials */
+
+MALWAYS_INLINE int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr)
+{
+ /* for baking selected to active non-traceable materials might still
+ * be in the raytree */
+ if (!(vlr->flag & R_TRACEBLE))
+ return 0;
+
+ /* I know... cpu cycle waste, might do smarter once */
+ if (is->mode == RE_RAY_MIRROR)
+ return !(vlr->mat->mode & MA_ONLYCAST);
+ else
+ return (vlr->mat->mode2 & MA_CASTSHADOW) && (is->lay & obi->lay);
+}
+
+MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen *UNUSED(obi), VlakRen *vlr)
+{
+ /* solid material types only */
+ if (vlr->mat->material_type == MA_TYPE_SURFACE)
+ return 1;
+ else
+ return 0;
+}
+
+MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen *obi, VlakRen *UNUSED(vlr))
+{
+ return (obi->obr->ob != is->userdata) && (obi->obr->ob->flag & SELECT);
+}
+
+/* Ray Triangle/Quad Intersection */
+
+static bool isect_ray_tri_watertight_no_sign_check_v3(
+ const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc,
+ const float v0[3], const float v1[3], const float v2[3],
+ float *r_lambda, float r_uv[2])
+{
+ const int kx = isect_precalc->kx;
+ const int ky = isect_precalc->ky;
+ const int kz = isect_precalc->kz;
+ const float sx = isect_precalc->sx;
+ const float sy = isect_precalc->sy;
+ const float sz = isect_precalc->sz;
+
+ /* Calculate vertices relative to ray origin. */
+ const float a[3] = {v0[0] - ray_origin[0], v0[1] - ray_origin[1], v0[2] - ray_origin[2]};
+ const float b[3] = {v1[0] - ray_origin[0], v1[1] - ray_origin[1], v1[2] - ray_origin[2]};
+ const float c[3] = {v2[0] - ray_origin[0], v2[1] - ray_origin[1], v2[2] - ray_origin[2]};
+
+ const float a_kx = a[kx], a_ky = a[ky], a_kz = a[kz];
+ const float b_kx = b[kx], b_ky = b[ky], b_kz = b[kz];
+ const float c_kx = c[kx], c_ky = c[ky], c_kz = c[kz];
+
+ /* Perform shear and scale of vertices. */
+ const float ax = a_kx - sx * a_kz;
+ const float ay = a_ky - sy * a_kz;
+ const float bx = b_kx - sx * b_kz;
+ const float by = b_ky - sy * b_kz;
+ const float cx = c_kx - sx * c_kz;
+ const float cy = c_ky - sy * c_kz;
+
+ /* Calculate scaled barycentric coordinates. */
+ const float u = cx * by - cy * bx;
+ const float v = ax * cy - ay * cx;
+ const float w = bx * ay - by * ax;
+ float det;
+
+ if ((u < 0.0f || v < 0.0f || w < 0.0f) &&
+ (u > 0.0f || v > 0.0f || w > 0.0f))
+ {
+ return false;
+ }
+
+ /* Calculate determinant. */
+ det = u + v + w;
+ if (UNLIKELY(det == 0.0f)) {
+ return false;
+ }
+ else {
+ /* Calculate scaled z-coordinates of vertices and use them to calculate
+ * the hit distance.
+ */
+ const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
+ /* Normalize u, v and t. */
+ const float inv_det = 1.0f / det;
+ if (r_uv) {
+ r_uv[0] = u * inv_det;
+ r_uv[1] = v * inv_det;
+ }
+ *r_lambda = t * inv_det;
+ return true;
+ }
+}
+
+MALWAYS_INLINE int isec_tri_quad(const float start[3],
+ const struct IsectRayPrecalc *isect_precalc,
+ const RayFace *face,
+ float r_uv[2], float *r_lambda)
+{
+ float uv[2], l;
+
+ if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v2, face->v3, &l, uv)) {
+ /* check if intersection is within ray length */
+ if (l > -RE_RAYTRACE_EPSILON && l < *r_lambda) {
+ r_uv[0] = -uv[0];
+ r_uv[1] = -uv[1];
+ *r_lambda = l;
+ return 1;
+ }
+ }
+
+ /* intersect second triangle in quad */
+ if (RE_rayface_isQuad(face)) {
+ if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v3, face->v4, &l, uv)) {
+ /* check if intersection is within ray length */
+ if (l > -RE_RAYTRACE_EPSILON && l < *r_lambda) {
+ r_uv[0] = -uv[0];
+ r_uv[1] = -uv[1];
+ *r_lambda = l;
+ return 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Simpler yes/no Ray Triangle/Quad Intersection */
+
+MALWAYS_INLINE int isec_tri_quad_neighbour(const float start[3],
+ const float dir[3],
+ const RayFace *face)
+{
+ float r[3];
+ struct IsectRayPrecalc isect_precalc;
+ float uv[2], l;
+
+ negate_v3_v3(r, dir); /* note, different than above function */
+
+ isect_ray_tri_watertight_v3_precalc(&isect_precalc, r);
+
+ if (isect_ray_tri_watertight_no_sign_check_v3(start, &isect_precalc, face->v1, face->v2, face->v3, &l, uv)) {
+ return 1;
+ }
+
+ /* intersect second triangle in quad */
+ if (RE_rayface_isQuad(face)) {
+ if (isect_ray_tri_watertight_no_sign_check_v3(start, &isect_precalc, face->v1, face->v3, face->v4, &l, uv)) {
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+/* RayFace intersection with checks and neighbor verifaction included,
+ * Isect is modified if the face is hit. */
+
+MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
+{
+ float dist, uv[2];
+ int ok = 0;
+
+ /* avoid self-intersection */
+ if (is->orig.ob == face->ob && is->orig.face == face->face)
+ return 0;
+
+ /* check if we should intersect this face */
+ if (is->check == RE_CHECK_VLR_RENDER) {
+ if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
+ return 0;
+ }
+ else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL) {
+ if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
+ return 0;
+ if (vlr_check_intersect_solid(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
+ return 0;
+ }
+ else if (is->check == RE_CHECK_VLR_BAKE) {
+ if (vlr_check_bake(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
+ return 0;
+ }
+
+ /* ray counter */
+ RE_RC_COUNT(is->raycounter->faces.test);
+
+ dist = is->dist;
+ ok = isec_tri_quad(is->start, &is->isect_precalc, face, uv, &dist);
+
+ if (ok) {
+
+ /* when a shadow ray leaves a face, it can be little outside the edges
+ * of it, causing intersection to be detected in its neighbor face */
+ if (is->skip & RE_SKIP_VLR_NEIGHBOUR) {
+ if (dist < 0.1f && is->orig.ob == face->ob) {
+ VlakRen *a = (VlakRen *)is->orig.face;
+ VlakRen *b = (VlakRen *)face->face;
+ ObjectRen *obr = ((ObjectInstanceRen *)face->ob)->obr;
+
+ VertRen **va, **vb;
+ int *org_idx_a, *org_idx_b;
+ int i, j;
+ bool is_neighbor = false;
+
+ /* "same" vertex means either the actual same VertRen, or the same 'final org index', if available
+ * (autosmooth only, currently). */
+ for (i = 0, va = &a->v1; !is_neighbor && i < 4 && *va; ++i, ++va) {
+ org_idx_a = RE_vertren_get_origindex(obr, *va, false);
+ for (j = 0, vb = &b->v1; !is_neighbor && j < 4 && *vb; ++j, ++vb) {
+ if (*va == *vb) {
+ is_neighbor = true;
+ }
+ else if (org_idx_a) {
+ org_idx_b = RE_vertren_get_origindex(obr, *vb, 0);
+ if (org_idx_b && *org_idx_a == *org_idx_b) {
+ is_neighbor = true;
+ }
+ }
+ }
+ }
+
+ /* So there's a shared edge or vertex, let's intersect ray with self, if that's true
+ * we can safely return 1, otherwise we assume the intersection is invalid, 0 */
+ if (is_neighbor) {
+ /* create RayFace from original face, transformed if necessary */
+ RayFace origface;
+ ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob;
+ rayface_from_vlak(&origface, ob, (VlakRen *)is->orig.face);
+
+ if (!isec_tri_quad_neighbour(is->start, is->dir, &origface)) {
+ return 0;
+ }
+ }
+ }
+ }
+
+ RE_RC_COUNT(is->raycounter->faces.hit);
+
+ is->isect = ok; // which half of the quad
+ is->dist = dist;
+ is->u = uv[0]; is->v = uv[1];
+
+ is->hit.ob = face->ob;
+ is->hit.face = face->face;
+#ifdef RT_USE_LAST_HIT
+ is->last_hit = hit_obj;
+#endif
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Intersection */
+
+int RE_rayobject_raycast(RayObject *r, Isect *isec)
+{
+ int i;
+
+ /* Pre-calculate orientation for watertight intersection checks. */
+ isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir);
+
+ RE_RC_COUNT(isec->raycounter->raycast.test);
+
+ /* setup vars used on raycast */
+ for (i = 0; i < 3; i++) {
+ isec->idot_axis[i] = 1.0f / isec->dir[i];
+
+ isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0;
+ isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
+
+ isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i];
+ isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
+ }
+
+#ifdef RT_USE_LAST_HIT
+ /* last hit heuristic */
+ if (isec->mode == RE_RAY_SHADOW && isec->last_hit) {
+ RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test);
+
+ if (RE_rayobject_intersect(isec->last_hit, isec)) {
+ RE_RC_COUNT(isec->raycounter->raycast.hit);
+ RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit);
+ return 1;
+ }
+ }
+#endif
+
+#ifdef RT_USE_HINT
+ isec->hit_hint = 0;
+#endif
+
+ if (RE_rayobject_intersect(r, isec)) {
+ RE_RC_COUNT(isec->raycounter->raycast.hit);
+
+#ifdef RT_USE_HINT
+ isec->hint = isec->hit_hint;
+#endif
+ return 1;
+ }
+
+ return 0;
+}
+
+int RE_rayobject_intersect(RayObject *r, Isect *i)
+{
+ if (RE_rayobject_isRayFace(r)) {
+ return intersect_rayface(r, (RayFace *) RE_rayobject_align(r), i);
+ }
+ else if (RE_rayobject_isVlakPrimitive(r)) {
+ //TODO optimize (useless copy to RayFace to avoid duplicate code)
+ VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
+ RayFace nface;
+ rayface_from_vlak(&nface, face->ob, face->face);
+
+ return intersect_rayface(r, &nface, i);
+ }
+ else if (RE_rayobject_isRayAPI(r)) {
+ r = RE_rayobject_align(r);
+ return r->api->raycast(r, i);
+ }
+ else {
+ assert(0);
+ return 0;
+ }
+}
+
+/* Building */
+
+void RE_rayobject_add(RayObject *r, RayObject *o)
+{
+ r = RE_rayobject_align(r);
+ return r->api->add(r, o);
+}
+
+void RE_rayobject_done(RayObject *r)
+{
+ r = RE_rayobject_align(r);
+ r->api->done(r);
+}
+
+void RE_rayobject_free(RayObject *r)
+{
+ r = RE_rayobject_align(r);
+ r->api->free(r);
+}
+
+float RE_rayobject_cost(RayObject *r)
+{
+ if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) {
+ return 1.0f;
+ }
+ else if (RE_rayobject_isRayAPI(r)) {
+ r = RE_rayobject_align(r);
+ return r->api->cost(r);
+ }
+ else {
+ assert(0);
+ return 1.0f;
+ }
+}
+
+/* Bounding Boxes */
+
+void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3])
+{
+ if (RE_rayobject_isRayFace(r)) {
+ RayFace *face = (RayFace *) RE_rayobject_align(r);
+
+ DO_MINMAX(face->v1, min, max);
+ DO_MINMAX(face->v2, min, max);
+ DO_MINMAX(face->v3, min, max);
+ if (RE_rayface_isQuad(face)) DO_MINMAX(face->v4, min, max);
+ }
+ else if (RE_rayobject_isVlakPrimitive(r)) {
+ VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
+ RayFace nface;
+ rayface_from_vlak(&nface, face->ob, face->face);
+
+ DO_MINMAX(nface.v1, min, max);
+ DO_MINMAX(nface.v2, min, max);
+ DO_MINMAX(nface.v3, min, max);
+ if (RE_rayface_isQuad(&nface)) DO_MINMAX(nface.v4, min, max);
+ }
+ else if (RE_rayobject_isRayAPI(r)) {
+ r = RE_rayobject_align(r);
+ r->api->bb(r, min, max);
+ }
+ else
+ assert(0);
+}
+
+/* Hints */
+
+void RE_rayobject_hint_bb(RayObject *r, RayHint *hint, float *min, float *max)
+{
+ if (RE_rayobject_isRayFace(r) || RE_rayobject_isVlakPrimitive(r)) {
+ return;
+ }
+ else if (RE_rayobject_isRayAPI(r)) {
+ r = RE_rayobject_align(r);
+ return r->api->hint_bb(r, hint, min, max);
+ }
+ else
+ assert(0);
+}
+
+/* RayObjectControl */
+
+int RE_rayobjectcontrol_test_break(RayObjectControl *control)
+{
+ if (control->test_break)
+ return control->test_break(control->data);
+
+ return 0;
+}
+
+void RE_rayobject_set_control(RayObject *r, void *data, RE_rayobjectcontrol_test_break_callback test_break)
+{
+ if (RE_rayobject_isRayAPI(r)) {
+ r = RE_rayobject_align(r);
+ r->control.data = data;
+ r->control.test_break = test_break;
+ }
+}
+
diff --git a/source/blender/render/intern/raytrace/rayobject_hint.h b/source/blender/render/intern/raytrace/rayobject_hint.h
new file mode 100644
index 00000000000..88a32819bd2
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_hint.h
@@ -0,0 +1,72 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_hint.h
+ * \ingroup render
+ */
+
+
+#ifndef __RAYOBJECT_HINT_H__
+#define __RAYOBJECT_HINT_H__
+
+#define HINT_RECURSE 1
+#define HINT_ACCEPT 0
+#define HINT_DISCARD -1
+
+struct HintBB {
+ float bb[6];
+};
+
+inline int hint_test_bb(HintBB *obj, float *Nmin, float *Nmax)
+{
+ if (bb_fits_inside(Nmin, Nmax, obj->bb, obj->bb + 3) )
+ return HINT_RECURSE;
+ else
+ return HINT_ACCEPT;
+}
+#if 0
+struct HintFrustum {
+ float co[3];
+ float no[4][3];
+};
+
+inline int hint_test_bb(HintFrustum &obj, float *Nmin, float *Nmax)
+{
+ //if frustum inside BB
+ {
+ return HINT_RECURSE;
+ }
+ //if BB outside frustum
+ {
+ return HINT_DISCARD;
+ }
+
+ return HINT_ACCEPT;
+}
+#endif
+
+#endif /* __RAYOBJECT_HINT_H__ */
diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp
new file mode 100644
index 00000000000..361e7963d96
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp
@@ -0,0 +1,211 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_instance.cpp
+ * \ingroup render
+ */
+
+
+#include <assert.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "rayintersection.h"
+#include "rayobject.h"
+
+#define RE_COST_INSTANCE (1.0f)
+
+static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec);
+static void RE_rayobject_instance_free(RayObject *o);
+static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max);
+static float RE_rayobject_instance_cost(RayObject *o);
+
+static void RE_rayobject_instance_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint),
+ float *UNUSED(min), float *UNUSED(max))
+{}
+
+static RayObjectAPI instance_api =
+{
+ RE_rayobject_instance_intersect,
+ NULL, //static void RE_rayobject_instance_add(RayObject *o, RayObject *ob);
+ NULL, //static void RE_rayobject_instance_done(RayObject *o);
+ RE_rayobject_instance_free,
+ RE_rayobject_instance_bb,
+ RE_rayobject_instance_cost,
+ RE_rayobject_instance_hint_bb
+};
+
+typedef struct InstanceRayObject {
+ RayObject rayobj;
+ RayObject *target;
+
+ void *ob; //Object represented by this instance
+ void *target_ob; //Object represented by the inner RayObject, needed to handle self-intersection
+
+ float global2target[4][4];
+ float target2global[4][4];
+
+} InstanceRayObject;
+
+
+RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob)
+{
+ InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject");
+ assert(RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */
+
+ obj->rayobj.api = &instance_api;
+ obj->target = target;
+ obj->ob = ob;
+ obj->target_ob = target_ob;
+
+ copy_m4_m4(obj->target2global, transform);
+ invert_m4_m4(obj->global2target, obj->target2global);
+
+ return RE_rayobject_unalignRayAPI((RayObject *) obj);
+}
+
+static int RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
+{
+ InstanceRayObject *obj = (InstanceRayObject *)o;
+ float start[3], dir[3], idot_axis[3], dist;
+ int changed = 0, i, res;
+
+ // TODO - this is disabling self intersection on instances
+ if (isec->orig.ob == obj->ob && obj->ob) {
+ changed = 1;
+ isec->orig.ob = obj->target_ob;
+ }
+
+ // backup old values
+ copy_v3_v3(start, isec->start);
+ copy_v3_v3(dir, isec->dir);
+ copy_v3_v3(idot_axis, isec->idot_axis);
+ dist = isec->dist;
+
+ // transform to target coordinates system
+ mul_m4_v3(obj->global2target, isec->start);
+ mul_mat3_m4_v3(obj->global2target, isec->dir);
+ isec->dist *= normalize_v3(isec->dir);
+
+ // update idot_axis and bv_index
+ for (i = 0; i < 3; i++) {
+ isec->idot_axis[i] = 1.0f / isec->dir[i];
+
+ isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0;
+ isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
+
+ isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i];
+ isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
+ }
+
+ // Pre-calculate orientation for watertight intersection checks.
+ isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir);
+
+ // raycast
+ res = RE_rayobject_intersect(obj->target, isec);
+
+ // map dist into original coordinate space
+ if (res == 0) {
+ isec->dist = dist;
+ }
+ else {
+ // note we don't just multiply dist, because of possible
+ // non-uniform scaling in the transform matrix
+ float vec[3];
+
+ mul_v3_v3fl(vec, isec->dir, isec->dist);
+ mul_mat3_m4_v3(obj->target2global, vec);
+
+ isec->dist = len_v3(vec);
+ isec->hit.ob = obj->ob;
+
+#ifdef RT_USE_LAST_HIT
+ // TODO support for last hit optimization in instances that can jump
+ // directly to the last hit face.
+ // For now it jumps directly to the last-hit instance root node.
+ isec->last_hit = RE_rayobject_unalignRayAPI((RayObject *) obj);
+#endif
+ }
+
+ // restore values
+ copy_v3_v3(isec->start, start);
+ copy_v3_v3(isec->dir, dir);
+ copy_v3_v3(isec->idot_axis, idot_axis);
+
+ if (changed)
+ isec->orig.ob = obj->ob;
+
+ // restore bv_index
+ for (i = 0; i < 3; i++) {
+ isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0f ? 1 : 0;
+ isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
+
+ isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i];
+ isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
+ }
+
+ // Pre-calculate orientation for watertight intersection checks.
+ isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir);
+
+ return res;
+}
+
+static void RE_rayobject_instance_free(RayObject *o)
+{
+ InstanceRayObject *obj = (InstanceRayObject *)o;
+ MEM_freeN(obj);
+}
+
+static float RE_rayobject_instance_cost(RayObject *o)
+{
+ InstanceRayObject *obj = (InstanceRayObject *)o;
+ return RE_rayobject_cost(obj->target) + RE_COST_INSTANCE;
+}
+
+static void RE_rayobject_instance_bb(RayObject *o, float *min, float *max)
+{
+ //TODO:
+ // *better bb.. calculated without rotations of bb
+ // *maybe cache that better-fitted-BB at the InstanceRayObject
+ InstanceRayObject *obj = (InstanceRayObject *)o;
+
+ float m[3], M[3], t[3];
+ int i, j;
+ INIT_MINMAX(m, M);
+ RE_rayobject_merge_bb(obj->target, m, M);
+
+ //There must be a faster way than rotating all the 8 vertexs of the BB
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 3; j++) t[j] = (i & (1 << j)) ? M[j] : m[j];
+ mul_m4_v3(obj->target2global, t);
+ DO_MINMAX(t, min, max);
+ }
+}
+
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
new file mode 100644
index 00000000000..4b73e64ca45
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -0,0 +1,1101 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 1990-1998 NeoGeo BV.
+ * All rights reserved.
+ *
+ * Contributors: 2004/2005 Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_octree.cpp
+ * \ingroup render
+ */
+
+
+/* IMPORTANT NOTE: this code must be independent of any other render code
+ * to use it outside the renderer! */
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <float.h>
+#include <assert.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_material_types.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "rayintersection.h"
+#include "rayobject.h"
+
+/* ********** structs *************** */
+#define BRANCH_ARRAY 1024
+#define NODE_ARRAY 4096
+
+typedef struct Branch {
+ struct Branch *b[8];
+} Branch;
+
+typedef struct OcVal {
+ short ocx, ocy, ocz;
+} OcVal;
+
+typedef struct Node {
+ struct RayFace *v[8];
+ struct OcVal ov[8];
+ struct Node *next;
+} Node;
+
+typedef struct Octree {
+ RayObject rayobj;
+
+ struct Branch **adrbranch;
+ struct Node **adrnode;
+ float ocsize; /* ocsize: mult factor, max size octree */
+ float ocfacx, ocfacy, ocfacz;
+ float min[3], max[3];
+ int ocres;
+ int branchcount, nodecount;
+
+ /* during building only */
+ char *ocface;
+
+ RayFace **ro_nodes;
+ int ro_nodes_size, ro_nodes_used;
+
+} Octree;
+
+static int RE_rayobject_octree_intersect(RayObject *o, Isect *isec);
+static void RE_rayobject_octree_add(RayObject *o, RayObject *ob);
+static void RE_rayobject_octree_done(RayObject *o);
+static void RE_rayobject_octree_free(RayObject *o);
+static void RE_rayobject_octree_bb(RayObject *o, float *min, float *max);
+
+/*
+ * This function is not expected to be called by current code state.
+ */
+static float RE_rayobject_octree_cost(RayObject *UNUSED(o))
+{
+ return 1.0;
+}
+
+static void RE_rayobject_octree_hint_bb(RayObject *UNUSED(o), RayHint *UNUSED(hint),
+ float *UNUSED(min), float *UNUSED(max))
+{
+ return;
+}
+
+static RayObjectAPI octree_api =
+{
+ RE_rayobject_octree_intersect,
+ RE_rayobject_octree_add,
+ RE_rayobject_octree_done,
+ RE_rayobject_octree_free,
+ RE_rayobject_octree_bb,
+ RE_rayobject_octree_cost,
+ RE_rayobject_octree_hint_bb
+};
+
+/* **************** ocval method ******************* */
+/* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */
+
+#define OCVALRES 15
+#define BROW16(min, max) \
+ (((max) >= OCVALRES ? 0xFFFF : (1 << ((max) + 1)) - 1) - (((min) > 0) ? ((1 << (min)) - 1) : 0))
+
+static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, short y, short z, OcVal *ov)
+{
+ float min[3], max[3];
+ int ocmin, ocmax;
+
+ copy_v3_v3(min, v1);
+ copy_v3_v3(max, v1);
+ DO_MINMAX(v2, min, max);
+ DO_MINMAX(v3, min, max);
+ if (v4) {
+ DO_MINMAX(v4, min, max);
+ }
+
+ ocmin = OCVALRES * (min[0] - x);
+ ocmax = OCVALRES * (max[0] - x);
+ ov->ocx = BROW16(ocmin, ocmax);
+
+ ocmin = OCVALRES * (min[1] - y);
+ ocmax = OCVALRES * (max[1] - y);
+ ov->ocy = BROW16(ocmin, ocmax);
+
+ ocmin = OCVALRES * (min[2] - z);
+ ocmax = OCVALRES * (max[2] - z);
+ ov->ocz = BROW16(ocmin, ocmax);
+
+}
+
+static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, float *vec2)
+{
+ int ocmin, ocmax;
+
+ if (vec1[0] < vec2[0]) {
+ ocmin = OCVALRES * (vec1[0] - xo);
+ ocmax = OCVALRES * (vec2[0] - xo);
+ }
+ else {
+ ocmin = OCVALRES * (vec2[0] - xo);
+ ocmax = OCVALRES * (vec1[0] - xo);
+ }
+ ov->ocx = BROW16(ocmin, ocmax);
+
+ if (vec1[1] < vec2[1]) {
+ ocmin = OCVALRES * (vec1[1] - yo);
+ ocmax = OCVALRES * (vec2[1] - yo);
+ }
+ else {
+ ocmin = OCVALRES * (vec2[1] - yo);
+ ocmax = OCVALRES * (vec1[1] - yo);
+ }
+ ov->ocy = BROW16(ocmin, ocmax);
+
+ if (vec1[2] < vec2[2]) {
+ ocmin = OCVALRES * (vec1[2] - zo);
+ ocmax = OCVALRES * (vec2[2] - zo);
+ }
+ else {
+ ocmin = OCVALRES * (vec2[2] - zo);
+ ocmax = OCVALRES * (vec1[2] - zo);
+ }
+ ov->ocz = BROW16(ocmin, ocmax);
+}
+
+/* ************* octree ************** */
+
+static Branch *addbranch(Octree *oc, Branch *br, short ocb)
+{
+ int index;
+
+ if (br->b[ocb]) return br->b[ocb];
+
+ oc->branchcount++;
+ index = oc->branchcount >> 12;
+
+ if (oc->adrbranch[index] == NULL)
+ oc->adrbranch[index] = (Branch *)MEM_callocN(4096 * sizeof(Branch), "new oc branch");
+
+ if (oc->branchcount >= BRANCH_ARRAY * 4096) {
+ printf("error; octree branches full\n");
+ oc->branchcount = 0;
+ }
+
+ return br->b[ocb] = oc->adrbranch[index] + (oc->branchcount & 4095);
+}
+
+static Node *addnode(Octree *oc)
+{
+ int index;
+
+ oc->nodecount++;
+ index = oc->nodecount >> 12;
+
+ if (oc->adrnode[index] == NULL)
+ oc->adrnode[index] = (Node *)MEM_callocN(4096 * sizeof(Node), "addnode");
+
+ if (oc->nodecount > NODE_ARRAY * NODE_ARRAY) {
+ printf("error; octree nodes full\n");
+ oc->nodecount = 0;
+ }
+
+ return oc->adrnode[index] + (oc->nodecount & 4095);
+}
+
+static bool face_in_node(RayFace *face, short x, short y, short z, float rtf[4][3])
+{
+ static float nor[3], d;
+ float fx, fy, fz;
+
+ // init static vars
+ if (face) {
+ normal_tri_v3(nor, rtf[0], rtf[1], rtf[2]);
+ d = -nor[0] * rtf[0][0] - nor[1] * rtf[0][1] - nor[2] * rtf[0][2];
+ return 0;
+ }
+
+ fx = x;
+ fy = y;
+ fz = z;
+
+ if ((fx) * nor[0] + (fy) * nor[1] + (fz) * nor[2] + d > 0.0f) {
+ if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1;
+ if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1;
+ if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d < 0.0f) return 1;
+
+ if ((fx ) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1;
+ if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1;
+ if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1;
+ if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d < 0.0f) return 1;
+ }
+ else {
+ if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1;
+ if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1;
+ if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz ) * nor[2] + d > 0.0f) return 1;
+
+ if ((fx ) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1;
+ if ((fx + 1) * nor[0] + (fy ) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1;
+ if ((fx ) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1;
+ if ((fx + 1) * nor[0] + (fy + 1) * nor[1] + (fz + 1) * nor[2] + d > 0.0f) return 1;
+ }
+
+ return 0;
+}
+
+static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short z, float rtf[4][3])
+{
+ Branch *br;
+ Node *no;
+ short a, oc0, oc1, oc2, oc3, oc4, oc5;
+
+ x <<= 2;
+ y <<= 1;
+
+ br = oc->adrbranch[0];
+
+ if (oc->ocres == 512) {
+ oc0 = ((x & 1024) + (y & 512) + (z & 256)) >> 8;
+ br = addbranch(oc, br, oc0);
+ }
+ if (oc->ocres >= 256) {
+ oc0 = ((x & 512) + (y & 256) + (z & 128)) >> 7;
+ br = addbranch(oc, br, oc0);
+ }
+ if (oc->ocres >= 128) {
+ oc0 = ((x & 256) + (y & 128) + (z & 64)) >> 6;
+ br = addbranch(oc, br, oc0);
+ }
+
+ oc0 = ((x & 128) + (y & 64) + (z & 32)) >> 5;
+ oc1 = ((x & 64) + (y & 32) + (z & 16)) >> 4;
+ oc2 = ((x & 32) + (y & 16) + (z & 8)) >> 3;
+ oc3 = ((x & 16) + (y & 8) + (z & 4)) >> 2;
+ oc4 = ((x & 8) + (y & 4) + (z & 2)) >> 1;
+ oc5 = ((x & 4) + (y & 2) + (z & 1));
+
+ br = addbranch(oc, br, oc0);
+ br = addbranch(oc, br, oc1);
+ br = addbranch(oc, br, oc2);
+ br = addbranch(oc, br, oc3);
+ br = addbranch(oc, br, oc4);
+ no = (Node *)br->b[oc5];
+ if (no == NULL) br->b[oc5] = (Branch *)(no = addnode(oc));
+
+ while (no->next) no = no->next;
+
+ a = 0;
+ if (no->v[7]) { /* node full */
+ no->next = addnode(oc);
+ no = no->next;
+ }
+ else {
+ while (no->v[a] != NULL) a++;
+ }
+
+ no->v[a] = (RayFace *) RE_rayobject_align(face);
+
+ if (quad)
+ calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x >> 2, y >> 1, z, &no->ov[a]);
+ else
+ calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x >> 2, y >> 1, z, &no->ov[a]);
+}
+
+static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[4][3], float rtf[4][3])
+{
+ int ocx1, ocx2, ocy1, ocy2;
+ int x, y, dx = 0, dy = 0;
+ float ox1, ox2, oy1, oy2;
+ float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy;
+
+ ocx1 = rts[b1][c1];
+ ocy1 = rts[b1][c2];
+ ocx2 = rts[b2][c1];
+ ocy2 = rts[b2][c2];
+
+ if (ocx1 == ocx2 && ocy1 == ocy2) {
+ ocface[oc->ocres * ocx1 + ocy1] = 1;
+ return;
+ }
+
+ ox1 = rtf[b1][c1];
+ oy1 = rtf[b1][c2];
+ ox2 = rtf[b2][c1];
+ oy2 = rtf[b2][c2];
+
+ if (ox1 != ox2) {
+ if (ox2 - ox1 > 0.0f) {
+ lambda_x = (ox1 - ocx1 - 1.0f) / (ox1 - ox2);
+ ldx = -1.0f / (ox1 - ox2);
+ dx = 1;
+ }
+ else {
+ lambda_x = (ox1 - ocx1) / (ox1 - ox2);
+ ldx = 1.0f / (ox1 - ox2);
+ dx = -1;
+ }
+ }
+ else {
+ lambda_x = 1.0f;
+ ldx = 0;
+ }
+
+ if (oy1 != oy2) {
+ if (oy2 - oy1 > 0.0f) {
+ lambda_y = (oy1 - ocy1 - 1.0f) / (oy1 - oy2);
+ ldy = -1.0f / (oy1 - oy2);
+ dy = 1;
+ }
+ else {
+ lambda_y = (oy1 - ocy1) / (oy1 - oy2);
+ ldy = 1.0f / (oy1 - oy2);
+ dy = -1;
+ }
+ }
+ else {
+ lambda_y = 1.0f;
+ ldy = 0;
+ }
+
+ x = ocx1; y = ocy1;
+ lambda = MIN2(lambda_x, lambda_y);
+
+ while (true) {
+
+ if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) {
+ /* pass*/
+ }
+ else {
+ ocface[oc->ocres * x + y] = 1;
+ }
+
+ lambda_o = lambda;
+ if (lambda_x == lambda_y) {
+ lambda_x += ldx;
+ x += dx;
+ lambda_y += ldy;
+ y += dy;
+ }
+ else {
+ if (lambda_x < lambda_y) {
+ lambda_x += ldx;
+ x += dx;
+ }
+ else {
+ lambda_y += ldy;
+ y += dy;
+ }
+ }
+ lambda = MIN2(lambda_x, lambda_y);
+ if (lambda == lambda_o) break;
+ if (lambda >= 1.0f) break;
+ }
+ ocface[oc->ocres * ocx2 + ocy2] = 1;
+}
+
+static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin, short *ocmax)
+{
+ int a, x, y, y1, y2;
+
+ for (x = ocmin[c1]; x <= ocmax[c1]; x++) {
+ a = oc->ocres * x;
+ for (y = ocmin[c2]; y <= ocmax[c2]; y++) {
+ if (ocface[a + y]) {
+ y++;
+ while (ocface[a + y] && y != ocmax[c2]) y++;
+ for (y1 = ocmax[c2]; y1 > y; y1--) {
+ if (ocface[a + y1]) {
+ for (y2 = y; y2 <= y1; y2++) ocface[a + y2] = 1;
+ y1 = 0;
+ }
+ }
+ y = ocmax[c2];
+ }
+ }
+ }
+}
+
+static void RE_rayobject_octree_free(RayObject *tree)
+{
+ Octree *oc = (Octree *)tree;
+
+#if 0
+ printf("branches %d nodes %d\n", oc->branchcount, oc->nodecount);
+ printf("raycount %d\n", raycount);
+ printf("ray coherent %d\n", coherent_ray);
+ printf("accepted %d rejected %d\n", accepted, rejected);
+#endif
+ if (oc->ocface)
+ MEM_freeN(oc->ocface);
+
+ if (oc->adrbranch) {
+ int a = 0;
+ while (oc->adrbranch[a]) {
+ MEM_freeN(oc->adrbranch[a]);
+ oc->adrbranch[a] = NULL;
+ a++;
+ }
+ MEM_freeN(oc->adrbranch);
+ oc->adrbranch = NULL;
+ }
+ oc->branchcount = 0;
+
+ if (oc->adrnode) {
+ int a = 0;
+ while (oc->adrnode[a]) {
+ MEM_freeN(oc->adrnode[a]);
+ oc->adrnode[a] = NULL;
+ a++;
+ }
+ MEM_freeN(oc->adrnode);
+ oc->adrnode = NULL;
+ }
+ oc->nodecount = 0;
+
+ MEM_freeN(oc);
+}
+
+
+RayObject *RE_rayobject_octree_create(int ocres, int size)
+{
+ Octree *oc = (Octree *)MEM_callocN(sizeof(Octree), "Octree");
+ assert(RE_rayobject_isAligned(oc) ); /* RayObject API assumes real data to be 4-byte aligned */
+
+ oc->rayobj.api = &octree_api;
+
+ oc->ocres = ocres;
+
+ oc->ro_nodes = (RayFace **)MEM_callocN(sizeof(RayFace *) * size, "octree rayobject nodes");
+ oc->ro_nodes_size = size;
+ oc->ro_nodes_used = 0;
+
+
+ return RE_rayobject_unalignRayAPI((RayObject *) oc);
+}
+
+
+static void RE_rayobject_octree_add(RayObject *tree, RayObject *node)
+{
+ Octree *oc = (Octree *)tree;
+
+ assert(RE_rayobject_isRayFace(node) );
+ assert(oc->ro_nodes_used < oc->ro_nodes_size);
+ oc->ro_nodes[oc->ro_nodes_used++] = (RayFace *)RE_rayobject_align(node);
+}
+
+static void octree_fill_rayface(Octree *oc, RayFace *face)
+{
+ float ocfac[3], rtf[4][3];
+ float co1[3], co2[3], co3[3], co4[3];
+ short rts[4][3];
+ short ocmin[3], ocmax[3];
+ char *ocface = oc->ocface; // front, top, size view of face, to fill in
+ int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2;
+
+ ocfac[0] = oc->ocfacx;
+ ocfac[1] = oc->ocfacy;
+ ocfac[2] = oc->ocfacz;
+
+ ocres2 = oc->ocres * oc->ocres;
+
+ copy_v3_v3(co1, face->v1);
+ copy_v3_v3(co2, face->v2);
+ copy_v3_v3(co3, face->v3);
+ if (RE_rayface_isQuad(face))
+ copy_v3_v3(co4, face->v4);
+
+ for (c = 0; c < 3; c++) {
+ rtf[0][c] = (co1[c] - oc->min[c]) * ocfac[c];
+ rts[0][c] = (short)rtf[0][c];
+ rtf[1][c] = (co2[c] - oc->min[c]) * ocfac[c];
+ rts[1][c] = (short)rtf[1][c];
+ rtf[2][c] = (co3[c] - oc->min[c]) * ocfac[c];
+ rts[2][c] = (short)rtf[2][c];
+ if (RE_rayface_isQuad(face)) {
+ rtf[3][c] = (co4[c] - oc->min[c]) * ocfac[c];
+ rts[3][c] = (short)rtf[3][c];
+ }
+ }
+
+ for (c = 0; c < 3; c++) {
+ oc1 = rts[0][c];
+ oc2 = rts[1][c];
+ oc3 = rts[2][c];
+ if (!RE_rayface_isQuad(face)) {
+ ocmin[c] = min_iii(oc1, oc2, oc3);
+ ocmax[c] = max_iii(oc1, oc2, oc3);
+ }
+ else {
+ oc4 = rts[3][c];
+ ocmin[c] = min_iiii(oc1, oc2, oc3, oc4);
+ ocmax[c] = max_iiii(oc1, oc2, oc3, oc4);
+ }
+ if (ocmax[c] > oc->ocres - 1) ocmax[c] = oc->ocres - 1;
+ if (ocmin[c] < 0) ocmin[c] = 0;
+ }
+
+ if (ocmin[0] == ocmax[0] && ocmin[1] == ocmax[1] && ocmin[2] == ocmax[2]) {
+ ocwrite(oc, face, RE_rayface_isQuad(face), ocmin[0], ocmin[1], ocmin[2], rtf);
+ }
+ else {
+
+ d2dda(oc, 0, 1, 0, 1, ocface + ocres2, rts, rtf);
+ d2dda(oc, 0, 1, 0, 2, ocface, rts, rtf);
+ d2dda(oc, 0, 1, 1, 2, ocface + 2 * ocres2, rts, rtf);
+ d2dda(oc, 1, 2, 0, 1, ocface + ocres2, rts, rtf);
+ d2dda(oc, 1, 2, 0, 2, ocface, rts, rtf);
+ d2dda(oc, 1, 2, 1, 2, ocface + 2 * ocres2, rts, rtf);
+ if (!RE_rayface_isQuad(face)) {
+ d2dda(oc, 2, 0, 0, 1, ocface + ocres2, rts, rtf);
+ d2dda(oc, 2, 0, 0, 2, ocface, rts, rtf);
+ d2dda(oc, 2, 0, 1, 2, ocface + 2 * ocres2, rts, rtf);
+ }
+ else {
+ d2dda(oc, 2, 3, 0, 1, ocface + ocres2, rts, rtf);
+ d2dda(oc, 2, 3, 0, 2, ocface, rts, rtf);
+ d2dda(oc, 2, 3, 1, 2, ocface + 2 * ocres2, rts, rtf);
+ d2dda(oc, 3, 0, 0, 1, ocface + ocres2, rts, rtf);
+ d2dda(oc, 3, 0, 0, 2, ocface, rts, rtf);
+ d2dda(oc, 3, 0, 1, 2, ocface + 2 * ocres2, rts, rtf);
+ }
+ /* nothing todo with triangle..., just fills :) */
+ filltriangle(oc, 0, 1, ocface + ocres2, ocmin, ocmax);
+ filltriangle(oc, 0, 2, ocface, ocmin, ocmax);
+ filltriangle(oc, 1, 2, ocface + 2 * ocres2, ocmin, ocmax);
+
+ /* init static vars here */
+ face_in_node(face, 0, 0, 0, rtf);
+
+ for (x = ocmin[0]; x <= ocmax[0]; x++) {
+ a = oc->ocres * x;
+ for (y = ocmin[1]; y <= ocmax[1]; y++) {
+ if (ocface[a + y + ocres2]) {
+ b = oc->ocres * y + 2 * ocres2;
+ for (z = ocmin[2]; z <= ocmax[2]; z++) {
+ if (ocface[b + z] && ocface[a + z]) {
+ if (face_in_node(NULL, x, y, z, rtf))
+ ocwrite(oc, face, RE_rayface_isQuad(face), x, y, z, rtf);
+ }
+ }
+ }
+ }
+ }
+
+ /* same loops to clear octree, doubt it can be done smarter */
+ for (x = ocmin[0]; x <= ocmax[0]; x++) {
+ a = oc->ocres * x;
+ for (y = ocmin[1]; y <= ocmax[1]; y++) {
+ /* x-y */
+ ocface[a + y + ocres2] = 0;
+
+ b = oc->ocres * y + 2 * ocres2;
+ for (z = ocmin[2]; z <= ocmax[2]; z++) {
+ /* y-z */
+ ocface[b + z] = 0;
+ /* x-z */
+ ocface[a + z] = 0;
+ }
+ }
+ }
+ }
+}
+
+static void RE_rayobject_octree_done(RayObject *tree)
+{
+ Octree *oc = (Octree *)tree;
+ int c;
+ float t00, t01, t02;
+ int ocres2 = oc->ocres * oc->ocres;
+
+ INIT_MINMAX(oc->min, oc->max);
+
+ /* Calculate Bounding Box */
+ for (c = 0; c < oc->ro_nodes_used; c++)
+ RE_rayobject_merge_bb(RE_rayobject_unalignRayFace(oc->ro_nodes[c]), oc->min, oc->max);
+
+ /* Alloc memory */
+ oc->adrbranch = (Branch **)MEM_callocN(sizeof(void *) * BRANCH_ARRAY, "octree branches");
+ oc->adrnode = (Node **)MEM_callocN(sizeof(void *) * NODE_ARRAY, "octree nodes");
+
+ oc->adrbranch[0] = (Branch *)MEM_callocN(4096 * sizeof(Branch), "makeoctree");
+
+ /* the lookup table, per face, for which nodes to fill in */
+ oc->ocface = (char *)MEM_callocN(3 * ocres2 + 8, "ocface");
+ memset(oc->ocface, 0, 3 * ocres2);
+
+ for (c = 0; c < 3; c++) { /* octree enlarge, still needed? */
+ oc->min[c] -= 0.01f;
+ oc->max[c] += 0.01f;
+ }
+
+ t00 = oc->max[0] - oc->min[0];
+ t01 = oc->max[1] - oc->min[1];
+ t02 = oc->max[2] - oc->min[2];
+
+ /* this minus 0.1 is old safety... seems to be needed? */
+ oc->ocfacx = (oc->ocres - 0.1f) / t00;
+ oc->ocfacy = (oc->ocres - 0.1f) / t01;
+ oc->ocfacz = (oc->ocres - 0.1f) / t02;
+
+ oc->ocsize = sqrtf(t00 * t00 + t01 * t01 + t02 * t02); /* global, max size octree */
+
+ for (c = 0; c < oc->ro_nodes_used; c++) {
+ octree_fill_rayface(oc, oc->ro_nodes[c]);
+ }
+
+ MEM_freeN(oc->ocface);
+ oc->ocface = NULL;
+ MEM_freeN(oc->ro_nodes);
+ oc->ro_nodes = NULL;
+
+#if 0
+ printf("%f %f - %f\n", oc->min[0], oc->max[0], oc->ocfacx);
+ printf("%f %f - %f\n", oc->min[1], oc->max[1], oc->ocfacy);
+ printf("%f %f - %f\n", oc->min[2], oc->max[2], oc->ocfacz);
+#endif
+}
+
+static void RE_rayobject_octree_bb(RayObject *tree, float *min, float *max)
+{
+ Octree *oc = (Octree *)tree;
+ DO_MINMAX(oc->min, min, max);
+ DO_MINMAX(oc->max, min, max);
+}
+
+/* check all faces in this node */
+static int testnode(Octree *UNUSED(oc), Isect *is, Node *no, OcVal ocval)
+{
+ short nr = 0;
+
+ /* return on any first hit */
+ if (is->mode == RE_RAY_SHADOW) {
+
+ for (; no; no = no->next) {
+ for (nr = 0; nr < 8; nr++) {
+ RayFace *face = no->v[nr];
+ OcVal *ov = no->ov + nr;
+
+ if (!face) break;
+
+ if ( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
+ if (RE_rayobject_intersect(RE_rayobject_unalignRayFace(face), is) )
+ return 1;
+ }
+ }
+ }
+ }
+ else {
+ /* else mirror or glass or shadowtra, return closest face */
+ int found = 0;
+
+ for (; no; no = no->next) {
+ for (nr = 0; nr < 8; nr++) {
+ RayFace *face = no->v[nr];
+ OcVal *ov = no->ov + nr;
+
+ if (!face) break;
+
+ if ( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
+ if (RE_rayobject_intersect(RE_rayobject_unalignRayFace(face), is) ) {
+ found = 1;
+ }
+ }
+ }
+ }
+
+ return found;
+ }
+
+ return 0;
+}
+
+/* find the Node for the octree coord x y z */
+static Node *ocread(Octree *oc, int x, int y, int z)
+{
+ Branch *br;
+ int oc1;
+
+ x <<= 2;
+ y <<= 1;
+
+ br = oc->adrbranch[0];
+
+ if (oc->ocres == 512) {
+ oc1 = ((x & 1024) + (y & 512) + (z & 256)) >> 8;
+ br = br->b[oc1];
+ if (br == NULL) {
+ return NULL;
+ }
+ }
+ if (oc->ocres >= 256) {
+ oc1 = ((x & 512) + (y & 256) + (z & 128)) >> 7;
+ br = br->b[oc1];
+ if (br == NULL) {
+ return NULL;
+ }
+ }
+ if (oc->ocres >= 128) {
+ oc1 = ((x & 256) + (y & 128) + (z & 64)) >> 6;
+ br = br->b[oc1];
+ if (br == NULL) {
+ return NULL;
+ }
+ }
+
+ oc1 = ((x & 128) + (y & 64) + (z & 32)) >> 5;
+ br = br->b[oc1];
+ if (br) {
+ oc1 = ((x & 64) + (y & 32) + (z & 16)) >> 4;
+ br = br->b[oc1];
+ if (br) {
+ oc1 = ((x & 32) + (y & 16) + (z & 8)) >> 3;
+ br = br->b[oc1];
+ if (br) {
+ oc1 = ((x & 16) + (y & 8) + (z & 4)) >> 2;
+ br = br->b[oc1];
+ if (br) {
+ oc1 = ((x & 8) + (y & 4) + (z & 2)) >> 1;
+ br = br->b[oc1];
+ if (br) {
+ oc1 = ((x & 4) + (y & 2) + (z & 1));
+ return (Node *)br->b[oc1];
+ }
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static int cliptest(float p, float q, float *u1, float *u2)
+{
+ float r;
+
+ if (p < 0.0f) {
+ if (q < p) return 0;
+ else if (q < 0.0f) {
+ r = q / p;
+ if (r > *u2) return 0;
+ else if (r > *u1) *u1 = r;
+ }
+ }
+ else {
+ if (p > 0.0f) {
+ if (q < 0.0f) return 0;
+ else if (q < p) {
+ r = q / p;
+ if (r < *u1) return 0;
+ else if (r < *u2) *u2 = r;
+ }
+ }
+ else if (q < 0.0f) return 0;
+ }
+ return 1;
+}
+
+/* extensive coherence checks/storage cancels out the benefit of it, and gives errors... we
+ * need better methods, sample code commented out below (ton) */
+
+#if 0
+
+in top : static int coh_nodes[16 * 16 * 16][6];
+in makeoctree : memset(coh_nodes, 0, sizeof(coh_nodes));
+
+static void add_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2)
+{
+ short *sp;
+
+ sp = coh_nodes[(ocx2 & 15) + 16 * (ocy2 & 15) + 256 * (ocz2 & 15)];
+ sp[0] = ocx1; sp[1] = ocy1; sp[2] = ocz1;
+ sp[3] = ocx2; sp[4] = ocy2; sp[5] = ocz2;
+
+}
+
+static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2)
+{
+ short *sp;
+
+ sp = coh_nodes[(ocx2 & 15) + 16 * (ocy2 & 15) + 256 * (ocz2 & 15)];
+ if (sp[0] == ocx1 && sp[1] == ocy1 && sp[2] == ocz1 &&
+ sp[3] == ocx2 && sp[4] == ocy2 && sp[5] == ocz2) return 1;
+ return 0;
+}
+
+#endif
+
+/* return 1: found valid intersection */
+/* starts with is->orig.face */
+static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is)
+{
+ Octree *oc = (Octree *)tree;
+ Node *no;
+ OcVal ocval;
+ float vec1[3], vec2[3], start[3], end[3];
+ float u1, u2, ox1, ox2, oy1, oy2, oz1, oz2;
+ float lambda_o, lambda_x, ldx, lambda_y, ldy, lambda_z, ldz, dda_lambda;
+ float o_lambda = 0;
+ int dx, dy, dz;
+ int xo, yo, zo, c1 = 0;
+ int ocx1, ocx2, ocy1, ocy2, ocz1, ocz2;
+
+ /* clip with octree */
+ if (oc->branchcount == 0) return 0;
+
+ /* do this before intersect calls */
+#if 0
+ is->facecontr = NULL; /* to check shared edge */
+ is->obcontr = 0;
+ is->faceisect = is->isect = 0; /* shared edge, quad half flag */
+ is->userdata = oc->userdata;
+#endif
+
+ copy_v3_v3(start, is->start);
+ madd_v3_v3v3fl(end, is->start, is->dir, is->dist);
+ ldx = is->dir[0] * is->dist;
+ o_lambda = is->dist;
+ u1 = 0.0f;
+ u2 = 1.0f;
+
+ /* clip with octree cube */
+ if (cliptest(-ldx, start[0] - oc->min[0], &u1, &u2)) {
+ if (cliptest(ldx, oc->max[0] - start[0], &u1, &u2)) {
+ ldy = is->dir[1] * is->dist;
+ if (cliptest(-ldy, start[1] - oc->min[1], &u1, &u2)) {
+ if (cliptest(ldy, oc->max[1] - start[1], &u1, &u2)) {
+ ldz = is->dir[2] * is->dist;
+ if (cliptest(-ldz, start[2] - oc->min[2], &u1, &u2)) {
+ if (cliptest(ldz, oc->max[2] - start[2], &u1, &u2)) {
+ c1 = 1;
+ if (u2 < 1.0f) {
+ end[0] = start[0] + u2 * ldx;
+ end[1] = start[1] + u2 * ldy;
+ end[2] = start[2] + u2 * ldz;
+ }
+
+ if (u1 > 0.0f) {
+ start[0] += u1 * ldx;
+ start[1] += u1 * ldy;
+ start[2] += u1 * ldz;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (c1 == 0) return 0;
+
+ /* reset static variables in ocread */
+ //ocread(oc, oc->ocres, 0, 0);
+
+ /* setup 3dda to traverse octree */
+ ox1 = (start[0] - oc->min[0]) * oc->ocfacx;
+ oy1 = (start[1] - oc->min[1]) * oc->ocfacy;
+ oz1 = (start[2] - oc->min[2]) * oc->ocfacz;
+ ox2 = (end[0] - oc->min[0]) * oc->ocfacx;
+ oy2 = (end[1] - oc->min[1]) * oc->ocfacy;
+ oz2 = (end[2] - oc->min[2]) * oc->ocfacz;
+
+ ocx1 = (int)ox1;
+ ocy1 = (int)oy1;
+ ocz1 = (int)oz1;
+ ocx2 = (int)ox2;
+ ocy2 = (int)oy2;
+ ocz2 = (int)oz2;
+
+ if (ocx1 == ocx2 && ocy1 == ocy2 && ocz1 == ocz2) {
+ no = ocread(oc, ocx1, ocy1, ocz1);
+ if (no) {
+ /* exact intersection with node */
+ vec1[0] = ox1; vec1[1] = oy1; vec1[2] = oz1;
+ vec2[0] = ox2; vec2[1] = oy2; vec2[2] = oz2;
+ calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2);
+ if (testnode(oc, is, no, ocval) ) return 1;
+ }
+ }
+ else {
+ int found = 0;
+ //static int coh_ocx1, coh_ocx2, coh_ocy1, coh_ocy2, coh_ocz1, coh_ocz2;
+ float dox, doy, doz;
+ int eqval;
+
+ /* calc lambda en ld */
+ dox = ox1 - ox2;
+ doy = oy1 - oy2;
+ doz = oz1 - oz2;
+
+ if (dox < -FLT_EPSILON) {
+ ldx = -1.0f / dox;
+ lambda_x = (ocx1 - ox1 + 1.0f) * ldx;
+ dx = 1;
+ }
+ else if (dox > FLT_EPSILON) {
+ ldx = 1.0f / dox;
+ lambda_x = (ox1 - ocx1) * ldx;
+ dx = -1;
+ }
+ else {
+ lambda_x = 1.0f;
+ ldx = 0;
+ dx = 0;
+ }
+
+ if (doy < -FLT_EPSILON) {
+ ldy = -1.0f / doy;
+ lambda_y = (ocy1 - oy1 + 1.0f) * ldy;
+ dy = 1;
+ }
+ else if (doy > FLT_EPSILON) {
+ ldy = 1.0f / doy;
+ lambda_y = (oy1 - ocy1) * ldy;
+ dy = -1;
+ }
+ else {
+ lambda_y = 1.0f;
+ ldy = 0;
+ dy = 0;
+ }
+
+ if (doz < -FLT_EPSILON) {
+ ldz = -1.0f / doz;
+ lambda_z = (ocz1 - oz1 + 1.0f) * ldz;
+ dz = 1;
+ }
+ else if (doz > FLT_EPSILON) {
+ ldz = 1.0f / doz;
+ lambda_z = (oz1 - ocz1) * ldz;
+ dz = -1;
+ }
+ else {
+ lambda_z = 1.0f;
+ ldz = 0;
+ dz = 0;
+ }
+
+ xo = ocx1; yo = ocy1; zo = ocz1;
+ dda_lambda = min_fff(lambda_x, lambda_y, lambda_z);
+
+ vec2[0] = ox1;
+ vec2[1] = oy1;
+ vec2[2] = oz1;
+
+ /* this loop has been constructed to make sure the first and last node of ray
+ * are always included, even when dda_lambda==1.0f or larger */
+
+ while (true) {
+
+ no = ocread(oc, xo, yo, zo);
+ if (no) {
+
+ /* calculate ray intersection with octree node */
+ copy_v3_v3(vec1, vec2);
+ // dox, y, z is negative
+ vec2[0] = ox1 - dda_lambda * dox;
+ vec2[1] = oy1 - dda_lambda * doy;
+ vec2[2] = oz1 - dda_lambda * doz;
+ calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2);
+
+ //is->dist = (u1 + dda_lambda * (u2 - u1)) * o_lambda;
+ if (testnode(oc, is, no, ocval) )
+ found = 1;
+
+ if (is->dist < (u1 + dda_lambda * (u2 - u1)) * o_lambda)
+ return found;
+ }
+
+
+ lambda_o = dda_lambda;
+
+ /* traversing octree nodes need careful detection of smallest values, with proper
+ * exceptions for equal lambdas */
+ eqval = (lambda_x == lambda_y);
+ if (lambda_y == lambda_z) eqval += 2;
+ if (lambda_x == lambda_z) eqval += 4;
+
+ if (eqval) { // only 4 cases exist!
+ if (eqval == 7) { // x=y=z
+ xo += dx; lambda_x += ldx;
+ yo += dy; lambda_y += ldy;
+ zo += dz; lambda_z += ldz;
+ }
+ else if (eqval == 1) { // x=y
+ if (lambda_y < lambda_z) {
+ xo += dx; lambda_x += ldx;
+ yo += dy; lambda_y += ldy;
+ }
+ else {
+ zo += dz; lambda_z += ldz;
+ }
+ }
+ else if (eqval == 2) { // y=z
+ if (lambda_x < lambda_y) {
+ xo += dx; lambda_x += ldx;
+ }
+ else {
+ yo += dy; lambda_y += ldy;
+ zo += dz; lambda_z += ldz;
+ }
+ }
+ else { // x=z
+ if (lambda_y < lambda_x) {
+ yo += dy; lambda_y += ldy;
+ }
+ else {
+ xo += dx; lambda_x += ldx;
+ zo += dz; lambda_z += ldz;
+ }
+ }
+ }
+ else { // all three different, just three cases exist
+ eqval = (lambda_x < lambda_y);
+ if (lambda_y < lambda_z) eqval += 2;
+ if (lambda_x < lambda_z) eqval += 4;
+
+ if (eqval == 7 || eqval == 5) { // x smallest
+ xo += dx; lambda_x += ldx;
+ }
+ else if (eqval == 2 || eqval == 6) { // y smallest
+ yo += dy; lambda_y += ldy;
+ }
+ else { // z smallest
+ zo += dz; lambda_z += ldz;
+ }
+
+ }
+
+ dda_lambda = min_fff(lambda_x, lambda_y, lambda_z);
+ if (dda_lambda == lambda_o) break;
+ /* to make sure the last node is always checked */
+ if (lambda_o >= 1.0f) break;
+ }
+ }
+
+ /* reached end, no intersections found */
+ return 0;
+}
+
+
+
diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
new file mode 100644
index 00000000000..8e3dd87efd1
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
@@ -0,0 +1,160 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_qbvh.cpp
+ * \ingroup render
+ */
+
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "vbvh.h"
+#include "svbvh.h"
+#include "reorganize.h"
+
+#ifdef __SSE__
+
+#define DFS_STACK_SIZE 256
+
+struct QBVHTree {
+ RayObject rayobj;
+
+ SVBVHNode *root;
+ MemArena *node_arena;
+
+ float cost;
+ RTBuilder *builder;
+};
+
+
+template<>
+void bvh_done<QBVHTree>(QBVHTree *obj)
+{
+ rtbuild_done(obj->builder, &obj->rayobj.control);
+
+ //TODO find a away to exactly calculate the needed memory
+ MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena");
+ BLI_memarena_use_malloc(arena1);
+
+ MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena 2");
+ BLI_memarena_use_malloc(arena2);
+ BLI_memarena_use_align(arena2, 16);
+
+ //Build and optimize the tree
+ //TODO do this in 1 pass (half memory usage during building)
+ VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder);
+
+ if (RE_rayobjectcontrol_test_break(&obj->rayobj.control)) {
+ BLI_memarena_free(arena1);
+ BLI_memarena_free(arena2);
+ return;
+ }
+
+ if (root) {
+ pushup_simd<VBVHNode, 4>(root);
+ obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
+ }
+ else
+ obj->root = NULL;
+
+ //Free data
+ BLI_memarena_free(arena1);
+
+ obj->node_arena = arena2;
+ obj->cost = 1.0;
+
+ rtbuild_free(obj->builder);
+ obj->builder = NULL;
+}
+
+template<int StackSize>
+static int intersect(QBVHTree *obj, Isect *isec)
+{
+ //TODO renable hint support
+ if (RE_rayobject_isAligned(obj->root)) {
+ if (isec->mode == RE_RAY_SHADOW)
+ return svbvh_node_stack_raycast<StackSize, true>(obj->root, isec);
+ else
+ return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec);
+ }
+ else
+ return RE_rayobject_intersect((RayObject *)obj->root, isec);
+}
+
+template<class Tree>
+static void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max))
+{
+ //TODO renable hint support
+ {
+ hint->size = 0;
+ hint->stack[hint->size++] = (RayObject *)tree->root;
+ }
+}
+/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
+template<class Tree, int STACK_SIZE>
+static RayObjectAPI make_api()
+{
+ static RayObjectAPI api =
+ {
+ (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
+ (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
+ (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
+ (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
+ (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
+ (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
+ (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
+ };
+
+ return api;
+}
+
+template<class Tree>
+RayObjectAPI *bvh_get_api(int maxstacksize)
+{
+ static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();
+
+ if (maxstacksize <= 1024) return &bvh_api256;
+ assert(maxstacksize <= 256);
+ return NULL;
+}
+
+RayObject *RE_rayobject_qbvh_create(int size)
+{
+ return bvh_create_tree<QBVHTree, DFS_STACK_SIZE>(size);
+}
+
+#else
+
+RayObject *RE_rayobject_qbvh_create(int UNUSED(size))
+{
+ puts("WARNING: SSE disabled at compile time\n");
+ return NULL;
+}
+
+#endif
diff --git a/source/blender/render/intern/raytrace/rayobject_raycounter.cpp b/source/blender/render/intern/raytrace/rayobject_raycounter.cpp
new file mode 100644
index 00000000000..429c47f1c0f
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_raycounter.cpp
@@ -0,0 +1,91 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_raycounter.cpp
+ * \ingroup render
+ */
+
+
+#include "rayobject.h"
+#include "raycounter.h"
+
+#ifdef RE_RAYCOUNTER
+
+void RE_RC_INFO(RayCounter *info)
+{
+ printf("----------- Raycast counter --------\n");
+ printf("Rays total: %llu\n", info->raycast.test );
+ printf("Rays hit: %llu\n", info->raycast.hit );
+ printf("\n");
+ printf("BB tests: %llu\n", info->bb.test );
+ printf("BB hits: %llu\n", info->bb.hit );
+ printf("\n");
+ printf("SIMD BB tests: %llu\n", info->simd_bb.test );
+ printf("SIMD BB hits: %llu\n", info->simd_bb.hit );
+ printf("\n");
+ printf("Primitives tests: %llu\n", info->faces.test );
+ printf("Primitives hits: %llu\n", info->faces.hit );
+ printf("------------------------------------\n");
+ printf("Shadow last-hit tests per ray: %f\n", info->rayshadow_last_hit.test / ((float)info->raycast.test) );
+ printf("Shadow last-hit hits per ray: %f\n", info->rayshadow_last_hit.hit / ((float)info->raycast.test) );
+ printf("\n");
+ printf("Hint tests per ray: %f\n", info->raytrace_hint.test / ((float)info->raycast.test) );
+ printf("Hint hits per ray: %f\n", info->raytrace_hint.hit / ((float)info->raycast.test) );
+ printf("\n");
+ printf("BB tests per ray: %f\n", info->bb.test / ((float)info->raycast.test) );
+ printf("BB hits per ray: %f\n", info->bb.hit / ((float)info->raycast.test) );
+ printf("\n");
+ printf("SIMD tests per ray: %f\n", info->simd_bb.test / ((float)info->raycast.test) );
+ printf("SIMD hits per ray: %f\n", info->simd_bb.hit / ((float)info->raycast.test) );
+ printf("\n");
+ printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) );
+ printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) );
+ printf("------------------------------------\n");
+}
+
+void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp)
+{
+ dest->faces.test += tmp->faces.test;
+ dest->faces.hit += tmp->faces.hit;
+
+ dest->bb.test += tmp->bb.test;
+ dest->bb.hit += tmp->bb.hit;
+
+ dest->simd_bb.test += tmp->simd_bb.test;
+ dest->simd_bb.hit += tmp->simd_bb.hit;
+
+ dest->raycast.test += tmp->raycast.test;
+ dest->raycast.hit += tmp->raycast.hit;
+
+ dest->rayshadow_last_hit.test += tmp->rayshadow_last_hit.test;
+ dest->rayshadow_last_hit.hit += tmp->rayshadow_last_hit.hit;
+
+ dest->raytrace_hint.test += tmp->raytrace_hint.test;
+ dest->raytrace_hint.hit += tmp->raytrace_hint.hit;
+}
+
+#endif
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
new file mode 100644
index 00000000000..51f89784674
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
@@ -0,0 +1,531 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_rtbuild.cpp
+ * \ingroup render
+ */
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <algorithm>
+
+#if __cplusplus >= 201103L
+#include <cmath>
+using std::isfinite;
+#else
+#include <math.h>
+#endif
+
+#include "rayobject_rtbuild.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+static bool selected_node(RTBuilder::Object *node)
+{
+ return node->selected;
+}
+
+static void rtbuild_init(RTBuilder *b)
+{
+ b->split_axis = -1;
+ b->primitives.begin = NULL;
+ b->primitives.end = NULL;
+ b->primitives.maxsize = 0;
+ b->depth = 0;
+
+ for (int i = 0; i < RTBUILD_MAX_CHILDS; i++)
+ b->child_offset[i] = 0;
+
+ for (int i = 0; i < 3; i++)
+ b->sorted_begin[i] = b->sorted_end[i] = NULL;
+
+ INIT_MINMAX(b->bb, b->bb + 3);
+}
+
+RTBuilder *rtbuild_create(int size)
+{
+ RTBuilder *builder = (RTBuilder *) MEM_mallocN(sizeof(RTBuilder), "RTBuilder");
+ RTBuilder::Object *memblock = (RTBuilder::Object *)MEM_mallocN(sizeof(RTBuilder::Object) * size, "RTBuilder.objects");
+
+
+ rtbuild_init(builder);
+
+ builder->primitives.begin = builder->primitives.end = memblock;
+ builder->primitives.maxsize = size;
+
+ for (int i = 0; i < 3; i++) {
+ builder->sorted_begin[i] = (RTBuilder::Object **)MEM_mallocN(sizeof(RTBuilder::Object *) * size, "RTBuilder.sorted_objects");
+ builder->sorted_end[i] = builder->sorted_begin[i];
+ }
+
+
+ return builder;
+}
+
+void rtbuild_free(RTBuilder *b)
+{
+ if (b->primitives.begin) MEM_freeN(b->primitives.begin);
+
+ for (int i = 0; i < 3; i++)
+ if (b->sorted_begin[i])
+ MEM_freeN(b->sorted_begin[i]);
+
+ MEM_freeN(b);
+}
+
+void rtbuild_add(RTBuilder *b, RayObject *o)
+{
+ float bb[6];
+
+ assert(b->primitives.begin + b->primitives.maxsize != b->primitives.end);
+
+ INIT_MINMAX(bb, bb + 3);
+ RE_rayobject_merge_bb(o, bb, bb + 3);
+
+ /* skip objects with invalid bounding boxes, nan causes DO_MINMAX
+ * to do nothing, so we get these invalid values. this shouldn't
+ * happen usually, but bugs earlier in the pipeline can cause it. */
+ if (bb[0] > bb[3] || bb[1] > bb[4] || bb[2] > bb[5])
+ return;
+ /* skip objects with inf bounding boxes */
+ if (!isfinite(bb[0]) || !isfinite(bb[1]) || !isfinite(bb[2]))
+ return;
+ if (!isfinite(bb[3]) || !isfinite(bb[4]) || !isfinite(bb[5]))
+ return;
+ /* skip objects with zero bounding box, they are of no use, and
+ * will give problems in rtbuild_heuristic_object_split later */
+ if (bb[0] == bb[3] && bb[1] == bb[4] && bb[2] == bb[5])
+ return;
+
+ copy_v3_v3(b->primitives.end->bb, bb);
+ copy_v3_v3(b->primitives.end->bb + 3, bb + 3);
+ b->primitives.end->obj = o;
+ b->primitives.end->cost = RE_rayobject_cost(o);
+
+ for (int i = 0; i < 3; i++) {
+ *(b->sorted_end[i]) = b->primitives.end;
+ b->sorted_end[i]++;
+ }
+ b->primitives.end++;
+}
+
+int rtbuild_size(RTBuilder *b)
+{
+ return b->sorted_end[0] - b->sorted_begin[0];
+}
+
+
+template<class Obj, int Axis>
+static bool obj_bb_compare(const Obj &a, const Obj &b)
+{
+ if (a->bb[Axis] != b->bb[Axis])
+ return a->bb[Axis] < b->bb[Axis];
+ return a->obj < b->obj;
+}
+
+template<class Item>
+static void object_sort(Item *begin, Item *end, int axis)
+{
+ if (axis == 0) return std::sort(begin, end, obj_bb_compare<Item, 0> );
+ if (axis == 1) return std::sort(begin, end, obj_bb_compare<Item, 1> );
+ if (axis == 2) return std::sort(begin, end, obj_bb_compare<Item, 2> );
+ assert(false);
+}
+
+void rtbuild_done(RTBuilder *b, RayObjectControl *ctrl)
+{
+ for (int i = 0; i < 3; i++) {
+ if (b->sorted_begin[i]) {
+ if (RE_rayobjectcontrol_test_break(ctrl)) break;
+ object_sort(b->sorted_begin[i], b->sorted_end[i], i);
+ }
+ }
+}
+
+RayObject *rtbuild_get_primitive(RTBuilder *b, int index)
+{
+ return b->sorted_begin[0][index]->obj;
+}
+
+RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp)
+{
+ rtbuild_init(tmp);
+
+ tmp->depth = b->depth + 1;
+
+ for (int i = 0; i < 3; i++)
+ if (b->sorted_begin[i]) {
+ tmp->sorted_begin[i] = b->sorted_begin[i] + b->child_offset[child];
+ tmp->sorted_end[i] = b->sorted_begin[i] + b->child_offset[child + 1];
+ }
+ else {
+ tmp->sorted_begin[i] = NULL;
+ tmp->sorted_end[i] = NULL;
+ }
+
+ return tmp;
+}
+
+static void rtbuild_calc_bb(RTBuilder *b)
+{
+ if (b->bb[0] == 1.0e30f) {
+ for (RTBuilder::Object **index = b->sorted_begin[0]; index != b->sorted_end[0]; index++)
+ RE_rayobject_merge_bb( (*index)->obj, b->bb, b->bb + 3);
+ }
+}
+
+void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3])
+{
+ rtbuild_calc_bb(b);
+ DO_MIN(b->bb, min);
+ DO_MAX(b->bb + 3, max);
+}
+
+#if 0
+int rtbuild_get_largest_axis(RTBuilder *b)
+{
+ rtbuild_calc_bb(b);
+ return bb_largest_axis(b->bb, b->bb + 3);
+}
+
+//Left balanced tree
+int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis)
+{
+ int i;
+ int mleafs_per_child, Mleafs_per_child;
+ int tot_leafs = rtbuild_size(b);
+ int missing_leafs;
+
+ long long s;
+
+ assert(nchilds <= RTBUILD_MAX_CHILDS);
+
+ //TODO optimize calc of leafs_per_child
+ for (s = nchilds; s < tot_leafs; s *= nchilds) ;
+ Mleafs_per_child = s / nchilds;
+ mleafs_per_child = Mleafs_per_child / nchilds;
+
+ //split min leafs per child
+ b->child_offset[0] = 0;
+ for (i = 1; i <= nchilds; i++)
+ b->child_offset[i] = mleafs_per_child;
+
+ //split remaining leafs
+ missing_leafs = tot_leafs - mleafs_per_child * nchilds;
+ for (i = 1; i <= nchilds; i++)
+ {
+ if (missing_leafs > Mleafs_per_child - mleafs_per_child)
+ {
+ b->child_offset[i] += Mleafs_per_child - mleafs_per_child;
+ missing_leafs -= Mleafs_per_child - mleafs_per_child;
+ }
+ else {
+ b->child_offset[i] += missing_leafs;
+ missing_leafs = 0;
+ break;
+ }
+ }
+
+ //adjust for accumulative offsets
+ for (i = 1; i <= nchilds; i++)
+ b->child_offset[i] += b->child_offset[i - 1];
+
+ //Count created childs
+ for (i = nchilds; b->child_offset[i] == b->child_offset[i - 1]; i--) ;
+ split_leafs(b, b->child_offset, i, axis);
+
+ assert(b->child_offset[0] == 0 && b->child_offset[i] == tot_leafs);
+ return i;
+}
+
+
+int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds)
+{
+ int axis = rtbuild_get_largest_axis(b);
+ return rtbuild_mean_split(b, nchilds, axis);
+}
+#endif
+
+/*
+ * "separators" is an array of dim NCHILDS-1
+ * and indicates where to cut the childs
+ */
+#if 0
+int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis)
+{
+ int size = rtbuild_size(b);
+
+ assert(nchilds <= RTBUILD_MAX_CHILDS);
+ if (size <= nchilds)
+ {
+ return rtbuild_mean_split(b, nchilds, axis);
+ }
+ else {
+ int i;
+
+ b->split_axis = axis;
+
+ //Calculate child offsets
+ b->child_offset[0] = 0;
+ for (i = 0; i < nchilds - 1; i++)
+ b->child_offset[i + 1] = split_leafs_by_plane(b, b->child_offset[i], size, separators[i]);
+ b->child_offset[nchilds] = size;
+
+ for (i = 0; i < nchilds; i++)
+ if (b->child_offset[i + 1] - b->child_offset[i] == size)
+ return rtbuild_mean_split(b, nchilds, axis);
+
+ return nchilds;
+ }
+}
+
+int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds)
+{
+ int la, i;
+ float separators[RTBUILD_MAX_CHILDS];
+
+ rtbuild_calc_bb(b);
+
+ la = bb_largest_axis(b->bb, b->bb + 3);
+ for (i = 1; i < nchilds; i++)
+ separators[i - 1] = (b->bb[la + 3] - b->bb[la]) * i / nchilds;
+
+ return rtbuild_median_split(b, separators, nchilds, la);
+}
+#endif
+
+//Heuristics Object Splitter
+
+
+struct SweepCost {
+ float bb[6];
+ float cost;
+};
+
+/* Object Surface Area Heuristic splitter */
+int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
+{
+ int size = rtbuild_size(b);
+ assert(nchilds == 2);
+ assert(size > 1);
+ int baxis = -1, boffset = 0;
+
+ if (size > nchilds) {
+ if (b->depth > RTBUILD_MAX_SAH_DEPTH) {
+ // for degenerate cases we avoid running out of stack space
+ // by simply splitting the children in the middle
+ b->child_offset[0] = 0;
+ b->child_offset[1] = (size+1)/2;
+ b->child_offset[2] = size;
+ return 2;
+ }
+
+ float bcost = FLT_MAX;
+ baxis = -1;
+ boffset = size / 2;
+
+ SweepCost *sweep = (SweepCost *)MEM_mallocN(sizeof(SweepCost) * size, "RTBuilder.HeuristicSweep");
+
+ for (int axis = 0; axis < 3; axis++) {
+ SweepCost sweep_left;
+
+ RTBuilder::Object **obj = b->sorted_begin[axis];
+
+// float right_cost = 0;
+ for (int i = size - 1; i >= 0; i--) {
+ if (i == size - 1) {
+ copy_v3_v3(sweep[i].bb, obj[i]->bb);
+ copy_v3_v3(sweep[i].bb + 3, obj[i]->bb + 3);
+ sweep[i].cost = obj[i]->cost;
+ }
+ else {
+ sweep[i].bb[0] = min_ff(obj[i]->bb[0], sweep[i + 1].bb[0]);
+ sweep[i].bb[1] = min_ff(obj[i]->bb[1], sweep[i + 1].bb[1]);
+ sweep[i].bb[2] = min_ff(obj[i]->bb[2], sweep[i + 1].bb[2]);
+ sweep[i].bb[3] = max_ff(obj[i]->bb[3], sweep[i + 1].bb[3]);
+ sweep[i].bb[4] = max_ff(obj[i]->bb[4], sweep[i + 1].bb[4]);
+ sweep[i].bb[5] = max_ff(obj[i]->bb[5], sweep[i + 1].bb[5]);
+ sweep[i].cost = obj[i]->cost + sweep[i + 1].cost;
+ }
+// right_cost += obj[i]->cost;
+ }
+
+ sweep_left.bb[0] = obj[0]->bb[0];
+ sweep_left.bb[1] = obj[0]->bb[1];
+ sweep_left.bb[2] = obj[0]->bb[2];
+ sweep_left.bb[3] = obj[0]->bb[3];
+ sweep_left.bb[4] = obj[0]->bb[4];
+ sweep_left.bb[5] = obj[0]->bb[5];
+ sweep_left.cost = obj[0]->cost;
+
+// right_cost -= obj[0]->cost; if (right_cost < 0) right_cost = 0;
+
+ for (int i = 1; i < size; i++) {
+ //Worst case heuristic (cost of each child is linear)
+ float hcost, left_side, right_side;
+
+ // not using log seems to have no impact on raytracing perf, but
+ // makes tree construction quicker, left out for now to test (brecht)
+ // left_side = bb_area(sweep_left.bb, sweep_left.bb + 3) * (sweep_left.cost + logf((float)i));
+ // right_side = bb_area(sweep[i].bb, sweep[i].bb + 3) * (sweep[i].cost + logf((float)size - i));
+ left_side = bb_area(sweep_left.bb, sweep_left.bb + 3) * (sweep_left.cost);
+ right_side = bb_area(sweep[i].bb, sweep[i].bb + 3) * (sweep[i].cost);
+ hcost = left_side + right_side;
+
+ assert(left_side >= 0);
+ assert(right_side >= 0);
+
+ if (left_side > bcost) break; //No way we can find a better heuristic in this axis
+
+ assert(hcost >= 0);
+ // this makes sure the tree built is the same whatever is the order of the sorting axis
+ if (hcost < bcost || (hcost == bcost && axis < baxis)) {
+ bcost = hcost;
+ baxis = axis;
+ boffset = i;
+ }
+ DO_MIN(obj[i]->bb, sweep_left.bb);
+ DO_MAX(obj[i]->bb + 3, sweep_left.bb + 3);
+
+ sweep_left.cost += obj[i]->cost;
+// right_cost -= obj[i]->cost; if (right_cost < 0) right_cost = 0;
+ }
+
+ //assert(baxis >= 0 && baxis < 3);
+ if (!(baxis >= 0 && baxis < 3))
+ baxis = 0;
+ }
+
+
+ MEM_freeN(sweep);
+ }
+ else if (size == 2) {
+ baxis = 0;
+ boffset = 1;
+ }
+ else if (size == 1) {
+ b->child_offset[0] = 0;
+ b->child_offset[1] = 1;
+ return 1;
+ }
+
+ b->child_offset[0] = 0;
+ b->child_offset[1] = boffset;
+ b->child_offset[2] = size;
+
+
+ /* Adjust sorted arrays for childs */
+ for (int i = 0; i < boffset; i++) b->sorted_begin[baxis][i]->selected = true;
+ for (int i = boffset; i < size; i++) b->sorted_begin[baxis][i]->selected = false;
+ for (int i = 0; i < 3; i++)
+ std::stable_partition(b->sorted_begin[i], b->sorted_end[i], selected_node);
+
+ return nchilds;
+}
+
+/*
+ * Helper code
+ * PARTITION code / used on mean-split
+ * basically this a std::nth_element (like on C++ STL algorithm)
+ */
+#if 0
+static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis)
+{
+ int i;
+ b->split_axis = split_axis;
+
+ for (i = 0; i < partitions - 1; i++)
+ {
+ assert(nth[i] < nth[i + 1] && nth[i + 1] < nth[partitions]);
+
+ if (split_axis == 0) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 0>);
+ if (split_axis == 1) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 1>);
+ if (split_axis == 2) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 2>);
+ }
+}
+#endif
+
+/*
+ * Bounding Box utils
+ */
+float bb_volume(const float min[3], const float max[3])
+{
+ return (max[0] - min[0]) * (max[1] - min[1]) * (max[2] - min[2]);
+}
+
+float bb_area(const float min[3], const float max[3])
+{
+ float sub[3], a;
+ sub[0] = max[0] - min[0];
+ sub[1] = max[1] - min[1];
+ sub[2] = max[2] - min[2];
+
+ a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2.0f;
+ /* used to have an assert() here on negative results
+ * however, in this case its likely some overflow or ffast math error.
+ * so just return 0.0f instead. */
+ return a < 0.0f ? 0.0f : a;
+}
+
+int bb_largest_axis(const float min[3], const float max[3])
+{
+ float sub[3];
+
+ sub[0] = max[0] - min[0];
+ sub[1] = max[1] - min[1];
+ sub[2] = max[2] - min[2];
+ if (sub[0] > sub[1]) {
+ if (sub[0] > sub[2])
+ return 0;
+ else
+ return 2;
+ }
+ else {
+ if (sub[1] > sub[2])
+ return 1;
+ else
+ return 2;
+ }
+}
+
+/* only returns 0 if merging inner and outerbox would create a box larger than outer box */
+int bb_fits_inside(const float outer_min[3], const float outer_max[3],
+ const float inner_min[3], const float inner_max[3])
+{
+ int i;
+ for (i = 0; i < 3; i++)
+ if (outer_min[i] > inner_min[i]) return 0;
+
+ for (i = 0; i < 3; i++)
+ if (outer_max[i] < inner_max[i]) return 0;
+
+ return 1;
+}
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h
new file mode 100644
index 00000000000..fc42bc36d92
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h
@@ -0,0 +1,125 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_rtbuild.h
+ * \ingroup render
+ */
+
+#ifndef __RAYOBJECT_RTBUILD_H__
+#define __RAYOBJECT_RTBUILD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "rayobject.h"
+
+
+/*
+ * Ray Tree Builder
+ * this structs helps building any type of tree
+ * it contains several methods to organize/split nodes
+ * allowing to create a given tree on the fly.
+ *
+ * Idea is that other trees BVH, BIH can use this code to
+ * generate with simple calls, and then convert to the theirs
+ * specific structure on the fly.
+ */
+#define RTBUILD_MAX_CHILDS 32
+#define RTBUILD_MAX_SAH_DEPTH 256
+
+
+typedef struct RTBuilder {
+ struct Object {
+ RayObject *obj;
+ float cost;
+ float bb[6];
+ int selected;
+ };
+
+ /* list to all primitives added in this tree */
+ struct {
+ Object *begin, *end;
+ int maxsize;
+ } primitives;
+
+ /* sorted list of rayobjects */
+ struct Object **sorted_begin[3], **sorted_end[3];
+
+ /* axis used (if any) on the split method */
+ int split_axis;
+
+ /* child partitions calculated during splitting */
+ int child_offset[RTBUILD_MAX_CHILDS + 1];
+
+// int child_sorted_axis; /* -1 if not sorted */
+
+ float bb[6];
+
+ /* current depth */
+ int depth;
+} RTBuilder;
+
+/* used during creation */
+RTBuilder *rtbuild_create(int size);
+void rtbuild_free(RTBuilder *b);
+void rtbuild_add(RTBuilder *b, RayObject *o);
+void rtbuild_done(RTBuilder *b, RayObjectControl *c);
+void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]);
+int rtbuild_size(RTBuilder *b);
+
+RayObject *rtbuild_get_primitive(RTBuilder *b, int offset);
+
+/* used during tree reorganization */
+RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp);
+
+/* Calculates child partitions and returns number of efectively needed partitions */
+int rtbuild_get_largest_axis(RTBuilder *b);
+
+//Object partition
+int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis);
+int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds);
+
+int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds);
+
+//Space partition
+int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis);
+int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds);
+
+
+/* bb utils */
+float bb_area(const float min[3], const float max[3]);
+float bb_volume(const float min[3], const float max[3]);
+int bb_largest_axis(const float min[3], const float max[3]);
+int bb_fits_inside(const float outer_min[3], const float outer_max[3],
+ const float inner_min[3], const float inner_max[3]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RAYOBJECT_RTBUILD_H__ */
diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
new file mode 100644
index 00000000000..fcd692fac02
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
@@ -0,0 +1,192 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_svbvh.cpp
+ * \ingroup render
+ */
+
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "vbvh.h"
+#include "svbvh.h"
+#include "reorganize.h"
+
+#ifdef __SSE__
+
+#define DFS_STACK_SIZE 256
+
+struct SVBVHTree {
+ RayObject rayobj;
+
+ SVBVHNode *root;
+ MemArena *node_arena;
+
+ float cost;
+ RTBuilder *builder;
+};
+
+/*
+ * Cost to test N childs
+ */
+struct PackCost {
+ float operator()(int n)
+ {
+ return (n / 4) + ((n % 4) > 2 ? 1 : n % 4);
+ }
+};
+
+
+template<>
+void bvh_done<SVBVHTree>(SVBVHTree *obj)
+{
+ rtbuild_done(obj->builder, &obj->rayobj.control);
+
+ //TODO find a away to exactly calculate the needed memory
+ MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena");
+ BLI_memarena_use_malloc(arena1);
+
+ MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena2");
+ BLI_memarena_use_malloc(arena2);
+ BLI_memarena_use_align(arena2, 16);
+
+ //Build and optimize the tree
+ if (0) {
+ VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder);
+
+ if (RE_rayobjectcontrol_test_break(&obj->rayobj.control)) {
+ BLI_memarena_free(arena1);
+ BLI_memarena_free(arena2);
+ return;
+ }
+
+ reorganize(root);
+ remove_useless(root, &root);
+ bvh_refit(root);
+
+ pushup(root);
+ pushdown(root);
+ pushup_simd<VBVHNode, 4>(root);
+
+ obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
+ }
+ else {
+ //Finds the optimal packing of this tree using a given cost model
+ //TODO this uses quite a lot of memory, find ways to reduce memory usage during building
+ OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder);
+
+ if (RE_rayobjectcontrol_test_break(&obj->rayobj.control)) {
+ BLI_memarena_free(arena1);
+ BLI_memarena_free(arena2);
+ return;
+ }
+
+ if (root) {
+ VBVH_optimalPackSIMD<OVBVHNode, PackCost>(PackCost()).transform(root);
+ obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root);
+ }
+ else
+ obj->root = NULL;
+ }
+
+ //Free data
+ BLI_memarena_free(arena1);
+
+ obj->node_arena = arena2;
+ obj->cost = 1.0;
+
+ rtbuild_free(obj->builder);
+ obj->builder = NULL;
+}
+
+template<int StackSize>
+static int intersect(SVBVHTree *obj, Isect *isec)
+{
+ //TODO renable hint support
+ if (RE_rayobject_isAligned(obj->root)) {
+ if (isec->mode == RE_RAY_SHADOW)
+ return svbvh_node_stack_raycast<StackSize, true>(obj->root, isec);
+ else
+ return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec);
+ }
+ else
+ return RE_rayobject_intersect( (RayObject *) obj->root, isec);
+}
+
+template<class Tree>
+static void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max))
+{
+ //TODO renable hint support
+ {
+ hint->size = 0;
+ hint->stack[hint->size++] = (RayObject *)tree->root;
+ }
+}
+/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
+template<class Tree, int STACK_SIZE>
+static RayObjectAPI make_api()
+{
+ static RayObjectAPI api =
+ {
+ (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
+ (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
+ (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
+ (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
+ (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
+ (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
+ (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
+ };
+
+ return api;
+}
+
+template<class Tree>
+static RayObjectAPI *bvh_get_api(int maxstacksize)
+{
+ static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();
+
+ if (maxstacksize <= 1024) return &bvh_api256;
+ assert(maxstacksize <= 256);
+ return NULL;
+}
+
+RayObject *RE_rayobject_svbvh_create(int size)
+{
+ return bvh_create_tree<SVBVHTree, DFS_STACK_SIZE>(size);
+}
+
+#else
+
+RayObject *RE_rayobject_svbvh_create(int UNUSED(size))
+{
+ puts("WARNING: SSE disabled at compile time\n");
+ return NULL;
+}
+
+#endif
diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
new file mode 100644
index 00000000000..b63a11047dd
--- /dev/null
+++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
@@ -0,0 +1,206 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/rayobject_vbvh.cpp
+ * \ingroup render
+ */
+
+
+int tot_pushup = 0;
+int tot_pushdown = 0;
+int tot_hints = 0;
+
+#include <assert.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_memarena.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_global.h"
+
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "rayobject_rtbuild.h"
+
+#include "reorganize.h"
+#include "bvh.h"
+#include "vbvh.h"
+
+#include <queue>
+#include <algorithm>
+
+#define DFS_STACK_SIZE 256
+
+struct VBVHTree {
+ RayObject rayobj;
+ VBVHNode *root;
+ MemArena *node_arena;
+ float cost;
+ RTBuilder *builder;
+};
+
+/*
+ * Cost to test N childs
+ */
+struct PackCost {
+ float operator()(int n)
+ {
+ return n;
+ }
+};
+
+template<>
+void bvh_done<VBVHTree>(VBVHTree *obj)
+{
+ rtbuild_done(obj->builder, &obj->rayobj.control);
+
+ //TODO find a away to exactly calculate the needed memory
+ MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena");
+ BLI_memarena_use_malloc(arena1);
+
+ //Build and optimize the tree
+ if (1) {
+ VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1, &obj->rayobj.control).transform(obj->builder);
+ if (RE_rayobjectcontrol_test_break(&obj->rayobj.control)) {
+ BLI_memarena_free(arena1);
+ return;
+ }
+
+ if (root) {
+ reorganize(root);
+ remove_useless(root, &root);
+ bvh_refit(root);
+
+ pushup(root);
+ pushdown(root);
+ obj->root = root;
+ }
+ else
+ obj->root = NULL;
+ }
+ else {
+ /* TODO */
+#if 0
+ MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena2");
+ BLI_memarena_use_malloc(arena2);
+
+ //Finds the optimal packing of this tree using a given cost model
+ //TODO this uses quite a lot of memory, find ways to reduce memory usage during building
+ OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena2).transform(obj->builder);
+ VBVH_optimalPackSIMD<OVBVHNode, PackCost>(PackCost()).transform(root);
+ obj->root = Reorganize_VBVH<OVBVHNode>(arena1).transform(root);
+
+ BLI_memarena_free(arena2);
+#endif
+ }
+
+ //Cleanup
+ rtbuild_free(obj->builder);
+ obj->builder = NULL;
+
+ obj->node_arena = arena1;
+ obj->cost = 1.0;
+}
+
+template<int StackSize>
+static int intersect(VBVHTree *obj, Isect *isec)
+{
+ //TODO renable hint support
+ if (RE_rayobject_isAligned(obj->root)) {
+ if (isec->mode == RE_RAY_SHADOW)
+ return bvh_node_stack_raycast<VBVHNode, StackSize, false, true>(obj->root, isec);
+ else
+ return bvh_node_stack_raycast<VBVHNode, StackSize, false, false>(obj->root, isec);
+ }
+ else
+ return RE_rayobject_intersect( (RayObject *) obj->root, isec);
+}
+
+template<class Tree>
+static void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max))
+{
+ //TODO renable hint support
+ {
+ hint->size = 0;
+ hint->stack[hint->size++] = (RayObject *)tree->root;
+ }
+}
+
+#if 0 /* UNUSED */
+static void bfree(VBVHTree *tree)
+{
+ if (tot_pushup + tot_pushdown + tot_hints + tot_moves) {
+ if (G.debug & G_DEBUG) {
+ printf("tot pushups: %d\n", tot_pushup);
+ printf("tot pushdowns: %d\n", tot_pushdown);
+ printf("tot moves: %d\n", tot_moves);
+ printf("tot hints created: %d\n", tot_hints);
+ }
+
+ tot_pushup = 0;
+ tot_pushdown = 0;
+ tot_hints = 0;
+ tot_moves = 0;
+ }
+ bvh_free(tree);
+}
+#endif
+
+/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
+template<class Tree, int STACK_SIZE>
+static RayObjectAPI make_api()
+{
+ static RayObjectAPI api =
+ {
+ (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
+ (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
+ (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
+ (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
+ (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
+ (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
+ (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
+ };
+
+ return api;
+}
+
+template<class Tree>
+RayObjectAPI *bvh_get_api(int maxstacksize)
+{
+ static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();
+
+ if (maxstacksize <= 1024) return &bvh_api256;
+ assert(maxstacksize <= 256);
+ return 0;
+}
+
+RayObject *RE_rayobject_vbvh_create(int size)
+{
+ return bvh_create_tree<VBVHTree, DFS_STACK_SIZE>(size);
+}
diff --git a/source/blender/render/intern/raytrace/reorganize.h b/source/blender/render/intern/raytrace/reorganize.h
new file mode 100644
index 00000000000..3fdd3363edb
--- /dev/null
+++ b/source/blender/render/intern/raytrace/reorganize.h
@@ -0,0 +1,513 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/reorganize.h
+ * \ingroup render
+ */
+
+
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
+#include <algorithm>
+#include <queue>
+#include <vector>
+
+#include "BKE_global.h"
+
+#ifdef _WIN32
+# ifdef INFINITY
+# undef INFINITY
+# endif
+# define INFINITY FLT_MAX // in mingw math.h: (1.0F/0.0F). This generates compile error, though.
+#endif
+
+extern int tot_pushup;
+extern int tot_pushdown;
+
+#if !defined(INFINITY) && defined(HUGE_VAL)
+#define INFINITY HUGE_VAL
+#endif
+
+template<class Node>
+static bool node_fits_inside(Node *a, Node *b)
+{
+ return bb_fits_inside(b->bb, b->bb + 3, a->bb, a->bb + 3);
+}
+
+template<class Node>
+static void reorganize_find_fittest_parent(Node *tree, Node *node, std::pair<float, Node *> &cost)
+{
+ std::queue<Node *> q;
+ q.push(tree);
+
+ while (!q.empty()) {
+ Node *parent = q.front();
+ q.pop();
+
+ if (parent == node) continue;
+ if (node_fits_inside(node, parent) && RE_rayobject_isAligned(parent->child) ) {
+ float pcost = bb_area(parent->bb, parent->bb + 3);
+ cost = std::min(cost, std::make_pair(pcost, parent) );
+ for (Node *child = parent->child; child; child = child->sibling)
+ q.push(child);
+ }
+ }
+}
+
+template<class Node>
+static void reorganize(Node *root)
+{
+ std::queue<Node *> q;
+
+ q.push(root);
+ while (!q.empty()) {
+ Node *node = q.front();
+ q.pop();
+
+ if (RE_rayobject_isAligned(node->child)) {
+ for (Node **prev = &node->child; *prev; ) {
+ assert(RE_rayobject_isAligned(*prev));
+ q.push(*prev);
+
+ std::pair<float, Node *> best(FLT_MAX, root);
+ reorganize_find_fittest_parent(root, *prev, best);
+
+ if (best.second == node) {
+ //Already inside the fitnest BB
+ prev = &(*prev)->sibling;
+ }
+ else {
+ Node *tmp = *prev;
+ *prev = (*prev)->sibling;
+
+ tmp->sibling = best.second->child;
+ best.second->child = tmp;
+ }
+
+
+ }
+ }
+ if (node != root) {
+ }
+ }
+}
+
+/*
+ * Prunes useless nodes from trees:
+ * erases nodes with total amount of primitives = 0
+ * prunes nodes with only one child (except if that child is a primitive)
+ */
+template<class Node>
+static void remove_useless(Node *node, Node **new_node)
+{
+ if (RE_rayobject_isAligned(node->child) ) {
+
+ for (Node **prev = &node->child; *prev; ) {
+ Node *next = (*prev)->sibling;
+ remove_useless(*prev, prev);
+ if (*prev == NULL)
+ *prev = next;
+ else {
+ (*prev)->sibling = next;
+ prev = &((*prev)->sibling);
+ }
+ }
+ }
+ if (node->child) {
+ if (RE_rayobject_isAligned(node->child) && node->child->sibling == 0)
+ *new_node = node->child;
+ }
+ else if (node->child == NULL) {
+ *new_node = NULL;
+ }
+}
+
+/*
+ * Minimizes expected number of BBtest by colapsing nodes
+ * it uses surface area heuristic for determining whether a node should be colapsed
+ */
+template<class Node>
+static void pushup(Node *parent)
+{
+ if (is_leaf(parent)) return;
+
+ float p_area = bb_area(parent->bb, parent->bb + 3);
+ Node **prev = &parent->child;
+ for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) {
+ const float c_area = bb_area(child->bb, child->bb + 3);
+ const int nchilds = count_childs(child);
+ float original_cost = ((p_area != 0.0f) ? (c_area / p_area) * nchilds : 1.0f) + 1;
+ float flatten_cost = nchilds;
+ if (flatten_cost < original_cost && nchilds >= 2) {
+ append_sibling(child, child->child);
+ child = child->sibling;
+ *prev = child;
+
+// *prev = child->child;
+// append_sibling( *prev, child->sibling );
+// child = *prev;
+ tot_pushup++;
+ }
+ else {
+ *prev = child;
+ prev = &(*prev)->sibling;
+ child = *prev;
+ }
+ }
+
+ for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; child = child->sibling)
+ pushup(child);
+}
+
+/*
+ * try to optimize number of childs to be a multiple of SSize
+ */
+template<class Node, int SSize>
+static void pushup_simd(Node *parent)
+{
+ if (is_leaf(parent)) return;
+
+ int n = count_childs(parent);
+
+ Node **prev = &parent->child;
+ for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) {
+ int cn = count_childs(child);
+ if (cn - 1 <= (SSize - (n % SSize) ) % SSize && RE_rayobject_isAligned(child->child) ) {
+ n += (cn - 1);
+ append_sibling(child, child->child);
+ child = child->sibling;
+ *prev = child;
+ }
+ else {
+ *prev = child;
+ prev = &(*prev)->sibling;
+ child = *prev;
+ }
+ }
+
+ for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; child = child->sibling)
+ pushup_simd<Node, SSize>(child);
+}
+
+
+/*
+ * Pushdown
+ * makes sure no child fits inside any of its sibling
+ */
+template<class Node>
+static void pushdown(Node *parent)
+{
+ Node **s_child = &parent->child;
+ Node *child = parent->child;
+
+ while (child && RE_rayobject_isAligned(child)) {
+ Node *next = child->sibling;
+ Node **next_s_child = &child->sibling;
+
+ //assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3));
+
+ for (Node *i = parent->child; RE_rayobject_isAligned(i) && i; i = i->sibling)
+ if (child != i && bb_fits_inside(i->bb, i->bb + 3, child->bb, child->bb + 3) && RE_rayobject_isAligned(i->child)) {
+// todo optimize (should the one with the smallest area?)
+// float ia = bb_area(i->bb, i->bb+3)
+// if (child->i)
+ *s_child = child->sibling;
+ child->sibling = i->child;
+ i->child = child;
+ next_s_child = s_child;
+
+ tot_pushdown++;
+ break;
+ }
+ child = next;
+ s_child = next_s_child;
+ }
+
+ for (Node *i = parent->child; RE_rayobject_isAligned(i) && i; i = i->sibling) {
+ pushdown(i);
+ }
+}
+
+
+/*
+ * BVH refit
+ * readjust nodes BB (useful if nodes childs where modified)
+ */
+template<class Node>
+static float bvh_refit(Node *node)
+{
+ if (is_leaf(node)) return 0;
+ if (is_leaf(node->child)) return 0;
+
+ float total = 0;
+
+ for (Node *child = node->child; child; child = child->sibling)
+ total += bvh_refit(child);
+
+ float old_area = bb_area(node->bb, node->bb + 3);
+ INIT_MINMAX(node->bb, node->bb + 3);
+ for (Node *child = node->child; child; child = child->sibling) {
+ DO_MIN(child->bb, node->bb);
+ DO_MAX(child->bb + 3, node->bb + 3);
+ }
+ total += old_area - bb_area(node->bb, node->bb + 3);
+ return total;
+}
+
+
+/*
+ * this finds the best way to packing a tree according to a given test cost function
+ * with the purpose to reduce the expected cost (eg.: number of BB tests).
+ */
+#include <vector>
+#define MAX_CUT_SIZE 4 /* svbvh assumes max 4 children! */
+#define MAX_OPTIMIZE_CHILDS MAX_CUT_SIZE
+
+#define CUT_SIZE_IS_VALID(cut_size) ((cut_size) < MAX_CUT_SIZE && (cut_size) >= 0)
+#define CUT_SIZE_INVALID -1
+
+
+struct OVBVHNode {
+ float bb[6];
+
+ OVBVHNode *child;
+ OVBVHNode *sibling;
+
+ /*
+ * Returns min cost to represent the subtree starting at the given node,
+ * allowing it to have a given cutsize
+ */
+ float cut_cost[MAX_CUT_SIZE];
+ float get_cost(int cutsize)
+ {
+ assert(CUT_SIZE_IS_VALID(cutsize - 1));
+ return cut_cost[cutsize - 1];
+ }
+
+ /*
+ * This saves the cut size of this child, when parent is reaching
+ * its minimum cut with the given cut size
+ */
+ int cut_size[MAX_CUT_SIZE];
+ int get_cut_size(int parent_cut_size)
+ {
+ assert(CUT_SIZE_IS_VALID(parent_cut_size - 1));
+ return cut_size[parent_cut_size - 1];
+ }
+
+ /*
+ * Reorganize the node based on calculated cut costs
+ */
+ int best_cutsize;
+ void set_cut(int cutsize, OVBVHNode ***cut)
+ {
+ if (cutsize == 1) {
+ **cut = this;
+ *cut = &(**cut)->sibling;
+ }
+ else {
+ if (cutsize > MAX_CUT_SIZE) {
+ for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
+ child->set_cut(1, cut);
+ cutsize--;
+ }
+ assert(cutsize == 0);
+ }
+ else {
+ for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
+ child->set_cut(child->get_cut_size(cutsize), cut);
+ }
+ }
+ }
+ }
+
+ void optimize()
+ {
+ if (RE_rayobject_isAligned(this->child)) {
+ //Calc new childs
+ if (this->best_cutsize != CUT_SIZE_INVALID) {
+ OVBVHNode **cut = &(this->child);
+ set_cut(this->best_cutsize, &cut);
+ *cut = NULL;
+ }
+
+ //Optimize new childs
+ for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling)
+ child->optimize();
+ }
+ }
+};
+
+/*
+ * Calculates an optimal SIMD packing
+ *
+ */
+template<class Node, class TestCost>
+struct VBVH_optimalPackSIMD {
+ TestCost testcost;
+
+ VBVH_optimalPackSIMD(TestCost testcost)
+ {
+ this->testcost = testcost;
+ }
+
+ /*
+ * calc best cut on a node
+ */
+ struct calc_best {
+ Node *child[MAX_OPTIMIZE_CHILDS];
+ float child_hit_prob[MAX_OPTIMIZE_CHILDS];
+
+ calc_best(Node *node)
+ {
+ int nchilds = 0;
+ //Fetch childs and needed data
+ {
+ float parent_area = bb_area(node->bb, node->bb + 3);
+ for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
+ this->child[nchilds] = child;
+ this->child_hit_prob[nchilds] = (parent_area != 0.0f) ? bb_area(child->bb, child->bb + 3) / parent_area : 1.0f;
+ nchilds++;
+ }
+
+ assert(nchilds >= 2 && nchilds <= MAX_OPTIMIZE_CHILDS);
+ }
+
+
+ //Build DP table to find minimum cost to represent this node with a given cutsize
+ int bt[MAX_OPTIMIZE_CHILDS + 1][MAX_CUT_SIZE + 1]; //backtrace table
+ float cost[MAX_OPTIMIZE_CHILDS + 1][MAX_CUT_SIZE + 1]; //cost table (can be reduced to float[2][MAX_CUT_COST])
+
+ for (int i = 0; i <= nchilds; i++) {
+ for (int j = 0; j <= MAX_CUT_SIZE; j++) {
+ cost[i][j] = INFINITY;
+ }
+ }
+
+ cost[0][0] = 0;
+
+ for (int i = 1; i <= nchilds; i++) {
+ for (int size = i - 1; size /*+(nchilds-i)*/ <= MAX_CUT_SIZE; size++) {
+ for (int cut = 1; cut + size /*+(nchilds-i)*/ <= MAX_CUT_SIZE; cut++) {
+ float new_cost = cost[i - 1][size] + child_hit_prob[i - 1] * child[i - 1]->get_cost(cut);
+ if (new_cost < cost[i][size + cut]) {
+ cost[i][size + cut] = new_cost;
+ bt[i][size + cut] = cut;
+ }
+ }
+ }
+ }
+
+ /* Save the ways to archive the minimum cost with a given cutsize */
+ for (int i = nchilds; i <= MAX_CUT_SIZE; i++) {
+ node->cut_cost[i - 1] = cost[nchilds][i];
+ if (cost[nchilds][i] < INFINITY) {
+ int current_size = i;
+ for (int j = nchilds; j > 0; j--) {
+ child[j - 1]->cut_size[i - 1] = bt[j][current_size];
+ current_size -= bt[j][current_size];
+ }
+ }
+ }
+ }
+ };
+
+ void calc_costs(Node *node)
+ {
+
+ if (RE_rayobject_isAligned(node->child) ) {
+ int nchilds = 0;
+ for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
+ calc_costs(child);
+ nchilds++;
+ }
+
+ for (int i = 0; i < MAX_CUT_SIZE; i++)
+ node->cut_cost[i] = INFINITY;
+
+ //We are not allowed to look on nodes with with so many childs
+ if (nchilds > MAX_CUT_SIZE) {
+ float cost = 0;
+
+ float parent_area = bb_area(node->bb, node->bb + 3);
+ for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
+ cost += ((parent_area != 0.0f) ? (bb_area(child->bb, child->bb + 3) / parent_area) : 1.0f) * child->get_cost(1);
+ }
+
+ cost += testcost(nchilds);
+ node->cut_cost[0] = cost;
+ node->best_cutsize = nchilds;
+ }
+ else {
+ calc_best calc(node);
+
+ //calc expected cost if we optimaly pack this node
+ for (int cutsize = nchilds; cutsize <= MAX_CUT_SIZE; cutsize++) {
+ float m = node->get_cost(cutsize) + testcost(cutsize);
+ if (m < node->cut_cost[0]) {
+ node->cut_cost[0] = m;
+ node->best_cutsize = cutsize;
+ }
+ }
+ }
+
+ if (node->cut_cost[0] == INFINITY) {
+ node->best_cutsize = CUT_SIZE_INVALID;
+ }
+ }
+ else {
+ node->cut_cost[0] = 1.0f;
+ for (int i = 1; i < MAX_CUT_SIZE; i++)
+ node->cut_cost[i] = INFINITY;
+
+ /* node->best_cutsize can remain unset here */
+ }
+ }
+
+ Node *transform(Node *node)
+ {
+ if (RE_rayobject_isAligned(node->child)) {
+#ifdef DEBUG
+ static int num = 0;
+ bool first = false;
+ if (num == 0) { num++; first = true; }
+#endif
+
+ calc_costs(node);
+
+#ifdef DEBUG
+ if (first && G.debug) {
+ printf("expected cost = %f (%d)\n", node->cut_cost[0], node->best_cutsize);
+ }
+#endif
+ node->optimize();
+ }
+ return node;
+ }
+};
diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h
new file mode 100644
index 00000000000..0a5690deb46
--- /dev/null
+++ b/source/blender/render/intern/raytrace/svbvh.h
@@ -0,0 +1,317 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/svbvh.h
+ * \ingroup render
+ */
+
+#ifndef __SVBVH_H__
+#define __SVBVH_H__
+
+#ifdef __SSE__
+
+#include "bvh.h"
+#include "BLI_memarena.h"
+#include <algorithm>
+
+struct SVBVHNode {
+ float child_bb[24];
+ SVBVHNode *child[4];
+ int nchilds;
+};
+
+static int svbvh_bb_intersect_test_simd4(const Isect *isec, const __m128 *bb_group)
+{
+ const __m128 tmin0 = _mm_setzero_ps();
+ const __m128 tmax0 = _mm_set_ps1(isec->dist);
+
+ const __m128 start0 = _mm_set_ps1(isec->start[0]);
+ const __m128 start1 = _mm_set_ps1(isec->start[1]);
+ const __m128 start2 = _mm_set_ps1(isec->start[2]);
+ const __m128 sub0 = _mm_sub_ps(bb_group[isec->bv_index[0]], start0);
+ const __m128 sub1 = _mm_sub_ps(bb_group[isec->bv_index[1]], start0);
+ const __m128 sub2 = _mm_sub_ps(bb_group[isec->bv_index[2]], start1);
+ const __m128 sub3 = _mm_sub_ps(bb_group[isec->bv_index[3]], start1);
+ const __m128 sub4 = _mm_sub_ps(bb_group[isec->bv_index[4]], start2);
+ const __m128 sub5 = _mm_sub_ps(bb_group[isec->bv_index[5]], start2);
+ const __m128 idot_axis0 = _mm_set_ps1(isec->idot_axis[0]);
+ const __m128 idot_axis1 = _mm_set_ps1(isec->idot_axis[1]);
+ const __m128 idot_axis2 = _mm_set_ps1(isec->idot_axis[2]);
+ const __m128 mul0 = _mm_mul_ps(sub0, idot_axis0);
+ const __m128 mul1 = _mm_mul_ps(sub1, idot_axis0);
+ const __m128 mul2 = _mm_mul_ps(sub2, idot_axis1);
+ const __m128 mul3 = _mm_mul_ps(sub3, idot_axis1);
+ const __m128 mul4 = _mm_mul_ps(sub4, idot_axis2);
+ const __m128 mul5 = _mm_mul_ps(sub5, idot_axis2);
+ const __m128 tmin1 = _mm_max_ps(tmin0, mul0);
+ const __m128 tmax1 = _mm_min_ps(tmax0, mul1);
+ const __m128 tmin2 = _mm_max_ps(tmin1, mul2);
+ const __m128 tmax2 = _mm_min_ps(tmax1, mul3);
+ const __m128 tmin3 = _mm_max_ps(tmin2, mul4);
+ const __m128 tmax3 = _mm_min_ps(tmax2, mul5);
+
+ return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3));
+}
+
+static int svbvh_bb_intersect_test(const Isect *isec, const float *_bb)
+{
+ const float *bb = _bb;
+
+ float t1x = (bb[isec->bv_index[0]] - isec->start[0]) * isec->idot_axis[0];
+ float t2x = (bb[isec->bv_index[1]] - isec->start[0]) * isec->idot_axis[0];
+ float t1y = (bb[isec->bv_index[2]] - isec->start[1]) * isec->idot_axis[1];
+ float t2y = (bb[isec->bv_index[3]] - isec->start[1]) * isec->idot_axis[1];
+ float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2];
+ float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2];
+
+ RE_RC_COUNT(isec->raycounter->bb.test);
+
+ if (t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0;
+ if (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) return 0;
+ if (t1x > isec->dist || t1y > isec->dist || t1z > isec->dist) return 0;
+
+ RE_RC_COUNT(isec->raycounter->bb.hit);
+
+ return 1;
+}
+
+static bool svbvh_node_is_leaf(const SVBVHNode *node)
+{
+ return !RE_rayobject_isAligned(node);
+}
+
+template<int MAX_STACK_SIZE, bool SHADOW>
+static int svbvh_node_stack_raycast(SVBVHNode *root, Isect *isec)
+{
+ SVBVHNode *stack[MAX_STACK_SIZE], *node;
+ int hit = 0, stack_pos = 0;
+
+ stack[stack_pos++] = root;
+
+ while (stack_pos) {
+ node = stack[--stack_pos];
+
+ if (!svbvh_node_is_leaf(node)) {
+ int nchilds = node->nchilds;
+
+ if (nchilds == 4) {
+ float *child_bb = node->child_bb;
+ int res = svbvh_bb_intersect_test_simd4(isec, ((__m128 *) (child_bb)));
+ SVBVHNode **child = node->child;
+
+ RE_RC_COUNT(isec->raycounter->simd_bb.test);
+
+ if (res & 1) { stack[stack_pos++] = child[0]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); }
+ if (res & 2) { stack[stack_pos++] = child[1]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); }
+ if (res & 4) { stack[stack_pos++] = child[2]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); }
+ if (res & 8) { stack[stack_pos++] = child[3]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); }
+ }
+ else {
+ float *child_bb = node->child_bb;
+ SVBVHNode **child = node->child;
+ int i;
+
+ for (i = 0; i < nchilds; i++) {
+ if (svbvh_bb_intersect_test(isec, (float *)child_bb + 6 * i)) {
+ stack[stack_pos++] = child[i];
+ }
+ }
+ }
+ }
+ else {
+ hit |= RE_rayobject_intersect((RayObject *)node, isec);
+ if (SHADOW && hit) break;
+ }
+ }
+
+ return hit;
+}
+
+
+template<>
+inline void bvh_node_merge_bb<SVBVHNode>(SVBVHNode *node, float min[3], float max[3])
+{
+ if (is_leaf(node)) {
+ RE_rayobject_merge_bb((RayObject *)node, min, max);
+ }
+ else {
+ int i;
+ for (i = 0; i + 4 <= node->nchilds; i += 4) {
+ float *res = node->child_bb + 6 * i;
+ for (int j = 0; j < 3; j++) {
+ min[j] = min_ff(min[j],
+ min_ffff(res[4 * j + 0],
+ res[4 * j + 1],
+ res[4 * j + 2],
+ res[4 * j + 3]));
+ }
+ for (int j = 0; j < 3; j++) {
+ max[j] = max_ff(max[j],
+ max_ffff(res[4 * (j + 3) + 0],
+ res[4 * (j + 3) + 1],
+ res[4 * (j + 3) + 2],
+ res[4 * (j + 3) + 3]));
+ }
+ }
+
+ for (; i < node->nchilds; i++) {
+ DO_MIN(node->child_bb + 6 * i, min);
+ DO_MAX(node->child_bb + 3 + 6 * i, max);
+ }
+ }
+}
+
+
+
+/*
+ * Builds a SVBVH tree form a VBVHTree
+ */
+template<class OldNode>
+struct Reorganize_SVBVH {
+ MemArena *arena;
+
+ float childs_per_node;
+ int nodes_with_childs[16];
+ int useless_bb;
+ int nodes;
+
+ Reorganize_SVBVH(MemArena *a)
+ {
+ arena = a;
+ nodes = 0;
+ childs_per_node = 0;
+ useless_bb = 0;
+
+ for (int i = 0; i < 16; i++) {
+ nodes_with_childs[i] = 0;
+ }
+ }
+
+ ~Reorganize_SVBVH()
+ {
+#if 0
+ {
+ printf("%f childs per node\n", childs_per_node / nodes);
+ printf("%d childs BB are useless\n", useless_bb);
+ for (int i = 0; i < 16; i++) {
+ printf("%i childs per node: %d/%d = %f\n", i, nodes_with_childs[i], nodes, nodes_with_childs[i] / float(nodes));
+ }
+ }
+#endif
+ }
+
+ SVBVHNode *create_node(int nchilds)
+ {
+ SVBVHNode *node = (SVBVHNode *)BLI_memarena_alloc(arena, sizeof(SVBVHNode));
+ node->nchilds = nchilds;
+
+ return node;
+ }
+
+ void copy_bb(float bb[6], const float old_bb[6])
+ {
+ std::copy(old_bb, old_bb + 6, bb);
+ }
+
+ void prepare_for_simd(SVBVHNode *node)
+ {
+ int i = 0;
+ while (i + 4 <= node->nchilds) {
+ float vec_tmp[4 * 6];
+ float *res = node->child_bb + 6 * i;
+ std::copy(res, res + 6 * 4, vec_tmp);
+
+ for (int j = 0; j < 6; j++) {
+ res[4 * j + 0] = vec_tmp[6 * 0 + j];
+ res[4 * j + 1] = vec_tmp[6 * 1 + j];
+ res[4 * j + 2] = vec_tmp[6 * 2 + j];
+ res[4 * j + 3] = vec_tmp[6 * 3 + j];
+ }
+
+ i += 4;
+ }
+ }
+
+ /* amt must be power of two */
+ inline int padup(int num, int amt)
+ {
+ return ((num + (amt - 1)) & ~(amt - 1));
+ }
+
+ SVBVHNode *transform(OldNode *old)
+ {
+ if (is_leaf(old))
+ return (SVBVHNode *)old;
+ if (is_leaf(old->child))
+ return (SVBVHNode *)old->child;
+
+ int nchilds = count_childs(old);
+ int alloc_childs = nchilds;
+ if (nchilds % 4 > 2)
+ alloc_childs = padup(nchilds, 4);
+
+ SVBVHNode *node = create_node(alloc_childs);
+
+ childs_per_node += nchilds;
+ nodes++;
+ if (nchilds < 16)
+ nodes_with_childs[nchilds]++;
+
+ useless_bb += alloc_childs - nchilds;
+ while (alloc_childs > nchilds) {
+ const static float def_bb[6] = {FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX};
+ alloc_childs--;
+ node->child[alloc_childs] = NULL;
+ copy_bb(node->child_bb + alloc_childs * 6, def_bb);
+ }
+
+ int i = nchilds;
+ for (OldNode *o_child = old->child; o_child; o_child = o_child->sibling) {
+ i--;
+ node->child[i] = transform(o_child);
+ if (is_leaf(o_child)) {
+ float bb[6];
+ INIT_MINMAX(bb, bb + 3);
+ RE_rayobject_merge_bb((RayObject *)o_child, bb, bb + 3);
+ copy_bb(node->child_bb + i * 6, bb);
+ break;
+ }
+ else {
+ copy_bb(node->child_bb + i * 6, o_child->bb);
+ }
+ }
+ assert(i == 0);
+
+ prepare_for_simd(node);
+
+ return node;
+ }
+};
+
+#endif /* __SSE__ */
+
+#endif /* __SVBVH_H__ */
diff --git a/source/blender/render/intern/raytrace/vbvh.h b/source/blender/render/intern/raytrace/vbvh.h
new file mode 100644
index 00000000000..0b0bbd19116
--- /dev/null
+++ b/source/blender/render/intern/raytrace/vbvh.h
@@ -0,0 +1,238 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): André Pinto.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/raytrace/vbvh.h
+ * \ingroup render
+ */
+
+
+#include <assert.h>
+#include <algorithm>
+
+#include "BLI_memarena.h"
+
+#include "rayobject_rtbuild.h"
+
+/*
+ * VBVHNode represents a BVHNode with support for a variable number of childrens
+ */
+struct VBVHNode {
+ float bb[6];
+
+ VBVHNode *child;
+ VBVHNode *sibling;
+};
+
+
+/*
+ * Push nodes (used on dfs)
+ */
+template<class Node>
+inline static void bvh_node_push_childs(Node *node, Isect *UNUSED(isec), Node **stack, int &stack_pos)
+{
+ Node *child = node->child;
+
+ if (is_leaf(child)) {
+ stack[stack_pos++] = child;
+ }
+ else {
+ while (child) {
+ /* Skips BB tests on primitives */
+#if 0
+ if (is_leaf(child->child)) {
+ stack[stack_pos++] = child->child;
+ }
+ else
+#endif
+ {
+ stack[stack_pos++] = child;
+ }
+
+ child = child->sibling;
+ }
+ }
+}
+
+
+template<class Node>
+static int count_childs(Node *parent)
+{
+ int n = 0;
+ for (Node *i = parent->child; i; i = i->sibling) {
+ n++;
+ if (is_leaf(i))
+ break;
+ }
+
+ return n;
+}
+
+
+template<class Node>
+static void append_sibling(Node *node, Node *sibling)
+{
+ while (node->sibling)
+ node = node->sibling;
+
+ node->sibling = sibling;
+}
+
+
+/*
+ * Builds a binary VBVH from a rtbuild
+ */
+template<class Node>
+struct BuildBinaryVBVH {
+ MemArena *arena;
+ RayObjectControl *control;
+
+ void test_break()
+ {
+ if (RE_rayobjectcontrol_test_break(control))
+ throw "Stop";
+ }
+
+ BuildBinaryVBVH(MemArena *a, RayObjectControl *c)
+ {
+ arena = a;
+ control = c;
+ }
+
+ Node *create_node()
+ {
+ Node *node = (Node *)BLI_memarena_alloc(arena, sizeof(Node) );
+ assert(RE_rayobject_isAligned(node));
+
+ node->sibling = NULL;
+ node->child = NULL;
+
+ return node;
+ }
+
+ int rtbuild_split(RTBuilder *builder)
+ {
+ return ::rtbuild_heuristic_object_split(builder, 2);
+ }
+
+ Node *transform(RTBuilder *builder)
+ {
+ try
+ {
+ return _transform(builder);
+
+ } catch (...)
+ {
+ }
+ return NULL;
+ }
+
+ Node *_transform(RTBuilder *builder)
+ {
+ int size = rtbuild_size(builder);
+
+ if (size == 0) {
+ return NULL;
+ }
+ else if (size == 1) {
+ Node *node = create_node();
+ INIT_MINMAX(node->bb, node->bb + 3);
+ rtbuild_merge_bb(builder, node->bb, node->bb + 3);
+ node->child = (Node *) rtbuild_get_primitive(builder, 0);
+ return node;
+ }
+ else {
+ test_break();
+
+ Node *node = create_node();
+
+ Node **child = &node->child;
+
+ int nc = rtbuild_split(builder);
+ INIT_MINMAX(node->bb, node->bb + 3);
+
+ assert(nc == 2);
+ for (int i = 0; i < nc; i++) {
+ RTBuilder tmp;
+ rtbuild_get_child(builder, i, &tmp);
+
+ *child = _transform(&tmp);
+ DO_MIN((*child)->bb, node->bb);
+ DO_MAX((*child)->bb + 3, node->bb + 3);
+ child = &((*child)->sibling);
+ }
+
+ *child = NULL;
+ return node;
+ }
+ }
+};
+
+#if 0
+template<class Tree, class OldNode>
+struct Reorganize_VBVH {
+ Tree *tree;
+
+ Reorganize_VBVH(Tree *t)
+ {
+ tree = t;
+ }
+
+ VBVHNode *create_node()
+ {
+ VBVHNode *node = (VBVHNode *)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode));
+ return node;
+ }
+
+ void copy_bb(VBVHNode *node, OldNode *old)
+ {
+ std::copy(old->bb, old->bb + 6, node->bb);
+ }
+
+ VBVHNode *transform(OldNode *old)
+ {
+ if (is_leaf(old))
+ return (VBVHNode *)old;
+
+ VBVHNode *node = create_node();
+ VBVHNode **child_ptr = &node->child;
+ node->sibling = 0;
+
+ copy_bb(node, old);
+
+ for (OldNode *o_child = old->child; o_child; o_child = o_child->sibling)
+ {
+ VBVHNode *n_child = transform(o_child);
+ *child_ptr = n_child;
+ if (is_leaf(n_child)) return node;
+ child_ptr = &n_child->sibling;
+ }
+ *child_ptr = 0;
+
+ return node;
+ }
+};
+#endif
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
new file mode 100644
index 00000000000..4a7962b1776
--- /dev/null
+++ b/source/blender/render/intern/source/bake.c
@@ -0,0 +1,1342 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
+ * Contributors: Vertex color baking, Copyright 2011 AutoCRC
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/bake.c
+ * \ingroup render
+ */
+
+
+/* system includes */
+#include <stdio.h>
+#include <string.h>
+
+/* External modules: */
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_rand.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_image_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_customdata.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+#include "BKE_library.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
+
+/* local include */
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "shading.h"
+#include "zbuf.h"
+
+#include "PIL_time.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+
+/* ************************* bake ************************ */
+
+
+typedef struct BakeShade {
+ int thread;
+
+ ShadeSample ssamp;
+ ObjectInstanceRen *obi;
+ VlakRen *vlr;
+
+ ZSpan *zspan;
+ Image *ima;
+ ImBuf *ibuf;
+
+ int rectx, recty, quad, type, vdone;
+ bool ready;
+
+ float dir[3];
+ Object *actob;
+
+ /* Output: vertex color or image data. If vcol is not NULL, rect and
+ * rect_float should be NULL. */
+ MPoly *mpoly;
+ MLoop *mloop;
+ MLoopCol *vcol;
+
+ unsigned int *rect;
+ float *rect_float;
+
+ /* displacement buffer used for normalization with unknown maximal distance */
+ bool use_displacement_buffer;
+ float *displacement_buffer;
+ float displacement_min, displacement_max;
+
+ bool use_mask;
+ char *rect_mask; /* bake pixel mask */
+
+ float dxco[3], dyco[3];
+
+ short *do_update;
+
+ struct ColorSpace *rect_colorspace;
+} BakeShade;
+
+static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int UNUSED(isect), int x, int y, float u, float v)
+{
+ if (quad)
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
+ else
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
+
+ /* cache for shadow */
+ shi->samplenr = R.shadowsamplenr[shi->thread]++;
+
+ shi->mask = 0xFFFF; /* all samples */
+
+ shi->u = -u;
+ shi->v = -v;
+ shi->xs = x;
+ shi->ys = y;
+
+ shade_input_set_uv(shi);
+ shade_input_set_normals(shi);
+
+ /* no normal flip */
+ if (shi->flippednor)
+ shade_input_flip_normals(shi);
+
+ /* set up view vector to look right at the surface (note that the normal
+ * is negated in the renderer so it does not need to be done here) */
+ shi->view[0] = shi->vn[0];
+ shi->view[1] = shi->vn[1];
+ shi->view[2] = shi->vn[2];
+}
+
+static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(quad), int x, int y, float UNUSED(u), float UNUSED(v), float *tvn, float *ttang)
+{
+ BakeShade *bs = handle;
+ ShadeSample *ssamp = &bs->ssamp;
+ ShadeResult shr;
+ VlakRen *vlr = shi->vlr;
+
+ shade_input_init_material(shi);
+
+ if (bs->type == RE_BAKE_AO) {
+ ambient_occlusion(shi);
+
+ if (R.r.bake_flag & R_BAKE_NORMALIZE) {
+ copy_v3_v3(shr.combined, shi->ao);
+ }
+ else {
+ zero_v3(shr.combined);
+ environment_lighting_apply(shi, &shr);
+ }
+ }
+ else {
+ if (bs->type == RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
+ shi->r = shi->g = shi->b = 1.0f;
+
+ shade_input_set_shade_texco(shi);
+
+ /* only do AO for a full bake (and obviously AO bakes)
+ * AO for light bakes is a leftover and might not be needed */
+ if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT))
+ shade_samples_do_AO(ssamp);
+
+ if (shi->mat->nodetree && shi->mat->use_nodes) {
+ ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
+ shi->mat = vlr->mat; /* shi->mat is being set in nodetree */
+ }
+ else
+ shade_material_loop(shi, &shr);
+
+ if (bs->type == RE_BAKE_NORMALS) {
+ float nor[3];
+
+ copy_v3_v3(nor, shi->vn);
+
+ if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) {
+ /* pass */
+ }
+ else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
+ float mat[3][3], imat[3][3];
+
+ /* bitangent */
+ if (tvn && ttang) {
+ copy_v3_v3(mat[0], ttang);
+ cross_v3_v3v3(mat[1], tvn, ttang);
+ mul_v3_fl(mat[1], ttang[3]);
+ copy_v3_v3(mat[2], tvn);
+ }
+ else {
+ copy_v3_v3(mat[0], shi->nmaptang);
+ cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang);
+ mul_v3_fl(mat[1], shi->nmaptang[3]);
+ copy_v3_v3(mat[2], shi->nmapnorm);
+ }
+
+ invert_m3_m3(imat, mat);
+ mul_m3_v3(imat, nor);
+ }
+ else if (R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
+ mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */
+ else if (R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
+ mul_mat3_m4_v3(R.viewinv, nor);
+
+ normalize_v3(nor); /* in case object has scaling */
+
+ /* The invert of the red channel is to make
+ * the normal map compliant with the outside world.
+ * It needs to be done because in Blender
+ * the normal used in the renderer points inward. It is generated
+ * this way in calc_vertexnormals(). Should this ever change
+ * this negate must be removed.
+ *
+ * there is also a small 1e-5f bias for precision issues. otherwise
+ * we randomly get 127 or 128 for neutral colors. we choose 128
+ * because it is the convention flat color. * */
+ shr.combined[0] = (-nor[0]) / 2.0f + 0.5f + 1e-5f;
+ shr.combined[1] = nor[1] / 2.0f + 0.5f + 1e-5f;
+ shr.combined[2] = nor[2] / 2.0f + 0.5f + 1e-5f;
+ }
+ else if (bs->type == RE_BAKE_TEXTURE) {
+ copy_v3_v3(shr.combined, &shi->r);
+ shr.alpha = shi->alpha;
+ }
+ else if (bs->type == RE_BAKE_SHADOW) {
+ copy_v3_v3(shr.combined, shr.shad);
+ shr.alpha = shi->alpha;
+ }
+ else if (bs->type == RE_BAKE_SPEC_COLOR) {
+ copy_v3_v3(shr.combined, &shi->specr);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_SPEC_INTENSITY) {
+ copy_v3_fl(shr.combined, shi->spec);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_MIRROR_COLOR) {
+ copy_v3_v3(shr.combined, &shi->mirr);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_MIRROR_INTENSITY) {
+ copy_v3_fl(shr.combined, shi->ray_mirror);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_ALPHA) {
+ copy_v3_fl(shr.combined, shi->alpha);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_EMIT) {
+ copy_v3_fl(shr.combined, shi->emit);
+ shr.alpha = 1.0f;
+ }
+ else if (bs->type == RE_BAKE_VERTEX_COLORS) {
+ copy_v3_v3(shr.combined, shi->vcol);
+ shr.alpha = shi->vcol[3];
+ }
+ }
+
+ if (bs->rect_float && !bs->vcol) {
+ float *col = bs->rect_float + 4 * (bs->rectx * y + x);
+ copy_v3_v3(col, shr.combined);
+ if (bs->type == RE_BAKE_ALL || bs->type == RE_BAKE_TEXTURE || bs->type == RE_BAKE_VERTEX_COLORS) {
+ col[3] = shr.alpha;
+ }
+ else {
+ col[3] = 1.0;
+ }
+ }
+ else {
+ /* Target is char (LDR). */
+ unsigned char col[4];
+
+ if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
+ float rgb[3];
+
+ copy_v3_v3(rgb, shr.combined);
+ if (R.scene_color_manage) {
+ /* Vertex colors have no way to specify color space, so they
+ * default to sRGB. */
+ if (!bs->vcol)
+ IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace);
+ else
+ linearrgb_to_srgb_v3_v3(rgb, rgb);
+ }
+ rgb_float_to_uchar(col, rgb);
+ }
+ else {
+ rgb_float_to_uchar(col, shr.combined);
+ }
+
+ if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE, RE_BAKE_VERTEX_COLORS)) {
+ col[3] = unit_float_to_uchar_clamp(shr.alpha);
+ }
+ else {
+ col[3] = 255;
+ }
+
+ if (bs->vcol) {
+ /* Vertex color baking. Vcol has no useful alpha channel (it exists
+ * but is used only for vertex painting). */
+ bs->vcol->r = col[0];
+ bs->vcol->g = col[1];
+ bs->vcol->b = col[2];
+ }
+ else {
+ unsigned char *imcol = (unsigned char *)(bs->rect + bs->rectx * y + x);
+ copy_v4_v4_uchar(imcol, col);
+ }
+
+ }
+
+ if (bs->rect_mask) {
+ bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED;
+ }
+
+ if (bs->do_update) {
+ *bs->do_update = true;
+ }
+}
+
+static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y)
+{
+ BakeShade *bs = handle;
+ float disp;
+
+ if (R.r.bake_flag & R_BAKE_NORMALIZE) {
+ if (R.r.bake_maxdist)
+ disp = (dist + R.r.bake_maxdist) / (R.r.bake_maxdist * 2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
+ else
+ disp = dist;
+ }
+ else {
+ disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
+ }
+
+ if (bs->displacement_buffer) {
+ float *displacement = bs->displacement_buffer + (bs->rectx * y + x);
+ *displacement = disp;
+ bs->displacement_min = min_ff(bs->displacement_min, disp);
+ bs->displacement_max = max_ff(bs->displacement_max, disp);
+ }
+
+ if (bs->rect_float && !bs->vcol) {
+ float *col = bs->rect_float + 4 * (bs->rectx * y + x);
+ col[0] = col[1] = col[2] = disp;
+ col[3] = 1.0f;
+ }
+ else {
+ /* Target is char (LDR). */
+ unsigned char col[4];
+ col[0] = col[1] = col[2] = unit_float_to_uchar_clamp(disp);
+ col[3] = 255;
+
+ if (bs->vcol) {
+ /* Vertex color baking. Vcol has no useful alpha channel (it exists
+ * but is used only for vertex painting). */
+ bs->vcol->r = col[0];
+ bs->vcol->g = col[1];
+ bs->vcol->b = col[2];
+ }
+ else {
+ unsigned char *imcol = (unsigned char *)(bs->rect + bs->rectx * y + x);
+ copy_v4_v4_uchar(imcol, col);
+ }
+ }
+ if (bs->rect_mask) {
+ bs->rect_mask[bs->rectx * y + x] = FILTER_MASK_USED;
+ }
+}
+
+static int bake_intersect_tree(RayObject *raytree, Isect *isect, float *start, float *dir, float sign, float *hitco, float *dist)
+{
+ float maxdist;
+ int hit;
+
+ /* might be useful to make a user setting for maxsize*/
+ if (R.r.bake_maxdist > 0.0f)
+ maxdist = R.r.bake_maxdist;
+ else
+ maxdist = RE_RAYTRACE_MAXDIST + R.r.bake_biasdist;
+
+ /* 'dir' is always normalized */
+ madd_v3_v3v3fl(isect->start, start, dir, -R.r.bake_biasdist);
+
+ mul_v3_v3fl(isect->dir, dir, sign);
+
+ isect->dist = maxdist;
+
+ hit = RE_rayobject_raycast(raytree, isect);
+ if (hit) {
+ madd_v3_v3v3fl(hitco, isect->start, isect->dir, isect->dist);
+
+ *dist = isect->dist;
+ }
+
+ return hit;
+}
+
+static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
+{
+ VlakRen *vlr = bs->vlr;
+ float A, d1, d2, d3, *v1, *v2, *v3;
+
+ if (bs->quad) {
+ v1 = vlr->v1->co;
+ v2 = vlr->v3->co;
+ v3 = vlr->v4->co;
+ }
+ else {
+ v1 = vlr->v1->co;
+ v2 = vlr->v2->co;
+ v3 = vlr->v3->co;
+ }
+
+ /* formula derived from barycentric coordinates:
+ * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea
+ * then taking u and v partial derivatives to get dxco and dyco */
+ A = (uv2[0] - uv1[0]) * (uv3[1] - uv1[1]) - (uv3[0] - uv1[0]) * (uv2[1] - uv1[1]);
+
+ if (fabsf(A) > FLT_EPSILON) {
+ A = 0.5f / A;
+
+ d1 = uv2[1] - uv3[1];
+ d2 = uv3[1] - uv1[1];
+ d3 = uv1[1] - uv2[1];
+ bs->dxco[0] = (v1[0] * d1 + v2[0] * d2 + v3[0] * d3) * A;
+ bs->dxco[1] = (v1[1] * d1 + v2[1] * d2 + v3[1] * d3) * A;
+ bs->dxco[2] = (v1[2] * d1 + v2[2] * d2 + v3[2] * d3) * A;
+
+ d1 = uv3[0] - uv2[0];
+ d2 = uv1[0] - uv3[0];
+ d3 = uv2[0] - uv1[0];
+ bs->dyco[0] = (v1[0] * d1 + v2[0] * d2 + v3[0] * d3) * A;
+ bs->dyco[1] = (v1[1] * d1 + v2[1] * d2 + v3[1] * d3) * A;
+ bs->dyco[2] = (v1[2] * d1 + v2[2] * d2 + v3[2] * d3) * A;
+ }
+ else {
+ bs->dxco[0] = bs->dxco[1] = bs->dxco[2] = 0.0f;
+ bs->dyco[0] = bs->dyco[1] = bs->dyco[2] = 0.0f;
+ }
+
+ if (bs->obi->flag & R_TRANSFORMED) {
+ mul_m3_v3(bs->obi->nmat, bs->dxco);
+ mul_m3_v3(bs->obi->nmat, bs->dyco);
+ }
+}
+
+static void do_bake_shade(void *handle, int x, int y, float u, float v)
+{
+ BakeShade *bs = handle;
+ VlakRen *vlr = bs->vlr;
+ ObjectInstanceRen *obi = bs->obi;
+ Object *ob = obi->obr->ob;
+ float l, *v1, *v2, *v3, tvn[3], ttang[4];
+ int quad;
+ ShadeSample *ssamp = &bs->ssamp;
+ ShadeInput *shi = ssamp->shi;
+
+ /* fast threadsafe break test */
+ if (R.test_break(R.tbh))
+ return;
+
+ /* setup render coordinates */
+ if (bs->quad) {
+ v1 = vlr->v1->co;
+ v2 = vlr->v3->co;
+ v3 = vlr->v4->co;
+ }
+ else {
+ v1 = vlr->v1->co;
+ v2 = vlr->v2->co;
+ v3 = vlr->v3->co;
+ }
+
+ l = 1.0f - u - v;
+
+ /* shrink barycentric coordinates inwards slightly to avoid some issues
+ * where baking selected to active might just miss the other face at the
+ * near the edge of a face */
+ if (bs->actob) {
+ const float eps = 1.0f - 1e-4f;
+ float invsum;
+
+ u = (u - 0.5f) * eps + 0.5f;
+ v = (v - 0.5f) * eps + 0.5f;
+ l = (l - 0.5f) * eps + 0.5f;
+
+ invsum = 1.0f / (u + v + l);
+
+ u *= invsum;
+ v *= invsum;
+ l *= invsum;
+ }
+
+ /* renderco */
+ shi->co[0] = l * v3[0] + u * v1[0] + v * v2[0];
+ shi->co[1] = l * v3[1] + u * v1[1] + v * v2[1];
+ shi->co[2] = l * v3[2] + u * v1[2] + v * v2[2];
+
+ /* avoid self shadow with vertex bake from adjacent faces [#33729] */
+ if ((bs->vcol != NULL) && (bs->actob == NULL)) {
+ madd_v3_v3fl(shi->co, vlr->n, 0.0001f);
+ }
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_v3(obi->mat, shi->co);
+
+ copy_v3_v3(shi->dxco, bs->dxco);
+ copy_v3_v3(shi->dyco, bs->dyco);
+
+ quad = bs->quad;
+ bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
+
+ if (bs->type == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
+ shade_input_set_shade_texco(shi);
+ copy_v3_v3(tvn, shi->nmapnorm);
+ copy_v4_v4(ttang, shi->nmaptang);
+ }
+
+ /* if we are doing selected to active baking, find point on other face */
+ if (bs->actob) {
+ Isect isec, minisec;
+ float co[3], minco[3], dist, mindist = 0.0f;
+ int hit, sign, dir = 1;
+
+ /* intersect with ray going forward and backward*/
+ hit = 0;
+ memset(&minisec, 0, sizeof(minisec));
+ minco[0] = minco[1] = minco[2] = 0.0f;
+
+ copy_v3_v3(bs->dir, shi->vn);
+
+ for (sign = -1; sign <= 1; sign += 2) {
+ memset(&isec, 0, sizeof(isec));
+ isec.mode = RE_RAY_MIRROR;
+
+ isec.orig.ob = obi;
+ isec.orig.face = vlr;
+ isec.userdata = bs->actob;
+ isec.check = RE_CHECK_VLR_BAKE;
+ isec.skip = RE_SKIP_VLR_NEIGHBOUR;
+
+ if (bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
+ if (!hit || len_squared_v3v3(shi->co, co) < len_squared_v3v3(shi->co, minco)) {
+ minisec = isec;
+ mindist = dist;
+ copy_v3_v3(minco, co);
+ hit = 1;
+ dir = sign;
+ }
+ }
+ }
+
+ if (ELEM(bs->type, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) {
+ if (hit)
+ bake_displacement(handle, shi, (dir == -1) ? mindist : -mindist, x, y);
+ else
+ bake_displacement(handle, shi, 0.0f, x, y);
+ return;
+ }
+
+ /* if hit, we shade from the new point, otherwise from point one starting face */
+ if (hit) {
+ obi = (ObjectInstanceRen *)minisec.hit.ob;
+ vlr = (VlakRen *)minisec.hit.face;
+ quad = (minisec.isect == 2);
+ copy_v3_v3(shi->co, minco);
+
+ u = -minisec.u;
+ v = -minisec.v;
+ bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
+ }
+ }
+
+ if (bs->type == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT)
+ bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
+ else
+ bake_shade(handle, ob, shi, quad, x, y, u, v, NULL, NULL);
+}
+
+static int get_next_bake_face(BakeShade *bs)
+{
+ ObjectRen *obr;
+ VlakRen *vlr;
+ MTFace *tface;
+ static int v = 0, vdone = false;
+ static ObjectInstanceRen *obi = NULL;
+
+ if (bs == NULL) {
+ vlr = NULL;
+ v = vdone = false;
+ obi = R.instancetable.first;
+ return 0;
+ }
+
+ BLI_thread_lock(LOCK_CUSTOM1);
+
+ for (; obi; obi = obi->next, v = 0) {
+ obr = obi->obr;
+
+ /* only allow non instances here */
+ if (obr->flag & R_INSTANCEABLE)
+ continue;
+
+ for (; v < obr->totvlak; v++) {
+ vlr = RE_findOrAddVlak(obr, v);
+
+ if ((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
+ if (R.r.bake_flag & R_BAKE_VCOL) {
+ /* Gather face data for vertex color bake */
+ Mesh *me;
+ int *origindex, vcollayer;
+ CustomDataLayer *cdl;
+
+ if (obr->ob->type != OB_MESH)
+ continue;
+ me = obr->ob->data;
+
+ origindex = RE_vlakren_get_origindex(obr, vlr, 0);
+ if (origindex == NULL)
+ continue;
+ if (*origindex >= me->totpoly) {
+ /* Small hack for Array modifier, which gives false
+ * original indices - z0r */
+ continue;
+ }
+#if 0
+ /* Only shade selected faces. */
+ if ((me->mface[*origindex].flag & ME_FACE_SEL) == 0)
+ continue;
+#endif
+
+ vcollayer = CustomData_get_render_layer_index(&me->ldata, CD_MLOOPCOL);
+ if (vcollayer == -1)
+ continue;
+
+ cdl = &me->ldata.layers[vcollayer];
+ bs->mpoly = me->mpoly + *origindex;
+ bs->vcol = ((MLoopCol *)cdl->data) + bs->mpoly->loopstart;
+ bs->mloop = me->mloop + bs->mpoly->loopstart;
+
+ /* Tag mesh for reevaluation. */
+ me->id.tag |= LIB_TAG_DOIT;
+ }
+ else {
+ Image *ima = NULL;
+ ImBuf *ibuf = NULL;
+ const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
+ const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
+ const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f};
+ const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};
+
+ tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
+
+ if (!tface || !tface->tpage)
+ continue;
+
+ ima = tface->tpage;
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+
+ if (ibuf == NULL)
+ continue;
+
+ if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ continue;
+ }
+
+ if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ continue;
+ }
+
+ if (ima->flag & IMA_USED_FOR_RENDER) {
+ ima->id.tag &= ~LIB_TAG_DOIT;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ continue;
+ }
+
+ /* find the image for the first time? */
+ if (ima->id.tag & LIB_TAG_DOIT) {
+ ima->id.tag &= ~LIB_TAG_DOIT;
+
+ /* we either fill in float or char, this ensures things go fine */
+ if (ibuf->rect_float)
+ imb_freerectImBuf(ibuf);
+ /* clear image */
+ if (R.r.bake_flag & R_BAKE_CLEAR) {
+ if (R.r.bake_mode == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT)
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
+ else if (ELEM(R.r.bake_mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE))
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid);
+ else
+ IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
+ }
+ /* might be read by UI to set active image for display */
+ R.bakebuf = ima;
+ }
+
+ /* Tag image for redraw. */
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+
+ bs->obi = obi;
+ bs->vlr = vlr;
+ bs->vdone++; /* only for error message if nothing was rendered */
+ v++;
+ BLI_thread_unlock(LOCK_CUSTOM1);
+ return 1;
+ }
+ }
+ }
+
+ BLI_thread_unlock(LOCK_CUSTOM1);
+ return 0;
+}
+
+static void bake_single_vertex(BakeShade *bs, VertRen *vert, float u, float v)
+{
+ int *origindex, i;
+ MLoopCol *basevcol;
+ MLoop *mloop;
+
+ /* per vertex fixed seed */
+ BLI_thread_srandom(bs->thread, vert->index);
+
+ origindex = RE_vertren_get_origindex(bs->obi->obr, vert, 0);
+ if (!origindex || *origindex == ORIGINDEX_NONE)
+ return;
+
+ /* Search for matching vertex index and apply shading. */
+ for (i = 0; i < bs->mpoly->totloop; i++) {
+ mloop = bs->mloop + i;
+ if (mloop->v != *origindex)
+ continue;
+ basevcol = bs->vcol;
+ bs->vcol = basevcol + i;
+ do_bake_shade(bs, 0, 0, u, v);
+ bs->vcol = basevcol;
+ break;
+ }
+}
+
+/* Bake all vertices of a face. Actually, this still works on a face-by-face
+ * basis, and each vertex on each face is shaded. Vertex colors are a property
+ * of loops, not vertices. */
+static void shade_verts(BakeShade *bs)
+{
+ VlakRen *vlr = bs->vlr;
+
+ /* Disable baking to image; write to vcol instead. vcol pointer is set in
+ * bake_single_vertex. */
+ bs->ima = NULL;
+ bs->rect = NULL;
+ bs->rect_float = NULL;
+ bs->displacement_buffer = NULL;
+ bs->displacement_min = FLT_MAX;
+ bs->displacement_max = -FLT_MAX;
+
+ bs->quad = 0;
+
+ /* No anti-aliasing for vertices. */
+ zero_v3(bs->dxco);
+ zero_v3(bs->dyco);
+
+ /* Shade each vertex of the face. u and v are barycentric coordinates; since
+ * we're only interested in vertices, these will be 0 or 1. */
+ if ((vlr->flag & R_FACE_SPLIT) == 0) {
+ /* Processing triangle face, whole quad, or first half of split quad. */
+
+ bake_single_vertex(bs, bs->vlr->v1, 1.0f, 0.0f);
+ bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f);
+ bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f);
+
+ if (vlr->v4) {
+ bs->quad = 1;
+ bake_single_vertex(bs, bs->vlr->v4, 0.0f, 0.0f);
+ }
+ }
+ else {
+ /* Processing second half of split quad. Only one vertex to go. */
+ if (vlr->flag & R_DIVIDE_24) {
+ bake_single_vertex(bs, bs->vlr->v2, 0.0f, 1.0f);
+ }
+ else {
+ bake_single_vertex(bs, bs->vlr->v3, 0.0f, 0.0f);
+ }
+ }
+}
+
+/* already have tested for tface and ima and zspan */
+static void shade_tface(BakeShade *bs)
+{
+ VlakRen *vlr = bs->vlr;
+ ObjectInstanceRen *obi = bs->obi;
+ ObjectRen *obr = obi->obr;
+ MTFace *tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
+ Image *ima = tface->tpage;
+ float vec[4][2];
+ int a, i1, i2, i3;
+
+ /* per face fixed seed */
+ BLI_thread_srandom(bs->thread, vlr->index);
+
+ /* check valid zspan */
+ if (ima != bs->ima) {
+ BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
+
+ bs->ima = ima;
+ bs->ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ /* note, these calls only free/fill contents of zspan struct, not zspan itself */
+ zbuf_free_span(bs->zspan);
+ zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
+ }
+
+ bs->rectx = bs->ibuf->x;
+ bs->recty = bs->ibuf->y;
+ bs->rect = bs->ibuf->rect;
+ bs->rect_colorspace = bs->ibuf->rect_colorspace;
+ bs->rect_float = bs->ibuf->rect_float;
+ bs->vcol = NULL;
+ bs->quad = 0;
+ bs->rect_mask = NULL;
+ bs->displacement_buffer = NULL;
+
+ if (bs->use_mask || bs->use_displacement_buffer) {
+ BakeImBufuserData *userdata = bs->ibuf->userdata;
+ if (userdata == NULL) {
+ BLI_thread_lock(LOCK_CUSTOM1);
+ userdata = bs->ibuf->userdata;
+ if (userdata == NULL) /* since the thread was locked, its possible another thread alloced the value */
+ userdata = MEM_callocN(sizeof(BakeImBufuserData), "BakeImBufuserData");
+
+ if (bs->use_mask) {
+ if (userdata->mask_buffer == NULL) {
+ userdata->mask_buffer = MEM_callocN(sizeof(char) * bs->rectx * bs->recty, "BakeMask");
+ }
+ }
+
+ if (bs->use_displacement_buffer) {
+ if (userdata->displacement_buffer == NULL) {
+ userdata->displacement_buffer = MEM_callocN(sizeof(float) * bs->rectx * bs->recty, "BakeDisp");
+ }
+ }
+
+ bs->ibuf->userdata = userdata;
+
+ BLI_thread_unlock(LOCK_CUSTOM1);
+ }
+
+ bs->rect_mask = userdata->mask_buffer;
+ bs->displacement_buffer = userdata->displacement_buffer;
+ }
+
+ /* get pixel level vertex coordinates */
+ for (a = 0; a < 4; a++) {
+ /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests
+ * where a pixel gets in between 2 faces or the middle of a quad,
+ * camera aligned quads also have this problem but they are less common.
+ * Add a small offset to the UVs, fixes bug #18685 - Campbell */
+ vec[a][0] = tface->uv[a][0] * (float)bs->rectx - (0.5f + 0.001f);
+ vec[a][1] = tface->uv[a][1] * (float)bs->recty - (0.5f + 0.002f);
+ }
+
+ /* UV indices have to be corrected for possible quad->tria splits */
+ i1 = 0; i2 = 1; i3 = 2;
+ vlr_set_uv_indices(vlr, &i1, &i2, &i3);
+ bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
+ zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
+
+ if (vlr->v4) {
+ bs->quad = 1;
+ bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
+ zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
+ }
+}
+
+static void *do_bake_thread(void *bs_v)
+{
+ BakeShade *bs = bs_v;
+
+ while (get_next_bake_face(bs)) {
+ if (R.r.bake_flag & R_BAKE_VCOL) {
+ shade_verts(bs);
+ }
+ else {
+ shade_tface(bs);
+ }
+
+ /* fast threadsafe break test */
+ if (R.test_break(R.tbh))
+ break;
+
+ /* access is not threadsafe but since its just true/false probably ok
+ * only used for interactive baking */
+ if (bs->do_update) {
+ *bs->do_update = true;
+ }
+ }
+ bs->ready = true;
+
+ BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
+
+ return NULL;
+}
+
+void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter)
+{
+ /* must check before filtering */
+ const bool is_new_alpha = (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf);
+
+ /* Margin */
+ if (filter) {
+ IMB_filter_extend(ibuf, mask, filter);
+ }
+
+ /* if the bake results in new alpha then change the image setting */
+ if (is_new_alpha) {
+ ibuf->planes = R_IMF_PLANES_RGBA;
+ }
+ else {
+ if (filter && ibuf->planes != R_IMF_PLANES_RGBA) {
+ /* clear alpha added by filtering */
+ IMB_rectfill_alpha(ibuf, 1.0f);
+ }
+ }
+}
+
+void RE_bake_ibuf_normalize_displacement(ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max)
+{
+ int i;
+ const float *current_displacement = displacement;
+ const char *current_mask = mask;
+ float max_distance;
+
+ max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max));
+
+ for (i = 0; i < ibuf->x * ibuf->y; i++) {
+ if (*current_mask == FILTER_MASK_USED) {
+ float normalized_displacement;
+
+ if (max_distance > 1e-5f)
+ normalized_displacement = (*current_displacement + max_distance) / (max_distance * 2);
+ else
+ normalized_displacement = 0.5f;
+
+ if (ibuf->rect_float) {
+ /* currently baking happens to RGBA only */
+ float *fp = ibuf->rect_float + i * 4;
+ fp[0] = fp[1] = fp[2] = normalized_displacement;
+ fp[3] = 1.0f;
+ }
+
+ if (ibuf->rect) {
+ unsigned char *cp = (unsigned char *) (ibuf->rect + i);
+ cp[0] = cp[1] = cp[2] = unit_float_to_uchar_clamp(normalized_displacement);
+ cp[3] = 255;
+ }
+ }
+
+ current_displacement++;
+ current_mask++;
+ }
+}
+
+/* using object selection tags, the faces with UV maps get baked */
+/* render should have been setup */
+/* returns 0 if nothing was handled */
+int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress)
+{
+ BakeShade *handles;
+ ListBase threads;
+ Image *ima;
+ int a, vdone = false, result = BAKE_RESULT_OK;
+ bool use_mask = false;
+ bool use_displacement_buffer = false;
+ bool do_manage = false;
+
+ if (ELEM(type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
+ do_manage = BKE_scene_check_color_management_enabled(re->scene);
+ }
+
+ re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene);
+
+ /* initialize render global */
+ R = *re;
+ R.bakebuf = NULL;
+
+ /* initialize static vars */
+ get_next_bake_face(NULL);
+
+ /* do we need a mask? */
+ if (re->r.bake_filter)
+ use_mask = true;
+
+ /* do we need buffer to store displacements */
+ if (ELEM(type, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) {
+ if (((R.r.bake_flag & R_BAKE_NORMALIZE) && R.r.bake_maxdist == 0.0f) ||
+ (type == RE_BAKE_DERIVATIVE))
+ {
+ use_displacement_buffer = true;
+ use_mask = true;
+ }
+ }
+
+ /* baker uses this flag to detect if image was initialized */
+ if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
+ for (ima = G.main->image.first; ima; ima = ima->id.next) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ ima->id.tag |= LIB_TAG_DOIT;
+ ima->flag &= ~IMA_USED_FOR_RENDER;
+ if (ibuf) {
+ ibuf->userdata = NULL; /* use for masking if needed */
+ }
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ }
+
+ if (R.r.bake_flag & R_BAKE_VCOL) {
+ /* untag all meshes */
+ BKE_main_id_tag_listbase(&G.main->mesh, LIB_TAG_DOIT, false);
+ }
+
+ BLI_threadpool_init(&threads, do_bake_thread, re->r.threads);
+
+ handles = MEM_callocN(sizeof(BakeShade) * re->r.threads, "BakeShade");
+
+ /* get the threads running */
+ for (a = 0; a < re->r.threads; a++) {
+ handles[a].thread = a;
+
+ /* set defaults in handles */
+ handles[a].ssamp.shi[0].lay = re->lay;
+
+ if (type == RE_BAKE_SHADOW) {
+ handles[a].ssamp.shi[0].passflag = SCE_PASS_SHADOW;
+ }
+ else {
+ handles[a].ssamp.shi[0].passflag = SCE_PASS_COMBINED;
+ }
+ handles[a].ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC);
+ handles[a].ssamp.shi[0].thread = a;
+ handles[a].ssamp.shi[0].do_manage = do_manage;
+ handles[a].ssamp.tot = 1;
+
+ handles[a].type = type;
+ handles[a].actob = actob;
+ if (R.r.bake_flag & R_BAKE_VCOL)
+ handles[a].zspan = NULL;
+ else
+ handles[a].zspan = MEM_callocN(sizeof(ZSpan), "zspan for bake");
+
+ handles[a].use_mask = use_mask;
+ handles[a].use_displacement_buffer = use_displacement_buffer;
+
+ handles[a].do_update = do_update; /* use to tell the view to update */
+
+ handles[a].displacement_min = FLT_MAX;
+ handles[a].displacement_max = -FLT_MAX;
+
+ BLI_threadpool_insert(&threads, &handles[a]);
+ }
+
+ /* wait for everything to be done */
+ a = 0;
+ while (a != re->r.threads) {
+ PIL_sleep_ms(50);
+
+ /* calculate progress */
+ for (vdone = false, a = 0; a < re->r.threads; a++)
+ vdone += handles[a].vdone;
+ if (progress)
+ *progress = (float)(vdone / (float)re->totvlak);
+
+ for (a = 0; a < re->r.threads; a++) {
+ if (handles[a].ready == false) {
+ break;
+ }
+ }
+ }
+
+ /* filter and refresh images */
+ if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
+ float displacement_min = FLT_MAX, displacement_max = -FLT_MAX;
+
+ if (use_displacement_buffer) {
+ for (a = 0; a < re->r.threads; a++) {
+ displacement_min = min_ff(displacement_min, handles[a].displacement_min);
+ displacement_max = max_ff(displacement_max, handles[a].displacement_max);
+ }
+ }
+
+ for (ima = G.main->image.first; ima; ima = ima->id.next) {
+ if ((ima->id.tag & LIB_TAG_DOIT) == 0) {
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ BakeImBufuserData *userdata;
+
+ if (ima->flag & IMA_USED_FOR_RENDER)
+ result = BAKE_RESULT_FEEDBACK_LOOP;
+
+ if (!ibuf)
+ continue;
+
+ userdata = (BakeImBufuserData *)ibuf->userdata;
+ if (userdata) {
+ if (use_displacement_buffer) {
+ if (type == RE_BAKE_DERIVATIVE) {
+ float user_scale = (R.r.bake_flag & R_BAKE_USERSCALE) ? R.r.bake_user_scale : -1.0f;
+ RE_bake_make_derivative(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ displacement_min, displacement_max, user_scale);
+ }
+ else {
+ RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ displacement_min, displacement_max);
+ }
+ }
+
+ RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, re->r.bake_filter);
+ }
+
+ ibuf->userflags |= IB_BITMAPDIRTY;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ }
+
+ /* calculate return value */
+ for (a = 0; a < re->r.threads; a++) {
+ zbuf_free_span(handles[a].zspan);
+ MEM_freeN(handles[a].zspan);
+ }
+ }
+
+ MEM_freeN(handles);
+
+ BLI_threadpool_end(&threads);
+
+ if (vdone == 0) {
+ result = BAKE_RESULT_NO_OBJECTS;
+ }
+
+ return result;
+}
+
+struct Image *RE_bake_shade_get_image(void)
+{
+ return R.bakebuf;
+}
+
+/* **************** Derivative Maps Baker **************** */
+
+static void add_single_heights_margin(const ImBuf *ibuf, const char *mask, float *heights_buffer)
+{
+ int x, y;
+
+ for (y = 0; y < ibuf->y; y++) {
+ for (x = 0; x < ibuf->x; x++) {
+ int index = ibuf->x * y + x;
+
+ /* If unassigned pixel, look for neighbors. */
+ if (mask[index] != FILTER_MASK_USED) {
+ float height_acc = 0;
+ int denom = 0;
+ int i, j;
+
+ for (j = -1; j <= 1; j++)
+ for (i = -1; i <= 1; i++) {
+ int w = (i == 0 ? 1 : 0) + (j == 0 ? 1 : 0) + 1;
+
+ if (i != 0 || j != 0) {
+ int index2 = 0;
+ int x0 = x + i;
+ int y0 = y + j;
+
+ CLAMP(x0, 0, ibuf->x - 1);
+ CLAMP(y0, 0, ibuf->y - 1);
+
+ index2 = ibuf->x * y0 + x0;
+
+ if (mask[index2] == FILTER_MASK_USED) {
+ height_acc += w * heights_buffer[index2];
+ denom += w;
+ }
+ }
+ }
+
+ /* Insert final value. */
+ if (denom > 0) {
+ heights_buffer[index] = height_acc / denom;
+ }
+ }
+ }
+ }
+}
+
+/* returns user-scale */
+float RE_bake_make_derivative(ImBuf *ibuf, float *heights_buffer, const char *mask,
+ const float height_min, const float height_max,
+ const float fmult)
+{
+ const float delta_height = height_max - height_min;
+ const float denom = delta_height > 0.0f ? (8 * delta_height) : 1.0f;
+ bool auto_range_fit = fmult <= 0.0f;
+ float max_num_deriv = -1.0f;
+ int x, y, index;
+
+ /* Need a single margin to calculate good derivatives. */
+ add_single_heights_margin(ibuf, mask, heights_buffer);
+
+ if (auto_range_fit) {
+ /* If automatic range fitting is enabled. */
+ for (y = 0; y < ibuf->y; y++) {
+ const int Yu = y == (ibuf->y - 1) ? (ibuf->y - 1) : (y + 1);
+ const int Yc = y;
+ const int Yd = y == 0 ? 0 : (y - 1);
+
+ for (x = 0; x < ibuf->x; x++) {
+ const int Xl = x == 0 ? 0 : (x - 1);
+ const int Xc = x;
+ const int Xr = x == (ibuf->x - 1) ? (ibuf->x - 1) : (x + 1);
+
+ const float Hcy = heights_buffer[Yc * ibuf->x + Xr] - heights_buffer[Yc * ibuf->x + Xl];
+ const float Hu = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yu * ibuf->x + Xl];
+ const float Hd = heights_buffer[Yd * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xl];
+
+ const float Hl = heights_buffer[Yu * ibuf->x + Xl] - heights_buffer[Yd * ibuf->x + Xl];
+ const float Hcx = heights_buffer[Yu * ibuf->x + Xc] - heights_buffer[Yd * ibuf->x + Xc];
+ const float Hr = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xr];
+
+ /* This corresponds to using the sobel kernel on the heights buffer
+ * to obtain the derivative multiplied by 8.
+ */
+ const float deriv_x = Hu + 2 * Hcy + Hd;
+ const float deriv_y = Hr + 2 * Hcx + Hl;
+
+ /* early out */
+ index = ibuf->x * y + x;
+ if (mask[index] != FILTER_MASK_USED) {
+ continue;
+ }
+
+ /* Widen bound. */
+ if (fabsf(deriv_x) > max_num_deriv) {
+ max_num_deriv = fabsf(deriv_x);
+ }
+
+ if (fabsf(deriv_y) > max_num_deriv) {
+ max_num_deriv = fabsf(deriv_y);
+ }
+ }
+ }
+ }
+
+ /* Output derivatives. */
+ auto_range_fit &= (max_num_deriv > 0);
+ for (y = 0; y < ibuf->y; y++) {
+ const int Yu = y == (ibuf->y - 1) ? (ibuf->y - 1) : (y + 1);
+ const int Yc = y;
+ const int Yd = y == 0 ? 0 : (y - 1);
+
+ for (x = 0; x < ibuf->x; x++) {
+ const int Xl = x == 0 ? 0 : (x - 1);
+ const int Xc = x;
+ const int Xr = x == (ibuf->x - 1) ? (ibuf->x - 1) : (x + 1);
+
+ const float Hcy = heights_buffer[Yc * ibuf->x + Xr] - heights_buffer[Yc * ibuf->x + Xl];
+ const float Hu = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yu * ibuf->x + Xl];
+ const float Hd = heights_buffer[Yd * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xl];
+
+ const float Hl = heights_buffer[Yu * ibuf->x + Xl] - heights_buffer[Yd * ibuf->x + Xl];
+ const float Hcx = heights_buffer[Yu * ibuf->x + Xc] - heights_buffer[Yd * ibuf->x + Xc];
+ const float Hr = heights_buffer[Yu * ibuf->x + Xr] - heights_buffer[Yd * ibuf->x + Xr];
+
+ /* This corresponds to using the sobel kernel on the heights buffer
+ * to obtain the derivative multiplied by 8.
+ */
+ float deriv_x = Hu + 2 * Hcy + Hd;
+ float deriv_y = Hr + 2 * Hcx + Hl;
+
+ /* Early out. */
+ index = ibuf->x * y + x;
+ if (mask[index] != FILTER_MASK_USED) {
+ continue;
+ }
+
+ if (auto_range_fit) {
+ deriv_x /= max_num_deriv;
+ deriv_y /= max_num_deriv;
+ }
+ else {
+ deriv_x *= (fmult / denom);
+ deriv_y *= (fmult / denom);
+ }
+
+ deriv_x = deriv_x * 0.5f + 0.5f;
+ deriv_y = deriv_y * 0.5f + 0.5f;
+
+ /* Clamp. */
+ CLAMP(deriv_x, 0.0f, 1.0f);
+ CLAMP(deriv_y, 0.0f, 1.0f);
+
+ /* Write out derivatives. */
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + index * 4;
+
+ rrgbf[0] = deriv_x;
+ rrgbf[1] = deriv_y;
+ rrgbf[2] = 0.0f;
+ rrgbf[3] = 1.0f;
+ }
+ else {
+ char *rrgb = (char *)ibuf->rect + index * 4;
+
+ rrgb[0] = unit_float_to_uchar_clamp(deriv_x);
+ rrgb[1] = unit_float_to_uchar_clamp(deriv_y);
+ rrgb[2] = 0;
+ rrgb[3] = 255;
+ }
+ }
+ }
+
+ /* Eeturn user-scale (for rendering). */
+ return auto_range_fit ? (max_num_deriv / denom) : (fmult > 0.0f ? (1.0f / fmult) : 0.0f);
+}
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
new file mode 100644
index 00000000000..8675ffec313
--- /dev/null
+++ b/source/blender/render/intern/source/convertblender.c
@@ -0,0 +1,6014 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/convertblender.c
+ * \ingroup render
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+#include "BLI_rand.h"
+#include "BLI_memarena.h"
+#ifdef WITH_FREESTYLE
+# include "BLI_edgehash.h"
+#endif
+
+#include "BLT_translation.h"
+
+#include "DNA_material_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_group_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_image_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_fluidsim_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
+
+#include "BKE_anim.h"
+#include "BKE_curve.h"
+#include "BKE_customdata.h"
+#include "BKE_colortools.h"
+#include "BKE_displist.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_key.h"
+#include "BKE_image.h"
+#include "BKE_lattice.h"
+#include "BKE_material.h"
+#include "BKE_main.h"
+#include "BKE_mball.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_node.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_scene.h"
+
+#include "PIL_time.h"
+
+#include "envmap.h"
+#include "occlusion.h"
+#include "pointdensity.h"
+#include "voxeldata.h"
+#include "render_types.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "renderpipeline.h"
+#include "shadbuf.h"
+#include "shading.h"
+#include "strand.h"
+#include "texture.h"
+#include "volume_precache.h"
+#include "sss.h"
+#include "zbuf.h"
+#include "sunsky.h"
+
+/* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp (for quad detection) */
+/* or for checking vertex normal flips */
+#define FLT_EPSILON10 1.19209290e-06F
+
+/* could enable at some point but for now there are far too many conversions */
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* tool functions/defines for ad hoc simplification and possible future
+ * cleanup */
+/* ------------------------------------------------------------------------- */
+
+#define UVTOINDEX(u, v) (startvlak + (u) * sizev + (v))
+/*
+ *
+ * NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !!
+ *
+ * ^ ()----p4----p3----()
+ * | | | | |
+ * u | | F1 | F2 |
+ * | | | |
+ * ()----p1----p2----()
+ * v ->
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#define CD_MASK_RENDER_INTERNAL \
+ (CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL)
+
+static void split_v_renderfaces(ObjectRen *obr, int startvlak, int UNUSED(startvert), int UNUSED(usize), int vsize, int uIndex, int UNUSED(cyclu), int cyclv)
+{
+ int vLen = vsize-1+(!!cyclv);
+ int v;
+
+ for (v=0; v<vLen; v++) {
+ VlakRen *vlr = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v);
+ VlakRen *vlr_other;
+ VertRen *vert = RE_vertren_copy(obr, vlr->v2);
+
+ if (cyclv) {
+ vlr->v2 = vert;
+
+ if (v == vLen - 1) {
+ vlr_other = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + 0);
+ vlr_other->v1 = vert;
+ }
+ else {
+ vlr_other = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v+1);
+ vlr_other->v1 = vert;
+ }
+ }
+ else {
+ vlr->v2 = vert;
+
+ if (v < vLen - 1) {
+ vlr_other = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v+1);
+ vlr_other->v1 = vert;
+ }
+
+ if (v == 0) {
+ vlr->v1 = RE_vertren_copy(obr, vlr->v1);
+ }
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* Stress, tangents and normals */
+/* ------------------------------------------------------------------------- */
+
+static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2)
+{
+ float len= len_v3v3(v1->co, v2->co)/len_v3v3(v1->orco, v2->orco);
+ float *acc;
+
+ acc= accum + 2*v1->index;
+ acc[0]+= len;
+ acc[1]+= 1.0f;
+
+ acc= accum + 2*v2->index;
+ acc[0]+= len;
+ acc[1]+= 1.0f;
+}
+
+static void calc_edge_stress(Render *UNUSED(re), ObjectRen *obr, Mesh *me)
+{
+ float loc[3], size[3], *accum, *acc, *accumoffs, *stress;
+ int a;
+
+ if (obr->totvert==0) return;
+
+ BKE_mesh_texspace_get(me, loc, NULL, size);
+
+ accum= MEM_callocN(2*sizeof(float)*obr->totvert, "temp accum for stress");
+
+ /* de-normalize orco */
+ for (a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
+ if (ver->orco) {
+ ver->orco[0]= ver->orco[0]*size[0] +loc[0];
+ ver->orco[1]= ver->orco[1]*size[1] +loc[1];
+ ver->orco[2]= ver->orco[2]*size[2] +loc[2];
+ }
+ }
+
+ /* add stress values */
+ accumoffs= accum; /* so we can use vertex index */
+ for (a=0; a<obr->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(obr, a);
+
+ if (vlr->v1->orco && vlr->v4) {
+ calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2);
+ calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3);
+ calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1);
+ if (vlr->v4) {
+ calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4);
+ calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1);
+ calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4);
+ }
+ }
+ }
+
+ for (a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
+ if (ver->orco) {
+ /* find stress value */
+ acc= accumoffs + 2*ver->index;
+ if (acc[1]!=0.0f)
+ acc[0]/= acc[1];
+ stress= RE_vertren_get_stress(obr, ver, 1);
+ *stress= *acc;
+
+ /* restore orcos */
+ ver->orco[0] = (ver->orco[0]-loc[0])/size[0];
+ ver->orco[1] = (ver->orco[1]-loc[1])/size[1];
+ ver->orco[2] = (ver->orco[2]-loc[2])/size[2];
+ }
+ }
+
+ MEM_freeN(accum);
+}
+
+/* gets tangent from tface or orco */
+static void calc_tangent_vector(ObjectRen *obr, VlakRen *vlr, int do_tangent)
+{
+ MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
+ VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
+ float tang[3], *tav;
+ float *uv1, *uv2, *uv3, *uv4;
+ float uv[4][2];
+
+ if (tface) {
+ uv1= tface->uv[0];
+ uv2= tface->uv[1];
+ uv3= tface->uv[2];
+ uv4= tface->uv[3];
+ }
+ else if (v1->orco) {
+ uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
+ map_to_sphere(&uv[0][0], &uv[0][1], v1->orco[0], v1->orco[1], v1->orco[2]);
+ map_to_sphere(&uv[1][0], &uv[1][1], v2->orco[0], v2->orco[1], v2->orco[2]);
+ map_to_sphere(&uv[2][0], &uv[2][1], v3->orco[0], v3->orco[1], v3->orco[2]);
+ if (v4)
+ map_to_sphere(&uv[3][0], &uv[3][1], v4->orco[0], v4->orco[1], v4->orco[2]);
+ }
+ else return;
+
+ tangent_from_uv_v3(uv1, uv2, uv3, v1->co, v2->co, v3->co, vlr->n, tang);
+
+ if (do_tangent) {
+ tav= RE_vertren_get_tangent(obr, v1, 1);
+ add_v3_v3(tav, tang);
+ tav= RE_vertren_get_tangent(obr, v2, 1);
+ add_v3_v3(tav, tang);
+ tav= RE_vertren_get_tangent(obr, v3, 1);
+ add_v3_v3(tav, tang);
+ }
+
+ if (v4) {
+ tangent_from_uv_v3(uv1, uv3, uv4, v1->co, v3->co, v4->co, vlr->n, tang);
+
+ if (do_tangent) {
+ tav= RE_vertren_get_tangent(obr, v1, 1);
+ add_v3_v3(tav, tang);
+ tav= RE_vertren_get_tangent(obr, v3, 1);
+ add_v3_v3(tav, tang);
+ tav= RE_vertren_get_tangent(obr, v4, 1);
+ add_v3_v3(tav, tang);
+ }
+ }
+}
+
+
+
+/****************************************************************
+ ************ tangent space generation interface ****************
+ ****************************************************************/
+
+typedef struct {
+ ObjectRen *obr;
+ int mtface_index;
+} SRenderMeshToTangent;
+
+/* interface */
+#include "mikktspace.h"
+
+static int GetNumFaces(const SMikkTSpaceContext *pContext)
+{
+ SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+ return pMesh->obr->totvlak;
+}
+
+static int GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
+{
+ SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+ VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
+ return vlr->v4!=NULL ? 4 : 3;
+}
+
+static void GetPosition(const SMikkTSpaceContext *pContext, float r_co[3], const int face_num, const int vert_index)
+{
+ //assert(vert_index>=0 && vert_index<4);
+ SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+ VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
+ const float *co = (&vlr->v1)[vert_index]->co;
+ copy_v3_v3(r_co, co);
+}
+
+static void GetTextureCoordinate(const SMikkTSpaceContext *pContext, float r_uv[2], const int face_num, const int vert_index)
+{
+ //assert(vert_index>=0 && vert_index<4);
+ SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+ VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
+ MTFace *tface= RE_vlakren_get_tface(pMesh->obr, vlr, pMesh->mtface_index, NULL, 0);
+ const float *coord;
+
+ if (tface != NULL) {
+ coord= tface->uv[vert_index];
+ copy_v2_v2(r_uv, coord);
+ }
+ else if ((coord = (&vlr->v1)[vert_index]->orco)) {
+ map_to_sphere(&r_uv[0], &r_uv[1], coord[0], coord[1], coord[2]);
+ }
+ else { /* else we get un-initialized value, 0.0 ok default? */
+ zero_v2(r_uv);
+ }
+}
+
+static void GetNormal(const SMikkTSpaceContext *pContext, float r_no[3], const int face_num, const int vert_index)
+{
+ //assert(vert_index>=0 && vert_index<4);
+ SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+ VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
+
+ if (vlr->flag & ME_SMOOTH) {
+ const float *n = (&vlr->v1)[vert_index]->n;
+ copy_v3_v3(r_no, n);
+ }
+ else {
+ negate_v3_v3(r_no, vlr->n);
+ }
+}
+static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign, const int face_num, const int iVert)
+{
+ //assert(vert_index>=0 && vert_index<4);
+ SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
+ VlakRen *vlr = RE_findOrAddVlak(pMesh->obr, face_num);
+ float *ftang = RE_vlakren_get_nmap_tangent(pMesh->obr, vlr, pMesh->mtface_index, true);
+ if (ftang!=NULL) {
+ copy_v3_v3(&ftang[iVert*4+0], fvTangent);
+ ftang[iVert*4+3]=fSign;
+ }
+}
+
+static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, bool do_vertex_normal, bool do_tangent, bool do_nmap_tangent)
+{
+ int a;
+
+ /* clear all vertex normals */
+ if (do_vertex_normal) {
+ for (a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
+ ver->n[0]=ver->n[1]=ver->n[2]= 0.0f;
+ }
+ }
+
+ /* calculate cos of angles and point-masses, use as weight factor to
+ * add face normal to vertex */
+ for (a=0; a<obr->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(obr, a);
+ if (do_vertex_normal && vlr->flag & ME_SMOOTH) {
+ float *n4= (vlr->v4)? vlr->v4->n: NULL;
+ const float *c4= (vlr->v4)? vlr->v4->co: NULL;
+
+ accumulate_vertex_normals_v3(vlr->v1->n, vlr->v2->n, vlr->v3->n, n4,
+ vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co, c4);
+ }
+ if (do_tangent) {
+ /* tangents still need to be calculated for flat faces too */
+ /* weighting removed, they are not vertexnormals */
+ calc_tangent_vector(obr, vlr, do_tangent);
+ }
+ }
+
+ /* do solid faces */
+ for (a=0; a<obr->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(obr, a);
+
+ if (do_vertex_normal && (vlr->flag & ME_SMOOTH)==0) {
+ if (is_zero_v3(vlr->v1->n)) copy_v3_v3(vlr->v1->n, vlr->n);
+ if (is_zero_v3(vlr->v2->n)) copy_v3_v3(vlr->v2->n, vlr->n);
+ if (is_zero_v3(vlr->v3->n)) copy_v3_v3(vlr->v3->n, vlr->n);
+ if (vlr->v4 && is_zero_v3(vlr->v4->n)) copy_v3_v3(vlr->v4->n, vlr->n);
+ }
+ }
+
+ /* normalize vertex normals */
+ for (a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
+ normalize_v3(ver->n);
+ if (do_tangent) {
+ float *tav= RE_vertren_get_tangent(obr, ver, 0);
+ if (tav) {
+ /* orthonorm. */
+ const float tdn = dot_v3v3(tav, ver->n);
+ tav[0] -= ver->n[0]*tdn;
+ tav[1] -= ver->n[1]*tdn;
+ tav[2] -= ver->n[2]*tdn;
+ normalize_v3(tav);
+ }
+ }
+ }
+
+ /* normal mapping tangent with mikktspace */
+ if (do_nmap_tangent != false) {
+ SRenderMeshToTangent mesh2tangent;
+ SMikkTSpaceContext sContext;
+ SMikkTSpaceInterface sInterface;
+ memset(&mesh2tangent, 0, sizeof(SRenderMeshToTangent));
+ memset(&sContext, 0, sizeof(SMikkTSpaceContext));
+ memset(&sInterface, 0, sizeof(SMikkTSpaceInterface));
+
+ mesh2tangent.obr = obr;
+
+ sContext.m_pUserData = &mesh2tangent;
+ sContext.m_pInterface = &sInterface;
+ sInterface.m_getNumFaces = GetNumFaces;
+ sInterface.m_getNumVerticesOfFace = GetNumVertsOfFace;
+ sInterface.m_getPosition = GetPosition;
+ sInterface.m_getTexCoord = GetTextureCoordinate;
+ sInterface.m_getNormal = GetNormal;
+ sInterface.m_setTSpaceBasic = SetTSpace;
+
+ for (a = 0; a < MAX_MTFACE; a++) {
+ if (obr->tangent_mask & 1 << a) {
+ mesh2tangent.mtface_index = a;
+ genTangSpaceDefault(&sContext);
+ }
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* Autosmoothing: */
+/* ------------------------------------------------------------------------- */
+
+typedef struct ASvert {
+ int totface;
+ ListBase faces;
+} ASvert;
+
+typedef struct ASface {
+ struct ASface *next, *prev;
+ VlakRen *vlr[4];
+ VertRen *nver[4];
+} ASface;
+
+static int as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr)
+{
+ ASface *asf;
+ int a = -1;
+
+ if (v1 == NULL)
+ return a;
+
+ asf = asv->faces.last;
+ if (asf) {
+ for (a = 0; a < 4 && asf->vlr[a]; a++) {
+ }
+ }
+ else {
+ a = 4;
+ }
+
+ /* new face struct */
+ if (a == 4) {
+ a = 0;
+ asf = MEM_callocN(sizeof(ASface), "asface");
+ BLI_addtail(&asv->faces, asf);
+ }
+
+ asf->vlr[a] = vlr;
+ asv->totface++;
+
+ return a;
+}
+
+static VertRen *as_findvertex_lnor(VlakRen *vlr, VertRen *ver, ASvert *asv, const float lnor[3])
+{
+ /* return when new vertex already was made, or existing one is OK */
+ ASface *asf;
+ int a;
+
+ /* First face, we can use existing vert and assign it current lnor! */
+ if (asv->totface == 1) {
+ copy_v3_v3(ver->n, lnor);
+ return ver;
+ }
+
+ /* In case existing ver has same normal as current lnor, we can simply use it! */
+ if (equals_v3v3(lnor, ver->n)) {
+ return ver;
+ }
+
+ asf = asv->faces.first;
+ while (asf) {
+ for (a = 0; a < 4; a++) {
+ if (asf->vlr[a] && asf->vlr[a] != vlr) {
+ /* this face already made a copy for this vertex! */
+ if (asf->nver[a]) {
+ if (equals_v3v3(lnor, asf->nver[a]->n)) {
+ return asf->nver[a];
+ }
+ }
+ }
+ }
+ asf = asf->next;
+ }
+
+ return NULL;
+}
+
+static void as_addvert_lnor(ObjectRen *obr, ASvert *asv, VertRen *ver, VlakRen *vlr, const short _lnor[3])
+{
+ VertRen *v1;
+ ASface *asf;
+ int asf_idx;
+ float lnor[3];
+
+ normal_short_to_float_v3(lnor, _lnor);
+
+ asf_idx = as_addvert(asv, ver, vlr);
+ if (asf_idx < 0) {
+ return;
+ }
+ asf = asv->faces.last;
+
+ /* already made a new vertex within threshold? */
+ v1 = as_findvertex_lnor(vlr, ver, asv, lnor);
+ if (v1 == NULL) {
+ /* make a new vertex */
+ v1 = RE_vertren_copy(obr, ver);
+ copy_v3_v3(v1->n, lnor);
+ }
+ if (v1 != ver) {
+ asf->nver[asf_idx] = v1;
+ if (vlr->v1 == ver) vlr->v1 = v1;
+ if (vlr->v2 == ver) vlr->v2 = v1;
+ if (vlr->v3 == ver) vlr->v3 = v1;
+ if (vlr->v4 == ver) vlr->v4 = v1;
+ }
+}
+
+/* note; autosmooth happens in object space still, after applying autosmooth we rotate */
+/* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */
+static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], short (*lnors)[4][3])
+{
+ ASvert *asverts;
+ VertRen *ver;
+ VlakRen *vlr;
+ int a, totvert;
+
+ float rot[3][3];
+
+ /* Note: For normals, we only want rotation, not scaling component.
+ * Negative scales (aka mirroring) give wrong results, see T44102. */
+ if (lnors) {
+ float mat3[3][3], size[3];
+
+ copy_m3_m4(mat3, mat);
+ mat3_to_rot_size(rot, size, mat3);
+ }
+
+ if (obr->totvert == 0)
+ return;
+
+ totvert = obr->totvert;
+ asverts = MEM_callocN(sizeof(ASvert) * totvert, "all smooth verts");
+
+ if (lnors) {
+ /* We construct listbase of all vertices and pointers to faces, and add new verts when needed
+ * (i.e. when existing ones do not share the same (loop)normal).
+ */
+ for (a = 0; a < obr->totvlak; a++, lnors++) {
+ vlr = RE_findOrAddVlak(obr, a);
+ /* skip wire faces */
+ if (vlr->v2 != vlr->v3) {
+ as_addvert_lnor(obr, asverts+vlr->v1->index, vlr->v1, vlr, (const short*)lnors[0][0]);
+ as_addvert_lnor(obr, asverts+vlr->v2->index, vlr->v2, vlr, (const short*)lnors[0][1]);
+ as_addvert_lnor(obr, asverts+vlr->v3->index, vlr->v3, vlr, (const short*)lnors[0][2]);
+ if (vlr->v4)
+ as_addvert_lnor(obr, asverts+vlr->v4->index, vlr->v4, vlr, (const short*)lnors[0][3]);
+ }
+ }
+ }
+
+ /* free */
+ for (a = 0; a < totvert; a++) {
+ BLI_freelistN(&asverts[a].faces);
+ }
+ MEM_freeN(asverts);
+
+ /* rotate vertices and calculate normal of faces */
+ for (a = 0; a < obr->totvert; a++) {
+ ver = RE_findOrAddVert(obr, a);
+ mul_m4_v3(mat, ver->co);
+ if (lnors) {
+ mul_m3_v3(rot, ver->n);
+ negate_v3(ver->n);
+ }
+ }
+ for (a = 0; a < obr->totvlak; a++) {
+ vlr = RE_findOrAddVlak(obr, a);
+
+ /* skip wire faces */
+ if (vlr->v2 != vlr->v3) {
+ if (vlr->v4)
+ normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ else
+ normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* Orco hash and Materials */
+/* ------------------------------------------------------------------------- */
+
+static float *get_object_orco(Render *re, void *ob)
+{
+ if (!re->orco_hash) {
+ return NULL;
+ }
+
+ return BLI_ghash_lookup(re->orco_hash, ob);
+}
+
+static void set_object_orco(Render *re, void *ob, float *orco)
+{
+ if (!re->orco_hash)
+ re->orco_hash = BLI_ghash_ptr_new("set_object_orco gh");
+
+ BLI_ghash_insert(re->orco_hash, ob, orco);
+}
+
+static void free_mesh_orco_hash(Render *re)
+{
+ if (re->orco_hash) {
+ BLI_ghash_free(re->orco_hash, NULL, MEM_freeN);
+ re->orco_hash = NULL;
+ }
+}
+
+static void check_material_mapto(Material *ma)
+{
+ int a;
+ ma->mapto_textured = 0;
+
+ /* cache which inputs are actually textured.
+ * this can avoid a bit of time spent iterating through all the texture slots, map inputs and map tos
+ * every time a property which may or may not be textured is accessed */
+
+ for (a=0; a<MAX_MTEX; a++) {
+ if (ma->mtex[a] && ma->mtex[a]->tex) {
+ /* currently used only in volume render, so we'll check for those flags */
+ if (ma->mtex[a]->mapto & MAP_DENSITY) ma->mapto_textured |= MAP_DENSITY;
+ if (ma->mtex[a]->mapto & MAP_EMISSION) ma->mapto_textured |= MAP_EMISSION;
+ if (ma->mtex[a]->mapto & MAP_EMISSION_COL) ma->mapto_textured |= MAP_EMISSION_COL;
+ if (ma->mtex[a]->mapto & MAP_SCATTERING) ma->mapto_textured |= MAP_SCATTERING;
+ if (ma->mtex[a]->mapto & MAP_TRANSMISSION_COL) ma->mapto_textured |= MAP_TRANSMISSION_COL;
+ if (ma->mtex[a]->mapto & MAP_REFLECTION) ma->mapto_textured |= MAP_REFLECTION;
+ if (ma->mtex[a]->mapto & MAP_REFLECTION_COL) ma->mapto_textured |= MAP_REFLECTION_COL;
+ }
+ }
+}
+static void flag_render_node_material(Render *re, bNodeTree *ntree)
+{
+ bNode *node;
+
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->id) {
+ if (GS(node->id->name)==ID_MA) {
+ Material *ma= (Material *)node->id;
+
+ if ((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))
+ re->flag |= R_ZTRA;
+
+ ma->flag |= MA_IS_USED;
+ }
+ else if (node->type==NODE_GROUP)
+ flag_render_node_material(re, (bNodeTree *)node->id);
+ }
+ }
+}
+
+static Material *give_render_material(Render *re, Object *ob, short nr)
+{
+ extern Material defmaterial; /* material.c */
+ Material *ma;
+
+ ma= give_current_material(ob, nr);
+ if (ma==NULL)
+ ma= &defmaterial;
+
+ if (re->r.mode & R_SPEED) ma->texco |= NEED_UV;
+
+ if (ma->material_type == MA_TYPE_VOLUME) {
+ ma->mode |= MA_TRANSP;
+ ma->mode &= ~MA_SHADBUF;
+ }
+ if ((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))
+ re->flag |= R_ZTRA;
+
+ /* for light groups and SSS */
+ ma->flag |= MA_IS_USED;
+
+ if (ma->nodetree && ma->use_nodes)
+ flag_render_node_material(re, ma->nodetree);
+
+ check_material_mapto(ma);
+
+ return ma;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Particles */
+/* ------------------------------------------------------------------------- */
+typedef struct ParticleStrandData {
+ struct MCol *mcol;
+ float *orco, *uvco, *surfnor;
+ float time, adapt_angle, adapt_pix, size;
+ int totuv, totcol;
+ int first, line, adapt, override_uv;
+}
+ParticleStrandData;
+/* future thread problem... */
+static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, ParticleStrandData *sd, const float vec[3], const float vec1[3])
+{
+ static VertRen *v1= NULL, *v2= NULL;
+ VlakRen *vlr= NULL;
+ float nor[3], cross[3], crosslen, w, dx, dy, width;
+ static float anor[3], avec[3];
+ int flag, i;
+ static int second=0;
+
+ sub_v3_v3v3(nor, vec, vec1);
+ normalize_v3(nor); /* nor needed as tangent */
+ cross_v3_v3v3(cross, vec, nor);
+
+ /* turn cross in pixelsize */
+ w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
+ dx= re->winx*cross[0]*re->winmat[0][0];
+ dy= re->winy*cross[1]*re->winmat[1][1];
+ w = sqrtf(dx * dx + dy * dy) / w;
+
+ if (w!=0.0f) {
+ float fac;
+ if (ma->strand_ease!=0.0f) {
+ if (ma->strand_ease<0.0f)
+ fac= pow(sd->time, 1.0f+ma->strand_ease);
+ else
+ fac= pow(sd->time, 1.0f/(1.0f-ma->strand_ease));
+ }
+ else fac= sd->time;
+
+ width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end);
+
+ /* use actual Blender units for strand width and fall back to minimum width */
+ if (ma->mode & MA_STR_B_UNITS) {
+ crosslen= len_v3(cross);
+ w= 2.0f*crosslen*ma->strand_min/w;
+
+ if (width < w)
+ width= w;
+
+ /*cross is the radius of the strand so we want it to be half of full width */
+ mul_v3_fl(cross, 0.5f/crosslen);
+ }
+ else
+ width/=w;
+
+ mul_v3_fl(cross, width);
+ }
+
+ if (ma->mode & MA_TANGENT_STR)
+ flag= R_SMOOTH|R_TANGENT;
+ else
+ flag= R_SMOOTH;
+
+ /* only 1 pixel wide strands filled in as quads now, otherwise zbuf errors */
+ if (ma->strand_sta==1.0f)
+ flag |= R_STRAND;
+
+ /* single face line */
+ if (sd->line) {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->flag= flag;
+ vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
+
+ copy_v3_v3(vlr->v1->co, vec);
+ add_v3_v3(vlr->v1->co, cross);
+ copy_v3_v3(vlr->v1->n, nor);
+ vlr->v1->orco= sd->orco;
+ vlr->v1->accum = -1.0f; /* accum abuse for strand texco */
+
+ copy_v3_v3(vlr->v2->co, vec);
+ sub_v3_v3v3(vlr->v2->co, vlr->v2->co, cross);
+ copy_v3_v3(vlr->v2->n, nor);
+ vlr->v2->orco= sd->orco;
+ vlr->v2->accum= vlr->v1->accum;
+
+ copy_v3_v3(vlr->v4->co, vec1);
+ add_v3_v3(vlr->v4->co, cross);
+ copy_v3_v3(vlr->v4->n, nor);
+ vlr->v4->orco= sd->orco;
+ vlr->v4->accum = 1.0f; /* accum abuse for strand texco */
+
+ copy_v3_v3(vlr->v3->co, vec1);
+ sub_v3_v3v3(vlr->v3->co, vlr->v3->co, cross);
+ copy_v3_v3(vlr->v3->n, nor);
+ vlr->v3->orco= sd->orco;
+ vlr->v3->accum= vlr->v4->accum;
+
+ normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V2V3;
+
+ if (sd->surfnor) {
+ float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
+ copy_v3_v3(snor, sd->surfnor);
+ }
+
+ if (sd->uvco) {
+ for (i=0; i<sd->totuv; i++) {
+ MTFace *mtf;
+ mtf=RE_vlakren_get_tface(obr, vlr, i, NULL, 1);
+ mtf->uv[0][0]=mtf->uv[1][0]=
+ mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0];
+ mtf->uv[0][1]=mtf->uv[1][1]=
+ mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1];
+ }
+ if (sd->override_uv>=0) {
+ MTFace *mtf;
+ mtf=RE_vlakren_get_tface(obr, vlr, sd->override_uv, NULL, 0);
+
+ mtf->uv[0][0]=mtf->uv[3][0]=0.0f;
+ mtf->uv[1][0]=mtf->uv[2][0]=1.0f;
+
+ mtf->uv[0][1]=mtf->uv[1][1]=0.0f;
+ mtf->uv[2][1]=mtf->uv[3][1]=1.0f;
+ }
+ }
+ if (sd->mcol) {
+ for (i=0; i<sd->totcol; i++) {
+ MCol *mc;
+ mc=RE_vlakren_get_mcol(obr, vlr, i, NULL, 1);
+ mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i];
+ mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i];
+ }
+ }
+ }
+ /* first two vertices of a strand */
+ else if (sd->first) {
+ if (sd->adapt) {
+ copy_v3_v3(anor, nor);
+ copy_v3_v3(avec, vec);
+ second=1;
+ }
+
+ v1= RE_findOrAddVert(obr, obr->totvert++);
+ v2= RE_findOrAddVert(obr, obr->totvert++);
+
+ copy_v3_v3(v1->co, vec);
+ add_v3_v3(v1->co, cross);
+ copy_v3_v3(v1->n, nor);
+ v1->orco= sd->orco;
+ v1->accum = -1.0f; /* accum abuse for strand texco */
+
+ copy_v3_v3(v2->co, vec);
+ sub_v3_v3v3(v2->co, v2->co, cross);
+ copy_v3_v3(v2->n, nor);
+ v2->orco= sd->orco;
+ v2->accum= v1->accum;
+ }
+ /* more vertices & faces to strand */
+ else {
+ if (sd->adapt==0 || second) {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->flag= flag;
+ vlr->v1= v1;
+ vlr->v2= v2;
+ vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
+
+ v1= vlr->v4; /* cycle */
+ v2= vlr->v3; /* cycle */
+
+
+ if (sd->adapt) {
+ second=0;
+ copy_v3_v3(anor, nor);
+ copy_v3_v3(avec, vec);
+ }
+
+ }
+ else if (sd->adapt) {
+ float dvec[3], pvec[3];
+ sub_v3_v3v3(dvec, avec, vec);
+ project_v3_v3v3(pvec, dvec, vec);
+ sub_v3_v3v3(dvec, dvec, pvec);
+
+ w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
+ dx= re->winx*dvec[0]*re->winmat[0][0]/w;
+ dy= re->winy*dvec[1]*re->winmat[1][1]/w;
+ w = sqrtf(dx * dx + dy * dy);
+ if (dot_v3v3(anor, nor)<sd->adapt_angle && w>sd->adapt_pix) {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->flag= flag;
+ vlr->v1= v1;
+ vlr->v2= v2;
+ vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
+
+ v1= vlr->v4; /* cycle */
+ v2= vlr->v3; /* cycle */
+
+ copy_v3_v3(anor, nor);
+ copy_v3_v3(avec, vec);
+ }
+ else {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak-1);
+ }
+ }
+
+ copy_v3_v3(vlr->v4->co, vec);
+ add_v3_v3(vlr->v4->co, cross);
+ copy_v3_v3(vlr->v4->n, nor);
+ vlr->v4->orco= sd->orco;
+ vlr->v4->accum= -1.0f + 2.0f * sd->time; /* accum abuse for strand texco */
+
+ copy_v3_v3(vlr->v3->co, vec);
+ sub_v3_v3v3(vlr->v3->co, vlr->v3->co, cross);
+ copy_v3_v3(vlr->v3->n, nor);
+ vlr->v3->orco= sd->orco;
+ vlr->v3->accum= vlr->v4->accum;
+
+ normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V2V3;
+
+ if (sd->surfnor) {
+ float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
+ copy_v3_v3(snor, sd->surfnor);
+ }
+
+ if (sd->uvco) {
+ for (i=0; i<sd->totuv; i++) {
+ MTFace *mtf;
+ mtf=RE_vlakren_get_tface(obr, vlr, i, NULL, 1);
+ mtf->uv[0][0]=mtf->uv[1][0]=
+ mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0];
+ mtf->uv[0][1]=mtf->uv[1][1]=
+ mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1];
+ }
+ if (sd->override_uv>=0) {
+ MTFace *mtf;
+ mtf=RE_vlakren_get_tface(obr, vlr, sd->override_uv, NULL, 0);
+
+ mtf->uv[0][0]=mtf->uv[3][0]=0.0f;
+ mtf->uv[1][0]=mtf->uv[2][0]=1.0f;
+
+ mtf->uv[0][1]=mtf->uv[1][1]=(vlr->v1->accum+1.0f)/2.0f;
+ mtf->uv[2][1]=mtf->uv[3][1]=(vlr->v3->accum+1.0f)/2.0f;
+ }
+ }
+ if (sd->mcol) {
+ for (i=0; i<sd->totcol; i++) {
+ MCol *mc;
+ mc=RE_vlakren_get_mcol(obr, vlr, i, NULL, 1);
+ mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i];
+ mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i];
+ }
+ }
+ }
+}
+
+static void static_particle_wire(ObjectRen *obr, Material *ma, const float vec[3], const float vec1[3], int first, int line)
+{
+ VlakRen *vlr;
+ static VertRen *v1;
+
+ if (line) {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v3= vlr->v2;
+ vlr->v4= NULL;
+
+ copy_v3_v3(vlr->v1->co, vec);
+ copy_v3_v3(vlr->v2->co, vec1);
+
+ sub_v3_v3v3(vlr->n, vec, vec1);
+ normalize_v3(vlr->n);
+ copy_v3_v3(vlr->v1->n, vlr->n);
+ copy_v3_v3(vlr->v2->n, vlr->n);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V1V2;
+
+ }
+ else if (first) {
+ v1= RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(v1->co, vec);
+ }
+ else {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= v1;
+ vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v3= vlr->v2;
+ vlr->v4= NULL;
+
+ v1= vlr->v2; /* cycle */
+ copy_v3_v3(v1->co, vec);
+
+ sub_v3_v3v3(vlr->n, vec, vec1);
+ normalize_v3(vlr->n);
+ copy_v3_v3(v1->n, vlr->n);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V1V2;
+ }
+
+}
+
+static void particle_curve(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd,
+ const float loc[3], const float loc1[3], int seed, float *pa_co)
+{
+ HaloRen *har = NULL;
+
+ if (ma->material_type == MA_TYPE_WIRE)
+ static_particle_wire(obr, ma, loc, loc1, sd->first, sd->line);
+ else if (ma->material_type == MA_TYPE_HALO) {
+ har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, sd->orco, sd->uvco, sd->size, 1.0, seed, pa_co);
+ if (har) har->lay= obr->ob->lay;
+ }
+ else
+ static_particle_strand(re, obr, ma, sd, loc, loc1);
+}
+static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, ParticleBillboardData *bb)
+{
+ VlakRen *vlr;
+ MTFace *mtf;
+ float xvec[3], yvec[3], zvec[3], bb_center[3];
+ /* Number of tiles */
+ int totsplit = bb->uv_split * bb->uv_split;
+ int tile, x, y;
+ /* Tile offsets */
+ float uvx = 0.0f, uvy = 0.0f, uvdx = 1.0f, uvdy = 1.0f, time = 0.0f;
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
+
+ psys_make_billboard(bb, xvec, yvec, zvec, bb_center);
+
+ add_v3_v3v3(vlr->v1->co, bb_center, xvec);
+ add_v3_v3(vlr->v1->co, yvec);
+ mul_m4_v3(re->viewmat, vlr->v1->co);
+
+ sub_v3_v3v3(vlr->v2->co, bb_center, xvec);
+ add_v3_v3(vlr->v2->co, yvec);
+ mul_m4_v3(re->viewmat, vlr->v2->co);
+
+ sub_v3_v3v3(vlr->v3->co, bb_center, xvec);
+ sub_v3_v3v3(vlr->v3->co, vlr->v3->co, yvec);
+ mul_m4_v3(re->viewmat, vlr->v3->co);
+
+ add_v3_v3v3(vlr->v4->co, bb_center, xvec);
+ sub_v3_v3(vlr->v4->co, yvec);
+ mul_m4_v3(re->viewmat, vlr->v4->co);
+
+ normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ copy_v3_v3(vlr->v1->n, vlr->n);
+ copy_v3_v3(vlr->v2->n, vlr->n);
+ copy_v3_v3(vlr->v3->n, vlr->n);
+ copy_v3_v3(vlr->v4->n, vlr->n);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V2V3;
+
+ if (bb->uv_split > 1) {
+ uvdx = uvdy = 1.0f / (float)bb->uv_split;
+
+ if (ELEM(bb->anim, PART_BB_ANIM_AGE, PART_BB_ANIM_FRAME)) {
+ if (bb->anim == PART_BB_ANIM_FRAME)
+ time = ((int)(bb->time * bb->lifetime) % totsplit)/(float)totsplit;
+ else
+ time = bb->time;
+ }
+ else if (bb->anim == PART_BB_ANIM_ANGLE) {
+ if (bb->align == PART_BB_VIEW) {
+ time = (float)fmod((bb->tilt + 1.0f) / 2.0f, 1.0);
+ }
+ else {
+ float axis1[3] = {0.0f, 0.0f, 0.0f};
+ float axis2[3] = {0.0f, 0.0f, 0.0f};
+
+ axis1[(bb->align + 1) % 3] = 1.0f;
+ axis2[(bb->align + 2) % 3] = 1.0f;
+
+ if (bb->lock == 0) {
+ zvec[bb->align] = 0.0f;
+ normalize_v3(zvec);
+ }
+
+ time = saacos(dot_v3v3(zvec, axis1)) / (float)M_PI;
+
+ if (dot_v3v3(zvec, axis2) < 0.0f)
+ time = 1.0f - time / 2.0f;
+ else
+ time /= 2.0f;
+ }
+ }
+
+ if (bb->split_offset == PART_BB_OFF_LINEAR)
+ time = (float)fmod(time + (float)bb->num / (float)totsplit, 1.0f);
+ else if (bb->split_offset==PART_BB_OFF_RANDOM)
+ time = (float)fmod(time + bb->random, 1.0f);
+
+ /* Find the coordinates in tile space (integer), then convert to UV
+ * space (float). Note that Y is flipped. */
+ tile = (int)((time + FLT_EPSILON10) * totsplit);
+ x = tile % bb->uv_split;
+ y = tile / bb->uv_split;
+ y = (bb->uv_split - 1) - y;
+ uvx = uvdx * x;
+ uvy = uvdy * y;
+ }
+
+ /* normal UVs */
+ if (bb->uv[0] >= 0) {
+ mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[0], NULL, 1);
+ mtf->uv[0][0] = 1.0f;
+ mtf->uv[0][1] = 1.0f;
+ mtf->uv[1][0] = 0.0f;
+ mtf->uv[1][1] = 1.0f;
+ mtf->uv[2][0] = 0.0f;
+ mtf->uv[2][1] = 0.0f;
+ mtf->uv[3][0] = 1.0f;
+ mtf->uv[3][1] = 0.0f;
+ }
+
+ /* time-index UVs */
+ if (bb->uv[1] >= 0) {
+ mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[1], NULL, 1);
+ mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = bb->time;
+ mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = (float)bb->num/(float)bb->totnum;
+ }
+
+ /* split UVs */
+ if (bb->uv_split > 1 && bb->uv[2] >= 0) {
+ mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[2], NULL, 1);
+ mtf->uv[0][0] = uvx + uvdx;
+ mtf->uv[0][1] = uvy + uvdy;
+ mtf->uv[1][0] = uvx;
+ mtf->uv[1][1] = uvy + uvdy;
+ mtf->uv[2][0] = uvx;
+ mtf->uv[2][1] = uvy;
+ mtf->uv[3][0] = uvx + uvdx;
+ mtf->uv[3][1] = uvy;
+ }
+}
+static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, ParticleBillboardData *bb, ParticleKey *state, int seed, float hasize, float *pa_co)
+{
+ float loc[3], loc0[3], loc1[3], vel[3];
+
+ copy_v3_v3(loc, state->co);
+
+ if (ren_as != PART_DRAW_BB)
+ mul_m4_v3(re->viewmat, loc);
+
+ switch (ren_as) {
+ case PART_DRAW_LINE:
+ sd->line = 1;
+ sd->time = 0.0f;
+ sd->size = hasize;
+
+ mul_v3_mat3_m4v3(vel, re->viewmat, state->vel);
+ normalize_v3(vel);
+
+ if (part->draw & PART_DRAW_VEL_LENGTH)
+ mul_v3_fl(vel, len_v3(state->vel));
+
+ madd_v3_v3v3fl(loc0, loc, vel, -part->draw_line[0]);
+ madd_v3_v3v3fl(loc1, loc, vel, part->draw_line[1]);
+
+ particle_curve(re, obr, dm, ma, sd, loc0, loc1, seed, pa_co);
+
+ break;
+
+ case PART_DRAW_BB:
+
+ copy_v3_v3(bb->vec, loc);
+ copy_v3_v3(bb->vel, state->vel);
+
+ particle_billboard(re, obr, ma, bb);
+
+ break;
+
+ default:
+ {
+ HaloRen *har = NULL;
+
+ har = RE_inithalo_particle(re, obr, dm, ma, loc, NULL, sd->orco, sd->uvco, hasize, 0.0, seed, pa_co);
+
+ if (har) har->lay= obr->ob->lay;
+
+ break;
+ }
+ }
+}
+static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int num, ParticleStrandData *sd)
+{
+ int i;
+
+ /* get uvco */
+ if (sd->uvco && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ for (i=0; i<sd->totuv; i++) {
+ if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
+ MFace *mface = dm->getTessFaceData(dm, num, CD_MFACE);
+ MTFace *mtface = (MTFace*)CustomData_get_layer_n(&dm->faceData, CD_MTFACE, i);
+ mtface += num;
+
+ psys_interpolate_uvs(mtface, mface->v4, fuv, sd->uvco + 2 * i);
+ }
+ else {
+ sd->uvco[2*i] = 0.0f;
+ sd->uvco[2*i + 1] = 0.0f;
+ }
+ }
+ }
+
+ /* get mcol */
+ if (sd->mcol && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ for (i=0; i<sd->totcol; i++) {
+ if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
+ MFace *mface = dm->getTessFaceData(dm, num, CD_MFACE);
+ MCol *mc = (MCol*)CustomData_get_layer_n(&dm->faceData, CD_MCOL, i);
+ mc += num * 4;
+
+ psys_interpolate_mcol(mc, mface->v4, fuv, sd->mcol + i);
+ }
+ else
+ memset(&sd->mcol[i], 0, sizeof(MCol));
+ }
+ }
+}
+static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset)
+{
+ Object *ob= obr->ob;
+// Object *tob=0;
+ Material *ma = NULL;
+ ParticleSystemModifierData *psmd;
+ ParticleSystem *tpsys = NULL;
+ ParticleSettings *part, *tpart = NULL;
+ ParticleData *pars, *pa = NULL, *tpa = NULL;
+ ParticleKey *states = NULL;
+ ParticleKey state;
+ ParticleCacheKey *cache = NULL;
+ ParticleBillboardData bb;
+ ParticleSimulationData sim = {NULL};
+ ParticleStrandData sd;
+ StrandBuffer *strandbuf = NULL;
+ StrandVert *svert = NULL;
+ StrandBound *sbound = NULL;
+ StrandRen *strand = NULL;
+ RNG *rng = NULL;
+ float loc[3], loc1[3], loc0[3], mat[4][4], nmat[3][3], co[3], nor[3], duplimat[4][4];
+ float strandlen=0.0f, curlen=0.0f;
+ float hasize, pa_size, r_tilt, r_length;
+ float pa_time, pa_birthtime, pa_dietime;
+ float random, simplify[2], pa_co[3];
+ const float cfra= BKE_scene_frame_get(re->scene);
+ int i, a, k, max_k=0, totpart;
+ bool do_simplify = false, do_surfacecache = false, use_duplimat = false;
+ int totchild=0, step_nbr;
+ int seed, path_nbr=0, orco1=0, num;
+ int totface;
+
+ const int *index_mf_to_mpoly = NULL;
+ const int *index_mp_to_orig = NULL;
+
+/* 1. check that everything is ok & updated */
+ if (psys==NULL)
+ return 0;
+
+ part=psys->part;
+ pars=psys->particles;
+
+ if (part==NULL || pars==NULL || !psys_check_enabled(ob, psys, G.is_rendering))
+ return 0;
+
+ if (part->ren_as==PART_DRAW_OB || part->ren_as==PART_DRAW_GR || part->ren_as==PART_DRAW_NOT)
+ return 1;
+
+ if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (ob->mode & OB_MODE_PARTICLE_EDIT))
+ return 0;
+
+ if (part->ren_as == PART_DRAW_BB && part->bb_ob == NULL && RE_GetCamera(re) == NULL)
+ return 0;
+
+/* 2. start initializing things */
+
+ /* last possibility to bail out! */
+ psmd = psys_get_modifier(ob, psys);
+ if (!(psmd->modifier.mode & eModifierMode_Render))
+ return 0;
+
+ sim.scene= re->scene;
+ sim.ob= ob;
+ sim.psys= psys;
+ sim.psmd= psmd;
+
+ if (part->phystype==PART_PHYS_KEYED)
+ psys_count_keyed_targets(&sim);
+
+ totchild=psys->totchild;
+
+ /* can happen for disconnected/global hair */
+ if (part->type==PART_HAIR && !psys->childcache)
+ totchild= 0;
+
+ if (re->r.scemode & R_VIEWPORT_PREVIEW) { /* preview render */
+ totchild = (int)((float)totchild * (float)part->disp / 100.0f);
+ step_nbr = 1 << part->draw_step;
+ }
+ else {
+ step_nbr = 1 << part->ren_step;
+ }
+ if (ELEM(part->kink, PART_KINK_SPIRAL))
+ step_nbr += part->kink_extra_steps;
+
+ psys->flag |= PSYS_DRAWING;
+
+ rng= BLI_rng_new(psys->seed);
+
+ totpart=psys->totpart;
+
+ memset(&sd, 0, sizeof(ParticleStrandData));
+ sd.override_uv = -1;
+
+/* 2.1 setup material stff */
+ ma= give_render_material(re, ob, part->omat);
+
+#if 0 /* XXX old animation system */
+ if (ma->ipo) {
+ calc_ipo(ma->ipo, cfra);
+ execute_ipo((ID *)ma, ma->ipo);
+ }
+#endif /* XXX old animation system */
+
+ hasize = ma->hasize;
+ seed = ma->seed1;
+
+ re->flag |= R_HALO;
+
+ RE_set_customdata_names(obr, &psmd->dm_final->faceData);
+ sd.totuv = CustomData_number_of_layers(&psmd->dm_final->faceData, CD_MTFACE);
+ sd.totcol = CustomData_number_of_layers(&psmd->dm_final->faceData, CD_MCOL);
+
+ if (ma->texco & TEXCO_UV && sd.totuv) {
+ sd.uvco = MEM_callocN(sd.totuv * 2 * sizeof(float), "particle_uvs");
+
+ if (ma->strand_uvname[0]) {
+ sd.override_uv = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, ma->strand_uvname);
+ sd.override_uv -= CustomData_get_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
+ }
+ }
+ else
+ sd.uvco = NULL;
+
+ if (sd.totcol)
+ sd.mcol = MEM_callocN(sd.totcol * sizeof(MCol), "particle_mcols");
+
+/* 2.2 setup billboards */
+ if (part->ren_as == PART_DRAW_BB) {
+ int first_uv = CustomData_get_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
+
+ bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[0]);
+ if (bb.uv[0] < 0)
+ bb.uv[0] = CustomData_get_active_layer_index(&psmd->dm_final->faceData, CD_MTFACE);
+
+ bb.uv[1] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[1]);
+
+ bb.uv[2] = CustomData_get_named_layer_index(&psmd->dm_final->faceData, CD_MTFACE, psys->bb_uvname[2]);
+
+ if (first_uv >= 0) {
+ bb.uv[0] -= first_uv;
+ bb.uv[1] -= first_uv;
+ bb.uv[2] -= first_uv;
+ }
+
+ bb.align = part->bb_align;
+ bb.anim = part->bb_anim;
+ bb.lock = part->draw & PART_DRAW_BB_LOCK;
+ bb.ob = (part->bb_ob ? part->bb_ob : RE_GetCamera(re));
+ bb.split_offset = part->bb_split_offset;
+ bb.totnum = totpart+totchild;
+ bb.uv_split = part->bb_uv_split;
+ }
+
+/* 2.5 setup matrices */
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat, mat); /* need to be that way, for imat texture */
+ transpose_m3_m4(nmat, ob->imat);
+
+ if (psys->flag & PSYS_USE_IMAT) {
+ /* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */
+ mul_m4_m4m4(duplimat, ob->obmat, psys->imat);
+ use_duplimat = true;
+ }
+
+/* 2.6 setup strand rendering */
+ if (part->ren_as == PART_DRAW_PATH && psys->pathcache) {
+ path_nbr = step_nbr;
+
+ if (path_nbr) {
+ if (!ELEM(ma->material_type, MA_TYPE_HALO, MA_TYPE_WIRE)) {
+ sd.orco = get_object_orco(re, psys);
+ if (!sd.orco) {
+ sd.orco = MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos");
+ set_object_orco(re, psys, sd.orco);
+ }
+ }
+ }
+
+ if (part->draw & PART_DRAW_REN_ADAPT) {
+ sd.adapt = 1;
+ sd.adapt_pix = (float)part->adapt_pix;
+ sd.adapt_angle = cosf(DEG2RADF((float)part->adapt_angle));
+ }
+
+ if (part->draw & PART_DRAW_REN_STRAND) {
+ strandbuf= RE_addStrandBuffer(obr, (totpart+totchild)*(path_nbr+1));
+ strandbuf->ma= ma;
+ strandbuf->lay= ob->lay;
+ copy_m4_m4(strandbuf->winmat, re->winmat);
+ strandbuf->winx= re->winx;
+ strandbuf->winy= re->winy;
+ strandbuf->maxdepth= 2;
+ strandbuf->adaptcos= cosf(DEG2RADF((float)part->adapt_angle));
+ strandbuf->overrideuv= sd.override_uv;
+ strandbuf->minwidth= ma->strand_min;
+
+ if (ma->strand_widthfade == 0.0f)
+ strandbuf->widthfade= -1.0f;
+ else if (ma->strand_widthfade >= 1.0f)
+ strandbuf->widthfade= 2.0f - ma->strand_widthfade;
+ else
+ strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f);
+
+ if (part->flag & PART_HAIR_BSPLINE)
+ strandbuf->flag |= R_STRAND_BSPLINE;
+ if (ma->mode & MA_STR_B_UNITS)
+ strandbuf->flag |= R_STRAND_B_UNITS;
+
+ svert= strandbuf->vert;
+
+ if (re->r.mode & R_SPEED)
+ do_surfacecache = true;
+ else if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
+ if (ma->amb != 0.0f)
+ do_surfacecache = true;
+
+ totface= psmd->dm_final->getNumTessFaces(psmd->dm_final);
+ index_mf_to_mpoly = psmd->dm_final->getTessFaceDataArray(psmd->dm_final, CD_ORIGINDEX);
+ index_mp_to_orig = psmd->dm_final->getPolyDataArray(psmd->dm_final, CD_ORIGINDEX);
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
+ }
+ for (a=0; a<totface; a++)
+ strandbuf->totbound = max_ii(strandbuf->totbound, (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a): a);
+
+ strandbuf->totbound++;
+ strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound");
+ sbound= strandbuf->bound;
+ sbound->start= sbound->end= 0;
+ }
+ }
+
+ if (sd.orco == NULL) {
+ sd.orco = MEM_mallocN(3 * sizeof(float), "particle orco");
+ orco1 = 1;
+ }
+
+ if (path_nbr == 0)
+ psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+
+/* 3. start creating renderable things */
+ for (a=0, pa=pars; a<totpart+totchild; a++, pa++, seed++) {
+ random = BLI_rng_get_float(rng);
+ /* setup per particle individual stuff */
+ if (a<totpart) {
+ if (pa->flag & PARS_UNEXIST) continue;
+
+ pa_time=(cfra-pa->time)/pa->lifetime;
+ pa_birthtime = pa->time;
+ pa_dietime = pa->dietime;
+
+ hasize = ma->hasize;
+
+ /* XXX 'tpsys' is alwyas NULL, this code won't run! */
+ /* get orco */
+ if (tpsys && part->phystype == PART_PHYS_NO) {
+ tpa = tpsys->particles + pa->num;
+ psys_particle_on_emitter(
+ psmd,
+ tpart->from, tpa->num, pa->num_dmcache, tpa->fuv,
+ tpa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
+ }
+ else {
+ psys_particle_on_emitter(
+ psmd,
+ part->from, pa->num, pa->num_dmcache,
+ pa->fuv, pa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
+ }
+
+ /* get uvco & mcol */
+ num= pa->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (pa->num < psmd->dm_final->getNumTessFaces(psmd->dm_final))
+ num= pa->num;
+
+ get_particle_uvco_mcol(part->from, psmd->dm_final, pa->fuv, num, &sd);
+
+ pa_size = pa->size;
+
+ r_tilt = 2.0f*(psys_frand(psys, a) - 0.5f);
+ r_length = psys_frand(psys, a+1);
+
+ if (path_nbr) {
+ cache = psys->pathcache[a];
+ max_k = (int)cache->segments;
+ }
+
+ if (totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
+ }
+ else {
+ ChildParticle *cpa= psys->child+a-totpart;
+
+ if (path_nbr) {
+ cache = psys->childcache[a-totpart];
+
+ if (cache->segments < 0)
+ continue;
+
+ max_k = (int)cache->segments;
+ }
+
+ pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
+ pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time);
+
+ r_tilt = 2.0f*(psys_frand(psys, a + 21) - 0.5f);
+ r_length = psys_frand(psys, a + 22);
+
+ num = cpa->num;
+
+ /* get orco */
+ if (part->childtype == PART_CHILD_FACES) {
+ psys_particle_on_emitter(
+ psmd,
+ PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD,
+ cpa->fuv, cpa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
+ }
+ else {
+ ParticleData *par = psys->particles + cpa->parent;
+ psys_particle_on_emitter(
+ psmd,
+ part->from, par->num, DMCACHE_ISCHILD, par->fuv,
+ par->foffset, co, nor, NULL, NULL, sd.orco, NULL);
+ }
+
+ /* get uvco & mcol */
+ if (part->childtype==PART_CHILD_FACES) {
+ get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm_final, cpa->fuv, cpa->num, &sd);
+ }
+ else {
+ ParticleData *parent = psys->particles + cpa->parent;
+ num = parent->num_dmcache;
+
+ if (num == DMCACHE_NOTFOUND)
+ if (parent->num < psmd->dm_final->getNumTessFaces(psmd->dm_final))
+ num = parent->num;
+
+ get_particle_uvco_mcol(part->from, psmd->dm_final, parent->fuv, num, &sd);
+ }
+
+ do_simplify = psys_render_simplify_params(psys, cpa, simplify);
+
+ if (strandbuf) {
+ int orignum = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, cpa->num) : cpa->num;
+
+ if ((orignum > sbound - strandbuf->bound) &&
+ (orignum < strandbuf->totbound))
+ {
+ sbound = &strandbuf->bound[orignum];
+ sbound->start = sbound->end = obr->totstrand;
+ }
+ }
+ }
+
+ /* TEXCO_PARTICLE */
+ pa_co[0] = pa_time;
+ pa_co[1] = 0.f;
+ pa_co[2] = 0.f;
+
+ /* surface normal shading setup */
+ if (ma->mode_l & MA_STR_SURFDIFF) {
+ mul_m3_v3(nmat, nor);
+ sd.surfnor= nor;
+ }
+ else
+ sd.surfnor= NULL;
+
+ /* strand render setup */
+ if (strandbuf) {
+ strand= RE_findOrAddStrand(obr, obr->totstrand++);
+ strand->buffer= strandbuf;
+ strand->vert= svert;
+ copy_v3_v3(strand->orco, sd.orco);
+
+ if (do_simplify) {
+ float *ssimplify= RE_strandren_get_simplify(obr, strand, 1);
+ ssimplify[0]= simplify[0];
+ ssimplify[1]= simplify[1];
+ }
+
+ if (sd.surfnor) {
+ float *snor= RE_strandren_get_surfnor(obr, strand, 1);
+ copy_v3_v3(snor, sd.surfnor);
+ }
+
+ if (do_surfacecache && num >= 0) {
+ int *facenum= RE_strandren_get_face(obr, strand, 1);
+ *facenum= num;
+ }
+
+ if (sd.uvco) {
+ for (i=0; i<sd.totuv; i++) {
+ if (i != sd.override_uv) {
+ float *uv= RE_strandren_get_uv(obr, strand, i, NULL, 1);
+
+ uv[0]= sd.uvco[2*i];
+ uv[1]= sd.uvco[2*i+1];
+ }
+ }
+ }
+ if (sd.mcol) {
+ for (i=0; i<sd.totcol; i++) {
+ MCol *mc= RE_strandren_get_mcol(obr, strand, i, NULL, 1);
+ *mc = sd.mcol[i];
+ }
+ }
+
+ sbound->end++;
+ }
+
+ /* strandco computation setup */
+ if (path_nbr) {
+ strandlen= 0.0f;
+ curlen= 0.0f;
+ for (k=1; k<=path_nbr; k++)
+ if (k<=max_k)
+ strandlen += len_v3v3((cache+k-1)->co, (cache+k)->co);
+ }
+
+ if (path_nbr) {
+ /* render strands */
+ for (k=0; k<=path_nbr; k++) {
+ float time;
+
+ if (k<=max_k) {
+ copy_v3_v3(state.co, (cache+k)->co);
+ copy_v3_v3(state.vel, (cache+k)->vel);
+ }
+ else
+ continue;
+
+ if (k > 0)
+ curlen += len_v3v3((cache+k-1)->co, (cache+k)->co);
+ time= curlen/strandlen;
+
+ copy_v3_v3(loc, state.co);
+ mul_m4_v3(re->viewmat, loc);
+
+ if (strandbuf) {
+ copy_v3_v3(svert->co, loc);
+ svert->strandco= -1.0f + 2.0f*time;
+ svert++;
+ strand->totvert++;
+ }
+ else {
+ sd.size = hasize;
+
+ if (k==1) {
+ sd.first = 1;
+ sd.time = 0.0f;
+ sub_v3_v3v3(loc0, loc1, loc);
+ add_v3_v3v3(loc0, loc1, loc0);
+
+ particle_curve(re, obr, psmd->dm_final, ma, &sd, loc1, loc0, seed, pa_co);
+ }
+
+ sd.first = 0;
+ sd.time = time;
+
+ if (k)
+ particle_curve(re, obr, psmd->dm_final, ma, &sd, loc, loc1, seed, pa_co);
+
+ copy_v3_v3(loc1, loc);
+ }
+ }
+
+ }
+ else {
+ /* render normal particles */
+ if (part->trail_count > 1) {
+ float length = part->path_end * (1.0f - part->randlength * r_length);
+ int trail_count = part->trail_count * (1.0f - part->randlength * r_length);
+ float ct = (part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time;
+ float dt = length / (trail_count ? (float)trail_count : 1.0f);
+
+ /* make sure we have pointcache in memory before getting particle on path */
+ psys_make_temp_pointcache(ob, psys);
+
+ for (i=0; i < trail_count; i++, ct -= dt) {
+ if (part->draw & PART_ABS_PATH_TIME) {
+ if (ct < pa_birthtime || ct > pa_dietime)
+ continue;
+ }
+ else if (ct < 0.0f || ct > 1.0f)
+ continue;
+
+ state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : ct;
+ psys_get_particle_on_path(&sim, a, &state, 1);
+
+ if (psys->parent)
+ mul_m4_v3(psys->parent->obmat, state.co);
+
+ if (use_duplimat)
+ mul_m4_v4(duplimat, state.co);
+
+ if (part->ren_as == PART_DRAW_BB) {
+ bb.random = random;
+ bb.offset[0] = part->bb_offset[0];
+ bb.offset[1] = part->bb_offset[1];
+ bb.size[0] = part->bb_size[0] * pa_size;
+ if (part->bb_align==PART_BB_VEL) {
+ float pa_vel = len_v3(state.vel);
+ float head = part->bb_vel_head*pa_vel;
+ float tail = part->bb_vel_tail*pa_vel;
+ bb.size[1] = part->bb_size[1]*pa_size + head + tail;
+ /* use offset to adjust the particle center. this is relative to size, so need to divide! */
+ if (bb.size[1] > 0.0f)
+ bb.offset[1] += (head-tail) / bb.size[1];
+ }
+ else
+ bb.size[1] = part->bb_size[1] * pa_size;
+ bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
+ bb.time = ct;
+ bb.num = a;
+ }
+
+ pa_co[0] = (part->draw & PART_ABS_PATH_TIME) ? (ct-pa_birthtime)/(pa_dietime-pa_birthtime) : ct;
+ pa_co[1] = (float)i/(float)(trail_count-1);
+
+ particle_normal_ren(part->ren_as, part, re, obr, psmd->dm_final, ma, &sd, &bb, &state, seed, hasize, pa_co);
+ }
+ }
+ else {
+ state.time=cfra;
+ if (psys_get_particle_state(&sim, a, &state, 0)==0)
+ continue;
+
+ if (psys->parent)
+ mul_m4_v3(psys->parent->obmat, state.co);
+
+ if (use_duplimat)
+ mul_m4_v3(duplimat, state.co);
+
+ if (part->ren_as == PART_DRAW_BB) {
+ bb.random = random;
+ bb.offset[0] = part->bb_offset[0];
+ bb.offset[1] = part->bb_offset[1];
+ bb.size[0] = part->bb_size[0] * pa_size;
+ if (part->bb_align==PART_BB_VEL) {
+ float pa_vel = len_v3(state.vel);
+ float head = part->bb_vel_head*pa_vel;
+ float tail = part->bb_vel_tail*pa_vel;
+ bb.size[1] = part->bb_size[1]*pa_size + head + tail;
+ /* use offset to adjust the particle center. this is relative to size, so need to divide! */
+ if (bb.size[1] > 0.0f)
+ bb.offset[1] += (head-tail) / bb.size[1];
+ }
+ else
+ bb.size[1] = part->bb_size[1] * pa_size;
+ bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt);
+ bb.time = pa_time;
+ bb.num = a;
+ bb.lifetime = pa_dietime-pa_birthtime;
+ }
+
+ particle_normal_ren(part->ren_as, part, re, obr, psmd->dm_final, ma, &sd, &bb, &state, seed, hasize, pa_co);
+ }
+ }
+
+ if (orco1==0)
+ sd.orco+=3;
+
+ if (re->test_break(re->tbh))
+ break;
+ }
+
+ if (do_surfacecache)
+ strandbuf->surface= cache_strand_surface(re, obr, psmd->dm_final, mat, timeoffset);
+
+/* 4. clean up */
+#if 0 /* XXX old animation system */
+ if (ma) do_mat_ipo(re->scene, ma);
+#endif /* XXX old animation system */
+
+ if (orco1)
+ MEM_freeN(sd.orco);
+
+ if (sd.uvco)
+ MEM_freeN(sd.uvco);
+
+ if (sd.mcol)
+ MEM_freeN(sd.mcol);
+
+ if (states)
+ MEM_freeN(states);
+
+ BLI_rng_free(rng);
+
+ psys->flag &= ~PSYS_DRAWING;
+
+ if (psys->lattice_deform_data) {
+ end_latt_deform(psys->lattice_deform_data);
+ psys->lattice_deform_data = NULL;
+ }
+
+ if (path_nbr && (ma->mode_l & MA_TANGENT_STR)==0)
+ calc_vertexnormals(re, obr, 1, 0, 0);
+
+ return 1;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Halo's */
+/* ------------------------------------------------------------------------- */
+
+static void make_render_halos(Render *re, ObjectRen *obr, Mesh *UNUSED(me), int totvert, MVert *mvert, Material *ma, float *orco)
+{
+ Object *ob= obr->ob;
+ HaloRen *har;
+ float xn, yn, zn, nor[3], view[3];
+ float vec[3], hasize, mat[4][4], imat[3][3];
+ int a, ok, seed= ma->seed1;
+
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ copy_m3_m4(imat, ob->imat);
+
+ re->flag |= R_HALO;
+
+ for (a=0; a<totvert; a++, mvert++) {
+ ok= 1;
+
+ if (ok) {
+ hasize= ma->hasize;
+
+ copy_v3_v3(vec, mvert->co);
+ mul_m4_v3(mat, vec);
+
+ if (ma->mode & MA_HALOPUNO) {
+ xn= mvert->no[0];
+ yn= mvert->no[1];
+ zn= mvert->no[2];
+
+ /* transpose ! */
+ nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ normalize_v3(nor);
+
+ copy_v3_v3(view, vec);
+ normalize_v3(view);
+
+ zn = dot_v3v3(nor, view);
+ if (zn>=0.0f) hasize= 0.0f;
+ else hasize*= zn*zn*zn*zn;
+ }
+
+ if (orco) har= RE_inithalo(re, obr, ma, vec, NULL, orco, hasize, 0.0, seed);
+ else har= RE_inithalo(re, obr, ma, vec, NULL, mvert->co, hasize, 0.0, seed);
+ if (har) har->lay= ob->lay;
+ }
+ if (orco) orco+= 3;
+ seed++;
+ }
+}
+
+static int verghalo(const void *a1, const void *a2)
+{
+ const HaloRen *har1= *(const HaloRen**)a1;
+ const HaloRen *har2= *(const HaloRen**)a2;
+
+ if (har1->zs < har2->zs) return 1;
+ else if (har1->zs > har2->zs) return -1;
+ return 0;
+}
+
+static void sort_halos(Render *re, int totsort)
+{
+ ObjectRen *obr;
+ HaloRen *har= NULL, **haso;
+ int a;
+
+ if (re->tothalo==0) return;
+
+ re->sortedhalos= MEM_callocN(sizeof(HaloRen*)*re->tothalo, "sorthalos");
+ haso= re->sortedhalos;
+
+ for (obr=re->objecttable.first; obr; obr=obr->next) {
+ for (a=0; a<obr->tothalo; a++) {
+ if ((a & 255)==0) har= obr->bloha[a>>8];
+ else har++;
+
+ *(haso++)= har;
+ }
+ }
+
+ qsort(re->sortedhalos, totsort, sizeof(HaloRen*), verghalo);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Displacement Mapping */
+/* ------------------------------------------------------------------------- */
+
+static short test_for_displace(Render *re, Object *ob)
+{
+ /* return 1 when this object uses displacement textures. */
+ Material *ma;
+ int i;
+
+ for (i=1; i<=ob->totcol; i++) {
+ ma=give_render_material(re, ob, i);
+ /* ma->mapto is ORed total of all mapto channels */
+ if (ma && (ma->mapto & MAP_DISPLACE)) return 1;
+ }
+ return 0;
+}
+
+static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale)
+{
+ MTFace *tface;
+ short texco= shi->mat->texco;
+ float sample=0, displace[3];
+ char *name;
+ int i;
+
+ /* shi->co is current render coord, just make sure at least some vector is here */
+ copy_v3_v3(shi->co, vr->co);
+ /* vertex normal is used for textures type 'col' and 'var' */
+ copy_v3_v3(shi->vn, vr->n);
+
+ if (texco & TEXCO_UV) {
+ shi->totuv= 0;
+ shi->actuv= obr->actmtface;
+
+ for (i=0; (tface=RE_vlakren_get_tface(obr, shi->vlr, i, &name, 0)); i++) {
+ ShadeInputUV *suv= &shi->uv[i];
+
+ /* shi.uv needs scale correction from tface uv */
+ suv->uv[0]= 2*tface->uv[vindex][0]-1.0f;
+ suv->uv[1]= 2*tface->uv[vindex][1]-1.0f;
+ suv->uv[2]= 0.0f;
+ suv->name= name;
+ shi->totuv++;
+ }
+ }
+
+ /* set all rendercoords, 'texco' is an ORed value for all textures needed */
+ if ((texco & TEXCO_ORCO) && (vr->orco)) {
+ copy_v3_v3(shi->lo, vr->orco);
+ }
+ if (texco & TEXCO_GLOB) {
+ copy_v3_v3(shi->gl, shi->co);
+ mul_m4_v3(re->viewinv, shi->gl);
+ }
+ if (texco & TEXCO_NORM) {
+ copy_v3_v3(shi->orn, shi->vn);
+ }
+ if (texco & TEXCO_REFL) {
+ /* not (yet?) */
+ }
+ if (texco & TEXCO_STRESS) {
+ const float *s= RE_vertren_get_stress(obr, vr, 0);
+
+ if (s) {
+ shi->stress= *s;
+ if (shi->stress<1.0f) shi->stress-= 1.0f;
+ else shi->stress= (shi->stress-1.0f)/shi->stress;
+ }
+ else
+ shi->stress= 0.0f;
+ }
+
+ shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0;
+
+ do_material_tex(shi, re);
+
+ //printf("no=%f, %f, %f\nbefore co=%f, %f, %f\n", vr->n[0], vr->n[1], vr->n[2],
+ //vr->co[0], vr->co[1], vr->co[2]);
+
+ displace[0]= shi->displace[0] * scale[0];
+ displace[1]= shi->displace[1] * scale[1];
+ displace[2]= shi->displace[2] * scale[2];
+
+ /* 0.5 could become button once? */
+ vr->co[0] += displace[0];
+ vr->co[1] += displace[1];
+ vr->co[2] += displace[2];
+
+ //printf("after co=%f, %f, %f\n", vr->co[0], vr->co[1], vr->co[2]);
+
+ /* we just don't do this vertex again, bad luck for other face using same vertex with
+ * different material... */
+ vr->flag |= 1;
+
+ /* Pass sample back so displace_face can decide which way to split the quad */
+ sample = shi->displace[0]*shi->displace[0];
+ sample += shi->displace[1]*shi->displace[1];
+ sample += shi->displace[2]*shi->displace[2];
+
+ vr->accum=sample;
+ /* Should be sqrt(sample), but I'm only looking for "bigger". Save the cycles. */
+ return;
+}
+
+static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale)
+{
+ ShadeInput shi;
+
+ /* Warning, This is not that nice, and possibly a bit slow,
+ * however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
+ memset(&shi, 0, sizeof(ShadeInput));
+ /* end warning! - Campbell */
+
+ /* set up shadeinput struct for multitex() */
+
+ /* memset above means we don't need this */
+ /*shi.osatex= 0;*/ /* signal not to use dx[] and dy[] texture AA vectors */
+
+ shi.obr= obr;
+ shi.vlr= vlr; /* current render face */
+ shi.mat= vlr->mat; /* current input material */
+ shi.thread= 0;
+
+ /* TODO, assign these, displacement with new bumpmap is skipped without - campbell */
+#if 0
+ /* order is not known ? */
+ shi.v1= vlr->v1;
+ shi.v2= vlr->v2;
+ shi.v3= vlr->v3;
+#endif
+
+ /* Displace the verts, flag is set when done */
+ if (!vlr->v1->flag)
+ displace_render_vert(re, obr, &shi, vlr->v1, 0, scale);
+
+ if (!vlr->v2->flag)
+ displace_render_vert(re, obr, &shi, vlr->v2, 1, scale);
+
+ if (!vlr->v3->flag)
+ displace_render_vert(re, obr, &shi, vlr->v3, 2, scale);
+
+ if (vlr->v4) {
+ if (!vlr->v4->flag)
+ displace_render_vert(re, obr, &shi, vlr->v4, 3, scale);
+
+ /* closest in displace value. This will help smooth edges. */
+ if (fabsf(vlr->v1->accum - vlr->v3->accum) > fabsf(vlr->v2->accum - vlr->v4->accum)) vlr->flag |= R_DIVIDE_24;
+ else vlr->flag &= ~R_DIVIDE_24;
+ }
+
+ /* Recalculate the face normal - if flipped before, flip now */
+ if (vlr->v4) {
+ normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ }
+ else {
+ normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ }
+}
+
+static void displace(Render *re, ObjectRen *obr)
+{
+ VertRen *vr;
+ VlakRen *vlr;
+// float min[3]={1e30, 1e30, 1e30}, max[3]={-1e30, -1e30, -1e30};
+ float scale[3]={1.0f, 1.0f, 1.0f}, temp[3];//, xn
+ int i; //, texflag=0;
+ Object *obt;
+
+ /* Object Size with parenting */
+ obt=obr->ob;
+ while (obt) {
+ mul_v3_v3v3(temp, obt->size, obt->dscale);
+ scale[0]*=temp[0]; scale[1]*=temp[1]; scale[2]*=temp[2];
+ obt=obt->parent;
+ }
+
+ /* Clear all flags */
+ for (i=0; i<obr->totvert; i++) {
+ vr= RE_findOrAddVert(obr, i);
+ vr->flag= 0;
+ }
+
+ for (i=0; i<obr->totvlak; i++) {
+ vlr=RE_findOrAddVlak(obr, i);
+ displace_render_face(re, obr, vlr, scale);
+ }
+
+ /* Recalc vertex normals */
+ calc_vertexnormals(re, obr, 1, 0, 0);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Metaball */
+/* ------------------------------------------------------------------------- */
+
+static void init_render_mball(Render *re, ObjectRen *obr)
+{
+ Object *ob= obr->ob;
+ DispList *dl;
+ VertRen *ver;
+ VlakRen *vlr, *vlr1;
+ Material *ma;
+ float *data, *nors, *orco=NULL, mat[4][4], imat[3][3], xn, yn, zn;
+ int a, need_orco, vlakindex, *index, negative_scale;
+ ListBase dispbase= {NULL, NULL};
+
+ if (ob!=BKE_mball_basis_find(re->eval_ctx, re->scene, ob))
+ return;
+
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat, mat);
+ copy_m3_m4(imat, ob->imat);
+ negative_scale = is_negative_m4(mat);
+
+ ma= give_render_material(re, ob, 1);
+
+ need_orco= 0;
+ if (ma->texco & TEXCO_ORCO) {
+ need_orco= 1;
+ }
+
+ BKE_displist_make_mball_forRender(re->eval_ctx, re->scene, ob, &dispbase);
+ dl= dispbase.first;
+ if (dl == NULL) return;
+
+ data= dl->verts;
+ nors= dl->nors;
+ if (need_orco) {
+ orco= get_object_orco(re, ob);
+
+ if (!orco) {
+ /* orco hasn't been found in cache - create new one and add to cache */
+ orco= BKE_mball_make_orco(ob, &dispbase);
+ set_object_orco(re, ob, orco);
+ }
+ }
+
+ for (a=0; a<dl->nr; a++, data+=3, nors+=3) {
+
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(ver->co, data);
+ mul_m4_v3(mat, ver->co);
+
+ /* render normals are inverted */
+ xn= -nors[0];
+ yn= -nors[1];
+ zn= -nors[2];
+
+ /* transpose ! */
+ ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ normalize_v3(ver->n);
+ //if (ob->transflag & OB_NEG_SCALE) negate_v3(ver->n);
+
+ if (need_orco) {
+ ver->orco= orco;
+ orco+=3;
+ }
+ }
+
+ index= dl->index;
+ for (a=0; a<dl->parts; a++, index+=4) {
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, index[0]);
+ vlr->v2= RE_findOrAddVert(obr, index[1]);
+ vlr->v3= RE_findOrAddVert(obr, index[2]);
+ vlr->v4 = NULL;
+
+ if (negative_scale)
+ normal_tri_v3(vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co);
+ else
+ normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+
+ vlr->mat= ma;
+ vlr->flag= ME_SMOOTH;
+ vlr->ec= 0;
+
+ /* mball -too bad- always has triangles, because quads can be non-planar */
+ if (index[3] && index[3]!=index[2]) {
+ vlr1= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlakindex= vlr1->index;
+ *vlr1= *vlr;
+ vlr1->index= vlakindex;
+ vlr1->v2= vlr1->v3;
+ vlr1->v3= RE_findOrAddVert(obr, index[3]);
+ if (negative_scale)
+ normal_tri_v3(vlr1->n, vlr1->v1->co, vlr1->v2->co, vlr1->v3->co);
+ else
+ normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co);
+ }
+ }
+
+ /* enforce display lists remade */
+ BKE_displist_free(&dispbase);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Surfaces and Curves */
+/* ------------------------------------------------------------------------- */
+
+/* returns amount of vertices added for orco */
+static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, float *orco, float mat[4][4])
+{
+ VertRen *v1, *v2, *v3, *v4, *ver;
+ VlakRen *vlr, *vlr1, *vlr2, *vlr3;
+ float *data, n1[3];
+ int u, v, orcoret= 0;
+ int p1, p2, p3, p4, a;
+ int sizeu, nsizeu, sizev, nsizev;
+ int startvert, startvlak;
+
+ startvert= obr->totvert;
+ nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr;
+
+ data= dl->verts;
+ for (u = 0; u < sizeu; u++) {
+ v1 = RE_findOrAddVert(obr, obr->totvert++); /* save this for possible V wrapping */
+ copy_v3_v3(v1->co, data); data += 3;
+ if (orco) {
+ v1->orco= orco; orco+= 3; orcoret++;
+ }
+ mul_m4_v3(mat, v1->co);
+
+ for (v = 1; v < sizev; v++) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(ver->co, data); data += 3;
+ if (orco) {
+ ver->orco= orco; orco+= 3; orcoret++;
+ }
+ mul_m4_v3(mat, ver->co);
+ }
+ /* if V-cyclic, add extra vertices at end of the row */
+ if (dl->flag & DL_CYCL_U) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(ver->co, v1->co);
+ if (orco) {
+ ver->orco= orco; orco+=3; orcoret++; //orcobase + 3*(u*sizev + 0);
+ }
+ }
+ }
+
+ /* Done before next loop to get corner vert */
+ if (dl->flag & DL_CYCL_U) nsizev++;
+ if (dl->flag & DL_CYCL_V) nsizeu++;
+
+ /* if U cyclic, add extra row at end of column */
+ if (dl->flag & DL_CYCL_V) {
+ for (v = 0; v < nsizev; v++) {
+ v1= RE_findOrAddVert(obr, startvert + v);
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(ver->co, v1->co);
+ if (orco) {
+ ver->orco= orco; orco+=3; orcoret++; //ver->orco= orcobase + 3*(0*sizev + v);
+ }
+ }
+ }
+
+ sizeu = nsizeu;
+ sizev = nsizev;
+
+ startvlak= obr->totvlak;
+
+ for (u = 0; u < sizeu - 1; u++) {
+ p1 = startvert + u * sizev; /* walk through face list */
+ p2 = p1 + 1;
+ p3 = p2 + sizev;
+ p4 = p3 - 1;
+
+ for (v = 0; v < sizev - 1; v++) {
+ v1= RE_findOrAddVert(obr, p1);
+ v2= RE_findOrAddVert(obr, p2);
+ v3= RE_findOrAddVert(obr, p3);
+ v4= RE_findOrAddVert(obr, p4);
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
+
+ normal_quad_v3(n1, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+
+ copy_v3_v3(vlr->n, n1);
+
+ vlr->mat= matar[ dl->col];
+ vlr->ec= ME_V1V2+ME_V2V3;
+ vlr->flag= dl->rt;
+
+ add_v3_v3(v1->n, n1);
+ add_v3_v3(v2->n, n1);
+ add_v3_v3(v3->n, n1);
+ add_v3_v3(v4->n, n1);
+
+ p1++; p2++; p3++; p4++;
+ }
+ }
+ /* fix normals for U resp. V cyclic faces */
+ sizeu--; sizev--; /* dec size for face array */
+ if (dl->flag & DL_CYCL_V) {
+
+ for (v = 0; v < sizev; v++) {
+ /* optimize! :*/
+ vlr= RE_findOrAddVlak(obr, UVTOINDEX(sizeu - 1, v));
+ vlr1= RE_findOrAddVlak(obr, UVTOINDEX(0, v));
+ add_v3_v3(vlr1->v1->n, vlr->n);
+ add_v3_v3(vlr1->v2->n, vlr->n);
+ add_v3_v3(vlr->v3->n, vlr1->n);
+ add_v3_v3(vlr->v4->n, vlr1->n);
+ }
+ }
+ if (dl->flag & DL_CYCL_U) {
+
+ for (u = 0; u < sizeu; u++) {
+ /* optimize! :*/
+ vlr= RE_findOrAddVlak(obr, UVTOINDEX(u, 0));
+ vlr1= RE_findOrAddVlak(obr, UVTOINDEX(u, sizev-1));
+ add_v3_v3(vlr1->v2->n, vlr->n);
+ add_v3_v3(vlr1->v3->n, vlr->n);
+ add_v3_v3(vlr->v1->n, vlr1->n);
+ add_v3_v3(vlr->v4->n, vlr1->n);
+ }
+ }
+
+ /* last vertex is an extra case:
+ *
+ * ^ ()----()----()----()
+ * | | | || |
+ * u | |(0,n)||(0,0)|
+ * | | || |
+ * ()====()====[]====()
+ * | | || |
+ * | |(m,n)||(m,0)|
+ * | | || |
+ * ()----()----()----()
+ * v ->
+ *
+ * vertex [] is no longer shared, therefore distribute
+ * normals of the surrounding faces to all of the duplicates of []
+ */
+
+ if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)) {
+ vlr= RE_findOrAddVlak(obr, UVTOINDEX(sizeu - 1, sizev - 1)); /* (m, n) */
+ vlr1= RE_findOrAddVlak(obr, UVTOINDEX(0, 0)); /* (0, 0) */
+ add_v3_v3v3(n1, vlr->n, vlr1->n);
+ vlr2= RE_findOrAddVlak(obr, UVTOINDEX(0, sizev-1)); /* (0, n) */
+ add_v3_v3(n1, vlr2->n);
+ vlr3= RE_findOrAddVlak(obr, UVTOINDEX(sizeu-1, 0)); /* (m, 0) */
+ add_v3_v3(n1, vlr3->n);
+ copy_v3_v3(vlr->v3->n, n1);
+ copy_v3_v3(vlr1->v1->n, n1);
+ copy_v3_v3(vlr2->v2->n, n1);
+ copy_v3_v3(vlr3->v4->n, n1);
+ }
+ for (a = startvert; a < obr->totvert; a++) {
+ ver= RE_findOrAddVert(obr, a);
+ normalize_v3(ver->n);
+ }
+
+
+ return orcoret;
+}
+
+static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
+ int timeoffset, float *orco, float mat[4][4])
+{
+ Object *ob= obr->ob;
+ int a, end, totvert, vertofs;
+ short mat_iter;
+ VertRen *ver;
+ VlakRen *vlr;
+ MVert *mvert = NULL;
+ MFace *mface;
+ Material *ma;
+#ifdef WITH_FREESTYLE
+ const int *index_mf_to_mpoly = NULL;
+ const int *index_mp_to_orig = NULL;
+ FreestyleFace *ffa = NULL;
+#endif
+ /* Curve *cu= ELEM(ob->type, OB_FONT, OB_CURVE) ? ob->data : NULL; */
+
+ mvert= dm->getVertArray(dm);
+ totvert= dm->getNumVerts(dm);
+
+ for (a=0; a<totvert; a++, mvert++) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(ver->co, mvert->co);
+ mul_m4_v3(mat, ver->co);
+
+ if (orco) {
+ ver->orco= orco;
+ orco+=3;
+ }
+ }
+
+ if (!timeoffset) {
+ /* store customdata names, because DerivedMesh is freed */
+ RE_set_customdata_names(obr, &dm->faceData);
+
+ /* still to do for keys: the correct local texture coordinate */
+
+ /* faces in order of color blocks */
+ vertofs= obr->totvert - totvert;
+ for (mat_iter= 0; (mat_iter < ob->totcol || (mat_iter==0 && ob->totcol==0)); mat_iter++) {
+
+ ma= give_render_material(re, ob, mat_iter+1);
+ end= dm->getNumTessFaces(dm);
+ mface= dm->getTessFaceArray(dm);
+
+#ifdef WITH_FREESTYLE
+ if (ob->type == OB_MESH) {
+ Mesh *me= ob->data;
+ index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ ffa= CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE);
+ }
+#endif
+
+ for (a=0; a<end; a++, mface++) {
+ int v1, v2, v3, v4, flag;
+
+ if (mface->mat_nr == mat_iter) {
+ float len;
+
+ v1= mface->v1;
+ v2= mface->v2;
+ v3= mface->v3;
+ v4= mface->v4;
+ flag= mface->flag & ME_SMOOTH;
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
+ vlr->v2= RE_findOrAddVert(obr, vertofs+v2);
+ vlr->v3= RE_findOrAddVert(obr, vertofs+v3);
+ if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4);
+ else vlr->v4 = NULL;
+
+ /* render normals are inverted in render */
+ if (vlr->v4)
+ len= normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ else
+ len= normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+
+ vlr->mat= ma;
+ vlr->flag= flag;
+ vlr->ec= 0; /* mesh edges rendered separately */
+#ifdef WITH_FREESTYLE
+ if (ffa) {
+ int index = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
+ vlr->freestyle_face_mark= (ffa[index].flag & FREESTYLE_FACE_MARK) ? 1 : 0;
+ }
+ else {
+ vlr->freestyle_face_mark= 0;
+ }
+#endif
+
+ if (len==0) obr->totvlak--;
+ else {
+ CustomDataLayer *layer;
+ MTFace *mtface, *mtf;
+ MCol *mcol, *mc;
+ int index, mtfn= 0, mcn= 0;
+ char *name;
+
+ for (index=0; index<dm->faceData.totlayer; index++) {
+ layer= &dm->faceData.layers[index];
+ name= layer->name;
+
+ if (layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
+ mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
+ mtface= (MTFace*)layer->data;
+ *mtf= mtface[a];
+ }
+ else if (layer->type == CD_MCOL && mcn < MAX_MCOL) {
+ mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
+ mcol= (MCol*)layer->data;
+ memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Normals */
+ calc_vertexnormals(re, obr, 1, 0, 0);
+ }
+
+}
+
+static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset)
+{
+ Object *ob= obr->ob;
+ Nurb *nu = NULL;
+ Curve *cu;
+ ListBase displist= {NULL, NULL};
+ DispList *dl;
+ Material **matar;
+ float *orco=NULL, mat[4][4];
+ int a, totmat;
+ bool need_orco = false;
+ DerivedMesh *dm= NULL;
+
+ cu= ob->data;
+ nu= cu->nurb.first;
+ if (nu == NULL) return;
+
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat, mat);
+
+ /* material array */
+ totmat= ob->totcol+1;
+ matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar");
+
+ for (a=0; a<totmat; a++) {
+ matar[a]= give_render_material(re, ob, a+1);
+
+ if (matar[a] && matar[a]->texco & TEXCO_ORCO)
+ need_orco= 1;
+ }
+
+ if (ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
+
+ BKE_displist_make_surf(re->scene, ob, &displist, &dm, 1, 0, 1);
+
+ if (dm) {
+ if (need_orco) {
+ orco = get_object_orco(re, ob);
+ if (!orco) {
+ orco= BKE_displist_make_orco(re->scene, ob, dm, true, true);
+ if (orco) {
+ set_object_orco(re, ob, orco);
+ }
+ }
+ }
+
+ init_render_dm(dm, re, obr, timeoffset, orco, mat);
+ dm->release(dm);
+ }
+ else {
+ if (need_orco) {
+ orco = get_object_orco(re, ob);
+ if (!orco) {
+ orco = BKE_curve_surf_make_orco(ob);
+ set_object_orco(re, ob, orco);
+ }
+ }
+
+ /* walk along displaylist and create rendervertices/-faces */
+ for (dl=displist.first; dl; dl=dl->next) {
+ /* watch out: u ^= y, v ^= x !! */
+ if (dl->type==DL_SURF)
+ orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
+ }
+ }
+
+ BKE_displist_free(&displist);
+
+ MEM_freeN(matar);
+}
+
+static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
+{
+ Object *ob= obr->ob;
+ Curve *cu;
+ VertRen *ver;
+ VlakRen *vlr;
+ DispList *dl;
+ DerivedMesh *dm = NULL;
+ ListBase disp={NULL, NULL};
+ Material **matar;
+ float *data, *fp, *orco=NULL;
+ float n[3], mat[4][4], nmat[4][4];
+ int nr, startvert, a, b, negative_scale;
+ bool need_orco = false;
+ int totmat;
+
+ cu= ob->data;
+ if (ob->type==OB_FONT && cu->str==NULL) return;
+ else if (ob->type==OB_CURVE && cu->nurb.first==NULL) return;
+
+ BKE_displist_make_curveTypes_forRender(re->scene, ob, &disp, &dm, false, true);
+ dl= disp.first;
+ if (dl==NULL) return;
+
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat, mat);
+ negative_scale = is_negative_m4(mat);
+
+ /* local object -> world space transform for normals */
+ transpose_m4_m4(nmat, mat);
+ invert_m4(nmat);
+
+ /* material array */
+ totmat= ob->totcol+1;
+ matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar");
+
+ for (a=0; a<totmat; a++) {
+ matar[a]= give_render_material(re, ob, a+1);
+
+ if (matar[a] && matar[a]->texco & TEXCO_ORCO)
+ need_orco= 1;
+ }
+
+ if (dm) {
+ if (need_orco) {
+ orco = get_object_orco(re, ob);
+ if (!orco) {
+ orco = BKE_displist_make_orco(re->scene, ob, dm, true, true);
+ if (orco) {
+ set_object_orco(re, ob, orco);
+ }
+ }
+ }
+
+ init_render_dm(dm, re, obr, timeoffset, orco, mat);
+ dm->release(dm);
+ }
+ else {
+ if (need_orco) {
+ orco = get_object_orco(re, ob);
+ if (!orco) {
+ orco = BKE_curve_make_orco(re->scene, ob, NULL);
+ set_object_orco(re, ob, orco);
+ }
+ }
+
+ while (dl) {
+ if (dl->col > ob->totcol) {
+ /* pass */
+ }
+ else if (dl->type==DL_INDEX3) {
+ const int *index;
+
+ startvert= obr->totvert;
+ data= dl->verts;
+
+ for (a=0; a<dl->nr; a++, data+=3) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(ver->co, data);
+
+ mul_m4_v3(mat, ver->co);
+
+ if (orco) {
+ ver->orco = orco;
+ orco += 3;
+ }
+ }
+
+ if (timeoffset==0) {
+ float tmp[3];
+ const int startvlak= obr->totvlak;
+
+ zero_v3(n);
+ index= dl->index;
+ for (a=0; a<dl->parts; a++, index+=3) {
+ int v1 = index[0], v2 = index[2], v3 = index[1];
+ float *co1 = &dl->verts[v1 * 3],
+ *co2 = &dl->verts[v2 * 3],
+ *co3 = &dl->verts[v3 * 3];
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, startvert + v1);
+ vlr->v2= RE_findOrAddVert(obr, startvert + v2);
+ vlr->v3= RE_findOrAddVert(obr, startvert + v3);
+ vlr->v4= NULL;
+
+ /* to prevent float accuracy issues, we calculate normal in local object space (not world) */
+ if (normal_tri_v3(tmp, co1, co2, co3) > FLT_EPSILON) {
+ if (negative_scale == false) {
+ add_v3_v3(n, tmp);
+ }
+ else {
+ sub_v3_v3(n, tmp);
+ }
+ }
+
+ vlr->mat= matar[ dl->col ];
+ vlr->flag= 0;
+ vlr->ec= 0;
+ }
+
+ /* transform normal to world space */
+ mul_m4_v3(nmat, n);
+ normalize_v3(n);
+
+ /* vertex normals */
+ for (a= startvlak; a<obr->totvlak; a++) {
+ vlr= RE_findOrAddVlak(obr, a);
+
+ copy_v3_v3(vlr->n, n);
+ add_v3_v3(vlr->v1->n, vlr->n);
+ add_v3_v3(vlr->v3->n, vlr->n);
+ add_v3_v3(vlr->v2->n, vlr->n);
+ }
+ for (a=startvert; a<obr->totvert; a++) {
+ ver= RE_findOrAddVert(obr, a);
+ normalize_v3(ver->n);
+ }
+ }
+ }
+ else if (dl->type==DL_SURF) {
+
+ /* cyclic U means an extruded full circular curve, we skip bevel splitting then */
+ if (dl->flag & DL_CYCL_U) {
+ orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
+ }
+ else {
+ int p1, p2, p3, p4;
+
+ fp= dl->verts;
+ startvert= obr->totvert;
+ nr= dl->nr*dl->parts;
+
+ while (nr--) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+
+ copy_v3_v3(ver->co, fp);
+ mul_m4_v3(mat, ver->co);
+ fp+= 3;
+
+ if (orco) {
+ ver->orco = orco;
+ orco += 3;
+ }
+ }
+
+ if (dl->flag & DL_CYCL_V && orco) {
+ fp = dl->verts;
+ nr = dl->nr;
+ while (nr--) {
+ ver = RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(ver->co, fp);
+ mul_m4_v3(mat, ver->co);
+ ver->orco = orco;
+ fp += 3;
+ orco += 3;
+ }
+ }
+
+ if (dl->bevel_split || timeoffset == 0) {
+ const int startvlak= obr->totvlak;
+
+ for (a=0; a<dl->parts; a++) {
+
+ if (BKE_displist_surfindex_get(dl, a, &b, &p1, &p2, &p3, &p4)==0)
+ break;
+
+ p1+= startvert;
+ p2+= startvert;
+ p3+= startvert;
+ p4+= startvert;
+
+ if (dl->flag & DL_CYCL_V && orco && a == dl->parts - 1) {
+ p3 = p1 + dl->nr;
+ p4 = p2 + dl->nr;
+ }
+
+ for (; b<dl->nr; b++) {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ /* important 1 offset in order is kept [#24913] */
+ vlr->v1= RE_findOrAddVert(obr, p2);
+ vlr->v2= RE_findOrAddVert(obr, p1);
+ vlr->v3= RE_findOrAddVert(obr, p3);
+ vlr->v4= RE_findOrAddVert(obr, p4);
+ vlr->ec= ME_V2V3+ME_V3V4;
+ if (a==0) vlr->ec+= ME_V1V2;
+
+ vlr->flag= dl->rt;
+
+ normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ vlr->mat= matar[ dl->col ];
+
+ p4= p3;
+ p3++;
+ p2= p1;
+ p1++;
+ }
+ }
+
+ if (dl->bevel_split) {
+ for (a = 0; a < dl->parts - 1 + !!(dl->flag & DL_CYCL_V); a++) {
+ if (BLI_BITMAP_TEST(dl->bevel_split, a)) {
+ split_v_renderfaces(
+ obr, startvlak, startvert, dl->parts, dl->nr, a,
+ /* intentionally swap (v, u) --> (u, v) */
+ dl->flag & DL_CYCL_V, dl->flag & DL_CYCL_U);
+ }
+ }
+ }
+
+ /* vertex normals */
+ for (a= startvlak; a<obr->totvlak; a++) {
+ vlr= RE_findOrAddVlak(obr, a);
+
+ add_v3_v3(vlr->v1->n, vlr->n);
+ add_v3_v3(vlr->v3->n, vlr->n);
+ add_v3_v3(vlr->v2->n, vlr->n);
+ add_v3_v3(vlr->v4->n, vlr->n);
+ }
+ for (a=startvert; a<obr->totvert; a++) {
+ ver= RE_findOrAddVert(obr, a);
+ normalize_v3(ver->n);
+ }
+ }
+ }
+ }
+
+ dl= dl->next;
+ }
+ }
+
+ BKE_displist_free(&disp);
+
+ MEM_freeN(matar);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Mesh */
+/* ------------------------------------------------------------------------- */
+
+struct edgesort {
+ unsigned int v1, v2;
+ int f;
+ unsigned int i1, i2;
+};
+
+/* edges have to be added with lowest index first for sorting */
+static void to_edgesort(struct edgesort *ed,
+ unsigned int i1, unsigned int i2,
+ unsigned int v1, unsigned int v2, int f)
+{
+ if (v1 > v2) {
+ SWAP(unsigned int, v1, v2);
+ SWAP(unsigned int, i1, i2);
+ }
+
+ ed->v1= v1;
+ ed->v2= v2;
+ ed->i1= i1;
+ ed->i2= i2;
+ ed->f = f;
+}
+
+static int vergedgesort(const void *v1, const void *v2)
+{
+ const struct edgesort *x1=v1, *x2=v2;
+
+ if ( x1->v1 > x2->v1) return 1;
+ else if ( x1->v1 < x2->v1) return -1;
+ else if ( x1->v2 > x2->v2) return 1;
+ else if ( x1->v2 < x2->v2) return -1;
+
+ return 0;
+}
+
+static struct edgesort *make_mesh_edge_lookup(DerivedMesh *dm, int *totedgesort)
+{
+ MFace *mf, *mface;
+ MTFace *tface=NULL;
+ struct edgesort *edsort, *ed;
+ unsigned int *mcol=NULL;
+ int a, totedge=0, totface;
+
+ mface= dm->getTessFaceArray(dm);
+ totface= dm->getNumTessFaces(dm);
+ tface= dm->getTessFaceDataArray(dm, CD_MTFACE);
+ mcol= dm->getTessFaceDataArray(dm, CD_MCOL);
+
+ if (mcol==NULL && tface==NULL) return NULL;
+
+ /* make sorted table with edges and face indices in it */
+ for (a= totface, mf= mface; a>0; a--, mf++) {
+ totedge += mf->v4 ? 4 : 3;
+ }
+
+ if (totedge==0)
+ return NULL;
+
+ ed= edsort= MEM_callocN(totedge*sizeof(struct edgesort), "edgesort");
+
+ for (a=0, mf=mface; a<totface; a++, mf++) {
+ to_edgesort(ed++, 0, 1, mf->v1, mf->v2, a);
+ to_edgesort(ed++, 1, 2, mf->v2, mf->v3, a);
+ if (mf->v4) {
+ to_edgesort(ed++, 2, 3, mf->v3, mf->v4, a);
+ to_edgesort(ed++, 3, 0, mf->v4, mf->v1, a);
+ }
+ else {
+ to_edgesort(ed++, 2, 3, mf->v3, mf->v1, a);
+ }
+ }
+
+ qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort);
+
+ *totedgesort= totedge;
+
+ return edsort;
+}
+
+static void use_mesh_edge_lookup(ObjectRen *obr, DerivedMesh *dm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge)
+{
+ struct edgesort ed, *edp;
+ CustomDataLayer *layer;
+ MTFace *mtface, *mtf;
+ MCol *mcol, *mc;
+ int index, mtfn, mcn;
+ char *name;
+
+ if (medge->v1 < medge->v2) {
+ ed.v1= medge->v1;
+ ed.v2= medge->v2;
+ }
+ else {
+ ed.v1= medge->v2;
+ ed.v2= medge->v1;
+ }
+
+ edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort);
+
+ /* since edges have different index ordering, we have to duplicate mcol and tface */
+ if (edp) {
+ mtfn= mcn= 0;
+
+ for (index=0; index<dm->faceData.totlayer; index++) {
+ layer= &dm->faceData.layers[index];
+ name= layer->name;
+
+ if (layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
+ mtface= &((MTFace*)layer->data)[edp->f];
+ mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
+
+ *mtf= *mtface;
+
+ memcpy(mtf->uv[0], mtface->uv[edp->i1], sizeof(float)*2);
+ memcpy(mtf->uv[1], mtface->uv[edp->i2], sizeof(float)*2);
+ memcpy(mtf->uv[2], mtface->uv[1], sizeof(float)*2);
+ memcpy(mtf->uv[3], mtface->uv[1], sizeof(float)*2);
+ }
+ else if (layer->type == CD_MCOL && mcn < MAX_MCOL) {
+ mcol= &((MCol*)layer->data)[edp->f*4];
+ mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
+
+ mc[0]= mcol[edp->i1];
+ mc[1]= mc[2]= mc[3]= mcol[edp->i2];
+ }
+ }
+ }
+}
+
+static void free_camera_inside_volumes(Render *re)
+{
+ BLI_freelistN(&re->render_volumes_inside);
+}
+
+static void init_camera_inside_volumes(Render *re)
+{
+ ObjectInstanceRen *obi;
+ VolumeOb *vo;
+ /* coordinates are all in camera space, so camera coordinate is zero. we also
+ * add an offset for the clip start, however note that with clip start it's
+ * actually impossible to do a single 'inside' test, since there will not be
+ * a single point where all camera rays start from, though for small clip start
+ * they will be close together. */
+ float co[3] = {0.f, 0.f, -re->clipsta};
+
+ for (vo= re->volumes.first; vo; vo= vo->next) {
+ for (obi= re->instancetable.first; obi; obi= obi->next) {
+ if (obi->obr == vo->obr) {
+ if (point_inside_volume_objectinstance(re, obi, co)) {
+ MatInside *mi;
+
+ mi = MEM_mallocN(sizeof(MatInside), "camera inside material");
+ mi->ma = vo->ma;
+ mi->obi = obi;
+
+ BLI_addtail(&(re->render_volumes_inside), mi);
+ }
+ }
+ }
+ }
+
+
+#if 0 /* debug */
+ {
+ MatInside *m;
+ for (m = re->render_volumes_inside.first; m; m = m->next) {
+ printf("matinside: ma: %s\n", m->ma->id.name + 2);
+ }
+ }
+#endif
+}
+
+static void add_volume(Render *re, ObjectRen *obr, Material *ma)
+{
+ struct VolumeOb *vo;
+
+ vo = MEM_mallocN(sizeof(VolumeOb), "volume object");
+
+ vo->ma = ma;
+ vo->obr = obr;
+
+ BLI_addtail(&re->volumes, vo);
+}
+
+#ifdef WITH_FREESTYLE
+static EdgeHash *make_freestyle_edge_mark_hash(DerivedMesh *dm)
+{
+ EdgeHash *edge_hash= NULL;
+ FreestyleEdge *fed;
+ MEdge *medge;
+ int totedge, a;
+
+ medge = dm->getEdgeArray(dm);
+ totedge = dm->getNumEdges(dm);
+ fed = dm->getEdgeDataArray(dm, CD_FREESTYLE_EDGE);
+ if (fed) {
+ edge_hash = BLI_edgehash_new(__func__);
+ for (a = 0; a < totedge; a++) {
+ if (fed[a].flag & FREESTYLE_EDGE_MARK)
+ BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a);
+ }
+ }
+ return edge_hash;
+}
+
+static bool has_freestyle_edge_mark(EdgeHash *edge_hash, int v1, int v2)
+{
+ MEdge *medge= BLI_edgehash_lookup(edge_hash, v1, v2);
+ return (!medge) ? 0 : 1;
+}
+#endif
+
+static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
+{
+ Object *ob= obr->ob;
+ Mesh *me;
+ MVert *mvert = NULL;
+ MFace *mface;
+ VlakRen *vlr; //, *vlr1;
+ VertRen *ver;
+ Material *ma;
+ DerivedMesh *dm;
+ CustomDataMask mask;
+ float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
+ float *orco = NULL;
+ short (*loop_nors)[4][3] = NULL;
+ bool need_orco = false, need_stress = false, need_tangent = false, need_origindex = false;
+ bool need_nmap_tangent_concrete = false;
+ int a, a1, ok, vertofs;
+ int end, totvert = 0;
+ bool do_autosmooth = false, do_displace = false;
+ bool use_original_normals = false;
+ int recalc_normals = 0; /* false by default */
+ int negative_scale;
+#ifdef WITH_FREESTYLE
+ FreestyleFace *ffa;
+#endif
+
+ me= ob->data;
+
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat, mat);
+ copy_m3_m4(imat, ob->imat);
+ negative_scale= is_negative_m4(mat);
+
+ need_orco= 0;
+ for (a=1; a<=ob->totcol; a++) {
+ ma= give_render_material(re, ob, a);
+ if (ma) {
+ if (ma->texco & (TEXCO_ORCO|TEXCO_STRESS))
+ need_orco= 1;
+ if (ma->texco & TEXCO_STRESS)
+ need_stress= 1;
+ /* normalmaps, test if tangents needed, separated from shading */
+ if (ma->mode_l & MA_TANGENT_V) {
+ need_tangent= 1;
+ if (me->mtpoly==NULL)
+ need_orco= 1;
+ }
+ if (ma->mode_l & MA_NORMAP_TANG) {
+ if (me->mtpoly==NULL) {
+ need_orco= 1;
+ }
+ need_tangent= 1;
+ }
+ if (ma->mode2_l & MA_TANGENT_CONCRETE) {
+ need_nmap_tangent_concrete = true;
+ }
+ }
+ }
+
+ if (re->flag & R_NEED_TANGENT) {
+ /* exception for tangent space baking */
+ if (me->mtpoly==NULL) {
+ need_orco= 1;
+ }
+ need_tangent= 1;
+ }
+
+ /* check autosmooth and displacement, we then have to skip only-verts optimize
+ * Note: not sure what we want to give higher priority, currently do_displace
+ * takes precedence over do_autosmooth.
+ */
+ do_displace = test_for_displace(re, ob);
+ do_autosmooth = ((me->flag & ME_AUTOSMOOTH) != 0) && !do_displace;
+ if (do_autosmooth || do_displace)
+ timeoffset = 0;
+
+ /* origindex currently used when using autosmooth, or baking to vertex colors. */
+ need_origindex = (do_autosmooth || ((re->flag & R_BAKING) && (re->r.bake_flag & R_BAKE_VCOL)));
+
+ mask = CD_MASK_RENDER_INTERNAL;
+ if (!timeoffset)
+ if (need_orco)
+ mask |= CD_MASK_ORCO;
+
+#ifdef WITH_FREESTYLE
+ mask |= CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
+#endif
+
+ if (re->r.scemode & R_VIEWPORT_PREVIEW)
+ dm= mesh_create_derived_view(re->scene, ob, mask);
+ else
+ dm= mesh_create_derived_render(re->scene, ob, mask);
+ if (dm==NULL) return; /* in case duplicated object fails? */
+
+ mvert= dm->getVertArray(dm);
+ totvert= dm->getNumVerts(dm);
+
+ if (totvert == 0) {
+ dm->release(dm);
+ return;
+ }
+
+ if (mask & CD_MASK_ORCO) {
+ orco = get_object_orco(re, ob);
+ if (!orco) {
+ orco= dm->getVertDataArray(dm, CD_ORCO);
+ if (orco) {
+ orco= MEM_dupallocN(orco);
+ set_object_orco(re, ob, orco);
+ }
+ }
+ }
+
+ /* attempt to autsmooth on original mesh, only without subsurf */
+ if (do_autosmooth && me->totvert==totvert && me->totface==dm->getNumTessFaces(dm))
+ use_original_normals= true;
+
+ ma= give_render_material(re, ob, 1);
+
+
+ if (ma->material_type == MA_TYPE_HALO) {
+ make_render_halos(re, obr, me, totvert, mvert, ma, orco);
+ }
+ else {
+ const int *index_vert_orig = NULL;
+ const int *index_mf_to_mpoly = NULL;
+ const int *index_mp_to_orig = NULL;
+ if (need_origindex) {
+ index_vert_orig = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ /* double lookup for faces -> polys */
+#ifdef WITH_FREESTYLE
+ index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+#endif
+ }
+
+ for (a=0; a<totvert; a++, mvert++) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ copy_v3_v3(ver->co, mvert->co);
+ if (do_autosmooth == false) { /* autosmooth on original unrotated data to prevent differences between frames */
+ normal_short_to_float_v3(ver->n, mvert->no);
+ mul_m4_v3(mat, ver->co);
+ mul_transposed_m3_v3(imat, ver->n);
+ normalize_v3(ver->n);
+ negate_v3(ver->n);
+ }
+
+ if (orco) {
+ ver->orco= orco;
+ orco+=3;
+ }
+
+ if (need_origindex) {
+ int *origindex;
+ origindex = RE_vertren_get_origindex(obr, ver, 1);
+
+ /* Use orig index array if it's available (e.g. in the presence
+ * of modifiers). */
+ if (index_vert_orig)
+ *origindex = index_vert_orig[a];
+ else
+ *origindex = a;
+ }
+ }
+
+ if (!timeoffset) {
+ short (*lnp)[4][3] = NULL;
+#ifdef WITH_FREESTYLE
+ EdgeHash *edge_hash;
+
+ /* create a hash table of Freestyle edge marks */
+ edge_hash = make_freestyle_edge_mark_hash(dm);
+#endif
+
+ /* store customdata names, because DerivedMesh is freed */
+ RE_set_customdata_names(obr, &dm->faceData);
+
+ /* add tangent layers if we need */
+ if ((ma->nmap_tangent_names_count && need_nmap_tangent_concrete) || need_tangent) {
+ dm->calcLoopTangents(
+ dm, need_tangent,
+ (const char (*)[MAX_NAME])ma->nmap_tangent_names, ma->nmap_tangent_names_count);
+ obr->tangent_mask = dm->tangent_mask;
+ DM_generate_tangent_tessface_data(dm, need_nmap_tangent_concrete || need_tangent);
+ }
+
+ /* still to do for keys: the correct local texture coordinate */
+
+ /* faces in order of color blocks */
+ vertofs= obr->totvert - totvert;
+ for (a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
+
+ ma= give_render_material(re, ob, a1+1);
+
+ /* test for 100% transparent */
+ ok = 1;
+ if ((ma->alpha == 0.0f) &&
+ (ma->spectra == 0.0f) &&
+ /* No need to test filter here, it's only active with MA_RAYTRANSP and we check against it below. */
+ /* (ma->filter == 0.0f) && */
+ (ma->mode & MA_TRANSP) &&
+ (ma->mode & (MA_RAYTRANSP | MA_RAYMIRROR)) == 0)
+ {
+ ok = 0;
+ /* texture on transparency? */
+ for (a=0; a<MAX_MTEX; a++) {
+ if (ma->mtex[a] && ma->mtex[a]->tex) {
+ if (ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
+ }
+ }
+ }
+
+ /* if wire material, and we got edges, don't do the faces */
+ if (ma->material_type == MA_TYPE_WIRE) {
+ end= dm->getNumEdges(dm);
+ if (end) ok= 0;
+ }
+
+ if (ok) {
+ end= dm->getNumTessFaces(dm);
+ mface= dm->getTessFaceArray(dm);
+ if (!loop_nors && do_autosmooth &&
+ (dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL) != NULL))
+ {
+ lnp = loop_nors = MEM_mallocN(sizeof(*loop_nors) * end, __func__);
+ }
+#ifdef WITH_FREESTYLE
+ index_mf_to_mpoly= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ index_mp_to_orig= dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ ffa= CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE);
+#endif
+
+ for (a=0; a<end; a++, mface++) {
+ int v1, v2, v3, v4, flag;
+
+ if ( mface->mat_nr==a1 ) {
+ float len;
+ bool reverse_verts = (negative_scale != 0 && do_autosmooth == false);
+ int rev_tab[] = {reverse_verts==0 ? 0 : 2, 1, reverse_verts==0 ? 2 : 0, 3};
+ v1= reverse_verts==0 ? mface->v1 : mface->v3;
+ v2= mface->v2;
+ v3= reverse_verts==0 ? mface->v3 : mface->v1;
+ v4= mface->v4;
+ flag = do_autosmooth ? ME_SMOOTH : mface->flag & ME_SMOOTH;
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
+ vlr->v2= RE_findOrAddVert(obr, vertofs+v2);
+ vlr->v3= RE_findOrAddVert(obr, vertofs+v3);
+ if (v4) vlr->v4 = RE_findOrAddVert(obr, vertofs+v4);
+ else vlr->v4 = NULL;
+
+#ifdef WITH_FREESTYLE
+ /* Freestyle edge/face marks */
+ if (edge_hash) {
+ int edge_mark = 0;
+
+ if (has_freestyle_edge_mark(edge_hash, v1, v2)) edge_mark |= R_EDGE_V1V2;
+ if (has_freestyle_edge_mark(edge_hash, v2, v3)) edge_mark |= R_EDGE_V2V3;
+ if (!v4) {
+ if (has_freestyle_edge_mark(edge_hash, v3, v1)) edge_mark |= R_EDGE_V3V1;
+ }
+ else {
+ if (has_freestyle_edge_mark(edge_hash, v3, v4)) edge_mark |= R_EDGE_V3V4;
+ if (has_freestyle_edge_mark(edge_hash, v4, v1)) edge_mark |= R_EDGE_V4V1;
+ }
+ vlr->freestyle_edge_mark= edge_mark;
+ }
+ if (ffa) {
+ int index = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
+ vlr->freestyle_face_mark= (ffa[index].flag & FREESTYLE_FACE_MARK) ? 1 : 0;
+ }
+ else {
+ vlr->freestyle_face_mark= 0;
+ }
+#endif
+
+ /* render normals are inverted in render */
+ if (use_original_normals) {
+ MFace *mf= me->mface+a;
+ MVert *mv= me->mvert;
+
+ if (vlr->v4)
+ len= normal_quad_v3(vlr->n, mv[mf->v4].co, mv[mf->v3].co, mv[mf->v2].co, mv[mf->v1].co);
+ else
+ len= normal_tri_v3(vlr->n, mv[mf->v3].co, mv[mf->v2].co, mv[mf->v1].co);
+ }
+ else {
+ if (vlr->v4)
+ len= normal_quad_v3(vlr->n, vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ else
+ len= normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ }
+
+ vlr->mat= ma;
+ vlr->flag= flag;
+ vlr->ec= 0; /* mesh edges rendered separately */
+
+ if (len==0) obr->totvlak--;
+ else {
+ CustomDataLayer *layer;
+ MTFace *mtface, *mtf;
+ MCol *mcol, *mc;
+ int index, mtfn= 0, mcn= 0, mln = 0, vindex;
+ char *name;
+ int nr_verts = v4!=0 ? 4 : 3;
+
+ for (index=0; index<dm->faceData.totlayer; index++) {
+ layer= &dm->faceData.layers[index];
+ name= layer->name;
+
+ if (layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
+ int t;
+ mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
+ mtface= (MTFace*)layer->data;
+ *mtf = mtface[a]; /* copy face info */
+ for (vindex=0; vindex<nr_verts; vindex++)
+ for (t=0; t<2; t++)
+ mtf->uv[vindex][t]=mtface[a].uv[rev_tab[vindex]][t];
+ }
+ else if (layer->type == CD_MCOL && mcn < MAX_MCOL) {
+ mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
+ mcol= (MCol*)layer->data;
+ for (vindex=0; vindex<nr_verts; vindex++)
+ mc[vindex]=mcol[a*4+rev_tab[vindex]];
+ }
+ else if (layer->type == CD_TANGENT) {
+ if (need_nmap_tangent_concrete || need_tangent) {
+ int uv_start = CustomData_get_layer_index(&dm->faceData, CD_MTFACE);
+ int uv_index = CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, layer->name);
+
+ /* if there are no UVs, orco tangents are in first slot */
+ int n = (uv_start >= 0 && uv_index >= 0) ? uv_index - uv_start : 0;
+
+ const float *tangent = (const float *) layer->data;
+ float *ftang = RE_vlakren_get_nmap_tangent(obr, vlr, n, true);
+
+ for (vindex=0; vindex<nr_verts; vindex++) {
+ copy_v4_v4(ftang+vindex*4, tangent+a*16+rev_tab[vindex]*4);
+ mul_mat3_m4_v3(mat, ftang+vindex*4);
+ normalize_v3(ftang+vindex*4);
+ }
+ }
+ }
+ else if (layer->type == CD_TESSLOOPNORMAL && mln < 1) {
+ if (loop_nors) {
+ const short (*lnors)[4][3] = (const short (*)[4][3])layer->data;
+ for (vindex = 0; vindex < 4; vindex++) {
+ //print_v3("lnors[a][rev_tab[vindex]]", lnors[a][rev_tab[vindex]]);
+ copy_v3_v3_short((short *)lnp[0][vindex], lnors[a][rev_tab[vindex]]);
+ /* If we copy loop normals, we are doing autosmooth, so we are still
+ * in object space, no need to multiply with mat!
+ */
+ }
+ lnp++;
+ }
+ mln++;
+ }
+ }
+
+ if (need_origindex) {
+ /* Find original index of mpoly for this tessface. Options:
+ * - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
+ * - OR Tesselated mesh; look up from tessface -> mpoly
+ * - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
+ int *origindex;
+ origindex = RE_vlakren_get_origindex(obr, vlr, 1);
+ if (index_mf_to_mpoly && index_mp_to_orig)
+ *origindex = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a);
+ else if (index_mf_to_mpoly)
+ *origindex = index_mf_to_mpoly[a];
+ else
+ *origindex = a;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#ifdef WITH_FREESTYLE
+ /* release the hash table of Freestyle edge marks */
+ if (edge_hash)
+ BLI_edgehash_free(edge_hash, NULL);
+#endif
+
+ /* exception... we do edges for wire mode. potential conflict when faces exist... */
+ end= dm->getNumEdges(dm);
+ mvert= dm->getVertArray(dm);
+ ma= give_render_material(re, ob, 1);
+ if (end && (ma->material_type == MA_TYPE_WIRE)) {
+ MEdge *medge;
+ struct edgesort *edgetable;
+ int totedge= 0;
+ recalc_normals= 1;
+
+ medge= dm->getEdgeArray(dm);
+
+ /* we want edges to have UV and vcol too... */
+ edgetable= make_mesh_edge_lookup(dm, &totedge);
+
+ for (a1=0; a1<end; a1++, medge++) {
+ if (medge->flag&ME_EDGERENDER) {
+ MVert *v0 = &mvert[medge->v1];
+ MVert *v1 = &mvert[medge->v2];
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, vertofs+medge->v1);
+ vlr->v2= RE_findOrAddVert(obr, vertofs+medge->v2);
+ vlr->v3= vlr->v2;
+ vlr->v4= NULL;
+
+ if (edgetable)
+ use_mesh_edge_lookup(obr, dm, medge, vlr, edgetable, totedge);
+
+ xn= -(v0->no[0]+v1->no[0]);
+ yn= -(v0->no[1]+v1->no[1]);
+ zn= -(v0->no[2]+v1->no[2]);
+ /* transpose ! */
+ vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ normalize_v3(vlr->n);
+
+ vlr->mat= ma;
+ vlr->flag= 0;
+ vlr->ec= ME_V1V2;
+ }
+ }
+ if (edgetable)
+ MEM_freeN(edgetable);
+ }
+ }
+ }
+
+ if (!timeoffset) {
+ if (need_stress)
+ calc_edge_stress(re, obr, me);
+
+ if (do_displace) {
+ calc_vertexnormals(re, obr, 1, 0, 0);
+ displace(re, obr);
+ recalc_normals = 0; /* Already computed by displace! */
+ }
+ else if (do_autosmooth) {
+ recalc_normals = (loop_nors == NULL); /* Should never happen, but better be safe than sorry. */
+ autosmooth(re, obr, mat, loop_nors);
+ }
+
+ if (recalc_normals!=0 || need_tangent!=0)
+ calc_vertexnormals(re, obr, recalc_normals, need_tangent, need_nmap_tangent_concrete);
+ }
+
+ MEM_SAFE_FREE(loop_nors);
+
+ dm->release(dm);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Lamps and Shadowbuffers */
+/* ------------------------------------------------------------------------- */
+
+static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4])
+{
+ struct ShadBuf *shb;
+ float viewinv[4][4];
+
+ /* if (la->spsi<16) return; */
+
+ /* memory alloc */
+ shb= (struct ShadBuf *)MEM_callocN(sizeof(struct ShadBuf), "initshadbuf");
+ lar->shb= shb;
+
+ if (shb==NULL) return;
+
+ VECCOPY(shb->co, lar->co); /* int copy */
+
+ /* percentage render: keep track of min and max */
+ shb->size= (lar->bufsize*re->r.size)/100;
+
+ if (shb->size<512) shb->size= 512;
+ else if (shb->size > lar->bufsize) shb->size= lar->bufsize;
+
+ shb->size &= ~15; /* make sure its multiples of 16 */
+
+ shb->samp= lar->samp;
+ shb->soft= lar->soft;
+ shb->shadhalostep= lar->shadhalostep;
+
+ normalize_m4(mat);
+ invert_m4_m4(shb->winmat, mat); /* winmat is temp */
+
+ /* matrix: combination of inverse view and lampmat */
+ /* calculate again: the ortho-render has no correct viewinv */
+ invert_m4_m4(viewinv, re->viewmat);
+ mul_m4_m4m4(shb->viewmat, shb->winmat, viewinv);
+
+ /* projection */
+ shb->d= lar->clipsta;
+ shb->clipend= lar->clipend;
+
+ /* bias is percentage, made 2x larger because of correction for angle of incidence */
+ /* when a ray is closer to parallel of a face, bias value is increased during render */
+ shb->bias= (0.02f*lar->bias)*0x7FFFFFFF;
+
+ /* halfway method (average of first and 2nd z) reduces bias issues */
+ if (ELEM(lar->buftype, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP))
+ shb->bias= 0.1f*shb->bias;
+
+ shb->compressthresh= lar->compressthresh;
+}
+
+void area_lamp_vectors(LampRen *lar)
+{
+ float xsize= 0.5f*lar->area_size, ysize= 0.5f*lar->area_sizey, multifac;
+
+ /* make it smaller, so area light can be multisampled */
+ multifac= 1.0f/sqrtf((float)lar->ray_totsamp);
+ xsize *= multifac;
+ ysize *= multifac;
+
+ /* corner vectors */
+ lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
+ lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
+ lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
+ lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
+ lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
+ lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
+ lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
+ lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
+ lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
+ /* only for correction button size, matrix size works on energy */
+ lar->areasize= lar->dist*lar->dist/(4.0f*xsize*ysize);
+}
+
+/* If lar takes more lamp data, the decoupling will be better. */
+static GroupObject *add_render_lamp(Render *re, Object *ob)
+{
+ Lamp *la= ob->data;
+ LampRen *lar;
+ GroupObject *go;
+ float mat[4][4], angle, xn, yn;
+ float vec[3];
+ int c;
+
+ /* previewrender sets this to zero... prevent accidents */
+ if (la==NULL) return NULL;
+
+ /* prevent only shadow from rendering light */
+ if (la->mode & LA_ONLYSHADOW)
+ if ((re->r.mode & R_SHADOW)==0)
+ return NULL;
+
+ re->totlamp++;
+
+ /* groups is used to unify support for lightgroups, this is the global lightgroup */
+ go= MEM_callocN(sizeof(GroupObject), "groupobject");
+ BLI_addtail(&re->lights, go);
+ go->ob= ob;
+ /* lamprens are in own list, for freeing */
+ lar= (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
+ BLI_addtail(&re->lampren, lar);
+ go->lampren= lar;
+
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat, mat);
+
+ copy_m4_m4(lar->lampmat, ob->obmat);
+ copy_m3_m4(lar->mat, mat);
+ copy_m3_m4(lar->imat, ob->imat);
+
+ lar->bufsize = la->bufsize;
+ lar->samp = la->samp;
+ lar->buffers= la->buffers;
+ if (lar->buffers==0) lar->buffers= 1;
+ lar->buftype= la->buftype;
+ lar->filtertype= la->filtertype;
+ lar->soft = la->soft;
+ lar->shadhalostep = la->shadhalostep;
+ lar->clipsta = la->clipsta;
+ lar->clipend = la->clipend;
+
+ lar->bias = la->bias;
+ lar->compressthresh = la->compressthresh;
+
+ lar->type= la->type;
+ lar->mode= la->mode;
+
+ lar->energy= la->energy;
+ if (la->mode & LA_NEG) lar->energy= -lar->energy;
+
+ lar->vec[0]= -mat[2][0];
+ lar->vec[1]= -mat[2][1];
+ lar->vec[2]= -mat[2][2];
+ normalize_v3(lar->vec);
+ lar->co[0]= mat[3][0];
+ lar->co[1]= mat[3][1];
+ lar->co[2]= mat[3][2];
+ lar->dist= la->dist;
+ lar->haint= la->haint;
+ lar->distkw= lar->dist*lar->dist;
+ lar->r= lar->energy*la->r;
+ lar->g= lar->energy*la->g;
+ lar->b= lar->energy*la->b;
+ lar->shdwr= la->shdwr;
+ lar->shdwg= la->shdwg;
+ lar->shdwb= la->shdwb;
+ lar->k= la->k;
+
+ /* area */
+ lar->ray_samp= la->ray_samp;
+ lar->ray_sampy= la->ray_sampy;
+ lar->ray_sampz= la->ray_sampz;
+
+ lar->area_size= la->area_size;
+ lar->area_sizey= la->area_sizey;
+ lar->area_sizez= la->area_sizez;
+
+ lar->area_shape= la->area_shape;
+
+ /* Annoying, lamp UI does this, but the UI might not have been used? - add here too.
+ * make sure this matches buttons_shading.c's logic */
+ if (ELEM(la->type, LA_AREA, LA_SPOT, LA_SUN, LA_LOCAL) && (la->mode & LA_SHAD_RAY))
+ if (ELEM(la->type, LA_SPOT, LA_SUN, LA_LOCAL))
+ if (la->ray_samp_method == LA_SAMP_CONSTANT) la->ray_samp_method = LA_SAMP_HALTON;
+
+ lar->ray_samp_method= la->ray_samp_method;
+ lar->ray_samp_type= la->ray_samp_type;
+
+ lar->adapt_thresh= la->adapt_thresh;
+ lar->sunsky = NULL;
+
+ if ( ELEM(lar->type, LA_SPOT, LA_LOCAL)) {
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
+ lar->area_shape = LA_AREA_SQUARE;
+ lar->area_sizey= lar->area_size;
+ }
+ else if (lar->type==LA_AREA) {
+ switch (lar->area_shape) {
+ case LA_AREA_SQUARE:
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
+ lar->ray_sampy= lar->ray_samp;
+ lar->area_sizey= lar->area_size;
+ break;
+ case LA_AREA_RECT:
+ lar->ray_totsamp= lar->ray_samp*lar->ray_sampy;
+ break;
+ case LA_AREA_CUBE:
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp;
+ lar->ray_sampy= lar->ray_samp;
+ lar->ray_sampz= lar->ray_samp;
+ lar->area_sizey= lar->area_size;
+ lar->area_sizez= lar->area_size;
+ break;
+ case LA_AREA_BOX:
+ lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz;
+ break;
+ }
+
+ area_lamp_vectors(lar);
+ init_jitter_plane(lar); /* subsamples */
+ }
+ else if (lar->type==LA_SUN) {
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
+ lar->area_shape = LA_AREA_SQUARE;
+ lar->area_sizey= lar->area_size;
+
+ if ((la->sun_effect_type & LA_SUN_EFFECT_SKY) ||
+ (la->sun_effect_type & LA_SUN_EFFECT_AP))
+ {
+ lar->sunsky = (struct SunSky*)MEM_callocN(sizeof(struct SunSky), "sunskyren");
+ lar->sunsky->effect_type = la->sun_effect_type;
+
+ copy_v3_v3(vec, ob->obmat[2]);
+ normalize_v3(vec);
+
+ InitSunSky(
+ lar->sunsky, la->atm_turbidity, vec, la->horizon_brightness,
+ la->spread, la->sun_brightness, la->sun_size, la->backscattered_light,
+ la->skyblendfac, la->skyblendtype, la->sky_exposure, la->sky_colorspace);
+ InitAtmosphere(
+ lar->sunsky, la->sun_intensity, 1.0, 1.0, la->atm_inscattering_factor, la->atm_extinction_factor,
+ la->atm_distance_factor);
+ }
+ }
+ else lar->ray_totsamp= 0;
+
+ lar->spotsi= la->spotsize;
+ if (lar->mode & LA_HALO) {
+ if (lar->spotsi > DEG2RADF(170.0f)) lar->spotsi = DEG2RADF(170.0f);
+ }
+ lar->spotsi= cosf(lar->spotsi * 0.5f);
+ lar->spotbl= (1.0f-lar->spotsi)*la->spotblend;
+
+ memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *));
+
+ lar->lay = ob->lay & 0xFFFFFF; /* higher 8 bits are localview layers */
+
+ lar->falloff_type = la->falloff_type;
+ lar->ld1= la->att1;
+ lar->ld2= la->att2;
+ lar->coeff_const= la->coeff_const;
+ lar->coeff_lin= la->coeff_lin;
+ lar->coeff_quad= la->coeff_quad;
+ lar->curfalloff = curvemapping_copy(la->curfalloff);
+
+ if (lar->curfalloff) {
+ /* so threads don't conflict on init */
+ curvemapping_initialize(lar->curfalloff);
+ }
+
+ if (lar->type==LA_SPOT) {
+
+ normalize_v3(lar->imat[0]);
+ normalize_v3(lar->imat[1]);
+ normalize_v3(lar->imat[2]);
+
+ xn = saacos(lar->spotsi);
+ xn = sinf(xn) / cosf(xn);
+ lar->spottexfac= 1.0f/(xn);
+
+ if (lar->mode & LA_ONLYSHADOW) {
+ if ((lar->mode & (LA_SHAD_BUF|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW;
+ }
+
+ }
+
+ /* set flag for spothalo en initvars */
+ if ((la->type == LA_SPOT) && (la->mode & LA_HALO) &&
+ (!(la->mode & LA_SHAD_BUF) || la->buftype != LA_SHADBUF_DEEP))
+ {
+ if (la->haint>0.0f) {
+ re->flag |= R_LAMPHALO;
+
+ /* camera position (0, 0, 0) rotate around lamp */
+ lar->sh_invcampos[0]= -lar->co[0];
+ lar->sh_invcampos[1]= -lar->co[1];
+ lar->sh_invcampos[2]= -lar->co[2];
+ mul_m3_v3(lar->imat, lar->sh_invcampos);
+
+ /* z factor, for a normalized volume */
+ angle= saacos(lar->spotsi);
+ xn= lar->spotsi;
+ yn = sinf(angle);
+ lar->sh_zfac= yn/xn;
+ /* pre-scale */
+ lar->sh_invcampos[2]*= lar->sh_zfac;
+
+ /* halfway shadow buffer doesn't work for volumetric effects */
+ if (ELEM(lar->buftype, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP))
+ lar->buftype = LA_SHADBUF_REGULAR;
+
+ }
+ }
+ else if (la->type==LA_HEMI) {
+ lar->mode &= ~(LA_SHAD_RAY|LA_SHAD_BUF);
+ }
+
+ for (c=0; c<MAX_MTEX; c++) {
+ if (la->mtex[c] && la->mtex[c]->tex) {
+ if (la->mtex[c]->mapto & LAMAP_COL)
+ lar->mode |= LA_TEXTURE;
+ if (la->mtex[c]->mapto & LAMAP_SHAD)
+ lar->mode |= LA_SHAD_TEX;
+
+ if (G.is_rendering) {
+ if (re->osa) {
+ if (la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX;
+ }
+ }
+ }
+ }
+
+ /* old code checked for internal render (aka not yafray) */
+ {
+ /* to make sure we can check ray shadow easily in the render code */
+ if (lar->mode & LA_SHAD_RAY) {
+ if ( (re->r.mode & R_RAYTRACE)==0)
+ lar->mode &= ~LA_SHAD_RAY;
+ }
+
+
+ if (re->r.mode & R_SHADOW) {
+
+ if (la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) && (lar->ray_samp_method == LA_SAMP_CONSTANT)) {
+ init_jitter_plane(lar);
+ }
+ else if (la->type==LA_SPOT && (lar->mode & LA_SHAD_BUF) ) {
+ /* Per lamp, one shadow buffer is made. */
+ lar->bufflag= la->bufflag;
+ copy_m4_m4(mat, ob->obmat);
+ initshadowbuf(re, lar, mat); /* mat is altered */
+ }
+
+
+ /* this is the way used all over to check for shadow */
+ if (lar->shb || (lar->mode & LA_SHAD_RAY)) {
+ LampShadowSample *ls;
+ LampShadowSubSample *lss;
+ int a, b;
+
+ memset(re->shadowsamplenr, 0, sizeof(re->shadowsamplenr));
+
+ lar->shadsamp= MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample");
+ ls= lar->shadsamp;
+
+ /* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */
+ for (a=0; a<re->r.threads; a++, ls++) {
+ lss= ls->s;
+ for (b=0; b<re->r.osa; b++, lss++) {
+ lss->samplenr= -1; /* used to detect whether we store or read */
+ lss->shadfac[0]= 1.0f;
+ lss->shadfac[1]= 1.0f;
+ lss->shadfac[2]= 1.0f;
+ lss->shadfac[3]= 1.0f;
+ }
+ }
+ }
+ }
+ }
+
+ return go;
+}
+
+static bool is_object_restricted(Render *re, Object *ob)
+{
+ if (re->r.scemode & R_VIEWPORT_PREVIEW)
+ return (ob->restrictflag & OB_RESTRICT_VIEW) != 0;
+ else
+ return (ob->restrictflag & OB_RESTRICT_RENDER) != 0;
+}
+
+static bool is_object_hidden(Render *re, Object *ob)
+{
+ if (is_object_restricted(re, ob))
+ return true;
+
+ if (re->r.scemode & R_VIEWPORT_PREVIEW) {
+ /* Mesh deform cages and so on mess up the preview. To avoid the problem,
+ * viewport doesn't show mesh object if its draw type is bounding box or wireframe.
+ * Unless it's an active smoke domain!
+ */
+ ModifierData *md = NULL;
+
+ if ((md = modifiers_findByType(ob, eModifierType_Smoke)) &&
+ (modifier_isEnabled(re->scene, md, eModifierMode_Realtime)))
+ {
+ return false;
+ }
+ return ELEM(ob->dt, OB_BOUNDBOX, OB_WIRE);
+ }
+ else {
+ return false;
+ }
+}
+
+/* layflag: allows material group to ignore layerflag */
+static void add_lightgroup(Render *re, Group *group, int exclusive)
+{
+ GroupObject *go, *gol;
+
+ group->id.tag &= ~LIB_TAG_DOIT;
+
+ /* it's a bit too many loops in loops... but will survive */
+ /* note that 'exclusive' will remove it from the global list */
+ for (go= group->gobject.first; go; go= go->next) {
+ go->lampren= NULL;
+
+ if (is_object_hidden(re, go->ob))
+ continue;
+
+ if (go->ob->lay & re->lay) {
+ if (go->ob && go->ob->type==OB_LAMP) {
+ for (gol= re->lights.first; gol; gol= gol->next) {
+ if (gol->ob==go->ob) {
+ go->lampren= gol->lampren;
+ break;
+ }
+ }
+ if (go->lampren==NULL)
+ gol= add_render_lamp(re, go->ob);
+ if (gol && exclusive) {
+ BLI_remlink(&re->lights, gol);
+ MEM_freeN(gol);
+ }
+ }
+ }
+ }
+}
+
+static void set_material_lightgroups(Render *re)
+{
+ Group *group;
+ Material *ma;
+
+ /* not for preview render */
+ if (re->scene->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))
+ return;
+
+ for (group= re->main->group.first; group; group=group->id.next)
+ group->id.tag |= LIB_TAG_DOIT;
+
+ /* it's a bit too many loops in loops... but will survive */
+ /* hola! materials not in use...? */
+ for (ma= re->main->mat.first; ma; ma=ma->id.next) {
+ if (ma->group && (ma->group->id.tag & LIB_TAG_DOIT))
+ add_lightgroup(re, ma->group, ma->mode & MA_GROUP_NOLAY);
+ }
+}
+
+static void set_renderlayer_lightgroups(Render *re, Scene *sce)
+{
+ SceneRenderLayer *srl;
+
+ for (srl= sce->r.layers.first; srl; srl= srl->next) {
+ if (srl->light_override)
+ add_lightgroup(re, srl->light_override, 0);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* World */
+/* ------------------------------------------------------------------------- */
+
+void init_render_world(Render *re)
+{
+ void *wrld_prev[2] = {
+ re->wrld.aotables,
+ re->wrld.aosphere,
+ };
+
+ int a;
+
+ if (re->scene && re->scene->world) {
+ re->wrld = *(re->scene->world);
+
+ copy_v3_v3(re->grvec, re->viewmat[2]);
+ normalize_v3(re->grvec);
+ copy_m3_m4(re->imat, re->viewinv);
+
+ for (a=0; a<MAX_MTEX; a++)
+ if (re->wrld.mtex[a] && re->wrld.mtex[a]->tex) re->wrld.skytype |= WO_SKYTEX;
+
+ /* AO samples should be OSA minimum */
+ if (re->osa)
+ while (re->wrld.aosamp*re->wrld.aosamp < re->osa)
+ re->wrld.aosamp++;
+ if (!(re->r.mode & R_RAYTRACE) && (re->wrld.ao_gather_method == WO_AOGATHER_RAYTRACE))
+ re->wrld.mode &= ~(WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT);
+ }
+ else {
+ memset(&re->wrld, 0, sizeof(World));
+ re->wrld.exp= 0.0f;
+ re->wrld.range= 1.0f;
+
+ /* for mist pass */
+ re->wrld.miststa= re->clipsta;
+ re->wrld.mistdist= re->clipend-re->clipsta;
+ re->wrld.misi= 1.0f;
+ }
+
+ re->wrld.linfac= 1.0f + powf((2.0f*re->wrld.exp + 0.5f), -10);
+ re->wrld.logfac= logf((re->wrld.linfac-1.0f)/re->wrld.linfac) / re->wrld.range;
+
+ /* restore runtime vars, needed for viewport rendering [#36005] */
+ re->wrld.aotables = wrld_prev[0];
+ re->wrld.aosphere = wrld_prev[1];
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Object Finalization */
+/* ------------------------------------------------------------------------- */
+
+/* prevent phong interpolation for giving ray shadow errors (terminator problem) */
+static void set_phong_threshold(ObjectRen *obr)
+{
+// VertRen *ver;
+ VlakRen *vlr;
+ float thresh= 0.0, dot;
+ int tot=0, i;
+
+ /* Added check for 'pointy' situations, only dotproducts of 0.9 and larger
+ * are taken into account. This threshold is meant to work on smooth geometry, not
+ * for extreme cases (ton) */
+
+ for (i=0; i<obr->totvlak; i++) {
+ vlr= RE_findOrAddVlak(obr, i);
+ if ((vlr->flag & R_SMOOTH) && (vlr->flag & R_STRAND)==0) {
+ dot= dot_v3v3(vlr->n, vlr->v1->n);
+ dot= ABS(dot);
+ if (dot>0.9f) {
+ thresh+= dot; tot++;
+ }
+ dot= dot_v3v3(vlr->n, vlr->v2->n);
+ dot= ABS(dot);
+ if (dot>0.9f) {
+ thresh+= dot; tot++;
+ }
+
+ dot= dot_v3v3(vlr->n, vlr->v3->n);
+ dot= ABS(dot);
+ if (dot>0.9f) {
+ thresh+= dot; tot++;
+ }
+
+ if (vlr->v4) {
+ dot= dot_v3v3(vlr->n, vlr->v4->n);
+ dot= ABS(dot);
+ if (dot>0.9f) {
+ thresh+= dot; tot++;
+ }
+ }
+ }
+ }
+
+ if (tot) {
+ thresh/= (float)tot;
+ obr->ob->smoothresh= cosf(0.5f*(float)M_PI-saacos(thresh));
+ }
+}
+
+/* per face check if all samples should be taken.
+ * if raytrace or multisample, do always for raytraced material, or when material full_osa set */
+static void set_fullsample_trace_flag(Render *re, ObjectRen *obr)
+{
+ VlakRen *vlr;
+ int a, trace, mode, osa;
+
+ osa= re->osa;
+ trace= re->r.mode & R_RAYTRACE;
+
+ for (a=obr->totvlak-1; a>=0; a--) {
+ vlr= RE_findOrAddVlak(obr, a);
+ mode= vlr->mat->mode;
+
+ if (trace && (mode & MA_TRACEBLE))
+ vlr->flag |= R_TRACEBLE;
+
+ if (osa) {
+ if (mode & MA_FULL_OSA) {
+ vlr->flag |= R_FULL_OSA;
+ }
+ else if (trace) {
+ if (mode & MA_SHLESS) {
+ /* pass */
+ }
+ else if (vlr->mat->material_type == MA_TYPE_VOLUME) {
+ /* pass */
+ }
+ else if ((mode & MA_RAYMIRROR) || ((mode & MA_TRANSP) && (mode & MA_RAYTRANSP))) {
+ /* for blurry reflect/refract, better to take more samples
+ * inside the raytrace than as OSA samples */
+ if ((vlr->mat->gloss_mir == 1.0f) && (vlr->mat->gloss_tra == 1.0f))
+ vlr->flag |= R_FULL_OSA;
+ }
+ }
+ }
+ }
+}
+
+/* split quads for predictable baking
+ * dir 1 == (0, 1, 2) (0, 2, 3), 2 == (1, 3, 0) (1, 2, 3)
+ */
+static void split_quads(ObjectRen *obr, int dir)
+{
+ VlakRen *vlr, *vlr1;
+ int a;
+
+ for (a=obr->totvlak-1; a>=0; a--) {
+ vlr= RE_findOrAddVlak(obr, a);
+
+ /* test if rendering as a quad or triangle, skip wire */
+ if ((vlr->flag & R_STRAND)==0 && (vlr->mat->material_type != MA_TYPE_WIRE)) {
+
+ if (vlr->v4) {
+
+ vlr1= RE_vlakren_copy(obr, vlr);
+ vlr1->flag |= R_FACE_SPLIT;
+
+ if ( dir==2 ) vlr->flag |= R_DIVIDE_24;
+ else vlr->flag &= ~R_DIVIDE_24;
+
+ /* new vertex pointers */
+ if (vlr->flag & R_DIVIDE_24) {
+ vlr1->v1= vlr->v2;
+ vlr1->v2= vlr->v3;
+ vlr1->v3= vlr->v4;
+
+ vlr->v3 = vlr->v4;
+
+ vlr1->flag |= R_DIVIDE_24;
+ }
+ else {
+ vlr1->v1= vlr->v1;
+ vlr1->v2= vlr->v3;
+ vlr1->v3= vlr->v4;
+
+ vlr1->flag &= ~R_DIVIDE_24;
+ }
+ vlr->v4 = vlr1->v4 = NULL;
+
+#ifdef WITH_FREESTYLE
+ /* Freestyle edge marks */
+ if (vlr->flag & R_DIVIDE_24) {
+ vlr1->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0);
+ vlr->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+ }
+ else {
+ vlr1->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+ vlr->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V2V3 : 0);
+ }
+#endif
+
+ /* new normals */
+ normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co);
+ }
+ /* clear the flag when not divided */
+ else vlr->flag &= ~R_DIVIDE_24;
+ }
+ }
+}
+
+static void check_non_flat_quads(ObjectRen *obr)
+{
+ VlakRen *vlr, *vlr1;
+ VertRen *v1, *v2, *v3, *v4;
+ float nor[3], xn, flen;
+ int a;
+
+ for (a=obr->totvlak-1; a>=0; a--) {
+ vlr= RE_findOrAddVlak(obr, a);
+
+ /* test if rendering as a quad or triangle, skip wire */
+ if (vlr->v4 && (vlr->flag & R_STRAND)==0 && (vlr->mat->material_type != MA_TYPE_WIRE)) {
+
+ /* check if quad is actually triangle */
+ v1= vlr->v1;
+ v2= vlr->v2;
+ v3= vlr->v3;
+ v4= vlr->v4;
+ sub_v3_v3v3(nor, v1->co, v2->co);
+ if ( ABS(nor[0])<FLT_EPSILON10 && ABS(nor[1])<FLT_EPSILON10 && ABS(nor[2])<FLT_EPSILON10 ) {
+ vlr->v1= v2;
+ vlr->v2= v3;
+ vlr->v3= v4;
+ vlr->v4= NULL;
+ vlr->flag |= (R_DIVIDE_24 | R_FACE_SPLIT);
+ }
+ else {
+ sub_v3_v3v3(nor, v2->co, v3->co);
+ if ( ABS(nor[0])<FLT_EPSILON10 && ABS(nor[1])<FLT_EPSILON10 && ABS(nor[2])<FLT_EPSILON10 ) {
+ vlr->v2= v3;
+ vlr->v3= v4;
+ vlr->v4= NULL;
+ vlr->flag |= R_FACE_SPLIT;
+ }
+ else {
+ sub_v3_v3v3(nor, v3->co, v4->co);
+ if ( ABS(nor[0])<FLT_EPSILON10 && ABS(nor[1])<FLT_EPSILON10 && ABS(nor[2])<FLT_EPSILON10 ) {
+ vlr->v4= NULL;
+ }
+ else {
+ sub_v3_v3v3(nor, v4->co, v1->co);
+ if ( ABS(nor[0])<FLT_EPSILON10 && ABS(nor[1])<FLT_EPSILON10 && ABS(nor[2])<FLT_EPSILON10 ) {
+ vlr->v4= NULL;
+ }
+ }
+ }
+ }
+
+ if (vlr->v4) {
+
+ /* Face is divided along edge with the least gradient */
+ /* Flagged with R_DIVIDE_24 if divide is from vert 2 to 4 */
+ /* 4---3 4---3 */
+ /* |\ 1| or |1 /| */
+ /* |0\ | |/ 0| */
+ /* 1---2 1---2 0 = orig face, 1 = new face */
+
+ /* render normals are inverted in render! we calculate normal of single tria here */
+ flen= normal_tri_v3(nor, vlr->v4->co, vlr->v3->co, vlr->v1->co);
+ if (flen==0.0f) normal_tri_v3(nor, vlr->v4->co, vlr->v2->co, vlr->v1->co);
+
+ xn = dot_v3v3(nor, vlr->n);
+
+ if (ABS(xn) < 0.999995f ) { /* checked on noisy fractal grid */
+
+ float d1, d2;
+
+ vlr1= RE_vlakren_copy(obr, vlr);
+ vlr1->flag |= R_FACE_SPLIT;
+
+ /* split direction based on vnorms */
+ normal_tri_v3(nor, vlr->v1->co, vlr->v2->co, vlr->v3->co);
+ d1 = dot_v3v3(nor, vlr->v1->n);
+
+ normal_tri_v3(nor, vlr->v2->co, vlr->v3->co, vlr->v4->co);
+ d2 = dot_v3v3(nor, vlr->v2->n);
+
+ if (fabsf(d1) < fabsf(d2) ) vlr->flag |= R_DIVIDE_24;
+ else vlr->flag &= ~R_DIVIDE_24;
+
+ /* new vertex pointers */
+ if (vlr->flag & R_DIVIDE_24) {
+ vlr1->v1= vlr->v2;
+ vlr1->v2= vlr->v3;
+ vlr1->v3= vlr->v4;
+
+ vlr->v3 = vlr->v4;
+
+ vlr1->flag |= R_DIVIDE_24;
+ }
+ else {
+ vlr1->v1= vlr->v1;
+ vlr1->v2= vlr->v3;
+ vlr1->v3= vlr->v4;
+
+ vlr1->flag &= ~R_DIVIDE_24;
+ }
+ vlr->v4 = vlr1->v4 = NULL;
+
+ /* new normals */
+ normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co);
+ normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co);
+
+#ifdef WITH_FREESTYLE
+ /* Freestyle edge marks */
+ if (vlr->flag & R_DIVIDE_24) {
+ vlr1->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0);
+ vlr->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+ }
+ else {
+ vlr1->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0);
+ vlr->freestyle_edge_mark=
+ ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) |
+ ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V2V3 : 0);
+ }
+#endif
+ }
+ /* clear the flag when not divided */
+ else vlr->flag &= ~R_DIVIDE_24;
+ }
+ }
+ }
+}
+
+static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
+{
+ Object *ob= obr->ob;
+ VertRen *ver= NULL;
+ StrandRen *strand= NULL;
+ StrandBound *sbound= NULL;
+ float min[3], max[3], smin[3], smax[3];
+ int a, b;
+
+ if (obr->totvert || obr->totvlak || obr->tothalo || obr->totstrand) {
+ /* the exception below is because displace code now is in init_render_mesh call,
+ * I will look at means to have autosmooth enabled for all object types
+ * and have it as general postprocess, like displace */
+ if (ob->type!=OB_MESH && test_for_displace(re, ob))
+ displace(re, obr);
+
+ if (!timeoffset) {
+ /* phong normal interpolation can cause error in tracing
+ * (terminator problem) */
+ ob->smoothresh= 0.0;
+ if ((re->r.mode & R_RAYTRACE) && (re->r.mode & R_SHADOW))
+ set_phong_threshold(obr);
+
+ if (re->flag & R_BAKING && re->r.bake_quad_split != 0) {
+ /* Baking lets us define a quad split order */
+ split_quads(obr, re->r.bake_quad_split);
+ }
+ else if (BKE_object_is_animated(re->scene, ob))
+ split_quads(obr, 1);
+ else {
+ if ((re->r.mode & R_SIMPLIFY && re->r.simplify_flag & R_SIMPLE_NO_TRIANGULATE) == 0)
+ check_non_flat_quads(obr);
+ }
+
+ set_fullsample_trace_flag(re, obr);
+
+ /* compute bounding boxes for clipping */
+ INIT_MINMAX(min, max);
+ for (a=0; a<obr->totvert; a++) {
+ if ((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+ else ver++;
+
+ minmax_v3v3_v3(min, max, ver->co);
+ }
+
+ if (obr->strandbuf) {
+ float width;
+
+ /* compute average bounding box of strandpoint itself (width) */
+ if (obr->strandbuf->flag & R_STRAND_B_UNITS)
+ obr->strandbuf->maxwidth = max_ff(obr->strandbuf->ma->strand_sta, obr->strandbuf->ma->strand_end);
+ else
+ obr->strandbuf->maxwidth= 0.0f;
+
+ width= obr->strandbuf->maxwidth;
+ sbound= obr->strandbuf->bound;
+ for (b=0; b<obr->strandbuf->totbound; b++, sbound++) {
+
+ INIT_MINMAX(smin, smax);
+
+ for (a=sbound->start; a<sbound->end; a++) {
+ strand= RE_findOrAddStrand(obr, a);
+ strand_minmax(strand, smin, smax, width);
+ }
+
+ copy_v3_v3(sbound->boundbox[0], smin);
+ copy_v3_v3(sbound->boundbox[1], smax);
+
+ minmax_v3v3_v3(min, max, smin);
+ minmax_v3v3_v3(min, max, smax);
+ }
+ }
+
+ copy_v3_v3(obr->boundbox[0], min);
+ copy_v3_v3(obr->boundbox[1], max);
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* Database */
+/* ------------------------------------------------------------------------- */
+
+static int render_object_type(short type)
+{
+ return OB_TYPE_SUPPORT_MATERIAL(type);
+}
+
+static void find_dupli_instances(Render *re, ObjectRen *obr, DupliObject *dob)
+{
+ ObjectInstanceRen *obi;
+ float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3];
+ int first = 1;
+
+ mul_m4_m4m4(obmat, re->viewmat, obr->obmat);
+ invert_m4_m4(imat, obmat);
+
+ /* for objects instanced by dupliverts/faces/particles, we go over the
+ * list of instances to find ones that instance obr, and setup their
+ * matrices and obr pointer */
+ for (obi=re->instancetable.last; obi; obi=obi->prev) {
+ if (!obi->obr && obi->ob == obr->ob && obi->psysindex == obr->psysindex) {
+ obi->obr= obr;
+
+ /* compute difference between object matrix and
+ * object matrix with dupli transform, in viewspace */
+ copy_m4_m4(obimat, obi->mat);
+ mul_m4_m4m4(obi->mat, obimat, imat);
+
+ copy_m3_m4(nmat, obi->mat);
+ invert_m3_m3(obi->nmat, nmat);
+ transpose_m3(obi->nmat);
+
+ if (dob) {
+ copy_v3_v3(obi->dupliorco, dob->orco);
+ obi->dupliuv[0]= dob->uv[0];
+ obi->dupliuv[1]= dob->uv[1];
+ }
+
+ if (!first) {
+ re->totvert += obr->totvert;
+ re->totvlak += obr->totvlak;
+ re->tothalo += obr->tothalo;
+ re->totstrand += obr->totstrand;
+ }
+ else
+ first= 0;
+ }
+ }
+}
+
+static void assign_dupligroup_dupli(Render *re, ObjectInstanceRen *obi, ObjectRen *obr, DupliObject *dob)
+{
+ float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3];
+
+ mul_m4_m4m4(obmat, re->viewmat, obr->obmat);
+ invert_m4_m4(imat, obmat);
+
+ obi->obr= obr;
+
+ /* compute difference between object matrix and
+ * object matrix with dupli transform, in viewspace */
+ copy_m4_m4(obimat, obi->mat);
+ mul_m4_m4m4(obi->mat, obimat, imat);
+
+ copy_m3_m4(nmat, obi->mat);
+ invert_m3_m3(obi->nmat, nmat);
+ transpose_m3(obi->nmat);
+
+ if (dob) {
+ copy_v3_v3(obi->dupliorco, dob->orco);
+ obi->dupliuv[0]= dob->uv[0];
+ obi->dupliuv[1]= dob->uv[1];
+ }
+
+ re->totvert += obr->totvert;
+ re->totvlak += obr->totvlak;
+ re->tothalo += obr->tothalo;
+ re->totstrand += obr->totstrand;
+}
+
+static ObjectRen *find_dupligroup_dupli(Render *re, Object *ob, int psysindex)
+{
+ ObjectRen *obr;
+
+ /* if the object is itself instanced, we don't want to create an instance
+ * for it */
+ if (ob->transflag & OB_RENDER_DUPLI)
+ return NULL;
+
+ /* try to find an object that was already created so we can reuse it
+ * and save memory */
+ for (obr=re->objecttable.first; obr; obr=obr->next)
+ if (obr->ob == ob && obr->psysindex == psysindex && (obr->flag & R_INSTANCEABLE))
+ return obr;
+
+ return NULL;
+}
+
+static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *dob, float omat[4][4])
+{
+ /* For duplis we need to have a matrix that transform the coordinate back
+ * to it's original position, without the dupli transforms. We also check
+ * the matrix is actually needed, to save memory on lots of dupliverts for
+ * example */
+ static Object *lastob= NULL;
+ static int needtexmat= 0;
+
+ /* init */
+ if (!re) {
+ lastob= NULL;
+ needtexmat= 0;
+ return;
+ }
+
+ /* check if we actually need it */
+ if (lastob != dob->ob) {
+ Material ***material;
+ short a, *totmaterial;
+
+ lastob= dob->ob;
+ needtexmat= 0;
+
+ totmaterial= give_totcolp(dob->ob);
+ material= give_matarar(dob->ob);
+
+ if (totmaterial && material)
+ for (a= 0; a<*totmaterial; a++)
+ if ((*material)[a] && (*material)[a]->texco & TEXCO_OBJECT)
+ needtexmat= 1;
+ }
+
+ if (needtexmat) {
+ float imat[4][4];
+
+ obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4);
+ invert_m4_m4(imat, dob->mat);
+ mul_m4_series(obi->duplitexmat, re->viewmat, omat, imat, re->viewinv);
+ }
+
+ copy_v3_v3(obi->dupliorco, dob->orco);
+ copy_v2_v2(obi->dupliuv, dob->uv);
+}
+
+static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
+{
+ Object *ob= obr->ob;
+ ParticleSystem *psys;
+ int i;
+
+ if (obr->psysindex) {
+ if ((!obr->prev || obr->prev->ob != ob || (obr->prev->flag & R_INSTANCEABLE)==0) && ob->type==OB_MESH) {
+ /* the emitter mesh wasn't rendered so the modifier stack wasn't
+ * evaluated with render settings */
+ DerivedMesh *dm;
+ const CustomDataMask mask = CD_MASK_RENDER_INTERNAL;
+
+ if (re->r.scemode & R_VIEWPORT_PREVIEW)
+ dm = mesh_create_derived_view(re->scene, ob, mask);
+ else
+ dm = mesh_create_derived_render(re->scene, ob, mask);
+ dm->release(dm);
+ }
+
+ for (psys=ob->particlesystem.first, i=0; i<obr->psysindex-1; i++)
+ psys= psys->next;
+
+ render_new_particle_system(re, obr, psys, timeoffset);
+ }
+ else {
+ if (ELEM(ob->type, OB_FONT, OB_CURVE))
+ init_render_curve(re, obr, timeoffset);
+ else if (ob->type==OB_SURF)
+ init_render_surf(re, obr, timeoffset);
+ else if (ob->type==OB_MESH)
+ init_render_mesh(re, obr, timeoffset);
+ else if (ob->type==OB_MBALL)
+ init_render_mball(re, obr);
+ }
+
+ finalize_render_object(re, obr, timeoffset);
+
+ re->totvert += obr->totvert;
+ re->totvlak += obr->totvlak;
+ re->tothalo += obr->tothalo;
+ re->totstrand += obr->totstrand;
+}
+
+static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, float omat[4][4], int timeoffset)
+{
+ ObjectRen *obr;
+ ObjectInstanceRen *obi;
+ ParticleSystem *psys;
+ int show_emitter, allow_render= 1, index, psysindex, i;
+
+ index= (dob)? dob->persistent_id[0]: 0;
+
+ /* It seems that we may generate psys->renderdata recursively in some nasty intricated cases of
+ * several levels of bupliobject (see T51524).
+ * For now, basic rule is, do not restore psys if it was already in 'render state'.
+ * Another, more robust solution could be to add some reference counting to that renderdata... */
+ bool psys_has_renderdata = false;
+
+ /* the emitter has to be processed first (render levels of modifiers) */
+ /* so here we only check if the emitter should be rendered */
+ if (ob->particlesystem.first) {
+ show_emitter= 0;
+ for (psys=ob->particlesystem.first; psys; psys=psys->next) {
+ show_emitter += psys->part->draw & PART_DRAW_EMITTER;
+ if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) {
+ psys_has_renderdata |= (psys->renderdata != NULL);
+ psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
+ }
+ }
+
+ /* if no psys has "show emitter" selected don't render emitter */
+ if (show_emitter == 0)
+ allow_render= 0;
+ }
+
+ /* one render object for the data itself */
+ if (allow_render) {
+ obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay);
+ if ((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) {
+ obr->flag |= R_INSTANCEABLE;
+ copy_m4_m4(obr->obmat, ob->obmat);
+ }
+ init_render_object_data(re, obr, timeoffset);
+
+ /* only add instance for objects that have not been used for dupli */
+ if (!(ob->transflag & OB_RENDER_DUPLI)) {
+ obi = RE_addRenderInstance(re, obr, ob, par, index, 0, NULL, ob->lay, dob);
+ if (dob) set_dupli_tex_mat(re, obi, dob, omat);
+ }
+ else
+ find_dupli_instances(re, obr, dob);
+
+ for (i=1; i<=ob->totcol; i++) {
+ Material* ma = give_render_material(re, ob, i);
+ if (ma && ma->material_type == MA_TYPE_VOLUME)
+ add_volume(re, obr, ma);
+ }
+ }
+
+ /* and one render object per particle system */
+ if (ob->particlesystem.first) {
+ psysindex= 1;
+ for (psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) {
+ if (!psys_check_enabled(ob, psys, G.is_rendering))
+ continue;
+
+ obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay);
+ if ((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) {
+ obr->flag |= R_INSTANCEABLE;
+ copy_m4_m4(obr->obmat, ob->obmat);
+ }
+ if (dob)
+ psys->flag |= PSYS_USE_IMAT;
+ init_render_object_data(re, obr, timeoffset);
+ if (!(re->r.scemode & R_VIEWPORT_PREVIEW) && !psys_has_renderdata) {
+ psys_render_restore(ob, psys);
+ }
+ psys->flag &= ~PSYS_USE_IMAT;
+
+ /* only add instance for objects that have not been used for dupli */
+ if (!(ob->transflag & OB_RENDER_DUPLI)) {
+ obi = RE_addRenderInstance(re, obr, ob, par, index, psysindex, NULL, ob->lay, dob);
+ if (dob) set_dupli_tex_mat(re, obi, dob, omat);
+ }
+ else
+ find_dupli_instances(re, obr, dob);
+ }
+ }
+}
+
+/* par = pointer to duplicator parent, needed for object lookup table */
+/* index = when duplicater copies same object (particle), the counter */
+static void init_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, float omat[4][4], int timeoffset)
+{
+ static double lasttime= 0.0;
+ double time;
+ float mat[4][4];
+
+ if (ob->type==OB_LAMP)
+ add_render_lamp(re, ob);
+ else if (render_object_type(ob->type))
+ add_render_object(re, ob, par, dob, omat, timeoffset);
+ else {
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat, mat);
+ }
+
+ time= PIL_check_seconds_timer();
+ if (time - lasttime > 1.0) {
+ lasttime= time;
+ /* clumsy copying still */
+ re->i.totvert= re->totvert;
+ re->i.totface= re->totvlak;
+ re->i.totstrand= re->totstrand;
+ re->i.tothalo= re->tothalo;
+ re->i.totlamp= re->totlamp;
+ re->stats_draw(re->sdh, &re->i);
+ }
+
+ ob->flag |= OB_DONE;
+}
+
+void RE_Database_Free(Render *re)
+{
+ LampRen *lar;
+
+ /* will crash if we try to free empty database */
+ if (!re->i.convertdone)
+ return;
+
+ /* statistics for debugging render memory usage */
+ if ((G.debug & G_DEBUG) && (G.is_rendering)) {
+ if ((re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) {
+ BKE_image_print_memlist();
+ MEM_printmemlist_stats();
+ }
+ }
+
+ /* FREE */
+
+ for (lar= re->lampren.first; lar; lar= lar->next) {
+ freeshadowbuf(lar);
+ if (lar->jitter) MEM_freeN(lar->jitter);
+ if (lar->shadsamp) MEM_freeN(lar->shadsamp);
+ if (lar->sunsky) MEM_freeN(lar->sunsky);
+ curvemapping_free(lar->curfalloff);
+ }
+
+ free_volume_precache(re);
+
+ BLI_freelistN(&re->lampren);
+ BLI_freelistN(&re->lights);
+
+ free_renderdata_tables(re);
+
+ /* free orco */
+ free_mesh_orco_hash(re);
+
+ if (re->main) {
+ end_render_materials(re->main);
+ end_render_textures(re);
+ free_pointdensities(re);
+ }
+
+ free_camera_inside_volumes(re);
+
+ if (re->wrld.aosphere) {
+ MEM_freeN(re->wrld.aosphere);
+ re->wrld.aosphere= NULL;
+ if (re->scene && re->scene->world)
+ re->scene->world->aosphere= NULL;
+ }
+ if (re->wrld.aotables) {
+ MEM_freeN(re->wrld.aotables);
+ re->wrld.aotables= NULL;
+ if (re->scene && re->scene->world)
+ re->scene->world->aotables= NULL;
+ }
+ if (re->r.mode & R_RAYTRACE)
+ free_render_qmcsampler(re);
+
+ if (re->r.mode & R_RAYTRACE) freeraytree(re);
+
+ free_sss(re);
+ free_occ(re);
+ free_strand_surface(re);
+
+ re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
+ re->i.convertdone = false;
+
+ re->bakebuf= NULL;
+
+ if (re->scene)
+ if (re->scene->r.scemode & R_FREE_IMAGE)
+ if ((re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0)
+ BKE_image_free_all_textures();
+
+ if (re->memArena) {
+ BLI_memarena_free(re->memArena);
+ re->memArena = NULL;
+ }
+}
+
+static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob)
+{
+ if (is_object_hidden(re, ob))
+ return 0;
+
+ /* Only handle dupli-hiding here if there is no particle systems. Else, let those handle show/noshow. */
+ if (!ob->particlesystem.first) {
+ if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) {
+ return 0;
+ }
+ }
+
+ /* don't add non-basic meta objects, ends up having renderobjects with no geometry */
+ if (ob->type == OB_MBALL && ob!=BKE_mball_basis_find(re->eval_ctx, re->scene, ob))
+ return 0;
+
+ if (nolamps && (ob->type==OB_LAMP))
+ return 0;
+
+ if (onlyselected && (ob!=actob && !(ob->flag & SELECT)))
+ return 0;
+
+ return 1;
+}
+
+static int allow_render_dupli_instance(Render *UNUSED(re), DupliObject *dob, Object *obd)
+{
+ ParticleSystem *psys;
+ Material *ma;
+ short a, *totmaterial;
+
+ /* don't allow objects with halos. we need to have
+ * all halo's to sort them globally in advance */
+ totmaterial= give_totcolp(obd);
+
+ if (totmaterial) {
+ for (a= 0; a<*totmaterial; a++) {
+ ma= give_current_material(obd, a + 1);
+ if (ma && (ma->material_type == MA_TYPE_HALO))
+ return 0;
+ }
+ }
+
+ for (psys=obd->particlesystem.first; psys; psys=psys->next)
+ if (!ELEM(psys->part->ren_as, PART_DRAW_BB, PART_DRAW_LINE, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR))
+ return 0;
+
+ /* don't allow lamp, animated duplis, or radio render */
+ return (render_object_type(obd->type) &&
+ (!(dob->type == OB_DUPLIGROUP) || !dob->animated));
+}
+
+static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, int level, int enable)
+{
+ /* ugly function, but we need to set particle systems to their render
+ * settings before calling object_duplilist, to get render level duplis */
+ Group *group;
+ GroupObject *go;
+ ParticleSystem *psys;
+ DerivedMesh *dm;
+
+ if (re->r.scemode & R_VIEWPORT_PREVIEW)
+ return;
+
+ if (level >= MAX_DUPLI_RECUR)
+ return;
+
+ if (ob->transflag & OB_DUPLIPARTS) {
+ for (psys=ob->particlesystem.first; psys; psys=psys->next) {
+ if (ELEM(psys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
+ if (enable)
+ psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
+ else
+ psys_render_restore(ob, psys);
+ }
+ }
+
+ if (enable) {
+ /* this is to make sure we get render level duplis in groups:
+ * the derivedmesh must be created before init_render_mesh,
+ * since object_duplilist does dupliparticles before that */
+ dm = mesh_create_derived_render(re->scene, ob, CD_MASK_RENDER_INTERNAL);
+ dm->release(dm);
+
+ for (psys=ob->particlesystem.first; psys; psys=psys->next)
+ psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
+ }
+ }
+
+ if (ob->dup_group==NULL) return;
+ group= ob->dup_group;
+
+ for (go= group->gobject.first; go; go= go->next)
+ dupli_render_particle_set(re, go->ob, timeoffset, level+1, enable);
+}
+
+static int get_vector_renderlayers(Scene *sce)
+{
+ SceneRenderLayer *srl;
+ unsigned int lay= 0;
+
+ for (srl= sce->r.layers.first; srl; srl= srl->next)
+ if (srl->passflag & SCE_PASS_VECTOR)
+ lay |= srl->lay;
+
+ return lay;
+}
+
+static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, int onlyselected, Object *actob, int timeoffset, int level)
+{
+ GroupObject *go;
+ Object *ob;
+
+ /* simple preventing of too deep nested groups */
+ if (level>MAX_DUPLI_RECUR) return;
+
+ /* recursively go into dupligroups to find objects with OB_RENDER_DUPLI
+ * that were not created yet */
+ for (go= group->gobject.first; go; go= go->next) {
+ ob= go->ob;
+
+ if (ob->flag & OB_DONE) {
+ if (ob->transflag & OB_RENDER_DUPLI) {
+ if (allow_render_object(re, ob, nolamps, onlyselected, actob)) {
+ init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
+ ob->transflag &= ~OB_RENDER_DUPLI;
+
+ if (ob->dup_group)
+ add_group_render_dupli_obs(re, ob->dup_group, nolamps, onlyselected, actob, timeoffset, level+1);
+ }
+ }
+ }
+ }
+}
+
+static void database_init_objects(Render *re, unsigned int renderlay, int nolamps, int onlyselected, Object *actob, int timeoffset)
+{
+ Base *base;
+ Object *ob;
+ Group *group;
+ ObjectInstanceRen *obi;
+ Scene *sce_iter;
+ int lay, vectorlay;
+
+ /* for duplis we need the Object texture mapping to work as if
+ * untransformed, set_dupli_tex_mat sets the matrix to allow that
+ * NULL is just for init */
+ set_dupli_tex_mat(NULL, NULL, NULL, NULL);
+
+ /* loop over all objects rather then using SETLOOPER because we may
+ * reference an mtex-mapped object which isn't rendered or is an
+ * empty in a dupli group. We could scan all render material/lamp/world
+ * mtex's for mapto objects but its easier just to set the
+ * 'imat' / 'imat_ren' on all and unlikely to be a performance hit
+ * See bug: [#28744] - campbell */
+ for (ob= re->main->object.first; ob; ob= ob->id.next) {
+ float mat[4][4];
+
+ /* imat objects has to be done here, since displace can have texture using Object map-input */
+ mul_m4_m4m4(mat, re->viewmat, ob->obmat);
+ invert_m4_m4(ob->imat_ren, mat);
+ copy_m4_m4(ob->imat, ob->imat_ren);
+ /* each object should only be rendered once */
+ ob->flag &= ~OB_DONE;
+ ob->transflag &= ~OB_RENDER_DUPLI;
+ }
+
+ for (SETLOOPER(re->scene, sce_iter, base)) {
+ ob= base->object;
+
+ /* in the prev/next pass for making speed vectors, avoid creating
+ * objects that are not on a renderlayer with a vector pass, can
+ * save a lot of time in complex scenes */
+ vectorlay= get_vector_renderlayers(re->scene);
+ lay= (timeoffset)? renderlay & vectorlay: renderlay;
+
+ /* if the object has been restricted from rendering in the outliner, ignore it */
+ if (is_object_restricted(re, ob)) continue;
+
+ /* OB_DONE means the object itself got duplicated, so was already converted */
+ if (ob->flag & OB_DONE) {
+ /* OB_RENDER_DUPLI means instances for it were already created, now
+ * it still needs to create the ObjectRen containing the data */
+ if (ob->transflag & OB_RENDER_DUPLI) {
+ if (allow_render_object(re, ob, nolamps, onlyselected, actob)) {
+ init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
+ ob->transflag &= ~OB_RENDER_DUPLI;
+ }
+ }
+ }
+ else if ((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->lay)) ) {
+ if ((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) {
+ DupliObject *dob;
+ ListBase *duplilist;
+ DupliApplyData *duplilist_apply_data = NULL;
+ int i;
+
+ /* create list of duplis generated by this object, particle
+ * system need to have render settings set for dupli particles */
+ dupli_render_particle_set(re, ob, timeoffset, 0, 1);
+ duplilist = object_duplilist(re->eval_ctx, re->scene, ob);
+ duplilist_apply_data = duplilist_apply(ob, NULL, duplilist);
+ /* postpone 'dupli_render_particle_set', since RE_addRenderInstance reads
+ * index values from 'dob->persistent_id[0]', referencing 'psys->child' which
+ * may be smaller once the particle system is restored, see: T45563. */
+
+ for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) {
+ DupliExtraData *dob_extra = &duplilist_apply_data->extra[i];
+ Object *obd= dob->ob;
+
+ copy_m4_m4(obd->obmat, dob->mat);
+
+ /* group duplis need to set ob matrices correct, for deform. so no_draw is part handled */
+ if (!(obd->transflag & OB_RENDER_DUPLI) && dob->no_draw)
+ continue;
+
+ if (is_object_hidden(re, obd))
+ continue;
+
+ if (obd->type==OB_MBALL)
+ continue;
+
+ if (!allow_render_object(re, obd, nolamps, onlyselected, actob))
+ continue;
+
+ if (allow_render_dupli_instance(re, dob, obd)) {
+ ParticleSystem *psys;
+ ObjectRen *obr = NULL;
+ int psysindex;
+ float mat[4][4];
+
+ obi=NULL;
+
+ /* instances instead of the actual object are added in two cases, either
+ * this is a duplivert/face/particle, or it is a non-animated object in
+ * a dupligroup that has already been created before */
+ if (dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, 0))) {
+ mul_m4_m4m4(mat, re->viewmat, dob->mat);
+ /* ob = particle system, use that layer */
+ obi = RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], 0, mat, ob->lay, dob);
+
+ /* fill in instance variables for texturing */
+ set_dupli_tex_mat(re, obi, dob, dob_extra->obmat);
+ if (dob->type != OB_DUPLIGROUP) {
+ copy_v3_v3(obi->dupliorco, dob->orco);
+ obi->dupliuv[0]= dob->uv[0];
+ obi->dupliuv[1]= dob->uv[1];
+ }
+ else {
+ /* for the second case, setup instance to point to the already
+ * created object, and possibly setup instances if this object
+ * itself was duplicated. for the first case find_dupli_instances
+ * will be called later. */
+ assign_dupligroup_dupli(re, obi, obr, dob);
+ if (obd->transflag & OB_RENDER_DUPLI)
+ find_dupli_instances(re, obr, dob);
+ }
+ }
+
+ /* same logic for particles, each particle system has it's own object, so
+ * need to go over them separately */
+ psysindex= 1;
+ for (psys=obd->particlesystem.first; psys; psys=psys->next) {
+ if (dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, psysindex))) {
+ if (obi == NULL)
+ mul_m4_m4m4(mat, re->viewmat, dob->mat);
+ obi = RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], psysindex++, mat, obd->lay, dob);
+
+ set_dupli_tex_mat(re, obi, dob, dob_extra->obmat);
+ if (dob->type != OB_DUPLIGROUP) {
+ copy_v3_v3(obi->dupliorco, dob->orco);
+ obi->dupliuv[0]= dob->uv[0];
+ obi->dupliuv[1]= dob->uv[1];
+ }
+ else {
+ assign_dupligroup_dupli(re, obi, obr, dob);
+ if (obd->transflag & OB_RENDER_DUPLI)
+ find_dupli_instances(re, obr, dob);
+ }
+ }
+ }
+
+ if (obi==NULL)
+ /* can't instance, just create the object */
+ init_render_object(re, obd, ob, dob, dob_extra->obmat, timeoffset);
+
+ if (dob->type != OB_DUPLIGROUP) {
+ obd->flag |= OB_DONE;
+ obd->transflag |= OB_RENDER_DUPLI;
+ }
+ }
+ else
+ init_render_object(re, obd, ob, dob, dob_extra->obmat, timeoffset);
+
+ if (re->test_break(re->tbh)) break;
+ }
+
+ /* restore particle system */
+ dupli_render_particle_set(re, ob, timeoffset, 0, false);
+
+ if (duplilist_apply_data) {
+ duplilist_restore(duplilist, duplilist_apply_data);
+ duplilist_free_apply_data(duplilist_apply_data);
+ }
+ free_object_duplilist(duplilist);
+
+ if (allow_render_object(re, ob, nolamps, onlyselected, actob))
+ init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
+ }
+ else if (allow_render_object(re, ob, nolamps, onlyselected, actob))
+ init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
+ }
+
+ if (re->test_break(re->tbh)) break;
+ }
+
+ /* objects in groups with OB_RENDER_DUPLI set still need to be created,
+ * since they may not be part of the scene */
+ for (group= re->main->group.first; group; group=group->id.next)
+ add_group_render_dupli_obs(re, group, nolamps, onlyselected, actob, timeoffset, 0);
+
+ if (!re->test_break(re->tbh))
+ RE_makeRenderInstances(re);
+}
+
+/* used to be 'rotate scene' */
+void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int lay, int use_camera_view)
+{
+ Scene *sce;
+ Object *camera;
+ float mat[4][4];
+ float amb[3];
+
+ re->main= bmain;
+ re->scene= scene;
+ re->lay= lay;
+
+ if (re->r.scemode & R_VIEWPORT_PREVIEW)
+ re->scene_color_manage = BKE_scene_check_color_management_enabled(scene);
+
+ /* scene needs to be set to get camera */
+ camera= RE_GetCamera(re);
+
+ /* per second, per object, stats print this */
+ re->i.infostr= "Preparing Scene data";
+ re->i.cfra= scene->r.cfra;
+ BLI_strncpy(re->i.scene_name, scene->id.name + 2, sizeof(re->i.scene_name));
+
+ /* XXX add test if dbase was filled already? */
+
+ re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "render db arena");
+ re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
+ re->lights.first= re->lights.last= NULL;
+ re->lampren.first= re->lampren.last= NULL;
+
+ re->i.partsdone = false; /* signal now in use for previewrender */
+
+ /* in localview, lamps are using normal layers, objects only local bits */
+ if (re->lay & 0xFF000000)
+ lay &= 0xFF000000;
+
+ /* applies changes fully */
+ if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) {
+ BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay);
+ render_update_anim_renderdata(re, &re->scene->r);
+ }
+
+ /* if no camera, viewmat should have been set! */
+ if (use_camera_view && camera) {
+ /* called before but need to call again in case of lens animation from the
+ * above call to BKE_scene_update_for_newframe, fixes bug. [#22702].
+ * following calls don't depend on 'RE_SetCamera' */
+ RE_SetCamera(re, camera);
+ RE_GetCameraModelMatrix(re, camera, mat);
+ invert_m4(mat);
+ RE_SetView(re, mat);
+
+ /* force correct matrix for scaled cameras */
+ DAG_id_tag_update_ex(re->main, &camera->id, OB_RECALC_OB);
+ }
+
+ /* store for incremental render, viewmat rotates dbase */
+ copy_m4_m4(re->viewmat_orig, re->viewmat);
+
+ init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
+ if (re->r.mode & R_RAYTRACE) {
+ init_render_qmcsampler(re);
+
+ if (re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT))
+ if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
+ init_ao_sphere(re, &re->wrld);
+ }
+
+ /* still bad... doing all */
+ init_render_textures(re);
+ copy_v3_v3(amb, &re->wrld.ambr);
+ init_render_materials(re->main, re->r.mode, amb, (re->r.scemode & R_BUTS_PREVIEW) == 0);
+ set_node_shader_lamp_loop(shade_material_loop);
+
+ /* MAKE RENDER DATA */
+ database_init_objects(re, lay, 0, 0, NULL, 0);
+
+ if (!re->test_break(re->tbh)) {
+ set_material_lightgroups(re);
+ for (sce= re->scene; sce; sce= sce->set)
+ set_renderlayer_lightgroups(re, sce);
+
+ /* for now some clumsy copying still */
+ re->i.totvert= re->totvert;
+ re->i.totface= re->totvlak;
+ re->i.totstrand= re->totstrand;
+ re->i.tothalo= re->tothalo;
+ re->i.totlamp= re->totlamp;
+ re->stats_draw(re->sdh, &re->i);
+ }
+}
+
+void RE_Database_Preprocess(Render *re)
+{
+ if (!re->test_break(re->tbh)) {
+ int tothalo;
+
+ tothalo= re->tothalo;
+ sort_halos(re, tothalo);
+
+ init_camera_inside_volumes(re);
+
+ re->i.infostr = IFACE_("Creating Shadowbuffers");
+ re->stats_draw(re->sdh, &re->i);
+
+ /* SHADOW BUFFER */
+ threaded_makeshadowbufs(re);
+
+ /* old code checked for internal render (aka not yafray) */
+ {
+ /* raytree */
+ if (!re->test_break(re->tbh)) {
+ if (re->r.mode & R_RAYTRACE) {
+ makeraytree(re);
+ }
+ }
+ /* ENVIRONMENT MAPS */
+ if (!re->test_break(re->tbh))
+ make_envmaps(re);
+
+ /* point density texture */
+ if (!re->test_break(re->tbh))
+ make_pointdensities(re);
+ /* voxel data texture */
+ if (!re->test_break(re->tbh))
+ make_voxeldata(re);
+ }
+
+ if (!re->test_break(re->tbh))
+ project_renderdata(re, projectverto, (re->r.mode & R_PANORAMA) != 0, 0, 1);
+
+ /* Occlusion */
+ if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh))
+ if (re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
+ if (re->r.mode & R_SHADOW)
+ make_occ_tree(re);
+
+ /* SSS */
+ if ((re->r.mode & R_SSS) && !re->test_break(re->tbh))
+ make_sss_tree(re);
+
+ if (!re->test_break(re->tbh))
+ if (re->r.mode & R_RAYTRACE)
+ volume_precache(re);
+ }
+
+ re->i.convertdone = true;
+
+ if (re->test_break(re->tbh))
+ RE_Database_Free(re);
+
+ re->i.infostr = NULL;
+ re->stats_draw(re->sdh, &re->i);
+}
+
+/* exported call to recalculate hoco for vertices, when winmat changed */
+void RE_DataBase_ApplyWindow(Render *re)
+{
+ project_renderdata(re, projectverto, 0, 0, 0);
+}
+
+/* exported call to rotate render data again, when viewmat changed */
+void RE_DataBase_IncrementalView(Render *re, float viewmat[4][4], int restore)
+{
+ float oldviewinv[4][4], tmat[4][4];
+
+ invert_m4_m4(oldviewinv, re->viewmat_orig);
+
+ /* we have to correct for the already rotated vertexcoords */
+ mul_m4_m4m4(tmat, viewmat, oldviewinv);
+
+ copy_m4_m4(re->viewmat, viewmat);
+ invert_m4_m4(re->viewinv, re->viewmat);
+
+ init_camera_inside_volumes(re);
+
+ env_rotate_scene(re, tmat, !restore);
+
+ /* SSS points distribution depends on view */
+ if ((re->r.mode & R_SSS) && !re->test_break(re->tbh))
+ make_sss_tree(re);
+}
+
+
+void RE_DataBase_GetView(Render *re, float mat[4][4])
+{
+ copy_m4_m4(mat, re->viewmat);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Speed Vectors */
+/* ------------------------------------------------------------------------- */
+
+static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int lay, int timeoffset)
+{
+ Object *camera= RE_GetCamera(re);
+ float mat[4][4];
+
+ re->scene= scene;
+ re->lay= lay;
+
+ /* XXX add test if dbase was filled already? */
+
+ re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vector render db arena");
+ re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
+ re->i.totface=re->i.totvert=re->i.totstrand=re->i.totlamp=re->i.tothalo= 0;
+ re->lights.first= re->lights.last= NULL;
+
+ /* in localview, lamps are using normal layers, objects only local bits */
+ if (re->lay & 0xFF000000)
+ lay &= 0xFF000000;
+
+ /* applies changes fully */
+ scene->r.cfra += timeoffset;
+ BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay);
+
+ /* if no camera, viewmat should have been set! */
+ if (camera) {
+ RE_GetCameraModelMatrix(re, camera, mat);
+ normalize_m4(mat);
+ invert_m4(mat);
+ RE_SetView(re, mat);
+ }
+
+ /* MAKE RENDER DATA */
+ database_init_objects(re, lay, 0, 0, NULL, timeoffset);
+
+ if (!re->test_break(re->tbh))
+ project_renderdata(re, projectverto, (re->r.mode & R_PANORAMA) != 0, 0, 1);
+
+ /* do this in end, particles for example need cfra */
+ scene->r.cfra -= timeoffset;
+}
+
+/* choose to use static, to prevent giving too many args to this call */
+static void speedvector_project(Render *re, float zco[2], const float co[3], const float ho[4])
+{
+ static float pixelphix=0.0f, pixelphiy=0.0f, zmulx=0.0f, zmuly=0.0f;
+ static int pano= 0;
+ float div;
+
+ /* initialize */
+ if (re) {
+ pano= re->r.mode & R_PANORAMA;
+
+ /* precalculate amount of radians 1 pixel rotates */
+ if (pano) {
+ /* size of 1 pixel mapped to viewplane coords */
+ float psize;
+
+ psize = BLI_rctf_size_x(&re->viewplane) / (float)re->winx;
+ /* x angle of a pixel */
+ pixelphix = atan(psize / re->clipsta);
+
+ psize = BLI_rctf_size_y(&re->viewplane) / (float)re->winy;
+ /* y angle of a pixel */
+ pixelphiy = atan(psize / re->clipsta);
+ }
+ zmulx= re->winx/2;
+ zmuly= re->winy/2;
+
+ return;
+ }
+
+ /* now map hocos to screenspace, uses very primitive clip still */
+ if (ho[3]<0.1f) div= 10.0f;
+ else div= 1.0f/ho[3];
+
+ /* use cylinder projection */
+ if (pano) {
+ float vec[3], ang;
+ /* angle between (0, 0, -1) and (co) */
+ copy_v3_v3(vec, co);
+
+ ang= saacos(-vec[2]/sqrtf(vec[0]*vec[0] + vec[2]*vec[2]));
+ if (vec[0]<0.0f) ang= -ang;
+ zco[0]= ang/pixelphix + zmulx;
+
+ ang= 0.5f*(float)M_PI - saacos(vec[1] / len_v3(vec));
+ zco[1]= ang/pixelphiy + zmuly;
+
+ }
+ else {
+ zco[0]= zmulx*(1.0f+ho[0]*div);
+ zco[1]= zmuly*(1.0f+ho[1]*div);
+ }
+}
+
+static void calculate_speedvector(const float vectors[2], int step, float winsq, float winroot, const float co[3], const float ho[4], float speed[4])
+{
+ float zco[2], len;
+
+ speedvector_project(NULL, zco, co, ho);
+
+ zco[0]= vectors[0] - zco[0];
+ zco[1]= vectors[1] - zco[1];
+
+ /* enable nice masks for hardly moving stuff or float inaccuracy */
+ if (zco[0]<0.1f && zco[0]>-0.1f && zco[1]<0.1f && zco[1]>-0.1f ) {
+ zco[0]= 0.0f;
+ zco[1]= 0.0f;
+ }
+
+ /* maximize speed for image width, otherwise it never looks good */
+ len= zco[0]*zco[0] + zco[1]*zco[1];
+ if (len > winsq) {
+ len= winroot/sqrtf(len);
+ zco[0]*= len;
+ zco[1]*= len;
+ }
+
+ /* note; in main vecblur loop speedvec is negated again */
+ if (step) {
+ speed[2]= -zco[0];
+ speed[3]= -zco[1];
+ }
+ else {
+ speed[0]= zco[0];
+ speed[1]= zco[1];
+ }
+}
+
+static float *calculate_strandsurface_speedvectors(Render *re, ObjectInstanceRen *obi, StrandSurface *mesh)
+{
+ if (mesh->co && mesh->prevco && mesh->nextco) {
+ float winsq= (float)re->winx*(float)re->winy; /* int's can wrap on large images */
+ float winroot= sqrtf(winsq);
+ float (*winspeed)[4];
+ float ho[4], prevho[4], nextho[4], winmat[4][4], vec[2];
+ int a;
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_m4m4(winmat, re->winmat, obi->mat);
+ else
+ copy_m4_m4(winmat, re->winmat);
+
+ winspeed= MEM_callocN(sizeof(float)*4*mesh->totvert, "StrandSurfWin");
+
+ for (a=0; a<mesh->totvert; a++) {
+ projectvert(mesh->co[a], winmat, ho);
+
+ projectvert(mesh->prevco[a], winmat, prevho);
+ speedvector_project(NULL, vec, mesh->prevco[a], prevho);
+ calculate_speedvector(vec, 0, winsq, winroot, mesh->co[a], ho, winspeed[a]);
+
+ projectvert(mesh->nextco[a], winmat, nextho);
+ speedvector_project(NULL, vec, mesh->nextco[a], nextho);
+ calculate_speedvector(vec, 1, winsq, winroot, mesh->co[a], ho, winspeed[a]);
+ }
+
+ return (float *)winspeed;
+ }
+
+ return NULL;
+}
+
+static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *vectors, int step)
+{
+ ObjectRen *obr= obi->obr;
+ VertRen *ver= NULL;
+ StrandRen *strand= NULL;
+ StrandBuffer *strandbuf;
+ StrandSurface *mesh= NULL;
+ float *speed, (*winspeed)[4]=NULL, ho[4], winmat[4][4];
+ float *co1, *co2, *co3, *co4, w[4];
+ float winsq = (float)re->winx * (float)re->winy, winroot = sqrtf(winsq); /* int's can wrap on large images */
+ int a, *face, *index;
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_m4m4(winmat, re->winmat, obi->mat);
+ else
+ copy_m4_m4(winmat, re->winmat);
+
+ if (obr->vertnodes) {
+ for (a=0; a<obr->totvert; a++, vectors+=2) {
+ if ((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+ else ver++;
+
+ speed= RE_vertren_get_winspeed(obi, ver, 1);
+ projectvert(ver->co, winmat, ho);
+ calculate_speedvector(vectors, step, winsq, winroot, ver->co, ho, speed);
+ }
+ }
+
+ if (obr->strandnodes) {
+ strandbuf= obr->strandbuf;
+ mesh= (strandbuf)? strandbuf->surface: NULL;
+
+ /* compute speed vectors at surface vertices */
+ if (mesh)
+ winspeed= (float(*)[4])calculate_strandsurface_speedvectors(re, obi, mesh);
+
+ if (winspeed) {
+ for (a=0; a<obr->totstrand; a++, vectors+=2) {
+ if ((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
+ else strand++;
+
+ index= RE_strandren_get_face(obr, strand, 0);
+ if (index && *index < mesh->totface) {
+ speed= RE_strandren_get_winspeed(obi, strand, 1);
+
+ /* interpolate speed vectors from strand surface */
+ face= mesh->face[*index];
+
+ co1 = mesh->co[face[0]];
+ co2 = mesh->co[face[1]];
+ co3 = mesh->co[face[2]];
+
+ if (face[3]) {
+ co4 = mesh->co[face[3]];
+ interp_weights_quad_v3(w, co1, co2, co3, co4, strand->vert->co);
+ }
+ else {
+ interp_weights_tri_v3(w, co1, co2, co3, strand->vert->co);
+ }
+
+ zero_v4(speed);
+ madd_v4_v4fl(speed, winspeed[face[0]], w[0]);
+ madd_v4_v4fl(speed, winspeed[face[1]], w[1]);
+ madd_v4_v4fl(speed, winspeed[face[2]], w[2]);
+ if (face[3])
+ madd_v4_v4fl(speed, winspeed[face[3]], w[3]);
+ }
+ }
+
+ MEM_freeN(winspeed);
+ }
+ }
+}
+
+static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *vectors, int step)
+{
+ ObjectRen *obr= obi->obr;
+ Object *fsob= obr->ob;
+ VertRen *ver= NULL;
+ float *speed, div, zco[2], avgvel[4] = {0.0, 0.0, 0.0, 0.0};
+ float zmulx= re->winx/2, zmuly= re->winy/2, len;
+ float winsq = (float)re->winx * (float)re->winy, winroot= sqrtf(winsq); /* int's can wrap on large images */
+ int a, j;
+ float hoco[4], ho[4], fsvec[4], camco[4];
+ float mat[4][4], winmat[4][4];
+ float imat[4][4];
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsob, eModifierType_Fluidsim);
+ FluidsimSettings *fss;
+ FluidVertexVelocity *velarray = NULL;
+
+ /* only one step needed */
+ if (step) return 1;
+
+ if (fluidmd)
+ fss = fluidmd->fss;
+ else
+ return 0;
+
+ copy_m4_m4(mat, re->viewmat);
+ invert_m4_m4(imat, mat);
+
+ /* set first vertex OK */
+ if (!fss->meshVelocities) return 0;
+
+ if ( obr->totvert != fss->totvert) {
+ //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", obr->totvert, fsob->fluidsimSettings->meshSurface->totvert); // DEBUG
+ return 0;
+ }
+
+ velarray = fss->meshVelocities;
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_m4m4(winmat, re->winmat, obi->mat);
+ else
+ copy_m4_m4(winmat, re->winmat);
+
+ /* (bad) HACK calculate average velocity */
+ /* better solution would be fixing getVelocityAt() in intern/elbeem/intern/solver_util.cpp
+ * so that also small drops/little water volumes return a velocity != 0.
+ * But I had no luck in fixing that function - DG */
+ for (a=0; a<obr->totvert; a++) {
+ for (j=0;j<3;j++) avgvel[j] += velarray[a].vel[j];
+
+ }
+ for (j=0;j<3;j++) avgvel[j] /= (float)(obr->totvert);
+
+
+ for (a=0; a<obr->totvert; a++, vectors+=2) {
+ if ((a & 255)==0)
+ ver= obr->vertnodes[a>>8].vert;
+ else
+ ver++;
+
+ /* get fluid velocity */
+ fsvec[3] = 0.0f;
+ //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.0; fsvec[2] = 2.0f; // NT fixed test
+ for (j=0;j<3;j++) fsvec[j] = velarray[a].vel[j];
+
+ /* (bad) HACK insert average velocity if none is there (see previous comment) */
+ if ((fsvec[0] == 0.0f) && (fsvec[1] == 0.0f) && (fsvec[2] == 0.0f)) {
+ fsvec[0] = avgvel[0];
+ fsvec[1] = avgvel[1];
+ fsvec[2] = avgvel[2];
+ }
+
+ /* transform (=rotate) to cam space */
+ camco[0] = dot_v3v3(imat[0], fsvec);
+ camco[1] = dot_v3v3(imat[1], fsvec);
+ camco[2] = dot_v3v3(imat[2], fsvec);
+
+ /* get homogeneous coordinates */
+ projectvert(camco, winmat, hoco);
+ projectvert(ver->co, winmat, ho);
+
+ /* now map hocos to screenspace, uses very primitive clip still */
+ /* use ho[3] of original vertex, xy component of vel. direction */
+ if (ho[3]<0.1f) div= 10.0f;
+ else div= 1.0f/ho[3];
+ zco[0]= zmulx*hoco[0]*div;
+ zco[1]= zmuly*hoco[1]*div;
+
+ /* maximize speed as usual */
+ len= zco[0]*zco[0] + zco[1]*zco[1];
+ if (len > winsq) {
+ len= winroot/sqrtf(len);
+ zco[0]*= len; zco[1]*= len;
+ }
+
+ speed= RE_vertren_get_winspeed(obi, ver, 1);
+ /* set both to the same value */
+ speed[0]= speed[2]= zco[0];
+ speed[1]= speed[3]= zco[1];
+ //if (a < 20) fprintf(stderr,"speed %d %f,%f | camco %f,%f,%f | hoco %f,%f,%f,%f\n", a, speed[0], speed[1], camco[0],camco[1], camco[2], hoco[0],hoco[1], hoco[2],hoco[3]); // NT DEBUG
+ }
+
+ return 1;
+}
+
+/* makes copy per object of all vectors */
+/* result should be that we can free entire database */
+static void copy_dbase_object_vectors(Render *re, ListBase *lb)
+{
+ ObjectInstanceRen *obi, *obilb;
+ ObjectRen *obr;
+ VertRen *ver= NULL;
+ float *vec, ho[4], winmat[4][4];
+ int a, totvector;
+
+ for (obi= re->instancetable.first; obi; obi= obi->next) {
+ obr= obi->obr;
+
+ obilb= MEM_mallocN(sizeof(ObjectInstanceRen), "ObInstanceVector");
+ memcpy(obilb, obi, sizeof(ObjectInstanceRen));
+ BLI_addtail(lb, obilb);
+
+ obilb->totvector= totvector= obr->totvert;
+
+ if (totvector > 0) {
+ vec= obilb->vectors= MEM_mallocN(2*sizeof(float)*totvector, "vector array");
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_m4m4(winmat, re->winmat, obi->mat);
+ else
+ copy_m4_m4(winmat, re->winmat);
+
+ for (a=0; a<obr->totvert; a++, vec+=2) {
+ if ((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+ else ver++;
+
+ projectvert(ver->co, winmat, ho);
+ speedvector_project(NULL, vec, ver->co, ho);
+ }
+ }
+ }
+}
+
+static void free_dbase_object_vectors(ListBase *lb)
+{
+ ObjectInstanceRen *obi;
+
+ for (obi= lb->first; obi; obi= obi->next)
+ if (obi->vectors)
+ MEM_freeN(obi->vectors);
+ BLI_freelistN(lb);
+}
+
+void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned int lay)
+{
+ ObjectInstanceRen *obi, *oldobi;
+ StrandSurface *mesh;
+ ListBase *table;
+ ListBase oldtable= {NULL, NULL}, newtable= {NULL, NULL};
+ ListBase strandsurface;
+ int step;
+
+ re->i.infostr = IFACE_("Calculating previous frame vectors");
+ re->r.mode |= R_SPEED;
+
+ speedvector_project(re, NULL, NULL, NULL); /* initializes projection code */
+
+ /* creates entire dbase */
+ database_fromscene_vectors(re, sce, lay, -1);
+
+ /* copy away vertex info */
+ copy_dbase_object_vectors(re, &oldtable);
+
+ /* free dbase and make the future one */
+ strandsurface= re->strandsurface;
+ memset(&re->strandsurface, 0, sizeof(ListBase));
+ re->i.convertdone = true;
+ RE_Database_Free(re);
+ re->strandsurface= strandsurface;
+
+ if (!re->test_break(re->tbh)) {
+ /* creates entire dbase */
+ re->i.infostr = IFACE_("Calculating next frame vectors");
+
+ database_fromscene_vectors(re, sce, lay, +1);
+ }
+ /* copy away vertex info */
+ copy_dbase_object_vectors(re, &newtable);
+
+ /* free dbase and make the real one */
+ strandsurface= re->strandsurface;
+ memset(&re->strandsurface, 0, sizeof(ListBase));
+ re->i.convertdone = true;
+ RE_Database_Free(re);
+ re->strandsurface= strandsurface;
+
+ if (!re->test_break(re->tbh)) {
+ RE_Database_FromScene(re, bmain, sce, lay, 1);
+ RE_Database_Preprocess(re);
+ }
+
+ if (!re->test_break(re->tbh)) {
+ int vectorlay= get_vector_renderlayers(re->scene);
+
+ for (step= 0; step<2; step++) {
+
+ if (step)
+ table= &newtable;
+ else
+ table= &oldtable;
+
+ oldobi= table->first;
+ for (obi= re->instancetable.first; obi && oldobi; obi= obi->next) {
+ int ok= 1;
+ FluidsimModifierData *fluidmd;
+
+ if (!(obi->lay & vectorlay))
+ continue;
+
+ obi->totvector= obi->obr->totvert;
+
+ /* find matching object in old table */
+ if (oldobi->ob!=obi->ob || oldobi->par!=obi->par || oldobi->index!=obi->index || oldobi->psysindex!=obi->psysindex) {
+ ok= 0;
+ for (oldobi= table->first; oldobi; oldobi= oldobi->next)
+ if (oldobi->ob==obi->ob && oldobi->par==obi->par && oldobi->index==obi->index && oldobi->psysindex==obi->psysindex)
+ break;
+ if (oldobi==NULL)
+ oldobi= table->first;
+ else
+ ok= 1;
+ }
+ if (ok==0) {
+ printf("speed table: missing object %s\n", obi->ob->id.name + 2);
+ continue;
+ }
+
+ /* NT check for fluidsim special treatment */
+ fluidmd = (FluidsimModifierData *)modifiers_findByType(obi->ob, eModifierType_Fluidsim);
+ if (fluidmd && fluidmd->fss && (fluidmd->fss->type & OB_FLUIDSIM_DOMAIN)) {
+ /* use preloaded per vertex simulation data, only does calculation for step=1 */
+ /* NOTE/FIXME - velocities and meshes loaded unnecessarily often during the database_fromscene_vectors calls... */
+ load_fluidsimspeedvectors(re, obi, oldobi->vectors, step);
+ }
+ else {
+ /* check if both have same amounts of vertices */
+ if (obi->totvector==oldobi->totvector)
+ calculate_speedvectors(re, obi, oldobi->vectors, step);
+ else
+ printf("Warning: object %s has different amount of vertices or strands on other frame\n", obi->ob->id.name + 2);
+ } /* not fluidsim */
+
+ oldobi= oldobi->next;
+ }
+ }
+ }
+
+ free_dbase_object_vectors(&oldtable);
+ free_dbase_object_vectors(&newtable);
+
+ for (mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
+ if (mesh->prevco) {
+ MEM_freeN(mesh->prevco);
+ mesh->prevco= NULL;
+ }
+ if (mesh->nextco) {
+ MEM_freeN(mesh->nextco);
+ mesh->nextco= NULL;
+ }
+ }
+
+ re->i.infostr = NULL;
+ re->stats_draw(re->sdh, &re->i);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* Baking */
+/* ------------------------------------------------------------------------- */
+
+/* setup for shaded view or bake, so only lamps and materials are initialized */
+/* type:
+ * RE_BAKE_LIGHT: for shaded view, only add lamps
+ * RE_BAKE_ALL: for baking, all lamps and objects
+ * RE_BAKE_NORMALS:for baking, no lamps and only selected objects
+ * RE_BAKE_AO: for baking, no lamps, but all objects
+ * RE_BAKE_TEXTURE:for baking, no lamps, only selected objects
+ * RE_BAKE_VERTEX_COLORS:for baking, no lamps, only selected objects
+ * RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects
+ * RE_BAKE_DERIVATIVE:for baking, no lamps, only selected objects
+ * RE_BAKE_SHADOW: for baking, only shadows, but all objects
+ */
+void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, const int type, Object *actob)
+{
+ Object *camera;
+ float mat[4][4];
+ float amb[3];
+ const short onlyselected= !ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW, RE_BAKE_AO, RE_BAKE_VERTEX_COLORS);
+ const short nolamps= ELEM(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_VERTEX_COLORS);
+
+ re->main= bmain;
+ re->scene= scene;
+ re->lay= lay;
+
+ /* renderdata setup and exceptions */
+ render_copy_renderdata(&re->r, &scene->r);
+
+ RE_init_threadcount(re);
+
+ re->flag |= R_BAKING;
+ re->excludeob= actob;
+ if (actob)
+ re->flag |= R_BAKE_TRACE;
+
+ if (type==RE_BAKE_NORMALS && re->r.bake_normal_space==R_BAKE_SPACE_TANGENT)
+ re->flag |= R_NEED_TANGENT;
+
+ if (type==RE_BAKE_VERTEX_COLORS)
+ re->flag |= R_NEED_VCOL;
+
+ if (!actob && ELEM(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_VERTEX_COLORS)) {
+ re->r.mode &= ~R_SHADOW;
+ re->r.mode &= ~R_RAYTRACE;
+ }
+
+ if (!actob && (type==RE_BAKE_SHADOW)) {
+ re->r.mode |= R_SHADOW;
+ }
+
+ /* setup render stuff */
+ re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "bake db arena");
+
+ re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
+ re->lights.first= re->lights.last= NULL;
+ re->lampren.first= re->lampren.last= NULL;
+
+ /* in localview, lamps are using normal layers, objects only local bits */
+ if (re->lay & 0xFF000000)
+ lay &= 0xFF000000;
+
+ camera= RE_GetCamera(re);
+
+ /* if no camera, set unit */
+ if (camera) {
+ normalize_m4_m4(mat, camera->obmat);
+ invert_m4(mat);
+ RE_SetView(re, mat);
+ }
+ else {
+ unit_m4(mat);
+ RE_SetView(re, mat);
+ }
+ copy_m3_m4(re->imat, re->viewinv);
+
+ /* TODO: deep shadow maps + baking + strands */
+ /* strands use the window matrix and view size, there is to correct
+ * window matrix but at least avoids malloc and crash loop [#27807] */
+ unit_m4(re->winmat);
+ re->winx= re->winy= 256;
+ /* done setting dummy values */
+
+ init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
+ if (re->r.mode & R_RAYTRACE) {
+ init_render_qmcsampler(re);
+
+ if (re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT))
+ if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
+ init_ao_sphere(re, &re->wrld);
+ }
+
+ /* still bad... doing all */
+ init_render_textures(re);
+
+ copy_v3_v3(amb, &re->wrld.ambr);
+ init_render_materials(re->main, re->r.mode, amb, true);
+
+ set_node_shader_lamp_loop(shade_material_loop);
+
+ /* MAKE RENDER DATA */
+ database_init_objects(re, lay, nolamps, onlyselected, actob, 0);
+
+ set_material_lightgroups(re);
+
+ /* SHADOW BUFFER */
+ if (type!=RE_BAKE_LIGHT)
+ if (re->r.mode & R_SHADOW)
+ threaded_makeshadowbufs(re);
+
+ /* raytree */
+ if (!re->test_break(re->tbh))
+ if (re->r.mode & R_RAYTRACE)
+ makeraytree(re);
+
+ /* point density texture */
+ if (!re->test_break(re->tbh))
+ make_pointdensities(re);
+
+ /* voxel data texture */
+ if (!re->test_break(re->tbh))
+ make_voxeldata(re);
+
+ /* occlusion */
+ if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh))
+ if (re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
+ if (re->r.mode & R_SHADOW)
+ make_occ_tree(re);
+
+ re->i.convertdone = true;
+}
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
new file mode 100644
index 00000000000..85a6af92a28
--- /dev/null
+++ b/source/blender/render/intern/source/envmap.c
@@ -0,0 +1,822 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/envmap.c
+ * \ingroup render
+ */
+
+#include <math.h>
+#include <string.h>
+
+/* external modules: */
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+#include "BLT_translation.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h" /* for rectcpy */
+
+#include "DNA_group_types.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
+
+#include "BKE_main.h"
+#include "BKE_image.h" /* BKE_imbuf_write */
+#include "BKE_texture.h"
+#include "BKE_scene.h"
+
+/* this module */
+#include "render_types.h"
+#include "envmap.h"
+#include "renderdatabase.h"
+#include "renderpipeline.h"
+#include "texture.h"
+#include "zbuf.h"
+#include "render_result.h"
+
+/* ------------------------------------------------------------------------- */
+
+static void envmap_split_ima(EnvMap *env, ImBuf *ibuf)
+{
+ int dx, part;
+
+ /* after lock we test cube[1], if set the other thread has done it fine */
+ BLI_thread_lock(LOCK_IMAGE);
+ if (env->cube[1] == NULL) {
+
+ BKE_texture_envmap_free_data(env);
+
+ dx = ibuf->y;
+ dx /= 2;
+ if (3 * dx == ibuf->x) {
+ env->type = ENV_CUBE;
+ env->ok = ENV_OSA;
+ }
+ else if (ibuf->x == ibuf->y) {
+ env->type = ENV_PLANE;
+ env->ok = ENV_OSA;
+ }
+ else {
+ printf("Incorrect envmap size\n");
+ env->ok = 0;
+ env->ima->ok = 0;
+ }
+
+ if (env->ok) {
+ if (env->type == ENV_CUBE) {
+ for (part = 0; part < 6; part++) {
+ env->cube[part] = IMB_allocImBuf(dx, dx, 24, IB_rect | IB_rectfloat);
+ }
+ IMB_float_from_rect(ibuf);
+
+ IMB_rectcpy(env->cube[0], ibuf,
+ 0, 0, 0, 0, dx, dx);
+ IMB_rectcpy(env->cube[1], ibuf,
+ 0, 0, dx, 0, dx, dx);
+ IMB_rectcpy(env->cube[2], ibuf,
+ 0, 0, 2 * dx, 0, dx, dx);
+ IMB_rectcpy(env->cube[3], ibuf,
+ 0, 0, 0, dx, dx, dx);
+ IMB_rectcpy(env->cube[4], ibuf,
+ 0, 0, dx, dx, dx, dx);
+ IMB_rectcpy(env->cube[5], ibuf,
+ 0, 0, 2 * dx, dx, dx, dx);
+
+ }
+ else { /* ENV_PLANE */
+ env->cube[1] = IMB_dupImBuf(ibuf);
+ IMB_float_from_rect(env->cube[1]);
+ }
+ }
+ }
+ BLI_thread_unlock(LOCK_IMAGE);
+}
+
+/* ------------------------------------------------------------------------- */
+/* ****************** RENDER ********************** */
+
+/* copy current render */
+static Render *envmap_render_copy(Render *re, EnvMap *env)
+{
+ Render *envre;
+ float viewscale;
+ int cuberes;
+
+ envre = RE_NewRender("Envmap");
+
+ env->lastsize = re->r.size;
+ cuberes = (env->cuberes * re->r.size) / 100;
+ cuberes &= 0xFFFC;
+
+ /* this flag has R_ZTRA in it for example */
+ envre->flag = re->flag;
+
+ /* set up renderdata */
+ render_copy_renderdata(&envre->r, &re->r);
+ envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR);
+ BLI_freelistN(&envre->r.layers);
+ BLI_freelistN(&envre->r.views);
+ envre->r.filtertype = 0;
+ envre->r.tilex = envre->r.xsch / 2;
+ envre->r.tiley = envre->r.ysch / 2;
+ envre->r.size = 100;
+ envre->r.yasp = envre->r.xasp = 1;
+
+ RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL);
+ envre->main = re->main;
+ envre->scene = re->scene; /* unsure about this... */
+ envre->scene_color_manage = re->scene_color_manage;
+ envre->lay = re->lay;
+
+ /* view stuff in env render */
+ viewscale = (env->type == ENV_PLANE) ? env->viewscale : 1.0f;
+ RE_SetEnvmapCamera(envre, env->object, viewscale, env->clipsta, env->clipend);
+ copy_m4_m4(envre->viewmat_orig, re->viewmat_orig);
+
+ /* callbacks */
+ envre->display_update = re->display_update;
+ envre->duh = re->duh;
+ envre->test_break = re->test_break;
+ envre->tbh = re->tbh;
+ envre->current_scene_update = re->current_scene_update;
+ envre->suh = re->suh;
+
+ /* and for the evil stuff; copy the database... */
+ envre->totvlak = re->totvlak;
+ envre->totvert = re->totvert;
+ envre->tothalo = re->tothalo;
+ envre->totstrand = re->totstrand;
+ envre->totlamp = re->totlamp;
+ envre->sortedhalos = re->sortedhalos;
+ envre->lights = re->lights;
+ envre->objecttable = re->objecttable;
+ envre->customdata_names = re->customdata_names;
+ envre->raytree = re->raytree;
+ envre->totinstance = re->totinstance;
+ envre->instancetable = re->instancetable;
+ envre->objectinstance = re->objectinstance;
+ envre->qmcsamplers = re->qmcsamplers;
+
+ return envre;
+}
+
+static void envmap_free_render_copy(Render *envre)
+{
+
+ envre->totvlak = 0;
+ envre->totvert = 0;
+ envre->tothalo = 0;
+ envre->totstrand = 0;
+ envre->totlamp = 0;
+ envre->totinstance = 0;
+ envre->sortedhalos = NULL;
+ BLI_listbase_clear(&envre->lights);
+ BLI_listbase_clear(&envre->objecttable);
+ BLI_listbase_clear(&envre->customdata_names);
+ envre->raytree = NULL;
+ BLI_listbase_clear(&envre->instancetable);
+ envre->objectinstance = NULL;
+ envre->qmcsamplers = NULL;
+
+ RE_FreeRender(envre);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void envmap_transmatrix(float mat[4][4], int part)
+{
+ float tmat[4][4], eul[3], rotmat[4][4];
+
+ eul[0] = eul[1] = eul[2] = 0.0;
+
+ if (part == 0) { /* neg z */
+ /* pass */
+ }
+ else if (part == 1) { /* pos z */
+ eul[0] = M_PI;
+ }
+ else if (part == 2) { /* pos y */
+ eul[0] = M_PI / 2.0;
+ }
+ else if (part == 3) { /* neg x */
+ eul[0] = M_PI / 2.0;
+ eul[2] = M_PI / 2.0;
+ }
+ else if (part == 4) { /* neg y */
+ eul[0] = M_PI / 2.0;
+ eul[2] = M_PI;
+ }
+ else { /* pos x */
+ eul[0] = M_PI / 2.0;
+ eul[2] = -M_PI / 2.0;
+ }
+
+ copy_m4_m4(tmat, mat);
+ eul_to_mat4(rotmat, eul);
+ mul_m4_m4m4(mat, tmat, rotmat);
+}
+/* ------------------------------------------------------------------------- */
+
+static void env_set_imats(Render *re)
+{
+ Base *base;
+ float mat[4][4];
+
+ base = re->scene->base.first;
+ while (base) {
+ mul_m4_m4m4(mat, re->viewmat, base->object->obmat);
+ invert_m4_m4(base->object->imat, mat);
+
+ base = base->next;
+ }
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+void env_rotate_scene(Render *re, float mat[4][4], int do_rotate)
+{
+ ObjectRen *obr;
+ ObjectInstanceRen *obi;
+ LampRen *lar = NULL;
+ HaloRen *har = NULL;
+ float imat[3][3], mat_inverse[4][4], smat[4][4], tmat[4][4], cmat[3][3], tmpmat[4][4];
+ int a;
+
+ if (do_rotate == 0) {
+ invert_m4_m4(tmat, mat);
+ copy_m3_m4(imat, tmat);
+
+ copy_m4_m4(mat_inverse, mat);
+ }
+ else {
+ copy_m4_m4(tmat, mat);
+ copy_m3_m4(imat, mat);
+
+ invert_m4_m4(mat_inverse, tmat);
+ }
+
+ for (obi = re->instancetable.first; obi; obi = obi->next) {
+ /* append or set matrix depending on dupli */
+ if (obi->flag & R_DUPLI_TRANSFORMED) {
+ copy_m4_m4(tmpmat, obi->mat);
+ mul_m4_m4m4(obi->mat, tmat, tmpmat);
+ }
+ else if (do_rotate == 1)
+ copy_m4_m4(obi->mat, tmat);
+ else
+ unit_m4(obi->mat);
+
+ copy_m3_m4(cmat, obi->mat);
+ invert_m3_m3(obi->nmat, cmat);
+ transpose_m3(obi->nmat);
+
+ /* indicate the renderer has to use transform matrices */
+ if (do_rotate == 0)
+ obi->flag &= ~R_ENV_TRANSFORMED;
+ else {
+ obi->flag |= R_ENV_TRANSFORMED;
+ copy_m4_m4(obi->imat, mat_inverse);
+ }
+ }
+
+
+ for (obr = re->objecttable.first; obr; obr = obr->next) {
+ for (a = 0; a < obr->tothalo; a++) {
+ if ((a & 255) == 0) har = obr->bloha[a >> 8];
+ else har++;
+
+ mul_m4_v3(tmat, har->co);
+ }
+
+ /* imat_ren is needed for correct texture coordinates */
+ mul_m4_m4m4(obr->ob->imat_ren, re->viewmat, obr->ob->obmat);
+ invert_m4(obr->ob->imat_ren);
+ }
+
+ for (lar = re->lampren.first; lar; lar = lar->next) {
+ float lamp_imat[4][4];
+
+ /* copy from add_render_lamp */
+ if (do_rotate == 1)
+ mul_m4_m4m4(tmpmat, re->viewmat, lar->lampmat);
+ else
+ mul_m4_m4m4(tmpmat, re->viewmat_orig, lar->lampmat);
+
+ invert_m4_m4(lamp_imat, tmpmat);
+ copy_m3_m4(lar->mat, tmpmat);
+ copy_m3_m4(lar->imat, lamp_imat);
+
+ lar->vec[0]= -tmpmat[2][0];
+ lar->vec[1]= -tmpmat[2][1];
+ lar->vec[2]= -tmpmat[2][2];
+ normalize_v3(lar->vec);
+ lar->co[0]= tmpmat[3][0];
+ lar->co[1]= tmpmat[3][1];
+ lar->co[2]= tmpmat[3][2];
+
+ if (lar->type == LA_AREA) {
+ area_lamp_vectors(lar);
+ }
+ else if (lar->type == LA_SPOT) {
+ normalize_v3(lar->imat[0]);
+ normalize_v3(lar->imat[1]);
+ normalize_v3(lar->imat[2]);
+
+ lar->sh_invcampos[0] = -lar->co[0];
+ lar->sh_invcampos[1] = -lar->co[1];
+ lar->sh_invcampos[2] = -lar->co[2];
+ mul_m3_v3(lar->imat, lar->sh_invcampos);
+ lar->sh_invcampos[2] *= lar->sh_zfac;
+
+ if (lar->shb) {
+ if (do_rotate == 1) {
+ mul_m4_m4m4(smat, lar->shb->viewmat, mat_inverse);
+ mul_m4_m4m4(lar->shb->persmat, lar->shb->winmat, smat);
+ }
+ else mul_m4_m4m4(lar->shb->persmat, lar->shb->winmat, lar->shb->viewmat);
+ }
+ }
+ }
+
+ if (do_rotate) {
+ init_render_world(re);
+ env_set_imats(re);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void env_layerflags(Render *re, unsigned int notlay)
+{
+ ObjectRen *obr;
+ VlakRen *vlr = NULL;
+ int a;
+
+ /* invert notlay, so if face is in multiple layers it will still be visible,
+ * unless all 'notlay' bits match the face bits.
+ * face: 0110
+ * not: 0100
+ * ~not: 1011
+ * now (face & ~not) is true
+ */
+
+ notlay = ~notlay;
+
+ for (obr = re->objecttable.first; obr; obr = obr->next) {
+ if ((obr->lay & notlay) == 0) {
+ for (a = 0; a < obr->totvlak; a++) {
+ if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak;
+ else vlr++;
+
+ vlr->flag |= R_HIDDEN;
+ }
+ }
+ }
+}
+
+static void env_hideobject(Render *re, Object *ob)
+{
+ ObjectRen *obr;
+ VlakRen *vlr = NULL;
+ int a;
+
+ for (obr = re->objecttable.first; obr; obr = obr->next) {
+ for (a = 0; a < obr->totvlak; a++) {
+ if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak;
+ else vlr++;
+
+ if (obr->ob == ob)
+ vlr->flag |= R_HIDDEN;
+ }
+ }
+}
+
+static void env_showobjects(Render *re)
+{
+ ObjectRen *obr;
+ VlakRen *vlr = NULL;
+ int a;
+
+ for (obr = re->objecttable.first; obr; obr = obr->next) {
+ for (a = 0; a < obr->totvlak; a++) {
+ if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak;
+ else vlr++;
+
+ vlr->flag &= ~R_HIDDEN;
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void render_envmap(Render *re, EnvMap *env)
+{
+ /* only the cubemap and planar map is implemented */
+ Render *envre;
+ ImBuf *ibuf;
+ float orthmat[4][4];
+ float oldviewinv[4][4], mat[4][4], tmat[4][4];
+ short part;
+
+ /* need a recalc: ortho-render has no correct viewinv */
+ invert_m4_m4(oldviewinv, re->viewmat);
+
+ envre = envmap_render_copy(re, env);
+
+ /* precalc orthmat for object */
+ copy_m4_m4(orthmat, env->object->obmat);
+ normalize_m4(orthmat);
+
+ /* need imat later for texture imat */
+ mul_m4_m4m4(mat, re->viewmat, orthmat);
+ invert_m4_m4(tmat, mat);
+ copy_m3_m4(env->obimat, tmat);
+
+ for (part = 0; part < 6; part++) {
+ if (env->type == ENV_PLANE && part != 1)
+ continue;
+
+ re->display_clear(re->dch, envre->result);
+
+ copy_m4_m4(tmat, orthmat);
+ envmap_transmatrix(tmat, part);
+ invert_m4_m4(mat, tmat);
+ /* mat now is the camera 'viewmat' */
+
+ copy_m4_m4(envre->viewmat, mat);
+ copy_m4_m4(envre->viewinv, tmat);
+
+ /* we have to correct for the already rotated vertexcoords */
+ mul_m4_m4m4(tmat, envre->viewmat, oldviewinv);
+ invert_m4_m4(env->imat, tmat);
+
+ env_rotate_scene(envre, tmat, 1);
+ project_renderdata(envre, projectverto, 0, 0, 1);
+ env_layerflags(envre, env->notlay);
+ env_hideobject(envre, env->object);
+
+ if (re->test_break(re->tbh) == 0) {
+ RE_TileProcessor(envre);
+ }
+
+ /* rotate back */
+ env_showobjects(envre);
+ env_rotate_scene(envre, tmat, 0);
+
+ if (re->test_break(re->tbh) == 0) {
+ int y;
+ float *alpha;
+ float *rect;
+
+ if (envre->result->do_exr_tile) {
+ BLI_rw_mutex_lock(&envre->resultmutex, THREAD_LOCK_WRITE);
+ render_result_exr_file_end(envre);
+ BLI_rw_mutex_unlock(&envre->resultmutex);
+ }
+
+ RenderLayer *rl = envre->result->layers.first;
+
+ /* envmap is rendered independently of multiview */
+ rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, "");
+ ibuf = IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect | IB_rectfloat);
+ memcpy(ibuf->rect_float, rect, ibuf->channels * ibuf->x * ibuf->y * sizeof(float));
+
+ /* envmap renders without alpha */
+ alpha = ibuf->rect_float + 3;
+ for (y = ibuf->x * ibuf->y - 1; y >= 0; y--, alpha += 4)
+ *alpha = 1.0;
+
+ env->cube[part] = ibuf;
+ }
+
+ if (re->test_break(re->tbh)) break;
+
+ }
+
+ if (re->test_break(re->tbh)) BKE_texture_envmap_free_data(env);
+ else {
+ if (envre->r.mode & R_OSA) env->ok = ENV_OSA;
+ else env->ok = ENV_NORMAL;
+ env->lastframe = re->scene->r.cfra;
+ }
+
+ /* restore */
+ envmap_free_render_copy(envre);
+ env_set_imats(re);
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+void make_envmaps(Render *re)
+{
+ Tex *tex;
+ bool do_init = false;
+ int depth = 0, trace;
+
+ if (!(re->r.mode & R_ENVMAP)) return;
+
+ /* we don't raytrace, disabling the flag will cause ray_transp render solid */
+ trace = (re->r.mode & R_RAYTRACE);
+ re->r.mode &= ~R_RAYTRACE;
+
+ re->i.infostr = IFACE_("Creating Environment maps");
+ re->stats_draw(re->sdh, &re->i);
+
+ /* 5 = hardcoded max recursion level */
+ while (depth < 5) {
+ tex = re->main->tex.first;
+ while (tex) {
+ if (tex->id.us && tex->type == TEX_ENVMAP) {
+ if (tex->env && tex->env->object) {
+ EnvMap *env = tex->env;
+
+ if (env->object->lay & re->lay) {
+ if (env->stype == ENV_LOAD) {
+ float orthmat[4][4], mat[4][4], tmat[4][4];
+
+ /* precalc orthmat for object */
+ copy_m4_m4(orthmat, env->object->obmat);
+ normalize_m4(orthmat);
+
+ /* need imat later for texture imat */
+ mul_m4_m4m4(mat, re->viewmat, orthmat);
+ invert_m4_m4(tmat, mat);
+ copy_m3_m4(env->obimat, tmat);
+ }
+ else {
+
+ /* decide if to render an envmap (again) */
+ if (env->depth >= depth) {
+
+ /* set 'recalc' to make sure it does an entire loop of recalcs */
+
+ if (env->ok) {
+ /* free when OSA, and old one isn't OSA */
+ if ((re->r.mode & R_OSA) && env->ok == ENV_NORMAL)
+ BKE_texture_envmap_free_data(env);
+ /* free when size larger */
+ else if (env->lastsize < re->r.size)
+ BKE_texture_envmap_free_data(env);
+ /* free when env is in recalcmode */
+ else if (env->recalc)
+ BKE_texture_envmap_free_data(env);
+ }
+
+ if (env->ok == 0 && depth == 0) env->recalc = 1;
+
+ if (env->ok == 0) {
+ do_init = true;
+ render_envmap(re, env);
+
+ if (depth == env->depth) env->recalc = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ tex = tex->id.next;
+ }
+ depth++;
+ }
+
+ if (do_init) {
+ re->display_init(re->dih, re->result);
+ re->display_clear(re->dch, re->result);
+ // re->flag |= R_REDRAW_PRV;
+ }
+ /* restore */
+ re->r.mode |= trace;
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int envcube_isect(EnvMap *env, const float vec[3], float answ[2])
+{
+ float lambda;
+ int face;
+
+ if (env->type == ENV_PLANE) {
+ face = 1;
+
+ lambda = 1.0f / vec[2];
+ answ[0] = env->viewscale * lambda * vec[0];
+ answ[1] = -env->viewscale * lambda * vec[1];
+ }
+ else {
+ /* which face */
+ if (vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) {
+ face = 0;
+ lambda = -1.0f / vec[2];
+ answ[0] = lambda * vec[0];
+ answ[1] = lambda * vec[1];
+ }
+ else if (vec[2] >= fabsf(vec[0]) && vec[2] >= fabsf(vec[1])) {
+ face = 1;
+ lambda = 1.0f / vec[2];
+ answ[0] = lambda * vec[0];
+ answ[1] = -lambda * vec[1];
+ }
+ else if (vec[1] >= fabsf(vec[0])) {
+ face = 2;
+ lambda = 1.0f / vec[1];
+ answ[0] = lambda * vec[0];
+ answ[1] = lambda * vec[2];
+ }
+ else if (vec[0] <= -fabsf(vec[1])) {
+ face = 3;
+ lambda = -1.0f / vec[0];
+ answ[0] = lambda * vec[1];
+ answ[1] = lambda * vec[2];
+ }
+ else if (vec[1] <= -fabsf(vec[0])) {
+ face = 4;
+ lambda = -1.0f / vec[1];
+ answ[0] = -lambda * vec[0];
+ answ[1] = lambda * vec[2];
+ }
+ else {
+ face = 5;
+ lambda = 1.0f / vec[0];
+ answ[0] = -lambda * vec[1];
+ answ[1] = lambda * vec[2];
+ }
+ }
+
+ answ[0] = 0.5f + 0.5f * answ[0];
+ answ[1] = 0.5f + 0.5f * answ[1];
+ return face;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void set_dxtdyt(float r_dxt[3], float r_dyt[3], const float dxt[3], const float dyt[3], int face)
+{
+ if (face == 2 || face == 4) {
+ r_dxt[0] = dxt[0];
+ r_dyt[0] = dyt[0];
+ r_dxt[1] = dxt[2];
+ r_dyt[1] = dyt[2];
+ }
+ else if (face == 3 || face == 5) {
+ r_dxt[0] = dxt[1];
+ r_dxt[1] = dxt[2];
+ r_dyt[0] = dyt[1];
+ r_dyt[1] = dyt[2];
+ }
+ else {
+ r_dxt[0] = dxt[0];
+ r_dyt[0] = dyt[0];
+ r_dxt[1] = dxt[1];
+ r_dyt[1] = dyt[1];
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool, const bool skip_load_image)
+{
+ extern Render R; /* only in this call */
+ /* texvec should be the already reflected normal */
+ EnvMap *env;
+ ImBuf *ibuf;
+ float fac, vec[3], sco[3], dxts[3], dyts[3];
+ int face, face1;
+
+ env = tex->env;
+ if (env == NULL || (env->stype != ENV_LOAD && env->object == NULL)) {
+ texres->tin = 0.0;
+ return 0;
+ }
+
+ if (env->stype == ENV_LOAD) {
+ env->ima = tex->ima;
+ if (env->ima && env->ima->ok) {
+ if (env->cube[1] == NULL) {
+ ImBuf *ibuf_ima = BKE_image_pool_acquire_ibuf(env->ima, NULL, pool);
+ if (ibuf_ima)
+ envmap_split_ima(env, ibuf_ima);
+ else
+ env->ok = 0;
+
+ if (env->type == ENV_PLANE)
+ tex->extend = TEX_EXTEND;
+
+ BKE_image_pool_release_ibuf(env->ima, ibuf_ima, pool);
+ }
+ }
+ }
+
+ if (env->ok == 0) {
+ texres->tin = 0.0;
+ return 0;
+ }
+
+ /* rotate to envmap space, if object is set */
+ copy_v3_v3(vec, texvec);
+ if (env->object) {
+ mul_m3_v3(env->obimat, vec);
+ if (osatex) {
+ mul_m3_v3(env->obimat, dxt);
+ mul_m3_v3(env->obimat, dyt);
+ }
+ }
+ else {
+ if (!BKE_scene_use_world_space_shading(R.scene)) {
+ // texvec is in view space
+ mul_mat3_m4_v3(R.viewinv, vec);
+ if (osatex) {
+ mul_mat3_m4_v3(R.viewinv, dxt);
+ mul_mat3_m4_v3(R.viewinv, dyt);
+ }
+ }
+ }
+
+ face = envcube_isect(env, vec, sco);
+ ibuf = env->cube[face];
+
+ if (osatex) {
+ set_dxtdyt(dxts, dyts, dxt, dyt, face);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres, pool, skip_load_image);
+
+ /* edges? */
+
+ if (texres->ta < 1.0f) {
+ TexResult texr1, texr2;
+
+ texr1.nor = texr2.nor = NULL;
+ texr1.talpha = texr2.talpha = texres->talpha; /* boxclip expects this initialized */
+
+ add_v3_v3(vec, dxt);
+ face1 = envcube_isect(env, vec, sco);
+ sub_v3_v3(vec, dxt);
+
+ if (face != face1) {
+ ibuf = env->cube[face1];
+ set_dxtdyt(dxts, dyts, dxt, dyt, face1);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1, pool, skip_load_image);
+ }
+ else texr1.tr = texr1.tg = texr1.tb = texr1.ta = 0.0;
+
+ /* here was the nasty bug! results were not zero-ed. FPE! */
+
+ add_v3_v3(vec, dyt);
+ face1 = envcube_isect(env, vec, sco);
+ sub_v3_v3(vec, dyt);
+
+ if (face != face1) {
+ ibuf = env->cube[face1];
+ set_dxtdyt(dxts, dyts, dxt, dyt, face1);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2, pool, skip_load_image);
+ }
+ else texr2.tr = texr2.tg = texr2.tb = texr2.ta = 0.0;
+
+ fac = (texres->ta + texr1.ta + texr2.ta);
+ if (fac != 0.0f) {
+ fac = 1.0f / fac;
+
+ texres->tr = fac * (texres->ta * texres->tr + texr1.ta * texr1.tr + texr2.ta * texr2.tr);
+ texres->tg = fac * (texres->ta * texres->tg + texr1.ta * texr1.tg + texr2.ta * texr2.tg);
+ texres->tb = fac * (texres->ta * texres->tb + texr1.ta * texr1.tb + texr2.ta * texr2.tb);
+ }
+ texres->ta = 1.0;
+ }
+ }
+ else {
+ imagewrap(tex, NULL, ibuf, sco, texres, pool, skip_load_image);
+ }
+
+ return 1;
+}
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index afdb8c5dd65..6e4336f80ea 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -112,11 +112,11 @@ void RE_engines_register(RenderEngineType *render_type)
RenderEngineType *RE_engines_find(const char *idname)
{
RenderEngineType *type;
-
+
type = BLI_findstring(&R_engines, idname, offsetof(RenderEngineType, idname));
if (!type)
type = BLI_findstring(&R_engines, "BLENDER_EEVEE", offsetof(RenderEngineType, idname));
-
+
return type;
}
@@ -320,7 +320,7 @@ int RE_engine_test_break(RenderEngine *engine)
if (re)
return re->test_break(re->tbh);
-
+
return 0;
}
@@ -497,7 +497,7 @@ static void engine_depsgraph_init(RenderEngine *engine, ViewLayer *view_layer)
engine->depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
DEG_debug_name_set(engine->depsgraph, "RENDER");
- BKE_scene_graph_update_tagged(engine->depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(engine->depsgraph, bmain);
}
static void engine_depsgraph_free(RenderEngine *engine)
@@ -513,6 +513,10 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
return;
}
+#ifdef WITH_PYTHON
+ BPy_BEGIN_ALLOW_THREADS;
+#endif
+
Render *re = engine->re;
double cfra = (double)frame + (double)subframe;
@@ -520,15 +524,11 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
BKE_scene_frame_set(re->scene, cfra);
BKE_scene_graph_update_for_newframe(engine->depsgraph, re->main);
-#ifdef WITH_PYTHON
- BPy_BEGIN_ALLOW_THREADS;
-#endif
+ BKE_scene_camera_switch_update(re->scene);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;
#endif
-
- BKE_scene_camera_switch_update(re->scene);
}
/* Bake */
@@ -776,7 +776,7 @@ int RE_engine_render(Render *re, int do_all)
if (BKE_reports_contain(re->reports, RPT_ERROR))
G.is_break = true;
-
+
#ifdef WITH_FREESTYLE
if (re->r.mode & R_EDGE_FRS)
RE_RenderFreestyleExternal(re);
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index b9d55916f51..1e9ad79e599 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -32,7 +32,7 @@
#include <fcntl.h>
#include <math.h>
#include <float.h>
-#ifndef WIN32
+#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
@@ -67,7 +67,7 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y)
{
int ofs = y * ibuf->x + x;
-
+
if (ibuf->rect_float) {
if (ibuf->channels==4) {
const float *fp= ibuf->rect_float + 4*ofs;
@@ -105,15 +105,15 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
int xi, yi; /* original values */
texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
-
+
/* we need to set retval OK, otherwise texture code generates normals itself... */
retval= texres->nor ? 3 : 1;
-
+
/* quick tests */
if (ibuf==NULL && ima==NULL)
return retval;
if (ima) {
-
+
/* hack for icon render */
if (skip_load_image && !BKE_image_has_loaded_ibuf(ima))
return retval;
@@ -127,7 +127,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
-
+
/* setup mapping */
if (tex->imaflag & TEX_IMAROT) {
fy= texvec[0];
@@ -137,10 +137,10 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
fx= texvec[0];
fy= texvec[1];
}
-
+
if (tex->extend == TEX_CHECKER) {
int xs, ys;
-
+
xs= (int)floor(fx);
ys= (int)floor(fy);
fx-= xs;
@@ -205,7 +205,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (y<0) y+= ibuf->y;
}
}
-
+
/* keep this before interpolation [#29761] */
if (ima) {
if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
@@ -232,7 +232,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
else { /* no filtering */
ibuf_get_color(&texres->tr, ibuf, x, y);
}
-
+
if (texres->nor) {
if (tex->imaflag & TEX_NORMALMAP) {
/* qdn: normal from color
@@ -283,7 +283,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
else {
texres->ta = texres->tin = 1.0;
}
-
+
if (tex->flag & TEX_NEGALPHA) {
texres->ta = 1.0f - texres->ta;
}
@@ -301,7 +301,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
BKE_image_pool_release_ibuf(ima, ibuf, pool);
BRICONTRGB;
-
+
return retval;
}
@@ -327,9 +327,9 @@ static void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2)
newrct->xmin = rf->xmin+(x2-x1);
newrct->ymin = rf->ymin;
newrct->ymax = rf->ymax;
-
+
if (newrct->xmin ==newrct->xmax) (*count)--;
-
+
rf->xmin = x1;
}
}
@@ -489,7 +489,7 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
else {
div= texres->tr= texres->tg= texres->tb= texres->ta= 0.0;
for (y=starty; y<=endy; y++) {
-
+
muly= 1.0;
if (starty==endy) {
@@ -499,10 +499,10 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
if (y==starty) muly= 1.0f-(rf->ymin - y);
if (y==endy) muly= (rf->ymax - y);
}
-
+
if (startx==endx) {
mulx= muly;
-
+
ibuf_get_color(col, ibuf, startx, y);
texres->ta+= mulx*col[3];
@@ -518,7 +518,7 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
if (x==endx) mulx*= (rf->xmax - x);
ibuf_get_color(col, ibuf, x, y);
-
+
if (mulx==1.0f) {
texres->ta+= col[3];
texres->tr+= col[0];
@@ -573,7 +573,7 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
rf->ymax = maxy*(ibuf->y);
texr.talpha= texres->talpha; /* is read by boxsample_clip */
-
+
if (imapextend) {
CLAMP(rf->xmin, 0.0f, ibuf->x-1);
CLAMP(rf->xmax, 0.0f, ibuf->x-1);
@@ -608,7 +608,7 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
tot= texres->tr= texres->tb= texres->tg= texres->ta= 0.0;
while (count--) {
boxsampleclip(ibuf, rf, &texr);
-
+
opp= square_rctf(rf);
tot+= opp;
@@ -629,7 +629,7 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
boxsampleclip(ibuf, rf, texres);
if (texres->talpha==0) texres->ta= 1.0;
-
+
if (alphaclip!=1.0f) {
/* premul it all */
texres->tr*= alphaclip;
@@ -637,7 +637,7 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
texres->tb*= alphaclip;
texres->ta*= alphaclip;
}
-}
+}
/*-----------------------------------------------------------------------------------------------------------------
* from here, some functions only used for the new filtering */
@@ -874,7 +874,7 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
{
if (tex->imaflag & TEX_MIPMAP) {
if ((ibuf->flags & IB_fields) == 0) {
-
+
if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) {
BLI_thread_lock(LOCK_IMAGE);
if (ibuf->userflags & IB_MIPMAP_INVALID) {
@@ -885,7 +885,7 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
}
if (ibuf->mipmap[0] == NULL) {
BLI_thread_lock(LOCK_IMAGE);
- if (ibuf->mipmap[0] == NULL)
+ if (ibuf->mipmap[0] == NULL)
IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
BLI_thread_unlock(LOCK_IMAGE);
}
@@ -895,7 +895,7 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
}
}
}
-
+
}
static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[2], float dyt[2], TexResult *texres, struct ImagePool *pool, const bool skip_load_image)
@@ -946,7 +946,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
/* mipmap test */
image_mipmap_test(tex, ibuf);
-
+
if (ima) {
if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
@@ -1281,7 +1281,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
else
texres->tin = texres->ta;
if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
-
+
if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) { /* normal from color */
/* The invert of the red channel is to make
* the normal map compliant with the outside world.
@@ -1312,7 +1312,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
BKE_image_pool_release_ibuf(ima, ibuf, pool);
BRICONTRGB;
-
+
return retval;
}
@@ -1334,10 +1334,10 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres, pool, skip_load_image);
texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
-
+
/* we need to set retval OK, otherwise texture code generates normals itself... */
retval = texres->nor ? 3 : 1;
-
+
/* quick tests */
if (ibuf==NULL && ima==NULL)
return retval;
@@ -1346,7 +1346,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* hack for icon render */
if (skip_load_image && !BKE_image_has_loaded_ibuf(ima))
return retval;
-
+
ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
ima->flag|= IMA_USED_FOR_RENDER;
@@ -1356,7 +1356,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
BKE_image_pool_release_ibuf(ima, ibuf, pool);
return retval;
}
-
+
/* mipmap test */
image_mipmap_test(tex, ibuf);
@@ -1367,9 +1367,9 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
}
}
}
-
+
texr.talpha= texres->talpha;
-
+
if (tex->imaflag & TEX_IMAROT) {
fy= texvec[0];
fx= texvec[1];
@@ -1378,7 +1378,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
fx= texvec[0];
fy= texvec[1];
}
-
+
/* pixel coordinates */
minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
@@ -1389,7 +1389,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* tex_sharper has been removed */
minx= (maxx-minx)/2.0f;
miny= (maxy-miny)/2.0f;
-
+
if (tex->imaflag & TEX_FILTER_MIN) {
/* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y);
@@ -1402,7 +1402,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
else if (tex->filtersize!=1.0f) {
minx*= tex->filtersize;
miny*= tex->filtersize;
-
+
dxt[0]*= tex->filtersize;
dxt[1]*= tex->filtersize;
dyt[0]*= tex->filtersize;
@@ -1410,13 +1410,13 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
}
if (tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
-
+
if (minx>0.25f) minx= 0.25f;
else if (minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */
if (miny>0.25f) miny= 0.25f;
else if (miny<0.00001f) miny= 0.00001f;
-
+
/* repeat and clip */
imaprepeat= (tex->extend==TEX_REPEAT);
imapextend= (tex->extend==TEX_EXTEND);
@@ -1430,10 +1430,10 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (tex->extend == TEX_CHECKER) {
int xs, ys, xs1, ys1, xs2, ys2, boundary;
-
+
xs= (int)floor(fx);
ys= (int)floor(fy);
-
+
/* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
if ( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
fx-= xs;
@@ -1447,7 +1447,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
return retval;
}
else {
-
+
xs1= (int)floor(fx-minx);
ys1= (int)floor(fy-miny);
xs2= (int)floor(fx+minx);
@@ -1479,14 +1479,14 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (tex->flag & TEX_CHECKER_ODD) {
if ((xs1+ys) & 1) fx-= xs2;
else fx-= xs1;
-
+
if ((ys1+xs) & 1) fy-= ys2;
else fy-= ys1;
}
if (tex->flag & TEX_CHECKER_EVEN) {
if ((xs1+ys) & 1) fx-= xs1;
else fx-= xs2;
-
+
if ((ys1+xs) & 1) fy-= ys1;
else fy-= ys2;
}
@@ -1525,7 +1525,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (fx>1.0f) fx -= (int)(fx);
else if (fx<0.0f) fx+= 1-(int)(fx);
}
-
+
if (imapextend) {
if (fy>1.0f) fy = 1.0f;
else if (fy<0.0f) fy= 0.0f;
@@ -1540,18 +1540,18 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (tex->imaflag & TEX_MIPMAP) {
ImBuf *previbuf, *curibuf;
float bumpscale;
-
+
dx = minx;
dy = miny;
maxd = max_ff(dx, dy);
if (maxd > 0.5f) maxd = 0.5f;
pixsize = 1.0f / (float) MIN2(ibuf->x, ibuf->y);
-
+
bumpscale= pixsize/maxd;
if (bumpscale>1.0f) bumpscale= 1.0f;
else bumpscale*=bumpscale;
-
+
curmap= 0;
previbuf= curibuf= ibuf;
while (curmap < IMB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
@@ -1567,12 +1567,12 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
}
-
+
if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
/* a bit extra filter */
//minx*= 1.35f;
//miny*= 1.35f;
-
+
boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
val1= texres->tr+texres->tg+texres->tb;
boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
@@ -1583,11 +1583,11 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* don't switch x or y! */
texres->nor[0]= (val1-val2);
texres->nor[1]= (val1-val3);
-
+
if (previbuf!=curibuf) { /* interpolate */
-
+
boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
-
+
/* calc rgb */
dx= 2.0f*(pixsize-maxd)/pixsize;
if (dx>=1.0f) {
@@ -1601,16 +1601,16 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
texres->tr= dy*texres->tr+ dx*texr.tr;
texres->ta= dy*texres->ta+ dx*texr.ta;
}
-
+
val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
-
+
texres->nor[0]= (val1-val2); /* vals have been interpolated above! */
texres->nor[1]= (val1-val3);
-
+
if (dx<1.0f) {
dy= 1.0f-dx;
texres->tb= dy*texres->tb+ dx*texr.tb;
@@ -1632,9 +1632,9 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (previbuf!=curibuf) { /* interpolate */
boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
-
+
fx= 2.0f*(pixsize-maxd)/pixsize;
-
+
if (fx>=1.0f) {
texres->ta= texr.ta; texres->tb= texr.tb;
texres->tg= texr.tg; texres->tr= texr.tr;
@@ -1672,7 +1672,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
else
boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
}
-
+
if (tex->imaflag & TEX_CALCALPHA) {
texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
}
@@ -1681,7 +1681,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
}
if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
-
+
if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
/* qdn: normal from color
* The invert of the red channel is to make
@@ -1705,7 +1705,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
BKE_image_pool_release_ibuf(ima, ibuf, pool);
BRICONTRGB;
-
+
return retval;
}
@@ -1713,16 +1713,16 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float resu
{
TexResult texres;
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, NULL, pool);
-
+
if (UNLIKELY(ibuf == NULL)) {
zero_v4(result);
return;
}
-
+
texres.talpha = true; /* boxsample expects to be initialized */
boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1);
copy_v4_v4(result, &texres.tr);
-
+
ima->flag|= IMA_USED_FOR_RENDER;
BKE_image_pool_release_ibuf(ima, ibuf, pool);
@@ -1737,11 +1737,11 @@ void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float resu
AFD.dyt[0] = dy; AFD.dyt[1] = dy;
//copy_v2_v2(AFD.dxt, dx);
//copy_v2_v2(AFD.dyt, dy);
-
+
AFD.intpol = 1;
AFD.extflag = TXC_EXTD;
ewa_eval(&texres, ibuf, fx, fy, &AFD);
-
+
copy_v4_v4(result, &texres.tr);
}
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 4274d641674..9611a8a7452 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -66,9 +66,9 @@ static float filt_quadratic(float x)
static float filt_cubic(float x)
{
float x2 = x * x;
-
+
if (x < 0.0f) x = -x;
-
+
if (x < 1.0f) return 0.5f * x * x2 - x2 + 2.0f / 3.0f;
if (x < 2.0f) return (2.0f - x) * (2.0f - x) * (2.0f - x) / 6.0f;
return 0.0f;
@@ -78,7 +78,7 @@ static float filt_cubic(float x)
static float filt_catrom(float x)
{
float x2 = x * x;
-
+
if (x < 0.0f) x = -x;
if (x < 1.0f) return 1.5f * x2 * x - 2.5f * x2 + 1.0f;
if (x < 2.0f) return -0.5f * x2 * x + 2.5f * x2 - 4.0f * x + 2.0f;
@@ -108,34 +108,34 @@ static float filt_mitchell(float x) /* Mitchell & Netravali's two-param cubic */
float RE_filter_value(int type, float x)
{
float gaussfac = 1.6f;
-
+
x = ABS(x);
-
+
switch (type) {
case R_FILTER_BOX:
if (x > 1.0f) return 0.0f;
return 1.0f;
-
+
case R_FILTER_TENT:
if (x > 1.0f) return 0.0f;
return 1.0f - x;
-
+
case R_FILTER_GAUSS:
{
const float two_gaussfac2 = 2.0f * gaussfac * gaussfac;
x *= 3.0f * gaussfac;
return 1.0f / sqrtf((float)M_PI * two_gaussfac2) * expf(-x*x / two_gaussfac2);
}
-
+
case R_FILTER_MITCH:
return filt_mitchell(x * gaussfac);
-
+
case R_FILTER_QUAD:
return filt_quadratic(x * gaussfac);
-
+
case R_FILTER_CUBIC:
return filt_cubic(x * gaussfac);
-
+
case R_FILTER_CATROM:
return filt_catrom(x * gaussfac);
}
@@ -221,20 +221,20 @@ void RE_parts_init(Render *re)
{
int nr, xd, yd, partx, party, xparts, yparts;
int xminb, xmaxb, yminb, ymaxb;
-
+
RE_parts_free(re);
-
+
/* this is render info for caller, is not reset when parts are freed! */
re->i.totpart = 0;
re->i.curpart = 0;
re->i.partsdone = 0;
-
+
/* just for readable code.. */
xminb = re->disprect.xmin;
yminb = re->disprect.ymin;
xmaxb = re->disprect.xmax;
ymaxb = re->disprect.ymax;
-
+
RE_parts_clamp(re);
partx = re->partx;
@@ -242,17 +242,17 @@ void RE_parts_init(Render *re)
/* part count */
xparts = (re->rectx + partx - 1) / partx;
yparts = (re->recty + party - 1) / party;
-
+
for (nr = 0; nr < xparts * yparts; nr++) {
rcti disprect;
int rectx, recty;
-
+
xd = (nr % xparts);
yd = (nr - xd) / xparts;
-
+
disprect.xmin = xminb + xd * partx;
disprect.ymin = yminb + yd * party;
-
+
/* ensure we cover the entire picture, so last parts go to end */
if (xd < xparts - 1) {
disprect.xmax = disprect.xmin + partx;
@@ -260,21 +260,21 @@ void RE_parts_init(Render *re)
disprect.xmax = xmaxb;
}
else disprect.xmax = xmaxb;
-
+
if (yd < yparts - 1) {
disprect.ymax = disprect.ymin + party;
if (disprect.ymax > ymaxb)
disprect.ymax = ymaxb;
}
else disprect.ymax = ymaxb;
-
+
rectx = BLI_rcti_size_x(&disprect);
recty = BLI_rcti_size_y(&disprect);
-
+
/* so, now can we add this part? */
if (rectx > 0 && recty > 0) {
RenderPart *pa = MEM_callocN(sizeof(RenderPart), "new part");
-
+
pa->disprect = disprect;
pa->rectx = rectx;
pa->recty = recty;
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
new file mode 100644
index 00000000000..8aa90a390b3
--- /dev/null
+++ b/source/blender/render/intern/source/occlusion.c
@@ -0,0 +1,1533 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/occlusion.c
+ * \ingroup render
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_material_types.h"
+
+#include "BLI_math.h"
+#include "BLI_memarena.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+#include "BLT_translation.h"
+
+#include "BKE_node.h"
+#include "BKE_scene.h"
+
+
+#include "RE_shader_ext.h"
+
+/* local includes */
+#include "occlusion.h"
+#include "render_types.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "shading.h"
+
+/* ------------------------- Declarations --------------------------- */
+
+#define INVPI ((float)M_1_PI)
+#define TOTCHILD 8
+#define CACHE_STEP 3
+
+typedef struct OcclusionCacheSample {
+ float co[3], n[3], ao[3], env[3], indirect[3], intensity, dist2;
+ int x, y, filled;
+} OcclusionCacheSample;
+
+typedef struct OcclusionCache {
+ OcclusionCacheSample *sample;
+ int x, y, w, h, step;
+} OcclusionCache;
+
+typedef struct OccFace {
+ int obi;
+ int facenr;
+} OccFace;
+
+typedef struct OccNode {
+ float co[3], area;
+ float sh[9], dco;
+ float occlusion, rad[3];
+ int childflag;
+ union {
+ //OccFace face;
+ int face;
+ struct OccNode *node;
+ } child[TOTCHILD];
+} OccNode;
+
+typedef struct OcclusionTree {
+ MemArena *arena;
+
+ float (*co)[3]; /* temporary during build */
+
+ OccFace *face; /* instance and face indices */
+ float *occlusion; /* occlusion for faces */
+ float (*rad)[3]; /* radiance for faces */
+
+ OccNode *root;
+
+ OccNode **stack[BLENDER_MAX_THREADS];
+ int maxdepth;
+
+ int totface;
+
+ float error;
+ float distfac;
+
+ int dothreadedbuild;
+ int totbuildthread;
+ int doindirect;
+
+ OcclusionCache *cache;
+
+ int num_threads;
+} OcclusionTree;
+
+typedef struct OcclusionThread {
+ Render *re;
+ StrandSurface *mesh;
+ float (*faceao)[3];
+ float (*faceenv)[3];
+ float (*faceindirect)[3];
+ int begin, end;
+ int thread;
+} OcclusionThread;
+
+typedef struct OcclusionBuildThread {
+ OcclusionTree *tree;
+ int begin, end, depth;
+ OccNode *node;
+} OcclusionBuildThread;
+
+/* ------------------------- Shading --------------------------- */
+
+extern Render R; /* meh */
+
+static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr, float *rad)
+{
+ ShadeInput *shi = ssamp->shi;
+ ShadeResult *shr = ssamp->shr;
+ float l, u, v, *v1, *v2, *v3;
+
+ /* init */
+ if (vlr->v4) {
+ shi->u = u = 0.5f;
+ shi->v = v = 0.5f;
+ }
+ else {
+ shi->u = u = 1.0f / 3.0f;
+ shi->v = v = 1.0f / 3.0f;
+ }
+
+ /* setup render coordinates */
+ v1 = vlr->v1->co;
+ v2 = vlr->v2->co;
+ v3 = vlr->v3->co;
+
+ /* renderco */
+ l = 1.0f - u - v;
+
+ shi->co[0] = l * v3[0] + u * v1[0] + v * v2[0];
+ shi->co[1] = l * v3[1] + u * v1[1] + v * v2[1];
+ shi->co[2] = l * v3[2] + u * v1[2] + v * v2[2];
+
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
+
+ /* set up view vector */
+ copy_v3_v3(shi->view, shi->co);
+ normalize_v3(shi->view);
+
+ /* cache for shadow */
+ shi->samplenr++;
+
+ shi->xs = 0; /* TODO */
+ shi->ys = 0;
+
+ shade_input_set_normals(shi);
+
+ /* no normal flip */
+ if (shi->flippednor)
+ shade_input_flip_normals(shi);
+
+ madd_v3_v3fl(shi->co, shi->facenor, -0.0001f); /* ugly.. */
+
+ /* not a pretty solution, but fixes common cases */
+ if (shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
+ negate_v3(shi->vn);
+ negate_v3(shi->vno);
+ negate_v3(shi->nmapnorm);
+ }
+
+ /* init material vars */
+ shade_input_init_material(shi);
+
+ /* render */
+ shade_input_set_shade_texco(shi);
+
+ if (shi->mat->nodetree && shi->mat->use_nodes) {
+ ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
+ shi->mat = vlr->mat; /* shi->mat is being set in nodetree */
+ }
+ else {
+ shade_material_loop(shi, shr);
+ }
+
+ copy_v3_v3(rad, shr->combined);
+}
+
+static void occ_build_shade(Render *re, OcclusionTree *tree)
+{
+ ShadeSample ssamp;
+ ObjectInstanceRen *obi;
+ VlakRen *vlr;
+ int a;
+
+ R = *re;
+
+ /* setup shade sample with correct passes */
+ memset(&ssamp, 0, sizeof(ShadeSample));
+ ssamp.shi[0].lay = re->lay;
+ ssamp.shi[0].passflag = SCE_PASS_DIFFUSE | SCE_PASS_RGBA;
+ ssamp.shi[0].combinedflag = ~(SCE_PASS_SPEC);
+ ssamp.tot = 1;
+
+ for (a = 0; a < tree->totface; a++) {
+ obi = &R.objectinstance[tree->face[a].obi];
+ vlr = RE_findOrAddVlak(obi->obr, tree->face[a].facenr);
+
+ occ_shade(&ssamp, obi, vlr, tree->rad[a]);
+
+ if (re->test_break(re->tbh))
+ break;
+ }
+}
+
+/* ------------------------- Spherical Harmonics --------------------------- */
+
+/* Use 2nd order SH => 9 coefficients, stored in this order:
+ * 0 = (0,0),
+ * 1 = (1,-1), 2 = (1,0), 3 = (1,1),
+ * 4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */
+
+static void sh_copy(float *shresult, float *sh)
+{
+ memcpy(shresult, sh, sizeof(float) * 9);
+}
+
+static void sh_mul(float *sh, float f)
+{
+ int i;
+
+ for (i = 0; i < 9; i++)
+ sh[i] *= f;
+}
+
+static void sh_add(float *shresult, float *sh1, float *sh2)
+{
+ int i;
+
+ for (i = 0; i < 9; i++)
+ shresult[i] = sh1[i] + sh2[i];
+}
+
+static void sh_from_disc(float *n, float area, float *shresult)
+{
+ /* See formula (3) in:
+ * "An Efficient Representation for Irradiance Environment Maps" */
+ float sh[9], x, y, z;
+
+ x = n[0];
+ y = n[1];
+ z = n[2];
+
+ sh[0] = 0.282095f;
+
+ sh[1] = 0.488603f * y;
+ sh[2] = 0.488603f * z;
+ sh[3] = 0.488603f * x;
+
+ sh[4] = 1.092548f * x * y;
+ sh[5] = 1.092548f * y * z;
+ sh[6] = 0.315392f * (3.0f * z * z - 1.0f);
+ sh[7] = 1.092548f * x * z;
+ sh[8] = 0.546274f * (x * x - y * y);
+
+ sh_mul(sh, area);
+ sh_copy(shresult, sh);
+}
+
+static float sh_eval(float *sh, float *v)
+{
+ /* See formula (13) in:
+ * "An Efficient Representation for Irradiance Environment Maps" */
+ static const float c1 = 0.429043f, c2 = 0.511664f, c3 = 0.743125f;
+ static const float c4 = 0.886227f, c5 = 0.247708f;
+ float x, y, z, sum;
+
+ x = v[0];
+ y = v[1];
+ z = v[2];
+
+ sum = c1 * sh[8] * (x * x - y * y);
+ sum += c3 * sh[6] * z * z;
+ sum += c4 * sh[0];
+ sum += -c5 * sh[6];
+ sum += 2.0f * c1 * (sh[4] * x * y + sh[7] * x * z + sh[5] * y * z);
+ sum += 2.0f * c2 * (sh[3] * x + sh[1] * y + sh[2] * z);
+
+ return sum;
+}
+
+/* ------------------------------ Building --------------------------------- */
+
+static void occ_face(const OccFace *face, float co[3], float normal[3], float *area)
+{
+ ObjectInstanceRen *obi;
+ VlakRen *vlr;
+ float v1[3], v2[3], v3[3], v4[3];
+
+ obi = &R.objectinstance[face->obi];
+ vlr = RE_findOrAddVlak(obi->obr, face->facenr);
+
+ if (co) {
+ if (vlr->v4)
+ mid_v3_v3v3(co, vlr->v1->co, vlr->v3->co);
+ else
+ mid_v3_v3v3v3(co, vlr->v1->co, vlr->v2->co, vlr->v3->co);
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_v3(obi->mat, co);
+ }
+
+ if (normal) {
+ normal[0] = -vlr->n[0];
+ normal[1] = -vlr->n[1];
+ normal[2] = -vlr->n[2];
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m3_v3(obi->nmat, normal);
+ }
+
+ if (area) {
+ copy_v3_v3(v1, vlr->v1->co);
+ copy_v3_v3(v2, vlr->v2->co);
+ copy_v3_v3(v3, vlr->v3->co);
+ if (vlr->v4) copy_v3_v3(v4, vlr->v4->co);
+
+ if (obi->flag & R_TRANSFORMED) {
+ mul_m4_v3(obi->mat, v1);
+ mul_m4_v3(obi->mat, v2);
+ mul_m4_v3(obi->mat, v3);
+ if (vlr->v4) mul_m4_v3(obi->mat, v4);
+ }
+
+ /* todo: correct area for instances */
+ if (vlr->v4)
+ *area = area_quad_v3(v1, v2, v3, v4);
+ else
+ *area = area_tri_v3(v1, v2, v3);
+ }
+}
+
+static void occ_sum_occlusion(OcclusionTree *tree, OccNode *node)
+{
+ OccNode *child;
+ float occ, area, totarea, rad[3];
+ int a, b, indirect = tree->doindirect;
+
+ occ = 0.0f;
+ totarea = 0.0f;
+ if (indirect) zero_v3(rad);
+
+ for (b = 0; b < TOTCHILD; b++) {
+ if (node->childflag & (1 << b)) {
+ a = node->child[b].face;
+ occ_face(&tree->face[a], NULL, NULL, &area);
+ occ += area * tree->occlusion[a];
+ if (indirect) madd_v3_v3fl(rad, tree->rad[a], area);
+ totarea += area;
+ }
+ else if (node->child[b].node) {
+ child = node->child[b].node;
+ occ_sum_occlusion(tree, child);
+
+ occ += child->area * child->occlusion;
+ if (indirect) madd_v3_v3fl(rad, child->rad, child->area);
+ totarea += child->area;
+ }
+ }
+
+ if (totarea != 0.0f) {
+ occ /= totarea;
+ if (indirect) mul_v3_fl(rad, 1.0f / totarea);
+ }
+
+ node->occlusion = occ;
+ if (indirect) copy_v3_v3(node->rad, rad);
+}
+
+static int occ_find_bbox_axis(OcclusionTree *tree, int begin, int end, float *min, float *max)
+{
+ float len, maxlen = -1.0f;
+ int a, axis = 0;
+
+ INIT_MINMAX(min, max);
+
+ for (a = begin; a < end; a++) {
+ minmax_v3v3_v3(min, max, tree->co[a]);
+ }
+
+ for (a = 0; a < 3; a++) {
+ len = max[a] - min[a];
+
+ if (len > maxlen) {
+ maxlen = len;
+ axis = a;
+ }
+ }
+
+ return axis;
+}
+
+static void occ_node_from_face(OccFace *face, OccNode *node)
+{
+ float n[3];
+
+ occ_face(face, node->co, n, &node->area);
+ node->dco = 0.0f;
+ sh_from_disc(n, node->area, node->sh);
+}
+
+static void occ_build_dco(OcclusionTree *tree, OccNode *node, const float co[3], float *dco)
+{
+ int b;
+ for (b = 0; b < TOTCHILD; b++) {
+ float dist, d[3], nco[3];
+
+ if (node->childflag & (1 << b)) {
+ occ_face(tree->face + node->child[b].face, nco, NULL, NULL);
+ }
+ else if (node->child[b].node) {
+ OccNode *child = node->child[b].node;
+ occ_build_dco(tree, child, co, dco);
+ copy_v3_v3(nco, child->co);
+ }
+ else {
+ continue;
+ }
+
+ sub_v3_v3v3(d, nco, co);
+ dist = dot_v3v3(d, d);
+ if (dist > *dco)
+ *dco = dist;
+ }
+}
+
+static void occ_build_split(OcclusionTree *tree, int begin, int end, int *split)
+{
+ float min[3], max[3], mid;
+ int axis, a, enda;
+
+ /* split in middle of boundbox. this seems faster than median split
+ * on complex scenes, possibly since it avoids two distant faces to
+ * be in the same node better? */
+ axis = occ_find_bbox_axis(tree, begin, end, min, max);
+ mid = 0.5f * (min[axis] + max[axis]);
+
+ a = begin;
+ enda = end;
+ while (a < enda) {
+ if (tree->co[a][axis] > mid) {
+ enda--;
+ SWAP(OccFace, tree->face[a], tree->face[enda]);
+ swap_v3_v3(tree->co[a], tree->co[enda]);
+ }
+ else
+ a++;
+ }
+
+ *split = enda;
+}
+
+static void occ_build_8_split(OcclusionTree *tree, int begin, int end, int *offset, int *count)
+{
+ /* split faces into eight groups */
+ int b, splitx, splity[2], splitz[4];
+
+ occ_build_split(tree, begin, end, &splitx);
+
+ /* force split if none found, to deal with degenerate geometry */
+ if (splitx == begin || splitx == end)
+ splitx = (begin + end) / 2;
+
+ occ_build_split(tree, begin, splitx, &splity[0]);
+ occ_build_split(tree, splitx, end, &splity[1]);
+
+ occ_build_split(tree, begin, splity[0], &splitz[0]);
+ occ_build_split(tree, splity[0], splitx, &splitz[1]);
+ occ_build_split(tree, splitx, splity[1], &splitz[2]);
+ occ_build_split(tree, splity[1], end, &splitz[3]);
+
+ offset[0] = begin;
+ offset[1] = splitz[0];
+ offset[2] = splity[0];
+ offset[3] = splitz[1];
+ offset[4] = splitx;
+ offset[5] = splitz[2];
+ offset[6] = splity[1];
+ offset[7] = splitz[3];
+
+ for (b = 0; b < 7; b++)
+ count[b] = offset[b + 1] - offset[b];
+ count[7] = end - offset[7];
+}
+
+static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, int end, int depth);
+
+static void *exec_occ_build(void *data)
+{
+ OcclusionBuildThread *othread = (OcclusionBuildThread *)data;
+
+ occ_build_recursive(othread->tree, othread->node, othread->begin, othread->end, othread->depth);
+
+ return NULL;
+}
+
+static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, int end, int depth)
+{
+ ListBase threads;
+ OcclusionBuildThread othreads[BLENDER_MAX_THREADS];
+ OccNode *child, tmpnode;
+ /* OccFace *face; */
+ int a, b, totthread = 0, offset[TOTCHILD], count[TOTCHILD];
+
+ /* add a new node */
+ node->occlusion = 1.0f;
+
+ /* leaf node with only children */
+ if (end - begin <= TOTCHILD) {
+ for (a = begin, b = 0; a < end; a++, b++) {
+ /* face= &tree->face[a]; */
+ node->child[b].face = a;
+ node->childflag |= (1 << b);
+ }
+ }
+ else {
+ /* order faces */
+ occ_build_8_split(tree, begin, end, offset, count);
+
+ if (depth == 1 && tree->dothreadedbuild)
+ BLI_threadpool_init(&threads, exec_occ_build, tree->totbuildthread);
+
+ for (b = 0; b < TOTCHILD; b++) {
+ if (count[b] == 0) {
+ node->child[b].node = NULL;
+ }
+ else if (count[b] == 1) {
+ /* face= &tree->face[offset[b]]; */
+ node->child[b].face = offset[b];
+ node->childflag |= (1 << b);
+ }
+ else {
+ if (tree->dothreadedbuild)
+ BLI_thread_lock(LOCK_CUSTOM1);
+
+ child = BLI_memarena_alloc(tree->arena, sizeof(OccNode));
+ node->child[b].node = child;
+
+ /* keep track of maximum depth for stack */
+ if (depth >= tree->maxdepth)
+ tree->maxdepth = depth + 1;
+
+ if (tree->dothreadedbuild)
+ BLI_thread_unlock(LOCK_CUSTOM1);
+
+ if (depth == 1 && tree->dothreadedbuild) {
+ othreads[totthread].tree = tree;
+ othreads[totthread].node = child;
+ othreads[totthread].begin = offset[b];
+ othreads[totthread].end = offset[b] + count[b];
+ othreads[totthread].depth = depth + 1;
+ BLI_threadpool_insert(&threads, &othreads[totthread]);
+ totthread++;
+ }
+ else
+ occ_build_recursive(tree, child, offset[b], offset[b] + count[b], depth + 1);
+ }
+ }
+
+ if (depth == 1 && tree->dothreadedbuild)
+ BLI_threadpool_end(&threads);
+ }
+
+ /* combine area, position and sh */
+ for (b = 0; b < TOTCHILD; b++) {
+ if (node->childflag & (1 << b)) {
+ child = &tmpnode;
+ occ_node_from_face(tree->face + node->child[b].face, &tmpnode);
+ }
+ else {
+ child = node->child[b].node;
+ }
+
+ if (child) {
+ node->area += child->area;
+ sh_add(node->sh, node->sh, child->sh);
+ madd_v3_v3fl(node->co, child->co, child->area);
+ }
+ }
+
+ if (node->area != 0.0f)
+ mul_v3_fl(node->co, 1.0f / node->area);
+
+ /* compute maximum distance from center */
+ node->dco = 0.0f;
+ if (node->area > 0.0f)
+ occ_build_dco(tree, node, node->co, &node->dco);
+}
+
+static void occ_build_sh_normalize(OccNode *node)
+{
+ /* normalize spherical harmonics to not include area, so
+ * we can clamp the dot product and then multiply by area */
+ int b;
+
+ if (node->area != 0.0f)
+ sh_mul(node->sh, 1.0f / node->area);
+
+ for (b = 0; b < TOTCHILD; b++) {
+ if (node->childflag & (1 << b)) {
+ /* pass */
+ }
+ else if (node->child[b].node) {
+ occ_build_sh_normalize(node->child[b].node);
+ }
+ }
+}
+
+static OcclusionTree *occ_tree_build(Render *re)
+{
+ const int num_threads = re->r.threads;
+ OcclusionTree *tree;
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ Material *ma;
+ VlakRen *vlr = NULL;
+ int a, b, c, totface;
+
+ /* count */
+ totface = 0;
+ for (obi = re->instancetable.first; obi; obi = obi->next) {
+ obr = obi->obr;
+ for (a = 0; a < obr->totvlak; a++) {
+ if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak;
+ else vlr++;
+
+ ma = vlr->mat;
+
+ if ((ma->shade_flag & MA_APPROX_OCCLUSION) && (ma->material_type == MA_TYPE_SURFACE))
+ totface++;
+ }
+ }
+
+ if (totface == 0)
+ return NULL;
+
+ tree = MEM_callocN(sizeof(OcclusionTree), "OcclusionTree");
+ tree->totface = totface;
+
+ /* parameters */
+ tree->error = get_render_aosss_error(&re->r, re->wrld.ao_approx_error);
+ tree->distfac = (re->wrld.aomode & WO_AODIST) ? re->wrld.aodistfac : 0.0f;
+ tree->doindirect = (re->wrld.ao_indirect_energy > 0.0f && re->wrld.ao_indirect_bounces > 0);
+
+ /* allocation */
+ tree->arena = BLI_memarena_new(0x8000 * sizeof(OccNode), "occ tree arena");
+ BLI_memarena_use_calloc(tree->arena);
+
+ if (re->wrld.aomode & WO_AOCACHE)
+ tree->cache = MEM_callocN(sizeof(OcclusionCache) * num_threads, "OcclusionCache");
+
+ tree->face = MEM_callocN(sizeof(OccFace) * totface, "OcclusionFace");
+ tree->co = MEM_callocN(sizeof(float) * 3 * totface, "OcclusionCo");
+ tree->occlusion = MEM_callocN(sizeof(float) * totface, "OcclusionOcclusion");
+
+ if (tree->doindirect)
+ tree->rad = MEM_callocN(sizeof(float) * 3 * totface, "OcclusionRad");
+
+ /* make array of face pointers */
+ for (b = 0, c = 0, obi = re->instancetable.first; obi; obi = obi->next, c++) {
+ obr = obi->obr;
+ for (a = 0; a < obr->totvlak; a++) {
+ if ((a & 255) == 0) vlr = obr->vlaknodes[a >> 8].vlak;
+ else vlr++;
+
+ ma = vlr->mat;
+
+ if ((ma->shade_flag & MA_APPROX_OCCLUSION) && (ma->material_type == MA_TYPE_SURFACE)) {
+ tree->face[b].obi = c;
+ tree->face[b].facenr = a;
+ tree->occlusion[b] = 1.0f;
+ occ_face(&tree->face[b], tree->co[b], NULL, NULL);
+ b++;
+ }
+ }
+ }
+
+ /* threads */
+ tree->totbuildthread = (re->r.threads > 1 && totface > 10000) ? 8 : 1;
+ tree->dothreadedbuild = (tree->totbuildthread > 1);
+
+ /* recurse */
+ tree->root = BLI_memarena_alloc(tree->arena, sizeof(OccNode));
+ tree->maxdepth = 1;
+ occ_build_recursive(tree, tree->root, 0, totface, 1);
+
+ if (tree->doindirect) {
+ if (!(re->test_break(re->tbh)))
+ occ_build_shade(re, tree);
+
+ if (!(re->test_break(re->tbh)))
+ occ_sum_occlusion(tree, tree->root);
+ }
+
+ MEM_freeN(tree->co);
+ tree->co = NULL;
+
+ if (!(re->test_break(re->tbh)))
+ occ_build_sh_normalize(tree->root);
+
+ for (a = 0; a < num_threads; a++)
+ tree->stack[a] = MEM_callocN(sizeof(OccNode) * TOTCHILD * (tree->maxdepth + 1), "OccStack");
+
+ tree->num_threads = num_threads;
+
+ return tree;
+}
+
+static void occ_free_tree(OcclusionTree *tree)
+{
+ int a;
+
+ if (tree) {
+ if (tree->arena) BLI_memarena_free(tree->arena);
+ for (a = 0; a < tree->num_threads; a++)
+ if (tree->stack[a])
+ MEM_freeN(tree->stack[a]);
+ if (tree->occlusion) MEM_freeN(tree->occlusion);
+ if (tree->cache) MEM_freeN(tree->cache);
+ if (tree->face) MEM_freeN(tree->face);
+ if (tree->rad) MEM_freeN(tree->rad);
+ MEM_freeN(tree);
+ }
+}
+
+/* ------------------------- Traversal --------------------------- */
+
+static float occ_solid_angle(OccNode *node, const float v[3], float d2, float invd2, const float receivenormal[3])
+{
+ float dotreceive, dotemit;
+ float ev[3];
+
+ ev[0] = -v[0] * invd2;
+ ev[1] = -v[1] * invd2;
+ ev[2] = -v[2] * invd2;
+ dotemit = sh_eval(node->sh, ev);
+ dotreceive = dot_v3v3(receivenormal, v) * invd2;
+
+ CLAMP(dotemit, 0.0f, 1.0f);
+ CLAMP(dotreceive, 0.0f, 1.0f);
+
+ return ((node->area * dotemit * dotreceive) / (d2 + node->area * INVPI)) * INVPI;
+}
+
+static float occ_form_factor(OccFace *face, float *p, float *n)
+{
+ ObjectInstanceRen *obi;
+ VlakRen *vlr;
+ float v1[3], v2[3], v3[3], v4[3], q0[3], q1[3], q2[3], q3[3], contrib = 0.0f;
+
+ obi = &R.objectinstance[face->obi];
+ vlr = RE_findOrAddVlak(obi->obr, face->facenr);
+
+ copy_v3_v3(v1, vlr->v1->co);
+ copy_v3_v3(v2, vlr->v2->co);
+ copy_v3_v3(v3, vlr->v3->co);
+
+ if (obi->flag & R_TRANSFORMED) {
+ mul_m4_v3(obi->mat, v1);
+ mul_m4_v3(obi->mat, v2);
+ mul_m4_v3(obi->mat, v3);
+ }
+
+ if (form_factor_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3))
+ contrib += form_factor_quad(p, n, q0, q1, q2, q3);
+
+ if (vlr->v4) {
+ copy_v3_v3(v4, vlr->v4->co);
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_v3(obi->mat, v4);
+
+ if (form_factor_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3))
+ contrib += form_factor_quad(p, n, q0, q1, q2, q3);
+ }
+
+ return contrib;
+}
+
+static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude,
+ const float pp[3], const float pn[3], float *occ, float rad[3], float bentn[3])
+{
+ OccNode *node, **stack;
+ OccFace *face;
+ float resultocc, resultrad[3], v[3], p[3], n[3], co[3], invd2;
+ float distfac, fac, error, d2, weight, emitarea;
+ int b, f, totstack;
+
+ /* init variables */
+ copy_v3_v3(p, pp);
+ copy_v3_v3(n, pn);
+ madd_v3_v3fl(p, n, 1e-4f);
+
+ if (bentn)
+ copy_v3_v3(bentn, n);
+
+ error = tree->error;
+ distfac = tree->distfac;
+
+ resultocc = 0.0f;
+ zero_v3(resultrad);
+
+ /* init stack */
+ stack = tree->stack[thread];
+ stack[0] = tree->root;
+ totstack = 1;
+
+ while (totstack) {
+ /* pop point off the stack */
+ node = stack[--totstack];
+
+ sub_v3_v3v3(v, node->co, p);
+ d2 = dot_v3v3(v, v) + 1e-16f;
+ emitarea = MAX2(node->area, node->dco);
+
+ if (d2 * error > emitarea) {
+ if (distfac != 0.0f) {
+ fac = 1.0f / (1.0f + distfac * d2);
+ if (fac < 0.01f)
+ continue;
+ }
+ else
+ fac = 1.0f;
+
+ /* accumulate occlusion from spherical harmonics */
+ invd2 = 1.0f / sqrtf(d2);
+ weight = occ_solid_angle(node, v, d2, invd2, n);
+
+ if (rad)
+ madd_v3_v3fl(resultrad, node->rad, weight * fac);
+
+ weight *= node->occlusion;
+
+ if (bentn) {
+ bentn[0] -= weight * invd2 * v[0];
+ bentn[1] -= weight * invd2 * v[1];
+ bentn[2] -= weight * invd2 * v[2];
+ }
+
+ resultocc += weight * fac;
+ }
+ else {
+ /* traverse into children */
+ for (b = 0; b < TOTCHILD; b++) {
+ if (node->childflag & (1 << b)) {
+ f = node->child[b].face;
+ face = &tree->face[f];
+
+ /* accumulate occlusion with face form factor */
+ if (!exclude || !(face->obi == exclude->obi && face->facenr == exclude->facenr)) {
+ if (bentn || distfac != 0.0f) {
+ occ_face(face, co, NULL, NULL);
+ sub_v3_v3v3(v, co, p);
+ d2 = dot_v3v3(v, v) + 1e-16f;
+
+ fac = (distfac == 0.0f) ? 1.0f : 1.0f / (1.0f + distfac * d2);
+ if (fac < 0.01f)
+ continue;
+ }
+ else
+ fac = 1.0f;
+
+ weight = occ_form_factor(face, p, n);
+
+ if (rad)
+ madd_v3_v3fl(resultrad, tree->rad[f], weight * fac);
+
+ weight *= tree->occlusion[f];
+
+ if (bentn) {
+ invd2 = 1.0f / sqrtf(d2);
+ bentn[0] -= weight * invd2 * v[0];
+ bentn[1] -= weight * invd2 * v[1];
+ bentn[2] -= weight * invd2 * v[2];
+ }
+
+ resultocc += weight * fac;
+ }
+ }
+ else if (node->child[b].node) {
+ /* push child on the stack */
+ stack[totstack++] = node->child[b].node;
+ }
+ }
+ }
+ }
+
+ if (occ) *occ = resultocc;
+ if (rad) copy_v3_v3(rad, resultrad);
+#if 0
+ if (rad && exclude) {
+ int a;
+ for (a = 0; a < tree->totface; a++)
+ if ((tree->face[a].obi == exclude->obi && tree->face[a].facenr == exclude->facenr))
+ copy_v3_v3(rad, tree->rad[a]);
+ }
+#endif
+ if (bentn) normalize_v3(bentn);
+}
+
+static void occ_compute_bounces(Render *re, OcclusionTree *tree, int totbounce)
+{
+ float (*rad)[3], (*sum)[3], (*tmp)[3], co[3], n[3], occ;
+ int bounce, i;
+
+ rad = MEM_callocN(sizeof(float) * 3 * tree->totface, "OcclusionBounceRad");
+ sum = MEM_dupallocN(tree->rad);
+
+ for (bounce = 1; bounce < totbounce; bounce++) {
+ for (i = 0; i < tree->totface; i++) {
+ occ_face(&tree->face[i], co, n, NULL);
+ madd_v3_v3fl(co, n, 1e-8f);
+
+ occ_lookup(tree, 0, &tree->face[i], co, n, &occ, rad[i], NULL);
+ rad[i][0] = MAX2(rad[i][0], 0.0f);
+ rad[i][1] = MAX2(rad[i][1], 0.0f);
+ rad[i][2] = MAX2(rad[i][2], 0.0f);
+ add_v3_v3(sum[i], rad[i]);
+
+ if (re->test_break(re->tbh))
+ break;
+ }
+
+ if (re->test_break(re->tbh))
+ break;
+
+ tmp = tree->rad;
+ tree->rad = rad;
+ rad = tmp;
+
+ occ_sum_occlusion(tree, tree->root);
+ }
+
+ MEM_freeN(rad);
+ MEM_freeN(tree->rad);
+ tree->rad = sum;
+
+ if (!re->test_break(re->tbh))
+ occ_sum_occlusion(tree, tree->root);
+}
+
+static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
+{
+ float *occ, co[3], n[3];
+ int pass, i;
+
+ occ = MEM_callocN(sizeof(float) * tree->totface, "OcclusionPassOcc");
+
+ for (pass = 0; pass < totpass; pass++) {
+ for (i = 0; i < tree->totface; i++) {
+ occ_face(&tree->face[i], co, n, NULL);
+ negate_v3(n);
+ madd_v3_v3fl(co, n, 1e-8f);
+
+ occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL, NULL);
+ if (re->test_break(re->tbh))
+ break;
+ }
+
+ if (re->test_break(re->tbh))
+ break;
+
+ for (i = 0; i < tree->totface; i++) {
+ tree->occlusion[i] -= occ[i]; //MAX2(1.0f-occ[i], 0.0f);
+ if (tree->occlusion[i] < 0.0f)
+ tree->occlusion[i] = 0.0f;
+ }
+
+ occ_sum_occlusion(tree, tree->root);
+ }
+
+ MEM_freeN(occ);
+}
+
+static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude,
+ const float co[3], const float n[3], int thread, int onlyshadow,
+ float *ao, float *env, float *indirect)
+{
+ float nn[3], bn[3], fac, occ, occlusion, correction, rad[3];
+ int envcolor;
+
+ envcolor = re->wrld.aocolor;
+ if (onlyshadow)
+ envcolor = WO_AOPLAIN;
+
+ negate_v3_v3(nn, n);
+
+ occ_lookup(tree, thread, exclude, co, nn, &occ, (tree->doindirect) ? rad : NULL, (env && envcolor) ? bn : NULL);
+
+ correction = re->wrld.ao_approx_correction;
+
+ occlusion = (1.0f - correction) * (1.0f - occ);
+ CLAMP(occlusion, 0.0f, 1.0f);
+ if (correction != 0.0f)
+ occlusion += correction * expf(-occ);
+
+ if (env) {
+ /* sky shading using bent normal */
+ if (ELEM(envcolor, WO_AOSKYCOL, WO_AOSKYTEX)) {
+ fac = 0.5f * (1.0f + dot_v3v3(bn, re->grvec));
+ env[0] = (1.0f - fac) * re->wrld.horr + fac * re->wrld.zenr;
+ env[1] = (1.0f - fac) * re->wrld.horg + fac * re->wrld.zeng;
+ env[2] = (1.0f - fac) * re->wrld.horb + fac * re->wrld.zenb;
+
+ mul_v3_fl(env, occlusion);
+ }
+ else {
+ env[0] = occlusion;
+ env[1] = occlusion;
+ env[2] = occlusion;
+ }
+#if 0
+ else { /* WO_AOSKYTEX */
+ float dxyview[3];
+ bn[0] = -bn[0];
+ bn[1] = -bn[1];
+ bn[2] = -bn[2];
+ dxyview[0] = 1.0f;
+ dxyview[1] = 1.0f;
+ dxyview[2] = 0.0f;
+ shadeSkyView(ao, co, bn, dxyview);
+ }
+#endif
+ }
+
+ if (ao) {
+ ao[0] = occlusion;
+ ao[1] = occlusion;
+ ao[2] = occlusion;
+ }
+
+ if (tree->doindirect) copy_v3_v3(indirect, rad);
+ else zero_v3(indirect);
+}
+
+/* ---------------------------- Caching ------------------------------- */
+
+static OcclusionCacheSample *find_occ_sample(OcclusionCache *cache, int x, int y)
+{
+ x -= cache->x;
+ y -= cache->y;
+
+ x /= cache->step;
+ y /= cache->step;
+ x *= cache->step;
+ y *= cache->step;
+
+ if (x < 0 || x >= cache->w || y < 0 || y >= cache->h)
+ return NULL;
+ else
+ return &cache->sample[y * cache->w + x];
+}
+
+static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int y, int thread, float *ao, float *env, float *indirect)
+{
+ OcclusionCache *cache;
+ OcclusionCacheSample *samples[4], *sample;
+ float wn[4], wz[4], wb[4], tx, ty, w, totw, mino, maxo;
+ float d[3], dist2;
+ int i, x1, y1, x2, y2;
+
+ if (!tree->cache)
+ return 0;
+
+ /* first try to find a sample in the same pixel */
+ cache = &tree->cache[thread];
+
+ if (cache->sample && cache->step) {
+ sample = &cache->sample[(y - cache->y) * cache->w + (x - cache->x)];
+ if (sample->filled) {
+ sub_v3_v3v3(d, sample->co, co);
+ dist2 = dot_v3v3(d, d);
+ if (dist2 < 0.5f * sample->dist2 && dot_v3v3(sample->n, n) > 0.98f) {
+ copy_v3_v3(ao, sample->ao);
+ copy_v3_v3(env, sample->env);
+ copy_v3_v3(indirect, sample->indirect);
+ return 1;
+ }
+ }
+ }
+ else
+ return 0;
+
+ /* try to interpolate between 4 neighboring pixels */
+ samples[0] = find_occ_sample(cache, x, y);
+ samples[1] = find_occ_sample(cache, x + cache->step, y);
+ samples[2] = find_occ_sample(cache, x, y + cache->step);
+ samples[3] = find_occ_sample(cache, x + cache->step, y + cache->step);
+
+ for (i = 0; i < 4; i++)
+ if (!samples[i] || !samples[i]->filled)
+ return 0;
+
+ /* require intensities not being too different */
+ mino = min_ffff(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
+ maxo = max_ffff(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
+
+ if (maxo - mino > 0.05f)
+ return 0;
+
+ /* compute weighted interpolation between samples */
+ zero_v3(ao);
+ zero_v3(env);
+ zero_v3(indirect);
+ totw = 0.0f;
+
+ x1 = samples[0]->x;
+ y1 = samples[0]->y;
+ x2 = samples[3]->x;
+ y2 = samples[3]->y;
+
+ tx = (float)(x2 - x) / (float)(x2 - x1);
+ ty = (float)(y2 - y) / (float)(y2 - y1);
+
+ wb[3] = (1.0f - tx) * (1.0f - ty);
+ wb[2] = (tx) * (1.0f - ty);
+ wb[1] = (1.0f - tx) * (ty);
+ wb[0] = tx * ty;
+
+ for (i = 0; i < 4; i++) {
+ sub_v3_v3v3(d, samples[i]->co, co);
+ //dist2 = dot_v3v3(d, d);
+
+ wz[i] = 1.0f; //(samples[i]->dist2/(1e-4f + dist2));
+ wn[i] = pow(dot_v3v3(samples[i]->n, n), 32.0f);
+
+ w = wb[i] * wn[i] * wz[i];
+
+ totw += w;
+ madd_v3_v3fl(ao, samples[i]->ao, w);
+ madd_v3_v3fl(env, samples[i]->env, w);
+ madd_v3_v3fl(indirect, samples[i]->indirect, w);
+ }
+
+ if (totw >= 0.9f) {
+ totw = 1.0f / totw;
+ mul_v3_fl(ao, totw);
+ mul_v3_fl(env, totw);
+ mul_v3_fl(indirect, totw);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void sample_occ_surface(ShadeInput *shi)
+{
+ StrandRen *strand = shi->strand;
+ StrandSurface *mesh = strand->buffer->surface;
+ const int *face, *index = RE_strandren_get_face(shi->obr, strand, 0);
+ float w[4], *co1, *co2, *co3, *co4;
+
+ if (mesh && mesh->face && mesh->co && mesh->ao && index) {
+ face = mesh->face[*index];
+
+ co1 = mesh->co[face[0]];
+ co2 = mesh->co[face[1]];
+ co3 = mesh->co[face[2]];
+
+ if (face[3]) {
+ co4 = mesh->co[face[3]];
+ interp_weights_quad_v3(w, co1, co2, co3, co4, strand->vert->co);
+ }
+ else {
+ interp_weights_tri_v3(w, co1, co2, co3, strand->vert->co);
+ }
+
+ zero_v3(shi->ao);
+ zero_v3(shi->env);
+ zero_v3(shi->indirect);
+
+ madd_v3_v3fl(shi->ao, mesh->ao[face[0]], w[0]);
+ madd_v3_v3fl(shi->env, mesh->env[face[0]], w[0]);
+ madd_v3_v3fl(shi->indirect, mesh->indirect[face[0]], w[0]);
+ madd_v3_v3fl(shi->ao, mesh->ao[face[1]], w[1]);
+ madd_v3_v3fl(shi->env, mesh->env[face[1]], w[1]);
+ madd_v3_v3fl(shi->indirect, mesh->indirect[face[1]], w[1]);
+ madd_v3_v3fl(shi->ao, mesh->ao[face[2]], w[2]);
+ madd_v3_v3fl(shi->env, mesh->env[face[2]], w[2]);
+ madd_v3_v3fl(shi->indirect, mesh->indirect[face[2]], w[2]);
+ if (face[3]) {
+ madd_v3_v3fl(shi->ao, mesh->ao[face[3]], w[3]);
+ madd_v3_v3fl(shi->env, mesh->env[face[3]], w[3]);
+ madd_v3_v3fl(shi->indirect, mesh->indirect[face[3]], w[3]);
+ }
+ }
+ else {
+ shi->ao[0] = 1.0f;
+ shi->ao[1] = 1.0f;
+ shi->ao[2] = 1.0f;
+ zero_v3(shi->env);
+ zero_v3(shi->indirect);
+ }
+}
+
+/* ------------------------- External Functions --------------------------- */
+
+static void *exec_strandsurface_sample(void *data)
+{
+ OcclusionThread *othread = (OcclusionThread *)data;
+ Render *re = othread->re;
+ StrandSurface *mesh = othread->mesh;
+ float ao[3], env[3], indirect[3], co[3], n[3], *co1, *co2, *co3, *co4;
+ int a, *face;
+
+ for (a = othread->begin; a < othread->end; a++) {
+ face = mesh->face[a];
+ co1 = mesh->co[face[0]];
+ co2 = mesh->co[face[1]];
+ co3 = mesh->co[face[2]];
+
+ if (face[3]) {
+ co4 = mesh->co[face[3]];
+
+ mid_v3_v3v3(co, co1, co3);
+ normal_quad_v3(n, co1, co2, co3, co4);
+ }
+ else {
+ mid_v3_v3v3v3(co, co1, co2, co3);
+ normal_tri_v3(n, co1, co2, co3);
+ }
+ negate_v3(n);
+
+ sample_occ_tree(re, re->occlusiontree, NULL, co, n, othread->thread, 0, ao, env, indirect);
+ copy_v3_v3(othread->faceao[a], ao);
+ copy_v3_v3(othread->faceenv[a], env);
+ copy_v3_v3(othread->faceindirect[a], indirect);
+ }
+
+ return NULL;
+}
+
+void make_occ_tree(Render *re)
+{
+ OcclusionThread othreads[BLENDER_MAX_THREADS];
+ OcclusionTree *tree;
+ StrandSurface *mesh;
+ ListBase threads;
+ float ao[3], env[3], indirect[3], (*faceao)[3], (*faceenv)[3], (*faceindirect)[3];
+ int a, totface, totthread, *face, *count;
+
+ /* ugly, needed for occ_face */
+ R = *re;
+
+ re->i.infostr = IFACE_("Occlusion preprocessing");
+ re->stats_draw(re->sdh, &re->i);
+
+ re->occlusiontree = tree = occ_tree_build(re);
+
+ if (tree && !re->test_break(re->tbh)) {
+ if (re->wrld.ao_approx_passes > 0)
+ occ_compute_passes(re, tree, re->wrld.ao_approx_passes);
+ if (tree->doindirect && (re->wrld.mode & WO_INDIRECT_LIGHT))
+ occ_compute_bounces(re, tree, re->wrld.ao_indirect_bounces);
+
+ for (mesh = re->strandsurface.first; mesh; mesh = mesh->next) {
+ if (!mesh->face || !mesh->co || !mesh->ao)
+ continue;
+
+ count = MEM_callocN(sizeof(int) * mesh->totvert, "OcclusionCount");
+ faceao = MEM_callocN(sizeof(float) * 3 * mesh->totface, "StrandSurfFaceAO");
+ faceenv = MEM_callocN(sizeof(float) * 3 * mesh->totface, "StrandSurfFaceEnv");
+ faceindirect = MEM_callocN(sizeof(float) * 3 * mesh->totface, "StrandSurfFaceIndirect");
+
+ totthread = (mesh->totface > 10000) ? re->r.threads : 1;
+ totface = mesh->totface / totthread;
+ for (a = 0; a < totthread; a++) {
+ othreads[a].re = re;
+ othreads[a].faceao = faceao;
+ othreads[a].faceenv = faceenv;
+ othreads[a].faceindirect = faceindirect;
+ othreads[a].thread = a;
+ othreads[a].mesh = mesh;
+ othreads[a].begin = a * totface;
+ othreads[a].end = (a == totthread - 1) ? mesh->totface : (a + 1) * totface;
+ }
+
+ if (totthread == 1) {
+ exec_strandsurface_sample(&othreads[0]);
+ }
+ else {
+ BLI_threadpool_init(&threads, exec_strandsurface_sample, totthread);
+
+ for (a = 0; a < totthread; a++)
+ BLI_threadpool_insert(&threads, &othreads[a]);
+
+ BLI_threadpool_end(&threads);
+ }
+
+ for (a = 0; a < mesh->totface; a++) {
+ face = mesh->face[a];
+
+ copy_v3_v3(ao, faceao[a]);
+ copy_v3_v3(env, faceenv[a]);
+ copy_v3_v3(indirect, faceindirect[a]);
+
+ add_v3_v3(mesh->ao[face[0]], ao);
+ add_v3_v3(mesh->env[face[0]], env);
+ add_v3_v3(mesh->indirect[face[0]], indirect);
+ count[face[0]]++;
+ add_v3_v3(mesh->ao[face[1]], ao);
+ add_v3_v3(mesh->env[face[1]], env);
+ add_v3_v3(mesh->indirect[face[1]], indirect);
+ count[face[1]]++;
+ add_v3_v3(mesh->ao[face[2]], ao);
+ add_v3_v3(mesh->env[face[2]], env);
+ add_v3_v3(mesh->indirect[face[2]], indirect);
+ count[face[2]]++;
+
+ if (face[3]) {
+ add_v3_v3(mesh->ao[face[3]], ao);
+ add_v3_v3(mesh->env[face[3]], env);
+ add_v3_v3(mesh->indirect[face[3]], indirect);
+ count[face[3]]++;
+ }
+ }
+
+ for (a = 0; a < mesh->totvert; a++) {
+ if (count[a]) {
+ mul_v3_fl(mesh->ao[a], 1.0f / count[a]);
+ mul_v3_fl(mesh->env[a], 1.0f / count[a]);
+ mul_v3_fl(mesh->indirect[a], 1.0f / count[a]);
+ }
+ }
+
+ MEM_freeN(count);
+ MEM_freeN(faceao);
+ MEM_freeN(faceenv);
+ MEM_freeN(faceindirect);
+ }
+ }
+}
+
+void free_occ(Render *re)
+{
+ if (re->occlusiontree) {
+ occ_free_tree(re->occlusiontree);
+ re->occlusiontree = NULL;
+ }
+}
+
+void sample_occ(Render *re, ShadeInput *shi)
+{
+ OcclusionTree *tree = re->occlusiontree;
+ OcclusionCache *cache;
+ OcclusionCacheSample *sample;
+ OccFace exclude;
+ int onlyshadow;
+
+ if (tree) {
+ if (shi->strand) {
+ sample_occ_surface(shi);
+ }
+ /* try to get result from the cache if possible */
+ else if (shi->depth != 0 || !sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao, shi->env, shi->indirect)) {
+ /* no luck, let's sample the occlusion */
+ exclude.obi = shi->obi - re->objectinstance;
+ exclude.facenr = shi->vlr->index;
+ onlyshadow = (shi->mat->mode & MA_ONLYSHADOW);
+ sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->env, shi->indirect);
+
+ /* fill result into sample, each time */
+ if (tree->cache) {
+ cache = &tree->cache[shi->thread];
+
+ if (cache->sample && cache->step) {
+ sample = &cache->sample[(shi->ys - cache->y) * cache->w + (shi->xs - cache->x)];
+ copy_v3_v3(sample->co, shi->co);
+ copy_v3_v3(sample->n, shi->vno);
+ copy_v3_v3(sample->ao, shi->ao);
+ copy_v3_v3(sample->env, shi->env);
+ copy_v3_v3(sample->indirect, shi->indirect);
+ sample->intensity = max_fff(sample->ao[0], sample->ao[1], sample->ao[2]);
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->env[0], sample->env[1], sample->env[2]));
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
+ sample->dist2 = dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco);
+ sample->filled = 1;
+ }
+ }
+ }
+ }
+ else {
+ shi->ao[0] = 1.0f;
+ shi->ao[1] = 1.0f;
+ shi->ao[2] = 1.0f;
+
+ shi->env[0] = 0.0f;
+ shi->env[1] = 0.0f;
+ shi->env[2] = 0.0f;
+
+ shi->indirect[0] = 0.0f;
+ shi->indirect[1] = 0.0f;
+ shi->indirect[2] = 0.0f;
+ }
+}
+
+void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp)
+{
+ OcclusionTree *tree = re->occlusiontree;
+ PixStr ps;
+ OcclusionCache *cache;
+ OcclusionCacheSample *sample;
+ OccFace exclude;
+ ShadeInput *shi;
+ intptr_t *rd = NULL;
+ int *ro = NULL, *rp = NULL, *rz = NULL, onlyshadow;
+ int x, y, step = CACHE_STEP;
+
+ if (!tree->cache)
+ return;
+
+ cache = &tree->cache[pa->thread];
+ cache->w = pa->rectx;
+ cache->h = pa->recty;
+ cache->x = pa->disprect.xmin;
+ cache->y = pa->disprect.ymin;
+ cache->step = step;
+ cache->sample = MEM_callocN(sizeof(OcclusionCacheSample) * cache->w * cache->h, "OcclusionCacheSample");
+ sample = cache->sample;
+
+ if (re->osa) {
+ rd = pa->rectdaps;
+ }
+ else {
+ /* fake pixel struct for non-osa */
+ ps.next = NULL;
+ ps.mask = 0xFFFF;
+
+ ro = pa->recto;
+ rp = pa->rectp;
+ rz = pa->rectz;
+ }
+
+ /* compute a sample at every step pixels */
+ for (y = pa->disprect.ymin; y < pa->disprect.ymax; y++) {
+ for (x = pa->disprect.xmin; x < pa->disprect.xmax; x++, sample++, rd++, ro++, rp++, rz++) {
+ if (!(((x - pa->disprect.xmin + step) % step) == 0 || x == pa->disprect.xmax - 1))
+ continue;
+ if (!(((y - pa->disprect.ymin + step) % step) == 0 || y == pa->disprect.ymax - 1))
+ continue;
+
+ if (re->osa) {
+ if (!*rd) continue;
+
+ shade_samples_fill_with_ps(ssamp, (PixStr *)(*rd), x, y);
+ }
+ else {
+ if (!*rp) continue;
+
+ ps.obi = *ro;
+ ps.facenr = *rp;
+ ps.z = *rz;
+ shade_samples_fill_with_ps(ssamp, &ps, x, y);
+ }
+
+ shi = ssamp->shi;
+ if (shi->vlr) {
+ onlyshadow = (shi->mat->mode & MA_ONLYSHADOW);
+ exclude.obi = shi->obi - re->objectinstance;
+ exclude.facenr = shi->vlr->index;
+ sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao, shi->env, shi->indirect);
+
+ copy_v3_v3(sample->co, shi->co);
+ copy_v3_v3(sample->n, shi->vno);
+ copy_v3_v3(sample->ao, shi->ao);
+ copy_v3_v3(sample->env, shi->env);
+ copy_v3_v3(sample->indirect, shi->indirect);
+ sample->intensity = max_fff(sample->ao[0], sample->ao[1], sample->ao[2]);
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->env[0], sample->env[1], sample->env[2]));
+ sample->intensity = max_ff(sample->intensity, max_fff(sample->indirect[0], sample->indirect[1], sample->indirect[2]));
+ sample->dist2 = dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco);
+ sample->x = shi->xs;
+ sample->y = shi->ys;
+ sample->filled = 1;
+ }
+
+ if (re->test_break(re->tbh))
+ break;
+ }
+ }
+}
+
+void free_occ_samples(Render *re, RenderPart *pa)
+{
+ OcclusionTree *tree = re->occlusiontree;
+ OcclusionCache *cache;
+
+ if (tree->cache) {
+ cache = &tree->cache[pa->thread];
+
+ if (cache->sample)
+ MEM_freeN(cache->sample);
+
+ cache->w = 0;
+ cache->h = 0;
+ cache->step = 0;
+ }
+}
+
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 595640489c8..c9f13004836 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -137,7 +137,7 @@
/* here we store all renders */
static struct {
ListBase renderlist;
-} RenderGlobal = {{NULL, NULL}};
+} RenderGlobal = {{NULL, NULL}};
/* ********* alloc and free ******** */
@@ -424,10 +424,10 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id)
if (re->result) {
RenderLayer *rl;
RenderView *rv;
-
+
rr->rectx = re->result->rectx;
rr->recty = re->result->recty;
-
+
/* actview view */
rv = RE_RenderViewGetById(re->result, view_id);
rr->have_combined = (rv->rectf != NULL);
@@ -494,7 +494,7 @@ Render *RE_NewRender(const char *name)
/* only one render per name exists */
re = RE_GetRender(name);
if (re == NULL) {
-
+
/* new render data struct */
re = MEM_callocN(sizeof(Render), "new render");
BLI_addtail(&RenderGlobal.renderlist, re);
@@ -502,7 +502,7 @@ Render *RE_NewRender(const char *name)
BLI_rw_mutex_init(&re->resultmutex);
BLI_rw_mutex_init(&re->partsmutex);
}
-
+
RE_InitRenderCB(re);
return re;
@@ -574,10 +574,10 @@ void RE_FreeRender(Render *re)
/* main dbase can already be invalid now, some database-free code checks it */
re->main = NULL;
re->scene = NULL;
-
+
render_result_free(re->result);
render_result_free(re->pushedresult);
-
+
BLI_remlink(&RenderGlobal.renderlist, re);
MEM_freeN(re);
}
@@ -715,7 +715,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd,
bool had_freestyle = (re->r.mode & R_EDGE_FRS) != 0;
re->ok = true; /* maybe flag */
-
+
re->i.starttime = PIL_check_seconds_timer();
/* copy render data and render layers for thread safety */
@@ -753,7 +753,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd,
}
re->r.scemode = check_mode_full_sample(&re->r);
-
+
if (single_layer) {
int index = BLI_findindex(render_layers, single_layer);
if (index != -1) {
@@ -761,7 +761,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd,
re->r.scemode |= R_SINGLE_LAYER;
}
}
-
+
/* if preview render, we try to keep old result */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
@@ -794,7 +794,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd,
}
}
else {
-
+
/* make empty render result, so display callbacks can initialize */
render_result_free(re->result);
re->result = MEM_callocN(sizeof(RenderResult), "new render result");
@@ -811,7 +811,7 @@ void RE_InitState(Render *re, Render *source, RenderData *rd,
RE_parts_clamp(re);
BLI_rw_mutex_unlock(&re->resultmutex);
-
+
RE_init_threadcount(re);
RE_point_density_fix_linking();
@@ -925,7 +925,7 @@ void render_update_anim_renderdata(Render *re, RenderData *rd, ListBase *render_
void RE_SetWindow(Render *re, const rctf *viewplane, float clipsta, float clipend)
{
/* re->ok flag? */
-
+
re->viewplane = *viewplane;
re->clipsta = clipsta;
re->clipend = clipend;
@@ -934,13 +934,13 @@ void RE_SetWindow(Render *re, const rctf *viewplane, float clipsta, float clipen
perspective_m4(re->winmat,
re->viewplane.xmin, re->viewplane.xmax,
re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend);
-
+
}
void RE_SetOrtho(Render *re, const rctf *viewplane, float clipsta, float clipend)
{
/* re->ok flag? */
-
+
re->viewplane = *viewplane;
re->clipsta = clipsta;
re->clipend = clipend;
@@ -961,7 +961,7 @@ void RE_SetView(Render *re, float mat[4][4])
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;
@@ -1028,7 +1028,7 @@ void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle))
#if 0
void RE_AddObject(Render *UNUSED(re), Object *UNUSED(ob))
{
-
+
}
#endif
@@ -1121,9 +1121,9 @@ static void do_render(Render *re)
/* now use renderdata and camera to set viewplane */
RE_SetCamera(re, camera);
-
+
do_render_3d(re);
-
+
/* when border render, check if we have to insert it in black */
render_result_uncrop(re);
}
@@ -1136,7 +1136,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
{
Render *resc = RE_NewSceneRender(sce);
int winx = re->winx, winy = re->winy;
-
+
sce->r.cfra = cfra;
BKE_scene_camera_switch_update(sce);
@@ -1146,7 +1146,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
winx = (sce->r.size * sce->r.xsch) / 100;
winy = (sce->r.size * sce->r.ysch) / 100;
}
-
+
/* initial setup */
RE_InitState(resc, re, &sce->r, &sce->view_layers, NULL, winx, winy, &re->disprect);
@@ -1157,7 +1157,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
resc->main = re->main;
resc->scene = sce;
resc->lay = sce->lay;
-
+
/* ensure scene has depsgraph, base flags etc OK */
BKE_scene_set_background(re->main, sce);
@@ -1170,7 +1170,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
resc->sdh = re->sdh;
resc->current_scene_update = re->current_scene_update;
resc->suh = re->suh;
-
+
do_render(resc);
}
@@ -1179,11 +1179,11 @@ static int composite_needs_render(Scene *sce, int this_scene)
{
bNodeTree *ntree = sce->nodetree;
bNode *node;
-
+
if (ntree == NULL) return 1;
if (sce->use_nodes == false) return 1;
if ((sce->r.scemode & R_DOCOMP) == 0) return 1;
-
+
for (node = ntree->nodes.first; node; node = node->next) {
if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0)
if (this_scene == 0 || node->id == NULL || node->id == &sce->id)
@@ -1334,14 +1334,14 @@ static void tag_scenes_for_render(Render *re)
{
bNode *node;
Scene *sce;
-
+
for (sce = re->main->scene.first; sce; sce = sce->id.next) {
sce->id.tag &= ~LIB_TAG_DOIT;
#ifdef DEPSGRAPH_WORKAROUND_HACK
tag_dependend_objects_for_render(re->main, sce);
#endif
}
-
+
#ifdef WITH_FREESTYLE
if (re->freestyle_bmain) {
for (sce = re->freestyle_bmain->scene.first; sce; sce = sce->id.next) {
@@ -1359,9 +1359,9 @@ static void tag_scenes_for_render(Render *re)
tag_dependend_objects_for_render(re->main, re->scene);
#endif
}
-
+
if (re->scene->nodetree == NULL) return;
-
+
/* check for render-layers nodes using other scenes, we tag them LIB_TAG_DOIT */
for (node = re->scene->nodetree->nodes.first; node; node = node->next) {
node->flag &= ~NODE_TEST;
@@ -1397,7 +1397,7 @@ static void tag_scenes_for_render(Render *re)
}
}
}
-
+
}
static void ntree_render_scenes(Render *re)
@@ -1406,15 +1406,15 @@ static void ntree_render_scenes(Render *re)
int cfra = re->scene->r.cfra;
Scene *restore_scene = re->scene;
bool scene_changed = false;
-
+
if (re->scene->nodetree == NULL) return;
-
+
tag_scenes_for_render(re);
#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK
tag_collections_for_render(re);
#endif
-
+
/* now foreach render-result node tagged we do a full render */
/* results are stored in a way compisitor will find it */
for (node = re->scene->nodetree->nodes.first; node; node = node->next) {
@@ -1426,7 +1426,7 @@ static void ntree_render_scenes(Render *re)
scene_changed |= scene != restore_scene;
render_scene(re, scene, cfra);
node->flag &= ~NODE_TEST;
-
+
nodeUpdate(restore_scene->nodetree, node);
}
}
@@ -1531,10 +1531,10 @@ static void do_render_composite(Render *re)
{
bNodeTree *ntree = re->scene->nodetree;
int update_newframe = 0;
-
+
/* INIT seeding, compositor can use random texture */
BLI_srandom(re->r.cfra);
-
+
if (composite_needs_render(re->scene, 1)) {
/* save memory... free all cached images */
ntreeFreeCache(ntree);
@@ -1550,7 +1550,7 @@ static void do_render_composite(Render *re)
/* ensure new result gets added, like for regular renders */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
-
+
render_result_free(re->result);
if ((re->r.mode & R_CROP) == 0) {
render_result_disprect_to_full_resolution(re);
@@ -1558,30 +1558,30 @@ static void do_render_composite(Render *re)
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
BLI_rw_mutex_unlock(&re->resultmutex);
-
+
/* scene render process already updates animsys */
update_newframe = 1;
}
-
+
/* swap render result */
if (re->r.scemode & R_SINGLE_LAYER) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
render_result_single_layer_end(re);
BLI_rw_mutex_unlock(&re->resultmutex);
}
-
+
if (!re->test_break(re->tbh)) {
-
+
if (ntree) {
ntreeCompositTagRender(re->scene);
ntreeCompositTagAnimated(ntree);
}
-
+
if (ntree && re->scene->use_nodes && re->r.scemode & R_DOCOMP) {
/* checks if there are render-result nodes that need scene */
if ((re->r.scemode & R_SINGLE_LAYER) == 0)
ntree_render_scenes(re);
-
+
if (!re->test_break(re->tbh)) {
ntree->stats_draw = render_composit_stats;
ntree->test_break = re->test_break;
@@ -1589,16 +1589,16 @@ static void do_render_composite(Render *re)
ntree->sdh = re;
ntree->tbh = re->tbh;
ntree->prh = re->prh;
-
+
if (update_newframe) {
/* If we have consistent depsgraph now would be a time to update them. */
}
-
+
RenderView *rv;
for (rv = re->result->views.first; rv; rv = rv->next) {
ntreeCompositExecTree(re->scene, ntree, &re->r, true, G.background == 0, &re->scene->view_settings, &re->scene->display_settings, rv->name);
}
-
+
ntree->stats_draw = NULL;
ntree->test_break = NULL;
ntree->progress = NULL;
@@ -1651,15 +1651,15 @@ int RE_seq_render_active(Scene *scene, RenderData *rd)
Sequence *seq;
ed = scene->ed;
-
+
if (!(rd->scemode & R_DOSEQ) || !ed || !ed->seqbase.first)
return 0;
-
+
for (seq = ed->seqbase.first; seq; seq = seq->next) {
if (seq->type != SEQ_TYPE_SOUND_RAM)
return 1;
}
-
+
return 0;
}
@@ -1810,18 +1810,18 @@ static void do_render_all_options(Render *re)
do_render_seq(re);
render_seq = true;
}
-
+
re->stats_draw(re->sdh, &re->i);
re->display_update(re->duh, re->result, NULL);
}
else {
do_render_composite(re);
}
-
+
re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
-
+
re->stats_draw(re->sdh, &re->i);
-
+
/* save render result stamp if needed */
if (re->result != NULL) {
camera = RE_GetCamera(re);
@@ -1975,7 +1975,7 @@ static int check_composite_output(Scene *scene)
bool RE_is_rendering_allowed(Scene *scene, ViewLayer *single_layer, Object *camera_override, ReportList *reports)
{
int scemode = check_mode_full_sample(&scene->r);
-
+
if (scene->r.mode & R_BORDER) {
if (scene->r.border.xmax <= scene->r.border.xmin ||
scene->r.border.ymax <= scene->r.border.ymin)
@@ -1984,30 +1984,30 @@ bool RE_is_rendering_allowed(Scene *scene, ViewLayer *single_layer, Object *came
return 0;
}
}
-
+
if (scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) {
char str[FILE_MAX];
-
+
render_result_exr_file_path(scene, "", 0, str);
-
+
if (!BLI_file_is_writable(str)) {
BKE_report(reports, RPT_ERROR, "Cannot save render buffers, check the temp default path");
return 0;
}
}
-
+
if (scemode & R_DOCOMP) {
if (scene->use_nodes) {
if (!scene->nodetree) {
BKE_report(reports, RPT_ERROR, "No node tree in scene");
return 0;
}
-
+
if (!check_composite_output(scene)) {
BKE_report(reports, RPT_ERROR, "No render output node in scene");
return 0;
}
-
+
if (scemode & R_FULL_SAMPLE) {
if (composite_needs_render(scene, 0) == 0) {
BKE_report(reports, RPT_ERROR, "Full sample AA not supported without 3D rendering");
@@ -2016,12 +2016,12 @@ bool RE_is_rendering_allowed(Scene *scene, ViewLayer *single_layer, Object *came
}
}
}
-
+
/* check valid camera, without camera render is OK (compo, seq) */
if (!check_valid_camera(scene, camera_override, reports)) {
return 0;
}
-
+
/* get panorama & ortho, only after camera is set */
BKE_camera_object_mode(&scene->r, camera_override ? camera_override : scene->camera);
@@ -2098,19 +2098,19 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain,
{
int winx, winy;
rcti disprect;
-
+
/* r.xsch and r.ysch has the actual view window size
* r.border is the clipping rect */
-
+
/* calculate actual render result and display size */
winx = (rd->size * rd->xsch) / 100;
winy = (rd->size * rd->ysch) / 100;
-
+
/* we always render smaller part, inserting it in larger image is compositor bizz, it uses disprect for it */
if (scene->r.mode & R_BORDER) {
disprect.xmin = rd->border.xmin * winx;
disprect.xmax = rd->border.xmax * winx;
-
+
disprect.ymin = rd->border.ymin * winy;
disprect.ymax = rd->border.ymax * winy;
}
@@ -2119,7 +2119,7 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain,
disprect.xmax = winx;
disprect.ymax = winy;
}
-
+
re->main = bmain;
re->scene = scene;
re->camera_override = camera_override;
@@ -2134,7 +2134,7 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain,
re->disprect = disprect;
return 1;
}
-
+
/* check all scenes involved */
tag_scenes_for_render(re);
@@ -2153,17 +2153,17 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain,
ViewLayer *view_layer = BKE_view_layer_context_active_PLACEHOLDER(scene);
update_physics_cache(re, scene, view_layer, anim_init);
}
-
+
if (single_layer || scene->r.scemode & R_SINGLE_LAYER) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
render_result_single_layer_begin(re);
BLI_rw_mutex_unlock(&re->resultmutex);
}
-
+
RE_InitState(re, NULL, &scene->r, &scene->view_layers, single_layer, winx, winy, &disprect);
if (!re->ok) /* if an error was printed, abort */
return 0;
-
+
/* initstate makes new result, have to send changed tags around */
ntreeCompositTagRender(re->scene);
@@ -2171,7 +2171,7 @@ static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain,
re->display_init(re->dih, re->result);
re->display_clear(re->dch, re->result);
-
+
return 1;
}
@@ -2188,9 +2188,9 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, ViewLayer *single_la
/* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */
G.is_rendering = true;
-
+
scene->r.cfra = frame;
-
+
if (render_initialize_from_main(re, &scene->r, bmain, scene, single_layer,
camera_override, lay_override, 0, 0))
{
@@ -2208,7 +2208,7 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, ViewLayer *single_la
else {
char name[FILE_MAX];
BKE_image_path_from_imformat(
- name, scene->r.pic, bmain->name, scene->r.cfra,
+ name, scene->r.pic, BKE_main_blendfile_path(bmain), scene->r.cfra,
&scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false, NULL);
/* reports only used for Movie */
@@ -2467,18 +2467,18 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
BLI_strncpy(name, name_override, sizeof(name));
else
BKE_image_path_from_imformat(
- name, scene->r.pic, bmain->name, scene->r.cfra,
+ name, scene->r.pic, BKE_main_blendfile_path(bmain), scene->r.cfra,
&scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true, NULL);
/* write images as individual images or stereo */
ok = RE_WriteRenderViewsImage(re->reports, &rres, scene, true, name);
}
-
+
RE_ReleaseResultImageViews(re, &rres);
render_time = re->i.lastframetime;
re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
-
+
BLI_timecode_string_from_time_simple(name, sizeof(name), re->i.lastframetime);
printf(" Time: %s", name);
@@ -2489,7 +2489,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
BLI_timecode_string_from_time_simple(name, sizeof(name), re->i.lastframetime - render_time);
printf(" (Saving: %s)\n", name);
-
+
fputc('\n', stdout);
fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
@@ -2647,7 +2647,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
if (is_movie == false) {
if (scene->r.mode & (R_NO_OVERWRITE | R_TOUCH))
BKE_image_path_from_imformat(
- name, scene->r.pic, bmain->name, scene->r.cfra,
+ name, scene->r.pic, BKE_main_blendfile_path(bmain), scene->r.cfra,
&scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true, NULL);
if (scene->r.mode & R_NO_OVERWRITE) {
@@ -2713,10 +2713,10 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
/* run callbacs before rendering, before the scene is updated */
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE);
-
+
do_render_all_options(re);
totrendered++;
-
+
if (re->test_break(re->tbh) == 0) {
if (!G.is_break)
if (!do_write_image_or_movie(re, bmain, scene, mh, totvideos, NULL))
@@ -2724,7 +2724,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
}
else
G.is_break = true;
-
+
if (G.is_break == true) {
/* remove touched file */
if (is_movie == false) {
@@ -2753,7 +2753,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
}
}
}
-
+
break;
}
@@ -2763,12 +2763,12 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
}
}
}
-
+
/* end movie */
if (is_movie) {
re_movie_free_all(re, mh, totvideos);
}
-
+
if (totskipped && totrendered == 0)
BKE_report(re->reports, RPT_INFO, "No frames rendered, skipped to not overwrite");
@@ -2812,16 +2812,16 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
int winx, winy;
bool success;
rcti disprect;
-
+
/* calculate actual render result and display size */
winx = (scene->r.size * scene->r.xsch) / 100;
winy = (scene->r.size * scene->r.ysch) / 100;
-
+
/* only in movie case we render smaller part */
if (scene->r.mode & R_BORDER) {
disprect.xmin = scene->r.border.xmin * winx;
disprect.xmax = scene->r.border.xmax * winx;
-
+
disprect.ymin = scene->r.border.ymin * winy;
disprect.ymax = scene->r.border.ymax * winy;
}
@@ -2830,17 +2830,17 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
disprect.xmax = winx;
disprect.ymax = winy;
}
-
+
if (scenode)
scene = scenode;
-
+
/* get render: it can be called from UI with draw callbacks */
re = RE_GetSceneRender(scene);
if (re == NULL)
re = RE_NewSceneRender(scene);
RE_InitState(re, NULL, &scene->r, &scene->view_layers, NULL, winx, winy, &disprect);
re->scene = scene;
-
+
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
success = render_result_exr_file_cache_read(re);
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -2850,7 +2850,7 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
return success;
}
-void RE_init_threadcount(Render *re)
+void RE_init_threadcount(Render *re)
{
re->r.threads = BKE_render_num_threads(&re->r);
}
@@ -3014,7 +3014,7 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha
rl->rectx = rr->rectx;
rl->recty = rr->recty;
}
-
+
/* clear previous pass if exist or the new image will be over previous one*/
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
if (rp) {
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
new file mode 100644
index 00000000000..c7cfe765f5b
--- /dev/null
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -0,0 +1,400 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): Full recode, 2004-2006 Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/pixelblending.c
+ * \ingroup render
+ *
+ * Functions to blend pixels with or without alpha, in various formats
+ * nzc - June 2000
+ */
+
+
+#include <math.h>
+#include <string.h>
+
+/* global includes */
+
+/* own includes */
+#include "render_types.h"
+#include "pixelblending.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+
+/* ------------------------------------------------------------------------- */
+/* Debug/behavior defines */
+/* if defined: alpha blending with floats clips color, as with shorts */
+/* #define RE_FLOAT_COLOR_CLIPPING */
+/* if defined: alpha values are clipped */
+/* For now, we just keep alpha clipping. We run into thresholding and */
+/* blending difficulties otherwise. Be careful here. */
+#define RE_ALPHA_CLIPPING
+
+
+
+/* Threshold for a 'full' pixel: pixels with alpha above this level are */
+/* considered opaque This is the decimal value for 0xFFF0 / 0xFFFF */
+#define RE_FULL_COLOR_FLOAT 0.9998f
+/* Threshold for an 'empty' pixel: pixels with alpha above this level are */
+/* considered completely transparent. This is the decimal value */
+/* for 0x000F / 0xFFFF */
+#define RE_EMPTY_COLOR_FLOAT 0.0002f
+
+
+/* ------------------------------------------------------------------------- */
+
+void addAlphaOverFloat(float dest[4], const float source[4])
+{
+ /* d = s + (1-alpha_s)d*/
+ float mul;
+
+ mul = 1.0f - source[3];
+
+ dest[0] = (mul * dest[0]) + source[0];
+ dest[1] = (mul * dest[1]) + source[1];
+ dest[2] = (mul * dest[2]) + source[2];
+ dest[3] = (mul * dest[3]) + source[3];
+
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+void addAlphaUnderFloat(float dest[4], const float source[4])
+{
+ float mul;
+
+ mul = 1.0f - dest[3];
+
+ dest[0] += (mul * source[0]);
+ dest[1] += (mul * source[1]);
+ dest[2] += (mul * source[2]);
+ dest[3] += (mul * source[3]);
+}
+
+
+/* ------------------------------------------------------------------------- */
+void addalphaAddfacFloat(float dest[4], const float source[4], char addfac)
+{
+ float m; /* weiging factor of destination */
+ float c; /* intermediate color */
+
+ /* Addfac is a number between 0 and 1: rescale */
+ /* final target is to diminish the influence of dest when addfac rises */
+ m = 1.0f - (source[3] * ((255 - addfac) / 255.0f));
+
+ /* blend colors*/
+ c = (m * dest[0]) + source[0];
+#ifdef RE_FLOAT_COLOR_CLIPPING
+ if (c >= RE_FULL_COLOR_FLOAT) dest[0] = RE_FULL_COLOR_FLOAT;
+ else
+#endif
+ dest[0] = c;
+
+ c = (m * dest[1]) + source[1];
+#ifdef RE_FLOAT_COLOR_CLIPPING
+ if (c >= RE_FULL_COLOR_FLOAT) dest[1] = RE_FULL_COLOR_FLOAT;
+ else
+#endif
+ dest[1] = c;
+
+ c = (m * dest[2]) + source[2];
+#ifdef RE_FLOAT_COLOR_CLIPPING
+ if (c >= RE_FULL_COLOR_FLOAT) dest[2] = RE_FULL_COLOR_FLOAT;
+ else
+#endif
+ dest[2] = c;
+
+ c = (m * dest[3]) + source[3];
+#ifdef RE_ALPHA_CLIPPING
+ if (c >= RE_FULL_COLOR_FLOAT) dest[3] = RE_FULL_COLOR_FLOAT;
+ else
+#endif
+ dest[3] = c;
+
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/* filtered adding to scanlines */
+void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w)
+{
+ /* calc the value of mask */
+ float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2;
+ float *rb1, *rb2, *rb3;
+ float val, r, g, b, al;
+ unsigned int a, maskand, maskshift;
+ int j;
+
+ r = col[0];
+ g = col[1];
+ b = col[2];
+ al = col[3];
+
+ rb2 = rowbuf - 4;
+ rb3 = rb2 - 4 * row_w;
+ rb1 = rb2 + 4 * row_w;
+
+ maskand = (mask & 255);
+ maskshift = (mask >> 8);
+
+ for (j = 2; j >= 0; j--) {
+
+ a = j;
+
+ val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+ if (val != 0.0f) {
+ rb1[0] += val * r;
+ rb1[1] += val * g;
+ rb1[2] += val * b;
+ rb1[3] += val * al;
+ }
+ a += 3;
+
+ val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+ if (val != 0.0f) {
+ rb2[0] += val * r;
+ rb2[1] += val * g;
+ rb2[2] += val * b;
+ rb2[3] += val * al;
+ }
+ a += 3;
+
+ val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+ if (val != 0.0f) {
+ rb3[0] += val * r;
+ rb3[1] += val * g;
+ rb3[2] += val * b;
+ rb3[3] += val * al;
+ }
+
+ rb1 += 4;
+ rb2 += 4;
+ rb3 += 4;
+ }
+}
+
+
+void mask_array(unsigned int mask, float filt[3][3])
+{
+ float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2;
+ unsigned int maskand = (mask & 255);
+ unsigned int maskshift = (mask >> 8);
+ int a, j;
+
+ for (j = 2; j >= 0; j--) {
+
+ a = j;
+
+ filt[2][2 - j] = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+
+ a += 3;
+
+ filt[1][2 - j] = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+
+ a += 3;
+
+ filt[0][2 - j] = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+ }
+}
+
+
+/**
+ * Index ordering, scanline based:
+ *
+ * <pre>
+ * --- --- ---
+ * | 2,0 | 2,1 | 2,2 |
+ * --- --- ---
+ * | 1,0 | 1,1 | 1,2 |
+ * --- --- ---
+ * | 0,0 | 0,1 | 0,2 |
+ * --- --- ---
+ * </pre>
+ */
+
+void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_stride, int x, int y, rcti *mask)
+{
+ float *fpoin[3][3];
+ float val, r, g, b, al, lfilt[3][3];
+
+ r = col[0];
+ g = col[1];
+ b = col[2];
+ al = col[3];
+
+ memcpy(lfilt, filt, sizeof(lfilt));
+
+ fpoin[0][1] = rowbuf - 4 * row_stride;
+ fpoin[1][1] = rowbuf;
+ fpoin[2][1] = rowbuf + 4 * row_stride;
+
+ fpoin[0][0] = fpoin[0][1] - 4;
+ fpoin[1][0] = fpoin[1][1] - 4;
+ fpoin[2][0] = fpoin[2][1] - 4;
+
+ fpoin[0][2] = fpoin[0][1] + 4;
+ fpoin[1][2] = fpoin[1][1] + 4;
+ fpoin[2][2] = fpoin[2][1] + 4;
+
+ /* limit filtering to withing a mask for border rendering, so pixels don't
+ * leak outside of the border */
+ if (y <= mask->ymin) {
+ fpoin[0][0] = fpoin[1][0];
+ fpoin[0][1] = fpoin[1][1];
+ fpoin[0][2] = fpoin[1][2];
+ /* filter needs the opposite value yes! */
+ lfilt[0][0] = filt[2][0];
+ lfilt[0][1] = filt[2][1];
+ lfilt[0][2] = filt[2][2];
+ }
+ else if (y >= mask->ymax - 1) {
+ fpoin[2][0] = fpoin[1][0];
+ fpoin[2][1] = fpoin[1][1];
+ fpoin[2][2] = fpoin[1][2];
+
+ lfilt[2][0] = filt[0][0];
+ lfilt[2][1] = filt[0][1];
+ lfilt[2][2] = filt[0][2];
+ }
+
+ if (x <= mask->xmin) {
+ fpoin[2][0] = fpoin[2][1];
+ fpoin[1][0] = fpoin[1][1];
+ fpoin[0][0] = fpoin[0][1];
+
+ lfilt[2][0] = filt[2][2];
+ lfilt[1][0] = filt[1][2];
+ lfilt[0][0] = filt[0][2];
+ }
+ else if (x >= mask->xmax - 1) {
+ fpoin[2][2] = fpoin[2][1];
+ fpoin[1][2] = fpoin[1][1];
+ fpoin[0][2] = fpoin[0][1];
+
+ lfilt[2][2] = filt[2][0];
+ lfilt[1][2] = filt[1][0];
+ lfilt[0][2] = filt[0][0];
+ }
+
+
+ /* loop unroll */
+#define MASKFILT(i, j) \
+ val = lfilt[i][j]; \
+ if (val != 0.0f) { \
+ float *fp = fpoin[i][j]; \
+ fp[0] += val * r; \
+ fp[1] += val * g; \
+ fp[2] += val * b; \
+ fp[3] += val * al; \
+ } (void)0
+
+ MASKFILT(0, 0);
+ MASKFILT(0, 1);
+ MASKFILT(0, 2);
+ MASKFILT(1, 0);
+ MASKFILT(1, 1);
+ MASKFILT(1, 2);
+ MASKFILT(2, 0);
+ MASKFILT(2, 1);
+ MASKFILT(2, 2);
+
+#undef MASKFILT
+}
+
+void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize)
+{
+ /* calc the value of mask */
+ float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2;
+ float *rb1, *rb2, *rb3;
+ float val;
+ unsigned int a, maskand, maskshift;
+ int i, j;
+
+ rb2 = rowbuf - pixsize;
+ rb3 = rb2 - pixsize * row_w;
+ rb1 = rb2 + pixsize * row_w;
+
+ maskand = (mask & 255);
+ maskshift = (mask >> 8);
+
+ for (j = 2; j >= 0; j--) {
+
+ a = j;
+
+ val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+ if (val != 0.0f) {
+ for (i = 0; i < pixsize; i++)
+ rb1[i] += val * in[i];
+ }
+ a += 3;
+
+ val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+ if (val != 0.0f) {
+ for (i = 0; i < pixsize; i++)
+ rb2[i] += val * in[i];
+ }
+ a += 3;
+
+ val = *(fmask1[a] + maskand) + *(fmask2[a] + maskshift);
+ if (val != 0.0f) {
+ for (i = 0; i < pixsize; i++)
+ rb3[i] += val * in[i];
+ }
+
+ rb1 += pixsize;
+ rb2 += pixsize;
+ rb3 += pixsize;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+void addalphaAddFloat(float dest[4], const float source[4])
+{
+
+ /* Makes me wonder whether this is required... */
+ if (dest[3] < RE_EMPTY_COLOR_FLOAT) {
+ dest[0] = source[0];
+ dest[1] = source[1];
+ dest[2] = source[2];
+ dest[3] = source[3];
+ return;
+ }
+
+ /* no clipping! */
+ dest[0] = dest[0] + source[0];
+ dest[1] = dest[1] + source[1];
+ dest[2] = dest[2] + source[2];
+ dest[3] = dest[3] + source[3];
+
+}
+
+
+/* ---------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
new file mode 100644
index 00000000000..7f202629ce4
--- /dev/null
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -0,0 +1,650 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): 2004-2006, Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/pixelshading.c
+ * \ingroup render
+ */
+
+
+#include <float.h>
+#include <math.h>
+#include <string.h>
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+/* External modules: */
+
+#include "DNA_group_types.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_image_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_lamp_types.h"
+
+#include "BKE_material.h"
+
+
+/* own module */
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "texture.h"
+#include "rendercore.h"
+#include "shadbuf.h"
+#include "pixelshading.h"
+#include "sunsky.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+
+extern const float hashvectf[];
+
+static void render_lighting_halo(HaloRen *har, float col_r[3])
+{
+ GroupObject *go;
+ LampRen *lar;
+ float i, inp, inpr, rco[3], dco[3], lv[3], lampdist, ld, t, *vn;
+ float ir, ig, ib, shadfac, soft, lacol[3];
+
+ ir= ig= ib= 0.0;
+
+ copy_v3_v3(rco, har->co);
+ dco[0]=dco[1]=dco[2]= 1.0f/har->rad;
+
+ vn= har->no;
+
+ for (go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+
+ /* test for lamplayer */
+ if (lar->mode & LA_LAYER) if ((lar->lay & har->lay)==0) continue;
+
+ /* lampdist cacluation */
+ if (lar->type==LA_SUN || lar->type==LA_HEMI) {
+ copy_v3_v3(lv, lar->vec);
+ lampdist= 1.0;
+ }
+ else {
+ lv[0]= rco[0]-lar->co[0];
+ lv[1]= rco[1]-lar->co[1];
+ lv[2]= rco[2]-lar->co[2];
+ ld = len_v3(lv);
+ lv[0]/= ld;
+ lv[1]/= ld;
+ lv[2]/= ld;
+
+ /* ld is re-used further on (texco's) */
+
+ if (lar->mode & LA_QUAD) {
+ t= 1.0;
+ if (lar->ld1>0.0f)
+ t= lar->dist/(lar->dist+lar->ld1*ld);
+ if (lar->ld2>0.0f)
+ t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);
+
+ lampdist= t;
+ }
+ else {
+ lampdist= (lar->dist/(lar->dist+ld));
+ }
+
+ if (lar->mode & LA_SPHERE) {
+ t= lar->dist - ld;
+ if (t<0.0f) continue;
+
+ t/= lar->dist;
+ lampdist*= (t);
+ }
+
+ }
+
+ lacol[0]= lar->r;
+ lacol[1]= lar->g;
+ lacol[2]= lar->b;
+
+ if (lar->mode & LA_TEXTURE) {
+ ShadeInput shi;
+
+ /* Warning, This is not that nice, and possibly a bit slow,
+ * however some variables were not initialized properly in, unless using shade_input_initialize(...),
+ * we need to do a memset */
+ memset(&shi, 0, sizeof(ShadeInput));
+ /* end warning! - Campbell */
+
+ copy_v3_v3(shi.co, rco);
+ shi.osatex= 0;
+ do_lamp_tex(lar, lv, &shi, lacol, LA_TEXTURE);
+ }
+
+ if (lar->type==LA_SPOT) {
+
+ if (lar->mode & LA_SQUARE) {
+ if (lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0f) {
+ float x, lvrot[3];
+
+ /* rotate view to lampspace */
+ copy_v3_v3(lvrot, lv);
+ mul_m3_v3(lar->imat, lvrot);
+
+ x = max_ff(fabsf(lvrot[0]/lvrot[2]), fabsf(lvrot[1]/lvrot[2]));
+ /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
+
+ inpr = 1.0f / (sqrtf(1.0f + x * x));
+ }
+ else inpr= 0.0;
+ }
+ else {
+ inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
+ }
+
+ t= lar->spotsi;
+ if (inpr<t) continue;
+ else {
+ t= inpr-t;
+ soft= 1.0;
+ if (t<lar->spotbl && lar->spotbl!=0.0f) {
+ /* soft area */
+ i= t/lar->spotbl;
+ t= i*i;
+ soft= (3.0f*t-2.0f*t*i);
+ inpr*= soft;
+ }
+ if (lar->mode & LA_ONLYSHADOW) {
+ /* if (ma->mode & MA_SHADOW) { */
+ /* dot product positive: front side face! */
+ inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
+ if (inp>0.0f) {
+ /* testshadowbuf==0.0 : 100% shadow */
+ shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
+ if ( shadfac>0.0f ) {
+ shadfac*= inp*soft*lar->energy;
+ ir -= shadfac;
+ ig -= shadfac;
+ ib -= shadfac;
+
+ continue;
+ }
+ }
+ /* } */
+ }
+ lampdist*=inpr;
+ }
+ if (lar->mode & LA_ONLYSHADOW) continue;
+
+ }
+
+ /* dot product and reflectivity*/
+
+ inp = 1.0f - fabsf(dot_v3v3(vn, lv));
+
+ /* inp= cos(0.5*M_PI-acos(inp)); */
+
+ i= inp;
+
+ if (lar->type==LA_HEMI) {
+ i= 0.5f*i+0.5f;
+ }
+ if (i>0.0f) {
+ i*= lampdist;
+ }
+
+ /* shadow */
+ if (i> -0.41f) { /* heuristic valua! */
+ if (lar->shb) {
+ shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
+ if (shadfac==0.0f) continue;
+ i*= shadfac;
+ }
+ }
+
+ if (i>0.0f) {
+ ir+= i*lacol[0];
+ ig+= i*lacol[1];
+ ib+= i*lacol[2];
+ }
+ }
+
+ if (ir<0.0f) ir= 0.0f;
+ if (ig<0.0f) ig= 0.0f;
+ if (ib<0.0f) ib= 0.0f;
+
+ col_r[0]*= ir;
+ col_r[1]*= ig;
+ col_r[2]*= ib;
+
+}
+
+
+/**
+ * Converts a halo z-buffer value to distance from the camera's near plane
+ * \param z The z-buffer value to convert
+ * \return a distance from the camera's near plane in blender units
+ */
+static float haloZtoDist(int z)
+{
+ float zco = 0;
+
+ if (z >= 0x7FFFFF)
+ return 10e10;
+ else {
+ zco = (float)z/(float)0x7FFFFF;
+ if (R.r.mode & R_ORTHO)
+ return (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2]);
+ else
+ return (R.winmat[3][2])/(R.winmat[2][2] - R.winmat[2][3]*zco);
+ }
+}
+
+/**
+ * \param col (float[4]) Store the rgb color here (with alpha)
+ * The alpha is used to blend the color to the background
+ * color_new = (1-alpha)*color_background + color
+ * \param zz The current zbuffer value at the place of this pixel
+ * \param dist Distance of the pixel from the center of the halo squared. Given in pixels
+ * \param xn The x coordinate of the pixel relaticve to the center of the halo. given in pixels
+ * \param yn The y coordinate of the pixel relaticve to the center of the halo. given in pixels
+ */
+int shadeHaloFloat(HaloRen *har, float col[4], int zz,
+ float dist, float xn, float yn, short flarec)
+{
+ /* fill in col */
+ float t, zn, radist, ringf=0.0f, linef=0.0f, alpha, si, co;
+ int a;
+
+ if (R.wrld.mode & WO_MIST) {
+ if (har->type & HA_ONLYSKY) {
+ alpha= har->alfa;
+ }
+ else {
+ /* a bit patchy... */
+ alpha= mistfactor(-har->co[2], har->co)*har->alfa;
+ }
+ }
+ else alpha= har->alfa;
+
+ if (alpha==0.0f)
+ return 0;
+
+ /* soften the halo if it intersects geometry */
+ if (har->mat && har->mat->mode & MA_HALO_SOFT) {
+ float segment_length, halo_depth, distance_from_z /* , visible_depth */ /* UNUSED */, soften;
+
+ /* calculate halo depth */
+ segment_length= har->hasize*sasqrt(1.0f - dist/(har->rad*har->rad));
+ halo_depth= 2.0f*segment_length;
+
+ if (halo_depth < FLT_EPSILON)
+ return 0;
+
+ /* calculate how much of this depth is visible */
+ distance_from_z = haloZtoDist(zz) - haloZtoDist(har->zs);
+ /* visible_depth = halo_depth; */ /* UNUSED */
+ if (distance_from_z < segment_length) {
+ soften= (segment_length + distance_from_z)/halo_depth;
+
+ /* apply softening to alpha */
+ if (soften < 1.0f)
+ alpha *= soften;
+ if (alpha <= 0.0f)
+ return 0;
+ }
+ }
+ else {
+ /* not a soft halo. use the old softening code */
+ /* halo being intersected? */
+ if (har->zs> zz-har->zd) {
+ t= ((float)(zz-har->zs))/(float)har->zd;
+ alpha*= sqrtf(sqrtf(t));
+ }
+ }
+
+ radist = sqrtf(dist);
+
+ /* watch it: not used nicely: flarec is set at zero in pixstruct */
+ if (flarec) har->pixels+= (int)(har->rad-radist);
+
+ if (har->ringc) {
+ const float *rc;
+ float fac;
+ int ofs;
+
+ /* per ring an antialised circle */
+ ofs= har->seed;
+
+ for (a= har->ringc; a>0; a--, ofs+=2) {
+
+ rc= hashvectf + (ofs % 768);
+
+ fac = fabsf(rc[1] * (har->rad * fabsf(rc[0]) - radist));
+
+ if (fac< 1.0f) {
+ ringf+= (1.0f-fac);
+ }
+ }
+ }
+
+ if (har->type & HA_VECT) {
+ dist= fabsf(har->cos * (yn) - har->sin * (xn)) / har->rad;
+ if (dist>1.0f) dist= 1.0f;
+ if (har->tex) {
+ zn= har->sin*xn - har->cos*yn;
+ yn= har->cos*xn + har->sin*yn;
+ xn= zn;
+ }
+ }
+ else dist= dist/har->radsq;
+
+ if (har->type & HA_FLARECIRC) {
+ dist = 0.5f + fabsf(dist - 0.5f);
+ }
+
+ if (har->hard>=30) {
+ dist = sqrtf(dist);
+ if (har->hard>=40) {
+ dist = sinf(dist*(float)M_PI_2);
+ if (har->hard>=50) {
+ dist = sqrtf(dist);
+ }
+ }
+ }
+ else if (har->hard<20) dist*=dist;
+
+ if (dist < 1.0f)
+ dist= (1.0f-dist);
+ else
+ dist= 0.0f;
+
+ if (har->linec) {
+ const float *rc;
+ float fac;
+ int ofs;
+
+ /* per starpoint an antialiased line */
+ ofs= har->seed;
+
+ for (a= har->linec; a>0; a--, ofs+=3) {
+
+ rc= hashvectf + (ofs % 768);
+
+ fac = fabsf((xn) * rc[0] + (yn) * rc[1]);
+
+ if (fac< 1.0f )
+ linef+= (1.0f-fac);
+ }
+
+ linef*= dist;
+ }
+
+ if (har->starpoints) {
+ float ster, angle;
+ /* rotation */
+ angle = atan2f(yn, xn);
+ angle *= (1.0f+0.25f*har->starpoints);
+
+ co= cosf(angle);
+ si= sinf(angle);
+
+ angle= (co*xn+si*yn)*(co*yn-si*xn);
+
+ ster = fabsf(angle);
+ if (ster>1.0f) {
+ ster= (har->rad)/(ster);
+
+ if (ster<1.0f) dist*= sqrtf(ster);
+ }
+ }
+
+ /* disputable optimize... (ton) */
+ if (dist<=0.00001f)
+ return 0;
+
+ dist*= alpha;
+ ringf*= dist;
+ linef*= alpha;
+
+ /* The color is either the rgb spec-ed by the user, or extracted from */
+ /* the texture */
+ if (har->tex) {
+ col[0]= har->r;
+ col[1]= har->g;
+ col[2]= har->b;
+ col[3]= dist;
+
+ do_halo_tex(har, xn, yn, col);
+
+ col[0]*= col[3];
+ col[1]*= col[3];
+ col[2]*= col[3];
+
+ }
+ else {
+ col[0]= dist*har->r;
+ col[1]= dist*har->g;
+ col[2]= dist*har->b;
+ if (har->type & HA_XALPHA) col[3]= dist*dist;
+ else col[3]= dist;
+ }
+
+ if (har->mat) {
+ if (har->mat->mode & MA_HALO_SHADE) {
+ /* we test for lights because of preview... */
+ if (R.lights.first) render_lighting_halo(har, col);
+ }
+
+ /* Next, we do the line and ring factor modifications. */
+ if (linef!=0.0f) {
+ Material *ma= har->mat;
+
+ col[0]+= linef * ma->specr;
+ col[1]+= linef * ma->specg;
+ col[2]+= linef * ma->specb;
+
+ if (har->type & HA_XALPHA) col[3]+= linef*linef;
+ else col[3]+= linef;
+ }
+ if (ringf!=0.0f) {
+ Material *ma= har->mat;
+
+ col[0]+= ringf * ma->mirr;
+ col[1]+= ringf * ma->mirg;
+ col[2]+= ringf * ma->mirb;
+
+ if (har->type & HA_XALPHA) col[3]+= ringf*ringf;
+ else col[3]+= ringf;
+ }
+ }
+
+ /* alpha requires clip, gives black dots */
+ if (col[3] > 1.0f)
+ col[3]= 1.0f;
+
+ return 1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Only view vector is important here. Result goes to col_r[3] */
+void shadeSkyView(float col_r[3], const float rco[3], const float view[3], const float dxyview[2], short thread)
+{
+ float zen[3], hor[3], blend, blendm;
+ int skyflag;
+
+ /* flag indicating if we render the top hemisphere */
+ skyflag = WO_ZENUP;
+
+ /* Some view vector stuff. */
+ if (R.wrld.skytype & WO_SKYREAL) {
+
+ blend = dot_v3v3(view, R.grvec);
+
+ if (blend<0.0f) skyflag= 0;
+
+ blend = fabsf(blend);
+ }
+ else if (R.wrld.skytype & WO_SKYPAPER) {
+ blend= 0.5f + 0.5f * view[1];
+ }
+ else {
+ /* the fraction of how far we are above the bottom of the screen */
+ blend = fabsf(0.5f + view[1]);
+ }
+
+ copy_v3_v3(hor, &R.wrld.horr);
+ copy_v3_v3(zen, &R.wrld.zenr);
+
+ /* Careful: SKYTEX and SKYBLEND are NOT mutually exclusive! If */
+ /* SKYBLEND is active, the texture and color blend are added. */
+ if (R.wrld.skytype & WO_SKYTEX) {
+ float lo[3];
+ copy_v3_v3(lo, view);
+ if (R.wrld.skytype & WO_SKYREAL) {
+
+ mul_m3_v3(R.imat, lo);
+
+ SWAP(float, lo[1], lo[2]);
+
+ }
+ do_sky_tex(rco, view, lo, dxyview, hor, zen, &blend, skyflag, thread);
+ }
+
+ if (blend>1.0f) blend= 1.0f;
+ blendm= 1.0f-blend;
+
+ /* No clipping, no conversion! */
+ if (R.wrld.skytype & WO_SKYBLEND) {
+ col_r[0] = (blendm*hor[0] + blend*zen[0]);
+ col_r[1] = (blendm*hor[1] + blend*zen[1]);
+ col_r[2] = (blendm*hor[2] + blend*zen[2]);
+ }
+ else {
+ /* Done when a texture was grabbed. */
+ col_r[0]= hor[0];
+ col_r[1]= hor[1];
+ col_r[2]= hor[2];
+ }
+}
+
+/* shade sky according to sun lamps, all parameters are like shadeSkyView except sunsky*/
+void shadeSunView(float col_r[3], const float view[3])
+{
+ GroupObject *go;
+ LampRen *lar;
+ float sview[3];
+ bool do_init = true;
+
+ for (go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if (lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_SKY)) {
+ float sun_collector[3];
+ float colorxyz[3];
+
+ if (do_init) {
+
+ normalize_v3_v3(sview, view);
+ mul_m3_v3(R.imat, sview);
+ if (sview[2] < 0.0f)
+ sview[2] = 0.0f;
+ normalize_v3(sview);
+ do_init = false;
+ }
+
+ GetSkyXYZRadiancef(lar->sunsky, sview, colorxyz);
+ xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &sun_collector[0], &sun_collector[1], &sun_collector[2],
+ lar->sunsky->sky_colorspace);
+
+ ramp_blend(lar->sunsky->skyblendtype, col_r, lar->sunsky->skyblendfac, sun_collector);
+ }
+ }
+}
+
+
+/*
+ * Stuff the sky color into the collector.
+ */
+void shadeSkyPixel(float collector[4], float fx, float fy, short thread)
+{
+ float view[3], dxyview[2];
+
+ /*
+ * The rules for sky:
+ * 1. Draw an image, if a background image was provided. Stop
+ * 2. get texture and color blend, and combine these.
+ */
+
+ float fac;
+
+ if ((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
+ /* 1. solid color */
+ copy_v3_v3(collector, &R.wrld.horr);
+
+ collector[3] = 0.0f;
+ }
+ else {
+ /* 2. */
+
+ /* This one true because of the context of this routine */
+ if (R.wrld.skytype & WO_SKYPAPER) {
+ view[0]= -1.0f + 2.0f*(fx/(float)R.winx);
+ view[1]= -1.0f + 2.0f*(fy/(float)R.winy);
+ view[2]= 0.0;
+
+ dxyview[0]= 1.0f/(float)R.winx;
+ dxyview[1]= 1.0f/(float)R.winy;
+ }
+ else {
+ calc_view_vector(view, fx, fy);
+ fac= normalize_v3(view);
+
+ if (R.wrld.skytype & WO_SKYTEX) {
+ dxyview[0]= -R.viewdx/fac;
+ dxyview[1]= -R.viewdy/fac;
+ }
+ }
+
+ /* get sky color in the collector */
+ shadeSkyView(collector, NULL, view, dxyview, thread);
+ collector[3] = 0.0f;
+ }
+
+ calc_view_vector(view, fx, fy);
+ shadeSunView(collector, view);
+}
+
+/* aerial perspective */
+void shadeAtmPixel(struct SunSky *sunsky, float collector[3], float fx, float fy, float distance)
+{
+ float view[3];
+
+ calc_view_vector(view, fx, fy);
+ normalize_v3(view);
+ /*mul_m3_v3(R.imat, view);*/
+ AtmospherePixleShader(sunsky, view, distance, collector);
+}
+
+/* eof */
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 53359c305dc..c025a1fdef7 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -102,7 +102,7 @@ static void point_data_pointers(PointDensity *pd,
const int totpoint = pd->totpoints;
float *data = pd->point_data;
int offset = 0;
-
+
if (data_used & POINT_DATA_VEL) {
if (r_data_velocity)
*r_data_velocity = data + offset;
@@ -112,7 +112,7 @@ static void point_data_pointers(PointDensity *pd,
if (r_data_velocity)
*r_data_velocity = NULL;
}
-
+
if (data_used & POINT_DATA_LIFE) {
if (r_data_life)
*r_data_life = data + offset;
@@ -122,7 +122,7 @@ static void point_data_pointers(PointDensity *pd,
if (r_data_life)
*r_data_life = NULL;
}
-
+
if (data_used & POINT_DATA_COLOR) {
if (r_data_color)
*r_data_color = data + offset;
@@ -283,19 +283,19 @@ static void pointdensity_cache_vertex_color(PointDensity *pd, Object *UNUSED(ob)
const MLoopCol *mcol;
char layername[MAX_CUSTOMDATA_LAYER_NAME];
int i;
-
+
BLI_assert(data_color);
-
+
if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPCOL))
return;
CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPCOL, pd->vertex_attribute_name, layername);
mcol = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPCOL, layername);
if (!mcol)
return;
-
+
/* Stores the number of MLoops using the same vertex, so we can normalize colors. */
int *mcorners = MEM_callocN(sizeof(int) * pd->totpoints, "point density corner count");
-
+
for (i = 0; i < totloop; i++) {
int v = mloop[i].v;
@@ -310,7 +310,7 @@ static void pointdensity_cache_vertex_color(PointDensity *pd, Object *UNUSED(ob)
++mcorners[v];
}
-
+
/* Normalize colors by averaging over mcorners.
* All the corners share the same vertex, ie. occupy the same point in space.
*/
@@ -318,7 +318,7 @@ static void pointdensity_cache_vertex_color(PointDensity *pd, Object *UNUSED(ob)
if (mcorners[i] > 0)
mul_v3_fl(&data_color[i*3], 1.0f / mcorners[i]);
}
-
+
MEM_freeN(mcorners);
}
@@ -328,9 +328,9 @@ static void pointdensity_cache_vertex_weight(PointDensity *pd, Object *ob, Mesh
const MDeformVert *mdef, *dv;
int mdef_index;
int i;
-
+
BLI_assert(data_color);
-
+
mdef = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
if (!mdef)
return;
@@ -339,11 +339,11 @@ static void pointdensity_cache_vertex_weight(PointDensity *pd, Object *ob, Mesh
mdef_index = ob->actdef - 1;
if (mdef_index < 0)
return;
-
+
for (i = 0, dv = mdef; i < totvert; ++i, ++dv, data_color += 3) {
MDeformWeight *dw;
int j;
-
+
for (j = 0, dw = dv->dw; j < dv->totweight; ++j, ++dw) {
if (dw->def_nr == mdef_index) {
copy_v3_fl(data_color, dw->weight);
@@ -357,9 +357,9 @@ static void pointdensity_cache_vertex_normal(PointDensity *pd, Object *UNUSED(ob
{
MVert *mvert = mesh->mvert, *mv;
int i;
-
+
BLI_assert(data_color);
-
+
for (i = 0, mv = mvert; i < pd->totpoints; i++, mv++, data_color += 3) {
normal_short_to_float_v3(data_color, mv->no);
}
@@ -413,7 +413,7 @@ static void pointdensity_cache_object(PointDensity *pd,
BLI_bvhtree_insert(pd->point_tree, i, co, 1);
}
-
+
switch (pd->ob_color_source) {
case TEX_PD_COLOR_VERTCOL:
pointdensity_cache_vertex_color(pd, ob, mesh, data_color);
@@ -506,7 +506,7 @@ static float density_falloff(PointDensityRangeData *pdr, int index, float square
{
const float dist = (pdr->squared_radius - squared_dist) / pdr->squared_radius * 0.5f;
float density = 0.0f;
-
+
switch (pdr->falloff_type) {
case TEX_PD_FALLOFF_STD:
density = dist;
@@ -536,12 +536,12 @@ static float density_falloff(PointDensityRangeData *pdr, int index, float square
density = dist;
break;
}
-
+
if (pdr->density_curve && dist != 0.0f) {
curvemapping_initialize(pdr->density_curve);
density = curvemapping_evaluateF(pdr->density_curve, 0, density / dist) * dist;
}
-
+
return density;
}
@@ -666,7 +666,7 @@ static void pointdensity_color(PointDensity *pd, TexResult *texres, float age, c
if (pd->source == TEX_PD_PSYS) {
float rgba[4];
-
+
switch (pd->color_source) {
case TEX_PD_COLOR_PARTAGE:
if (pd->coba) {
@@ -681,7 +681,7 @@ static void pointdensity_color(PointDensity *pd, TexResult *texres, float age, c
case TEX_PD_COLOR_PARTSPEED:
{
float speed = len_v3(vec) * pd->speed_scale;
-
+
if (pd->coba) {
if (BKE_colorband_evaluate(pd->coba, speed, rgba)) {
texres->talpha = true;
@@ -704,7 +704,7 @@ static void pointdensity_color(PointDensity *pd, TexResult *texres, float age, c
}
else {
float rgba[4];
-
+
switch (pd->ob_color_source) {
case TEX_PD_COLOR_VERTCOL:
texres->talpha = true;
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
new file mode 100644
index 00000000000..df1cb868230
--- /dev/null
+++ b/source/blender/render/intern/source/rayshade.c
@@ -0,0 +1,2503 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 1990-1998 NeoGeo BV.
+ * All rights reserved.
+ *
+ * Contributors: 2004/2005 Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/rayshade.c
+ * \ingroup render
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <float.h>
+#include <assert.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_material_types.h"
+#include "DNA_lamp_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_system.h"
+#include "BLI_math.h"
+#include "BLI_rand.h"
+#include "BLI_utildefines.h"
+
+#include "BLT_translation.h"
+
+#include "BKE_node.h"
+
+#include "render_result.h"
+#include "render_types.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "pixelshading.h"
+#include "shading.h"
+#include "volumetric.h"
+
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "raycounter.h"
+
+#define RAY_TRA 1
+#define RAY_INSIDE 2
+
+#define DEPTH_SHADOW_TRA 10
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+static int test_break(void *data)
+{
+ Render *re = (Render *)data;
+ return re->test_break(re->tbh);
+}
+
+static void RE_rayobject_config_control(RayObject *r, Render *re)
+{
+ if (RE_rayobject_isRayAPI(r)) {
+ r = RE_rayobject_align(r);
+ r->control.data = re;
+ r->control.test_break = test_break;
+ }
+}
+
+RayObject *RE_rayobject_create(int type, int size, int octree_resolution)
+{
+ RayObject * res = NULL;
+
+ if (type == R_RAYSTRUCTURE_AUTO) {
+ /* TODO */
+ //if (detect_simd())
+#ifdef __SSE__
+ type = BLI_cpu_support_sse2()? R_RAYSTRUCTURE_SIMD_SVBVH: R_RAYSTRUCTURE_VBVH;
+#else
+ type = R_RAYSTRUCTURE_VBVH;
+#endif
+ }
+
+#ifndef __SSE__
+ if (type == R_RAYSTRUCTURE_SIMD_SVBVH || type == R_RAYSTRUCTURE_SIMD_QBVH) {
+ puts("Warning: Using VBVH (SSE was disabled at compile time)");
+ type = R_RAYSTRUCTURE_VBVH;
+ }
+#endif
+
+
+ if (type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres
+ res = RE_rayobject_octree_create(octree_resolution, size);
+ else if (type == R_RAYSTRUCTURE_VBVH)
+ res = RE_rayobject_vbvh_create(size);
+ else if (type == R_RAYSTRUCTURE_SIMD_SVBVH)
+ res = RE_rayobject_svbvh_create(size);
+ else if (type == R_RAYSTRUCTURE_SIMD_QBVH)
+ res = RE_rayobject_qbvh_create(size);
+ else
+ res = RE_rayobject_vbvh_create(size); //Fallback
+
+ return res;
+}
+
+static RayObject* rayobject_create(Render *re, int type, int size)
+{
+ RayObject * res = NULL;
+
+ res = RE_rayobject_create(type, size, re->r.ocres);
+
+ if (res)
+ RE_rayobject_config_control(res, re);
+
+ return res;
+}
+
+#ifdef RE_RAYCOUNTER
+RayCounter re_rc_counter[BLENDER_MAX_THREADS];
+#endif
+
+
+void freeraytree(Render *re)
+{
+ ObjectInstanceRen *obi;
+
+ if (re->raytree) {
+ RE_rayobject_free(re->raytree);
+ re->raytree = NULL;
+ }
+ if (re->rayfaces) {
+ MEM_freeN(re->rayfaces);
+ re->rayfaces = NULL;
+ }
+ if (re->rayprimitives) {
+ MEM_freeN(re->rayprimitives);
+ re->rayprimitives = NULL;
+ }
+
+ for (obi=re->instancetable.first; obi; obi=obi->next) {
+ ObjectRen *obr = obi->obr;
+ if (obr->raytree) {
+ RE_rayobject_free(obr->raytree);
+ obr->raytree = NULL;
+ }
+ if (obr->rayfaces) {
+ MEM_freeN(obr->rayfaces);
+ obr->rayfaces = NULL;
+ }
+ if (obi->raytree) {
+ RE_rayobject_free(obi->raytree);
+ obi->raytree = NULL;
+ }
+ }
+
+#ifdef RE_RAYCOUNTER
+ {
+ const int num_threads = re->r.threads;
+ RayCounter sum;
+ memset(&sum, 0, sizeof(sum));
+ int i;
+ for (i=0; i<num_threads; i++)
+ RE_RC_MERGE(&sum, re_rc_counter+i);
+ RE_RC_INFO(&sum);
+ }
+#endif
+}
+
+static bool is_raytraceable_vlr(Render *re, VlakRen *vlr)
+{
+ /* note: volumetric must be tracable, wire must not */
+ if ((re->flag & R_BAKE_TRACE) || (vlr->flag & R_TRACEBLE) || (vlr->mat->material_type == MA_TYPE_VOLUME))
+ if (vlr->mat->material_type != MA_TYPE_WIRE)
+ return 1;
+ return 0;
+}
+
+static bool is_raytraceable(Render *re, ObjectInstanceRen *obi)
+{
+ int v;
+ ObjectRen *obr = obi->obr;
+
+ if (re->excludeob && obr->ob == re->excludeob)
+ return 0;
+
+ for (v=0;v<obr->totvlak;v++) {
+ VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
+
+ if (is_raytraceable_vlr(re, vlr))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
+{
+ /*TODO
+ * out-of-memory safeproof
+ * break render
+ * update render stats */
+ ObjectRen *obr = obi->obr;
+
+ if (obr->raytree == NULL) {
+ RayObject *raytree;
+ RayFace *face = NULL;
+ VlakPrimitive *vlakprimitive = NULL;
+ int v;
+
+ //Count faces
+ int faces = 0;
+ for (v=0;v<obr->totvlak;v++) {
+ VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
+ if (is_raytraceable_vlr(re, vlr))
+ faces++;
+ }
+
+ if (faces == 0)
+ return NULL;
+
+ //Create Ray cast accelaration structure
+ raytree = rayobject_create( re, re->r.raytrace_structure, faces );
+ if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
+ vlakprimitive = obr->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "ObjectRen primitives");
+ else
+ face = obr->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "ObjectRen faces");
+
+ obr->rayobi = obi;
+
+ for (v=0;v<obr->totvlak;v++) {
+ VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
+ if (is_raytraceable_vlr(re, vlr)) {
+ if ((re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS)) {
+ RE_rayobject_add(raytree, RE_vlakprimitive_from_vlak(vlakprimitive, obi, vlr));
+ vlakprimitive++;
+ }
+ else {
+ RE_rayface_from_vlak(face, obi, vlr);
+ RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face));
+ face++;
+ }
+ }
+ }
+ RE_rayobject_done(raytree);
+
+ /* in case of cancel during build, raytree is not usable */
+ if (test_break(re))
+ RE_rayobject_free(raytree);
+ else
+ obr->raytree= raytree;
+ }
+
+ if (obr->raytree) {
+ if ((obi->flag & R_TRANSFORMED) && obi->raytree == NULL) {
+ obi->transform_primitives = 0;
+ obi->raytree = RE_rayobject_instance_create( obr->raytree, obi->mat, obi, obi->obr->rayobi );
+ }
+ }
+
+ if (obi->raytree) return obi->raytree;
+ return obi->obr->raytree;
+}
+
+static bool has_special_rayobject(Render *re, ObjectInstanceRen *obi)
+{
+ if ( (obi->flag & R_TRANSFORMED) && (re->r.raytrace_options & R_RAYTRACE_USE_INSTANCES) ) {
+ ObjectRen *obr = obi->obr;
+ int v, faces = 0;
+
+ for (v=0;v<obr->totvlak;v++) {
+ VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
+ if (is_raytraceable_vlr(re, vlr)) {
+ faces++;
+ if (faces > 4)
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+/*
+ * create a single raytrace structure with all faces
+ */
+static void makeraytree_single(Render *re)
+{
+ ObjectInstanceRen *obi;
+ RayObject *raytree;
+ RayFace *face = NULL;
+ VlakPrimitive *vlakprimitive = NULL;
+ int faces = 0, special = 0;
+
+ for (obi = re->instancetable.first; obi; obi = obi->next) {
+ if (is_raytraceable(re, obi)) {
+ ObjectRen *obr = obi->obr;
+
+ if (has_special_rayobject(re, obi)) {
+ special++;
+ }
+ else {
+ int v;
+ for (v = 0;v < obr->totvlak; v++) {
+ VlakRen *vlr = obr->vlaknodes[v >> 8].vlak + (v&255);
+ if (is_raytraceable_vlr(re, vlr)) {
+ faces++;
+ }
+ }
+ }
+ }
+ }
+
+ if (faces + special == 0) {
+ re->raytree = RE_rayobject_empty_create();
+ return;
+ }
+
+ //Create raytree
+ raytree = re->raytree = rayobject_create( re, re->r.raytrace_structure, faces+special );
+
+ if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) {
+ vlakprimitive = re->rayprimitives = (VlakPrimitive *)MEM_callocN(faces * sizeof(VlakPrimitive), "Raytrace vlak-primitives");
+ }
+ else {
+ face = re->rayfaces = (RayFace *)MEM_callocN(faces * sizeof(RayFace), "Render ray faces");
+ }
+
+ for (obi=re->instancetable.first; obi; obi=obi->next)
+ if (is_raytraceable(re, obi)) {
+ if (test_break(re))
+ break;
+
+ if (has_special_rayobject(re, obi)) {
+ RayObject *obj = makeraytree_object(re, obi);
+
+ if (test_break(re))
+ break;
+
+ if (obj)
+ RE_rayobject_add(re->raytree, obj);
+ }
+ else {
+ int v;
+ ObjectRen *obr = obi->obr;
+
+ if (obi->flag & R_TRANSFORMED) {
+ obi->transform_primitives = 1;
+ }
+
+ for (v=0;v<obr->totvlak;v++) {
+ VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
+ if (is_raytraceable_vlr(re, vlr)) {
+ if ((re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS)) {
+ RayObject *obj = RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr );
+ RE_rayobject_add(raytree, obj);
+ vlakprimitive++;
+ }
+ else {
+ RE_rayface_from_vlak(face, obi, vlr);
+ if ((obi->flag & R_TRANSFORMED)) {
+ mul_m4_v3(obi->mat, face->v1);
+ mul_m4_v3(obi->mat, face->v2);
+ mul_m4_v3(obi->mat, face->v3);
+ if (RE_rayface_isQuad(face))
+ mul_m4_v3(obi->mat, face->v4);
+ }
+
+ RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face));
+ face++;
+ }
+ }
+ }
+ }
+ }
+
+ if (!test_break(re)) {
+ re->i.infostr = IFACE_("Raytree.. building");
+ re->stats_draw(re->sdh, &re->i);
+
+ RE_rayobject_done(raytree);
+ }
+}
+
+void makeraytree(Render *re)
+{
+ float min[3], max[3], sub[3];
+ int i;
+
+ re->i.infostr = IFACE_("Raytree.. preparing");
+ re->stats_draw(re->sdh, &re->i);
+
+ /* disable options not yet supported by octree,
+ * they might actually never be supported (unless people really need it) */
+ if (re->r.raytrace_structure == R_RAYSTRUCTURE_OCTREE)
+ re->r.raytrace_options &= ~( R_RAYTRACE_USE_INSTANCES | R_RAYTRACE_USE_LOCAL_COORDS);
+
+ makeraytree_single(re);
+
+ if (test_break(re)) {
+ freeraytree(re);
+
+ re->i.infostr = IFACE_("Raytree building canceled");
+ re->stats_draw(re->sdh, &re->i);
+ }
+ else {
+ /* Calculate raytree max_size
+ * This is ONLY needed to kept a bogus behavior of SUN and HEMI lights */
+ INIT_MINMAX(min, max);
+ RE_rayobject_merge_bb(re->raytree, min, max);
+ if (min[0] > max[0]) { /* empty raytree */
+ zero_v3(min);
+ zero_v3(max);
+ }
+ for (i=0; i<3; i++) {
+ /* TODO: explain why add top both min and max??? */
+ min[i] += 0.01f;
+ max[i] += 0.01f;
+ sub[i] = max[i]-min[i];
+ }
+
+ re->maxdist = len_v3(sub);
+
+ re->i.infostr = IFACE_("Raytree finished");
+ re->stats_draw(re->sdh, &re->i);
+ }
+
+#ifdef RE_RAYCOUNTER
+ memset(re_rc_counter, 0, sizeof(re_rc_counter));
+#endif
+}
+
+/* if (shi->osatex) */
+static void shade_ray_set_derivative(ShadeInput *shi)
+{
+ float detsh, t00, t10, t01, t11;
+ int axis1, axis2;
+
+ /* find most stable axis to project */
+ axis_dominant_v3(&axis1, &axis2, shi->facenor);
+
+ /* compute u,v and derivatives */
+ if (shi->obi->flag & R_TRANSFORMED) {
+ float v1[3], v2[3], v3[3];
+
+ mul_v3_m3v3(v1, shi->obi->nmat, shi->v1->co);
+ mul_v3_m3v3(v2, shi->obi->nmat, shi->v2->co);
+ mul_v3_m3v3(v3, shi->obi->nmat, shi->v3->co);
+
+ /* same as below */
+ t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
+ t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
+ }
+ else {
+ const float *v1= shi->v1->co;
+ const float *v2= shi->v2->co;
+ const float *v3= shi->v3->co;
+
+ /* same as above */
+ t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
+ t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
+ }
+
+ detsh= 1.0f/(t00*t11-t10*t01);
+ t00*= detsh; t01*=detsh;
+ t10*=detsh; t11*=detsh;
+
+ shi->dx_u= shi->dxco[axis1]*t11- shi->dxco[axis2]*t10;
+ shi->dx_v= shi->dxco[axis2]*t00- shi->dxco[axis1]*t01;
+ shi->dy_u= shi->dyco[axis1]*t11- shi->dyco[axis2]*t10;
+ shi->dy_v= shi->dyco[axis2]*t00- shi->dyco[axis1]*t01;
+
+}
+
+/* main ray shader */
+void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
+{
+ ObjectInstanceRen *obi = (ObjectInstanceRen *)is->hit.ob;
+ VlakRen *vlr = (VlakRen *)is->hit.face;
+
+ /* set up view vector */
+ copy_v3_v3(shi->view, is->dir);
+
+ /* render co */
+ shi->co[0]= is->start[0]+is->dist*(shi->view[0]);
+ shi->co[1]= is->start[1]+is->dist*(shi->view[1]);
+ shi->co[2]= is->start[2]+is->dist*(shi->view[2]);
+
+ normalize_v3(shi->view);
+
+ shi->obi= obi;
+ shi->obr= obi->obr;
+ shi->vlr= vlr;
+ shi->mat= vlr->mat;
+ shade_input_init_material(shi);
+
+ if (is->isect==2)
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
+ else
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
+
+ shi->u= is->u;
+ shi->v= is->v;
+ shi->dx_u= shi->dx_v= shi->dy_u= shi->dy_v= 0.0f;
+
+ if (shi->osatex)
+ shade_ray_set_derivative(shi);
+ shade_input_set_normals(shi);
+
+ shade_input_set_shade_texco(shi);
+ if (shi->mat->material_type == MA_TYPE_VOLUME) {
+ if (ELEM(is->mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) {
+ shade_volume_shadow(shi, shr, is);
+ }
+ else {
+ shade_volume_outside(shi, shr);
+ }
+ }
+ else if (is->mode==RE_RAY_SHADOW_TRA) {
+ /* temp hack to prevent recursion */
+ if (shi->nodes==0 && shi->mat->nodetree && shi->mat->use_nodes) {
+ ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
+ shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
+ }
+ else
+ shade_color(shi, shr);
+ }
+ else {
+ if (shi->mat->nodetree && shi->mat->use_nodes) {
+ ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
+ shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
+ }
+ else {
+ shade_material_loop(shi, shr);
+ }
+
+ /* raytrace likes to separate the spec color */
+ sub_v3_v3v3(shr->diff, shr->combined, shr->spec);
+ copy_v3_v3(shr->diffshad, shr->diff);
+ }
+
+}
+
+static int refraction(float refract[3], const float n[3], const float view[3], float index)
+{
+ float dot, fac;
+
+ copy_v3_v3(refract, view);
+
+ dot = dot_v3v3(view, n);
+
+ if (dot>0.0f) {
+ index = 1.0f/index;
+ fac= 1.0f - (1.0f - dot*dot)*index*index;
+ if (fac <= 0.0f) return 0;
+ fac= -dot*index + sqrtf(fac);
+ }
+ else {
+ fac= 1.0f - (1.0f - dot*dot)*index*index;
+ if (fac <= 0.0f) return 0;
+ fac= -dot*index - sqrtf(fac);
+ }
+
+ refract[0]= index*view[0] + fac*n[0];
+ refract[1]= index*view[1] + fac*n[1];
+ refract[2]= index*view[2] + fac*n[2];
+
+ return 1;
+}
+
+static void reflection_simple(float ref[3], float n[3], const float view[3])
+{
+ const float f1= -2.0f * dot_v3v3(n, view);
+ madd_v3_v3v3fl(ref, view, n, f1);
+}
+
+/* orn = original face normal */
+static void reflection(float ref[3], float n[3], const float view[3], const float orn[3])
+{
+ float f1;
+
+ reflection_simple(ref, n, view);
+
+ /* test phong normals, then we should prevent vector going to the back */
+ f1= dot_v3v3(ref, orn);
+ if (f1>0.0f) {
+ f1+= 0.01f;
+ ref[0]-= f1*orn[0];
+ ref[1]-= f1*orn[1];
+ ref[2]-= f1*orn[2];
+ }
+}
+
+#if 0
+static void color_combine(float *result, float fac1, float fac2, float col1[3], float col2[3])
+{
+ float col1t[3], col2t[3];
+
+ col1t[0]= sqrt(col1[0]);
+ col1t[1]= sqrt(col1[1]);
+ col1t[2]= sqrt(col1[2]);
+ col2t[0]= sqrt(col2[0]);
+ col2t[1]= sqrt(col2[1]);
+ col2t[2]= sqrt(col2[2]);
+
+ result[0]= (fac1*col1t[0] + fac2*col2t[0]);
+ result[0]*= result[0];
+ result[1]= (fac1*col1t[1] + fac2*col2t[1]);
+ result[1]*= result[1];
+ result[2]= (fac1*col1t[2] + fac2*col2t[2]);
+ result[2]*= result[2];
+}
+#endif
+
+static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)
+{
+ float d;
+ if (0 == (shi->mat->mode & MA_TRANSP))
+ return -1;
+
+ if (shi->mat->tx_limit <= 0.0f) {
+ d= 1.0f;
+ }
+ else {
+ float p;
+
+ /* shi.co[] calculated by shade_ray() */
+ const float dx= shi->co[0] - is->start[0];
+ const float dy= shi->co[1] - is->start[1];
+ const float dz= shi->co[2] - is->start[2];
+ d = sqrtf(dx * dx + dy * dy + dz * dz);
+ if (d > shi->mat->tx_limit)
+ d= shi->mat->tx_limit;
+
+ p = shi->mat->tx_falloff;
+ if (p < 0.0f) p= 0.0f;
+ else if (p > 10.0f) p= 10.0f;
+
+ shr->alpha *= powf(d, p);
+ if (shr->alpha > 1.0f)
+ shr->alpha= 1.0f;
+ }
+
+ return d;
+}
+
+static void ray_fadeout_endcolor(float col[3], ShadeInput *origshi, ShadeInput *shi, ShadeResult *shr, Isect *isec, const float vec[3])
+{
+ /* un-intersected rays get either rendered material color or sky color */
+ if (origshi->mat->fadeto_mir == MA_RAYMIR_FADETOMAT) {
+ copy_v3_v3(col, shr->combined);
+ }
+ else if (origshi->mat->fadeto_mir == MA_RAYMIR_FADETOSKY) {
+ copy_v3_v3(shi->view, vec);
+ normalize_v3(shi->view);
+
+ shadeSkyView(col, isec->start, shi->view, NULL, shi->thread);
+ shadeSunView(col, shi->view);
+ }
+}
+
+static void ray_fadeout(Isect *is, ShadeInput *shi, float col[3], const float blendcol[3], float dist_mir)
+{
+ /* if fading out, linear blend against fade color */
+ float blendfac;
+
+ blendfac = 1.0f - len_v3v3(shi->co, is->start)/dist_mir;
+
+ col[0] = col[0]*blendfac + (1.0f - blendfac)*blendcol[0];
+ col[1] = col[1]*blendfac + (1.0f - blendfac)*blendcol[1];
+ col[2] = col[2]*blendfac + (1.0f - blendfac)*blendcol[2];
+}
+
+/* the main recursive tracer itself
+ * note: 'col' must be initialized */
+static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, const float start[3], const float dir[3], float col[4], ObjectInstanceRen *obi, VlakRen *vlr, int traflag)
+{
+ ShadeInput shi = {NULL};
+ Isect isec;
+ float dist_mir = origshi->mat->dist_mir;
+
+ /* with high depth the number of rays can explode due to the path splitting
+ * in two each time, giving 2^depth rays. we need to be able to cancel such
+ * a render to avoid hanging, a better solution would be random picking
+ * between directions and russian roulette termination */
+ if (R.test_break(R.tbh)) {
+ zero_v4(col);
+ return;
+ }
+
+ copy_v3_v3(isec.start, start);
+ copy_v3_v3(isec.dir, dir);
+ isec.dist = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST;
+ isec.mode= RE_RAY_MIRROR;
+ isec.check = RE_CHECK_VLR_RENDER;
+ isec.skip = RE_SKIP_VLR_NEIGHBOUR;
+ isec.hint = NULL;
+
+ isec.orig.ob = obi;
+ isec.orig.face = vlr;
+ RE_RC_INIT(isec, shi);
+
+ /* database is in original view, obi->imat transforms current position back to original */
+ RE_instance_rotate_ray(origshi->obi, &isec);
+
+ if (RE_rayobject_raycast(R.raytree, &isec)) {
+ ShadeResult shr= {{0}};
+ float d= 1.0f;
+
+ RE_instance_rotate_ray_restore(origshi->obi, &isec);
+
+ /* for as long we don't have proper dx/dy transform for rays we copy over original */
+ copy_v3_v3(shi.dxco, origshi->dxco);
+ copy_v3_v3(shi.dyco, origshi->dyco);
+
+ shi.mask= origshi->mask;
+ shi.osatex= origshi->osatex;
+ shi.depth= origshi->depth + 1; /* only used to indicate tracing */
+ shi.thread= origshi->thread;
+ //shi.sample= 0; // memset above, so don't need this
+ shi.xs= origshi->xs;
+ shi.ys= origshi->ys;
+ shi.do_manage= origshi->do_manage;
+ shi.lay= origshi->lay;
+ shi.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */
+ shi.combinedflag= 0xFFFFFF; /* ray trace does all options */
+ //shi.do_preview = false; // memset above, so don't need this
+ shi.light_override= origshi->light_override;
+ shi.mat_override= origshi->mat_override;
+
+ shade_ray(&isec, &shi, &shr);
+ /* ray has traveled inside the material, so shade by transmission */
+ if (traflag & RAY_INSIDE)
+ d= shade_by_transmission(&isec, &shi, &shr);
+
+ if (depth>0) {
+ float fr, fg, fb, f1;
+
+ if ((shi.mat->mode_l & MA_TRANSP) && shr.alpha < 1.0f && (shi.mat->mode_l & (MA_ZTRANSP | MA_RAYTRANSP))) {
+ float nf, f, refract[3], tracol[4];
+
+ tracol[0]= shi.r;
+ tracol[1]= shi.g;
+ tracol[2]= shi.b;
+ tracol[3]= col[3]; /* we pass on and accumulate alpha */
+
+ if ((shi.mat->mode & MA_TRANSP) && (shi.mat->mode & MA_RAYTRANSP)) {
+ /* don't overwrite traflag, it's value is used in mirror reflection */
+ int new_traflag = traflag;
+
+ if (new_traflag & RAY_INSIDE) {
+ /* inside the material, so use inverse normal */
+ float norm[3];
+ norm[0]= - shi.vn[0];
+ norm[1]= - shi.vn[1];
+ norm[2]= - shi.vn[2];
+
+ if (refraction(refract, norm, shi.view, shi.ang)) {
+ /* ray comes out from the material into air */
+ new_traflag &= ~RAY_INSIDE;
+ }
+ else {
+ /* total internal reflection (ray stays inside the material) */
+ reflection(refract, norm, shi.view, shi.vn);
+ }
+ }
+ else {
+ if (refraction(refract, shi.vn, shi.view, shi.ang)) {
+ /* ray goes in to the material from air */
+ new_traflag |= RAY_INSIDE;
+ }
+ else {
+ /* total external reflection (ray doesn't enter the material) */
+ reflection(refract, shi.vn, shi.view, shi.vn);
+ }
+ }
+ traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, new_traflag);
+ }
+ else
+ traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0);
+
+ f= shr.alpha; f1= 1.0f-f;
+ nf= (shi.mat->mode & MA_RAYTRANSP) ? d * shi.mat->filter : 0.0f;
+ fr= 1.0f+ nf*(shi.r-1.0f);
+ fg= 1.0f+ nf*(shi.g-1.0f);
+ fb= 1.0f+ nf*(shi.b-1.0f);
+ shr.diff[0]= f*shr.diff[0] + f1*fr*tracol[0];
+ shr.diff[1]= f*shr.diff[1] + f1*fg*tracol[1];
+ shr.diff[2]= f*shr.diff[2] + f1*fb*tracol[2];
+
+ shr.spec[0] *=f;
+ shr.spec[1] *=f;
+ shr.spec[2] *=f;
+
+ col[3]= f1*tracol[3] + f;
+ }
+ else {
+ col[3]= 1.0f;
+ }
+
+ float f;
+ if (shi.mat->mode_l & MA_RAYMIRROR) {
+ f= shi.ray_mirror;
+ if (f!=0.0f) f*= fresnel_fac(shi.view, shi.vn, shi.mat->fresnel_mir_i, shi.mat->fresnel_mir);
+ }
+ else f= 0.0f;
+
+ if (f!=0.0f) {
+ float mircol[4];
+ float ref[3];
+
+ reflection_simple(ref, shi.vn, shi.view);
+ traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, traflag);
+
+ f1= 1.0f-f;
+
+ /* combine */
+ //color_combine(col, f*fr*(1.0f-shr.spec[0]), f1, col, shr.diff);
+ //col[0]+= shr.spec[0];
+ //col[1]+= shr.spec[1];
+ //col[2]+= shr.spec[2];
+
+ fr= shi.mirr;
+ fg= shi.mirg;
+ fb= shi.mirb;
+
+ col[0]= f*fr*(1.0f-shr.spec[0])*mircol[0] + f1*shr.diff[0] + shr.spec[0];
+ col[1]= f*fg*(1.0f-shr.spec[1])*mircol[1] + f1*shr.diff[1] + shr.spec[1];
+ col[2]= f*fb*(1.0f-shr.spec[2])*mircol[2] + f1*shr.diff[2] + shr.spec[2];
+ }
+ else {
+ col[0]= shr.diff[0] + shr.spec[0];
+ col[1]= shr.diff[1] + shr.spec[1];
+ col[2]= shr.diff[2] + shr.spec[2];
+ }
+
+ if (dist_mir > 0.0f) {
+ float blendcol[3];
+
+ /* max ray distance set, but found an intersection, so fade this color
+ * out towards the sky/material color for a smooth transition */
+ ray_fadeout_endcolor(blendcol, origshi, &shi, origshr, &isec, dir);
+ ray_fadeout(&isec, &shi, col, blendcol, dist_mir);
+ }
+ }
+ else {
+ col[0]= shr.diff[0] + shr.spec[0];
+ col[1]= shr.diff[1] + shr.spec[1];
+ col[2]= shr.diff[2] + shr.spec[2];
+ }
+
+ }
+ else {
+ ray_fadeout_endcolor(col, origshi, &shi, origshr, &isec, dir);
+ }
+ RE_RC_MERGE(&origshi->raycounter, &shi.raycounter);
+}
+
+/* **************** jitter blocks ********** */
+
+/* calc distributed planar energy */
+
+static void DP_energy(float *table, float vec[2], int tot, float xsize, float ysize)
+{
+ int x, y, a;
+ float *fp, force[3], result[3];
+ float dx, dy, dist, min;
+
+ min= MIN2(xsize, ysize);
+ min*= min;
+ result[0]= result[1]= 0.0f;
+
+ for (y= -1; y<2; y++) {
+ dy= ysize*y;
+ for (x= -1; x<2; x++) {
+ dx= xsize*x;
+ fp= table;
+ for (a=0; a<tot; a++, fp+= 2) {
+ force[0]= vec[0] - fp[0]-dx;
+ force[1]= vec[1] - fp[1]-dy;
+ dist= force[0]*force[0] + force[1]*force[1];
+ if (dist < min && dist>0.0f) {
+ result[0]+= force[0]/dist;
+ result[1]+= force[1]/dist;
+ }
+ }
+ }
+ }
+ vec[0] += 0.1f*min*result[0]/(float)tot;
+ vec[1] += 0.1f*min*result[1]/(float)tot;
+ /* cyclic clamping */
+ vec[0]= vec[0] - xsize*floorf(vec[0]/xsize + 0.5f);
+ vec[1]= vec[1] - ysize*floorf(vec[1]/ysize + 0.5f);
+}
+
+/* random offset of 1 in 2 */
+static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float sizex, float sizey, float ofsx, float ofsy)
+{
+ float dsizex= sizex*ofsx;
+ float dsizey= sizey*ofsy;
+ float hsizex= 0.5f*sizex, hsizey= 0.5f*sizey;
+ int x;
+
+ for (x=tot; x>0; x--, jitter1+=2, jitter2+=2) {
+ jitter2[0]= jitter1[0] + dsizex;
+ jitter2[1]= jitter1[1] + dsizey;
+ if (jitter2[0] > hsizex) jitter2[0]-= sizex;
+ if (jitter2[1] > hsizey) jitter2[1]-= sizey;
+ }
+}
+
+/* called from convertBlenderScene.c */
+/* we do this in advance to get consistent random, not alter the render seed, and be threadsafe */
+void init_jitter_plane(LampRen *lar)
+{
+ float *fp;
+ int x, tot= lar->ray_totsamp;
+
+ /* test if already initialized */
+ if (lar->jitter) return;
+
+ /* at least 4, or max threads+1 tables */
+ if (BLENDER_MAX_THREADS < 4) x= 4;
+ else x= BLENDER_MAX_THREADS+1;
+ fp= lar->jitter= MEM_callocN(x*tot*2*sizeof(float), "lamp jitter tab");
+
+ /* if 1 sample, we leave table to be zero's */
+ if (tot>1) {
+ /* set per-lamp fixed seed */
+ RNG *rng = BLI_rng_new_srandom(tot);
+ int iter=12;
+
+ /* fill table with random locations, area_size large */
+ for (x=0; x<tot; x++, fp+=2) {
+ fp[0]= (BLI_rng_get_float(rng)-0.5f)*lar->area_size;
+ fp[1]= (BLI_rng_get_float(rng)-0.5f)*lar->area_sizey;
+ }
+
+ while (iter--) {
+ fp= lar->jitter;
+ for (x=tot; x>0; x--, fp+=2) {
+ DP_energy(lar->jitter, fp, tot, lar->area_size, lar->area_sizey);
+ }
+ }
+
+ BLI_rng_free(rng);
+ }
+ /* create the dithered tables (could just check lamp type!) */
+ jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.0f);
+ jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.5f);
+ jitter_plane_offset(lar->jitter, lar->jitter+6*tot, tot, lar->area_size, lar->area_sizey, 0.0f, 0.5f);
+}
+
+/* table around origin, -0.5*size to 0.5*size */
+static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys)
+{
+ int tot;
+
+ tot= lar->ray_totsamp;
+
+ if (lar->ray_samp_type & LA_SAMP_JITTER) {
+ /* made it threadsafe */
+
+ if (lar->xold[thread]!=xs || lar->yold[thread]!=ys) {
+ jitter_plane_offset(lar->jitter, lar->jitter+2*(thread+1)*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(thread), BLI_thread_frand(thread));
+ lar->xold[thread]= xs;
+ lar->yold[thread]= ys;
+ }
+ return lar->jitter+2*(thread+1)*tot;
+ }
+ if (lar->ray_samp_type & LA_SAMP_DITHER) {
+ return lar->jitter + 2*tot*((xs & 1)+2*(ys & 1));
+ }
+
+ return lar->jitter;
+}
+
+
+/* **************** QMC sampling *************** */
+
+static void halton_sample(double *ht_invprimes, double *ht_nums, double *v)
+{
+ /* incremental halton sequence generator, from:
+ * "Instant Radiosity", Keller A. */
+ unsigned int i;
+
+ for (i = 0; i < 2; i++) {
+ double r = fabs((1.0 - ht_nums[i]) - 1e-10);
+
+ if (ht_invprimes[i] >= r) {
+ double lasth;
+ double h = ht_invprimes[i];
+
+ do {
+ lasth = h;
+ h *= ht_invprimes[i];
+ } while (h >= r);
+
+ ht_nums[i] += ((lasth + h) - 1.0);
+ }
+ else
+ ht_nums[i] += ht_invprimes[i];
+
+ v[i] = (float)ht_nums[i];
+ }
+}
+
+/* Generate Hammersley points in [0,1)^2
+ * From Lucille renderer */
+static void hammersley_create(double *out, int n)
+{
+ double p, t;
+ int k, kk;
+
+ for (k = 0; k < n; k++) {
+ t = 0;
+ for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1) {
+ if (kk & 1) { /* kk mod 2 = 1 */
+ t += p;
+ }
+ }
+
+ out[2 * k + 0] = (double)k / (double)n;
+ out[2 * k + 1] = t;
+ }
+}
+
+static struct QMCSampler *QMC_initSampler(int type, int tot)
+{
+ QMCSampler *qsa = MEM_callocN(sizeof(QMCSampler), "qmc sampler");
+ qsa->samp2d = MEM_callocN(2*sizeof(double)*tot, "qmc sample table");
+
+ qsa->tot = tot;
+ qsa->type = type;
+
+ if (qsa->type==SAMP_TYPE_HAMMERSLEY)
+ hammersley_create(qsa->samp2d, qsa->tot);
+
+ return qsa;
+}
+
+static void QMC_initPixel(QMCSampler *qsa, int thread)
+{
+ if (qsa->type==SAMP_TYPE_HAMMERSLEY) {
+ /* hammersley sequence is fixed, already created in QMCSampler init.
+ * per pixel, gets a random offset. We create separate offsets per thread, for write-safety */
+ qsa->offs[thread][0] = 0.5f * BLI_thread_frand(thread);
+ qsa->offs[thread][1] = 0.5f * BLI_thread_frand(thread);
+ }
+ else { /* SAMP_TYPE_HALTON */
+
+ /* generate a new randomized halton sequence per pixel
+ * to alleviate qmc artifacts and make it reproducible
+ * between threads/frames */
+ double ht_invprimes[2], ht_nums[2];
+ double r[2];
+ int i;
+
+ ht_nums[0] = BLI_thread_frand(thread);
+ ht_nums[1] = BLI_thread_frand(thread);
+ ht_invprimes[0] = 0.5;
+ ht_invprimes[1] = 1.0/3.0;
+
+ for (i=0; i< qsa->tot; i++) {
+ halton_sample(ht_invprimes, ht_nums, r);
+ qsa->samp2d[2*i+0] = r[0];
+ qsa->samp2d[2*i+1] = r[1];
+ }
+ }
+}
+
+static void QMC_freeSampler(QMCSampler *qsa)
+{
+ MEM_freeN(qsa->samp2d);
+ MEM_freeN(qsa);
+}
+
+static void QMC_getSample(double *s, QMCSampler *qsa, int thread, int num)
+{
+ if (qsa->type == SAMP_TYPE_HAMMERSLEY) {
+ s[0] = fmod(qsa->samp2d[2*num+0] + qsa->offs[thread][0], 1.0f);
+ s[1] = fmod(qsa->samp2d[2*num+1] + qsa->offs[thread][1], 1.0f);
+ }
+ else { /* SAMP_TYPE_HALTON */
+ s[0] = qsa->samp2d[2*num+0];
+ s[1] = qsa->samp2d[2*num+1];
+ }
+}
+
+/* phong weighted disc using 'blur' for exponent, centred on 0,0 */
+static void QMC_samplePhong(float vec[3], QMCSampler *qsa, int thread, int num, float blur)
+{
+ double s[2];
+ float phi, pz, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2*M_PI;
+ pz = pow(s[1], blur);
+ sqr = sqrtf(1.0f - pz * pz);
+
+ vec[0] = (float)(cosf(phi)*sqr);
+ vec[1] = (float)(sinf(phi)*sqr);
+ vec[2] = 0.0f;
+}
+
+/* rect of edge lengths sizex, sizey, centred on 0.0,0.0 i.e. ranging from -sizex/2 to +sizey/2 */
+static void QMC_sampleRect(float vec[3], QMCSampler *qsa, int thread, int num, float sizex, float sizey)
+{
+ double s[2];
+
+ QMC_getSample(s, qsa, thread, num);
+
+ vec[0] = (float)(s[0] - 0.5) * sizex;
+ vec[1] = (float)(s[1] - 0.5) * sizey;
+ vec[2] = 0.0f;
+}
+
+/* disc of radius 'radius', centred on 0,0 */
+static void QMC_sampleDisc(float vec[3], QMCSampler *qsa, int thread, int num, float radius)
+{
+ double s[2];
+ float phi, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2*M_PI;
+ sqr = sqrt(s[1]);
+
+ vec[0] = cosf(phi)*sqr* radius/2.0f;
+ vec[1] = sinf(phi)*sqr* radius/2.0f;
+ vec[2] = 0.0f;
+}
+
+/* uniform hemisphere sampling */
+static void QMC_sampleHemi(float vec[3], QMCSampler *qsa, int thread, int num)
+{
+ double s[2];
+ float phi, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2.0*M_PI;
+ sqr = sqrt(s[1]);
+
+ vec[0] = cosf(phi)*sqr;
+ vec[1] = sinf(phi)*sqr;
+ vec[2] = (float)(1.0 - s[1]*s[1]);
+}
+
+#if 0 /* currently not used */
+/* cosine weighted hemisphere sampling */
+static void QMC_sampleHemiCosine(float vec[3], QMCSampler *qsa, int thread, int num)
+{
+ double s[2];
+ float phi, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2.f*M_PI;
+ sqr = s[1]*sqrt(2-s[1]*s[1]);
+
+ vec[0] = cos(phi)*sqr;
+ vec[1] = sin(phi)*sqr;
+ vec[2] = 1.f - s[1]*s[1];
+
+}
+#endif
+
+/* called from convertBlenderScene.c */
+void init_render_qmcsampler(Render *re)
+{
+ const int num_threads = re->r.threads;
+ re->qmcsamplers= MEM_callocN(sizeof(ListBase)*num_threads, "QMCListBase");
+ re->num_qmc_samplers = num_threads;
+}
+
+static QMCSampler *get_thread_qmcsampler(Render *re, int thread, int type, int tot)
+{
+ QMCSampler *qsa;
+
+ /* create qmc samplers as needed, since recursion makes it hard to
+ * predict how many are needed */
+
+ for (qsa=re->qmcsamplers[thread].first; qsa; qsa=qsa->next) {
+ if (qsa->type == type && qsa->tot == tot && !qsa->used) {
+ qsa->used = true;
+ return qsa;
+ }
+ }
+
+ qsa= QMC_initSampler(type, tot);
+ qsa->used = true;
+ BLI_addtail(&re->qmcsamplers[thread], qsa);
+
+ return qsa;
+}
+
+static void release_thread_qmcsampler(Render *UNUSED(re), int UNUSED(thread), QMCSampler *qsa)
+{
+ qsa->used= 0;
+}
+
+void free_render_qmcsampler(Render *re)
+{
+ if (re->qmcsamplers) {
+ QMCSampler *qsa, *next;
+ int a;
+ for (a = 0; a < re->num_qmc_samplers; a++) {
+ for (qsa=re->qmcsamplers[a].first; qsa; qsa=next) {
+ next= qsa->next;
+ QMC_freeSampler(qsa);
+ }
+
+ re->qmcsamplers[a].first= re->qmcsamplers[a].last= NULL;
+ }
+
+ MEM_freeN(re->qmcsamplers);
+ re->qmcsamplers= NULL;
+ }
+}
+
+static int adaptive_sample_variance(int samples, const float col[3], const float colsq[3], float thresh)
+{
+ float var[3], mean[3];
+
+ /* scale threshold just to give a bit more precision in input rather than dealing with
+ * tiny tiny numbers in the UI */
+ thresh /= 2;
+
+ mean[0] = col[0] / (float)samples;
+ mean[1] = col[1] / (float)samples;
+ mean[2] = col[2] / (float)samples;
+
+ var[0] = (colsq[0] / (float)samples) - (mean[0]*mean[0]);
+ var[1] = (colsq[1] / (float)samples) - (mean[1]*mean[1]);
+ var[2] = (colsq[2] / (float)samples) - (mean[2]*mean[2]);
+
+ if ((var[0] * 0.4f < thresh) && (var[1] * 0.3f < thresh) && (var[2] * 0.6f < thresh))
+ return 1;
+ else
+ return 0;
+}
+
+static int adaptive_sample_contrast_val(int samples, float prev, float val, float thresh)
+{
+ /* if the last sample's contribution to the total value was below a small threshold
+ * (i.e. the samples taken are very similar), then taking more samples that are probably
+ * going to be the same is wasting effort */
+ if (fabsf(prev / (float)(samples - 1) - val / (float)samples ) < thresh) {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static float get_avg_speed(ShadeInput *shi)
+{
+ float pre_x, pre_y, post_x, post_y, speedavg;
+
+ pre_x = (shi->winspeed[0] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[0];
+ pre_y = (shi->winspeed[1] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[1];
+ post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[2];
+ post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[3];
+
+ speedavg = (sqrtf(pre_x * pre_x + pre_y * pre_y) + sqrtf(post_x * post_x + post_y * post_y)) / 2.0f;
+
+ return speedavg;
+}
+
+/* ***************** main calls ************** */
+
+
+static void trace_refract(float col[4], ShadeInput *shi, ShadeResult *shr)
+{
+ QMCSampler *qsa=NULL;
+ int samp_type;
+ int traflag=0;
+
+ float samp3d[3], orthx[3], orthy[3];
+ float v_refract[3], v_refract_new[3];
+ float sampcol[4], colsq[4];
+
+ float blur = pow3f(1.0f - shi->mat->gloss_tra);
+ short max_samples = shi->mat->samp_gloss_tra;
+ float adapt_thresh = shi->mat->adapt_thresh_tra;
+
+ int samples=0;
+
+ colsq[0] = colsq[1] = colsq[2] = 0.0;
+ col[0] = col[1] = col[2] = 0.0;
+ col[3]= shr->alpha;
+
+ if (blur > 0.0f) {
+ if (adapt_thresh != 0.0f) samp_type = SAMP_TYPE_HALTON;
+ else samp_type = SAMP_TYPE_HAMMERSLEY;
+
+ /* all samples are generated per pixel */
+ qsa = get_thread_qmcsampler(&R, shi->thread, samp_type, max_samples);
+ QMC_initPixel(qsa, shi->thread);
+ }
+ else
+ max_samples = 1;
+
+
+ while (samples < max_samples) {
+ if (refraction(v_refract, shi->vn, shi->view, shi->ang)) {
+ traflag |= RAY_INSIDE;
+ }
+ else {
+ /* total external reflection can happen for materials with IOR < 1.0 */
+ if ((shi->vlr->flag & R_SMOOTH))
+ reflection(v_refract, shi->vn, shi->view, shi->facenor);
+ else
+ reflection_simple(v_refract, shi->vn, shi->view);
+
+ /* can't blur total external reflection */
+ max_samples = 1;
+ }
+
+ if (max_samples > 1) {
+ /* get a quasi-random vector from a phong-weighted disc */
+ QMC_samplePhong(samp3d, qsa, shi->thread, samples, blur);
+
+ ortho_basis_v3v3_v3(orthx, orthy, v_refract);
+ mul_v3_fl(orthx, samp3d[0]);
+ mul_v3_fl(orthy, samp3d[1]);
+
+ /* and perturb the refraction vector in it */
+ add_v3_v3v3(v_refract_new, v_refract, orthx);
+ add_v3_v3(v_refract_new, orthy);
+
+ normalize_v3(v_refract_new);
+ }
+ else {
+ /* no blurriness, use the original normal */
+ copy_v3_v3(v_refract_new, v_refract);
+ }
+
+ sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f;
+
+ traceray(shi, shr, shi->mat->ray_depth_tra, shi->co, v_refract_new, sampcol, shi->obi, shi->vlr, traflag);
+
+ col[0] += sampcol[0];
+ col[1] += sampcol[1];
+ col[2] += sampcol[2];
+ col[3] += sampcol[3];
+
+ /* for variance calc */
+ colsq[0] += sampcol[0]*sampcol[0];
+ colsq[1] += sampcol[1]*sampcol[1];
+ colsq[2] += sampcol[2]*sampcol[2];
+
+ samples++;
+
+ /* adaptive sampling */
+ if (adapt_thresh < 1.0f && samples > max_samples/2) {
+ if (adaptive_sample_variance(samples, col, colsq, adapt_thresh))
+ break;
+
+ /* if the pixel so far is very dark, we can get away with less samples */
+ if ( (col[0] + col[1] + col[2])/3.0f/(float)samples < 0.01f )
+ max_samples--;
+ }
+ }
+
+ col[0] /= (float)samples;
+ col[1] /= (float)samples;
+ col[2] /= (float)samples;
+ col[3] /= (float)samples;
+
+ if (qsa)
+ release_thread_qmcsampler(&R, shi->thread, qsa);
+}
+
+static void trace_reflect(float col[3], ShadeInput *shi, ShadeResult *shr, float fresnelfac)
+{
+ QMCSampler *qsa=NULL;
+ int samp_type;
+
+ float samp3d[3], orthx[3], orthy[3];
+ float v_nor_new[3], v_reflect[3];
+ float sampcol[4], colsq[4];
+
+ float blur = pow3f(1.0f - shi->mat->gloss_mir);
+ short max_samples = shi->mat->samp_gloss_mir;
+ float adapt_thresh = shi->mat->adapt_thresh_mir;
+ float aniso = 1.0f - shi->mat->aniso_gloss_mir;
+
+ int samples=0;
+
+ col[0] = col[1] = col[2] = 0.0;
+ colsq[0] = colsq[1] = colsq[2] = 0.0;
+
+ if (blur > 0.0f) {
+ if (adapt_thresh != 0.0f) samp_type = SAMP_TYPE_HALTON;
+ else samp_type = SAMP_TYPE_HAMMERSLEY;
+
+ /* all samples are generated per pixel */
+ qsa = get_thread_qmcsampler(&R, shi->thread, samp_type, max_samples);
+ QMC_initPixel(qsa, shi->thread);
+ }
+ else
+ max_samples = 1;
+
+ while (samples < max_samples) {
+
+ if (max_samples > 1) {
+ /* get a quasi-random vector from a phong-weighted disc */
+ QMC_samplePhong(samp3d, qsa, shi->thread, samples, blur);
+
+ /* find the normal's perpendicular plane, blurring along tangents
+ * if tangent shading enabled */
+ if (shi->mat->mode & (MA_TANGENT_V)) {
+ cross_v3_v3v3(orthx, shi->vn, shi->tang); // bitangent
+ copy_v3_v3(orthy, shi->tang);
+ mul_v3_fl(orthx, samp3d[0]);
+ mul_v3_fl(orthy, samp3d[1]*aniso);
+ }
+ else {
+ ortho_basis_v3v3_v3(orthx, orthy, shi->vn);
+ mul_v3_fl(orthx, samp3d[0]);
+ mul_v3_fl(orthy, samp3d[1]);
+ }
+
+ /* and perturb the normal in it */
+ add_v3_v3v3(v_nor_new, shi->vn, orthx);
+ add_v3_v3(v_nor_new, orthy);
+ normalize_v3(v_nor_new);
+ }
+ else {
+ /* no blurriness, use the original normal */
+ copy_v3_v3(v_nor_new, shi->vn);
+ }
+
+ if ((shi->vlr->flag & R_SMOOTH))
+ reflection(v_reflect, v_nor_new, shi->view, shi->facenor);
+ else
+ reflection_simple(v_reflect, v_nor_new, shi->view);
+
+ sampcol[0]= sampcol[1]= sampcol[2]= sampcol[3]= 0.0f;
+
+ traceray(shi, shr, shi->mat->ray_depth, shi->co, v_reflect, sampcol, shi->obi, shi->vlr, 0);
+
+
+ col[0] += sampcol[0];
+ col[1] += sampcol[1];
+ col[2] += sampcol[2];
+
+ /* for variance calc */
+ colsq[0] += sampcol[0]*sampcol[0];
+ colsq[1] += sampcol[1]*sampcol[1];
+ colsq[2] += sampcol[2]*sampcol[2];
+
+ samples++;
+
+ /* adaptive sampling */
+ if (adapt_thresh > 0.0f && samples > max_samples/3) {
+ if (adaptive_sample_variance(samples, col, colsq, adapt_thresh))
+ break;
+
+ /* if the pixel so far is very dark, we can get away with less samples */
+ if ( (col[0] + col[1] + col[2])/3.0f/(float)samples < 0.01f )
+ max_samples--;
+
+ /* reduce samples when reflection is dim due to low ray mirror blend value or fresnel factor
+ * and when reflection is blurry */
+ if (fresnelfac < 0.1f * (blur+1)) {
+ max_samples--;
+
+ /* even more for very dim */
+ if (fresnelfac < 0.05f * (blur+1))
+ max_samples--;
+ }
+ }
+ }
+
+ col[0] /= (float)samples;
+ col[1] /= (float)samples;
+ col[2] /= (float)samples;
+
+ if (qsa)
+ release_thread_qmcsampler(&R, shi->thread, qsa);
+}
+
+/* extern call from render loop */
+void ray_trace(ShadeInput *shi, ShadeResult *shr)
+{
+ float f1, fr, fg, fb;
+ float mircol[4], tracol[4];
+ float diff[3];
+ int do_tra, do_mir;
+
+ do_tra = ((shi->mode & MA_TRANSP) && (shi->mode & MA_RAYTRANSP) && shr->alpha != 1.0f && (shi->depth <= shi->mat->ray_depth_tra));
+ do_mir = ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror != 0.0f && (shi->depth <= shi->mat->ray_depth));
+
+ /* raytrace mirror and refract like to separate the spec color */
+ if (shi->combinedflag & SCE_PASS_SPEC)
+ sub_v3_v3v3(diff, shr->combined, shr->spec);
+ else
+ copy_v3_v3(diff, shr->combined);
+
+ if (do_tra) {
+ float olddiff[3], f;
+
+ trace_refract(tracol, shi, shr);
+
+ f= shr->alpha; f1= 1.0f-f;
+ fr= 1.0f+ shi->mat->filter*(shi->r-1.0f);
+ fg= 1.0f+ shi->mat->filter*(shi->g-1.0f);
+ fb= 1.0f+ shi->mat->filter*(shi->b-1.0f);
+
+ /* for refract pass */
+ copy_v3_v3(olddiff, diff);
+
+ diff[0]= f*diff[0] + f1*fr*tracol[0];
+ diff[1]= f*diff[1] + f1*fg*tracol[1];
+ diff[2]= f*diff[2] + f1*fb*tracol[2];
+
+ if (shi->passflag & SCE_PASS_REFRACT)
+ sub_v3_v3v3(shr->refr, diff, olddiff);
+
+ if (!(shi->combinedflag & SCE_PASS_REFRACT))
+ sub_v3_v3v3(diff, diff, shr->refr);
+
+ shr->alpha = min_ff(1.0f, tracol[3]);
+ }
+
+ if (do_mir) {
+ const float i= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->mat->fresnel_mir_i, shi->mat->fresnel_mir);
+ if (i!=0.0f) {
+
+ trace_reflect(mircol, shi, shr, i);
+
+ fr= i*shi->mirr;
+ fg= i*shi->mirg;
+ fb= i*shi->mirb;
+
+ if (shi->passflag & SCE_PASS_REFLECT) {
+ /* mirror pass is not blocked out with spec */
+ shr->refl[0]= fr*mircol[0] - fr*diff[0];
+ shr->refl[1]= fg*mircol[1] - fg*diff[1];
+ shr->refl[2]= fb*mircol[2] - fb*diff[2];
+ }
+
+ if (shi->combinedflag & SCE_PASS_REFLECT) {
+ /* values in shr->spec can be greater than 1.0.
+ * In this case the mircol uses a zero blending factor, so ignoring it is ok.
+ * Fixes bug #18837 - when the spec is higher then 1.0,
+ * diff can become a negative color - Campbell */
+
+ f1= 1.0f-i;
+
+ diff[0] *= f1;
+ diff[1] *= f1;
+ diff[2] *= f1;
+
+ if (shr->spec[0]<1.0f) diff[0] += mircol[0] * (fr*(1.0f-shr->spec[0]));
+ if (shr->spec[1]<1.0f) diff[1] += mircol[1] * (fg*(1.0f-shr->spec[1]));
+ if (shr->spec[2]<1.0f) diff[2] += mircol[2] * (fb*(1.0f-shr->spec[2]));
+ }
+ }
+ }
+ /* put back together */
+ if (shi->combinedflag & SCE_PASS_SPEC)
+ add_v3_v3v3(shr->combined, diff, shr->spec);
+ else
+ copy_v3_v3(shr->combined, diff);
+}
+
+/* color 'shadfac' passes through 'col' with alpha and filter */
+/* filter is only applied on alpha defined transparent part */
+static void addAlphaLight(float shadfac[4], const float col[3], float alpha, float filter)
+{
+ float fr, fg, fb;
+
+ fr= 1.0f+ filter*(col[0]-1.0f);
+ fg= 1.0f+ filter*(col[1]-1.0f);
+ fb= 1.0f+ filter*(col[2]-1.0f);
+
+ shadfac[0]= alpha*col[0] + fr*(1.0f-alpha)*shadfac[0];
+ shadfac[1]= alpha*col[1] + fg*(1.0f-alpha)*shadfac[1];
+ shadfac[2]= alpha*col[2] + fb*(1.0f-alpha)*shadfac[2];
+
+ shadfac[3]= (1.0f-alpha)*shadfac[3];
+}
+
+static void ray_trace_shadow_tra(Isect *is, ShadeInput *origshi, int depth, int traflag, float col[4])
+{
+ /* ray to lamp, find first face that intersects, check alpha properties,
+ * if it has col[3]>0.0f continue. so exit when alpha is full */
+ const float initial_dist = is->dist;
+
+ if (RE_rayobject_raycast(R.raytree, is)) {
+ /* Warning regarding initializing to zero's, This is not that nice,
+ * and possibly a bit slow for every ray, however some variables were
+ * not initialized properly in, unless using
+ * shade_input_initialize(...), we need to zero them. */
+ ShadeInput shi= {NULL};
+ /* end warning! - Campbell */
+
+ ShadeResult shr;
+
+ /* we got a face */
+
+ shi.depth= origshi->depth + 1; /* only used to indicate tracing */
+ shi.mask= origshi->mask;
+ shi.thread= origshi->thread;
+ shi.passflag= SCE_PASS_COMBINED;
+ shi.combinedflag= 0xFFFFFF; /* ray trace does all options */
+
+ shi.xs= origshi->xs;
+ shi.ys= origshi->ys;
+ shi.do_manage= origshi->do_manage;
+ shi.lay= origshi->lay;
+ shi.nodes= origshi->nodes;
+
+ RE_instance_rotate_ray_restore(origshi->obi, is);
+
+ shade_ray(is, &shi, &shr);
+ if (shi.mat->material_type == MA_TYPE_SURFACE) {
+ const float d = (shi.mat->mode & MA_RAYTRANSP) ?
+ ((traflag & RAY_TRA) ? shade_by_transmission(is, &shi, &shr) : 1.0f) :
+ 0.0f;
+ /* mix colors based on shadfac (rgb + amount of light factor) */
+ addAlphaLight(col, shr.diff, shr.alpha, d*shi.mat->filter);
+ }
+ else if (shi.mat->material_type == MA_TYPE_VOLUME) {
+ const float a = col[3];
+
+ col[0] = a*col[0] + shr.alpha*shr.combined[0];
+ col[1] = a*col[1] + shr.alpha*shr.combined[1];
+ col[2] = a*col[2] + shr.alpha*shr.combined[2];
+
+ col[3] = (1.0f - shr.alpha)*a;
+ }
+
+ if (depth>0 && col[3]>0.0f) {
+
+ /* adapt isect struct */
+ copy_v3_v3(is->start, shi.co);
+ is->dist = initial_dist-is->dist;
+ is->orig.ob = shi.obi;
+ is->orig.face = shi.vlr;
+
+ ray_trace_shadow_tra(is, origshi, depth-1, traflag | RAY_TRA, col);
+ }
+
+ RE_RC_MERGE(&origshi->raycounter, &shi.raycounter);
+ }
+}
+
+
+/* aolight: function to create random unit sphere vectors for total random sampling */
+
+/* calc distributed spherical energy */
+static void DS_energy(float *sphere, int tot, float vec[3])
+{
+ float *fp, fac, force[3], res[3];
+ int a;
+
+ res[0]= res[1]= res[2]= 0.0f;
+
+ for (a=0, fp=sphere; a<tot; a++, fp+=3) {
+ sub_v3_v3v3(force, vec, fp);
+ fac = dot_v3v3(force, force);
+ if (fac!=0.0f) {
+ fac= 1.0f/fac;
+ res[0]+= fac*force[0];
+ res[1]+= fac*force[1];
+ res[2]+= fac*force[2];
+ }
+ }
+
+ mul_v3_fl(res, 0.5);
+ add_v3_v3(vec, res);
+ normalize_v3(vec);
+
+}
+
+/* called from convertBlenderScene.c */
+/* creates an equally distributed spherical sample pattern */
+/* and allocates threadsafe memory */
+void init_ao_sphere(Render *re, World *wrld)
+{
+ /* fixed random */
+ const int num_threads = re->r.threads;
+ RNG *rng;
+ float *fp;
+ int a, tot, iter= 16;
+
+ /* we make twice the amount of samples, because only a hemisphere is used */
+ tot= 2*wrld->aosamp*wrld->aosamp;
+
+ wrld->aosphere= MEM_mallocN(3*tot*sizeof(float), "AO sphere");
+ rng = BLI_rng_new_srandom(tot);
+
+ /* init */
+ fp= wrld->aosphere;
+ for (a=0; a<tot; a++, fp+= 3) {
+ BLI_rng_get_float_unit_v3(rng, fp);
+ }
+
+ while (iter--) {
+ for (a=0, fp= wrld->aosphere; a<tot; a++, fp+= 3) {
+ DS_energy(wrld->aosphere, tot, fp);
+ }
+ }
+
+ /* tables */
+ wrld->aotables= MEM_mallocN(num_threads*3*tot*sizeof(float), "AO tables");
+
+ BLI_rng_free(rng);
+}
+
+/* give per thread a table, we have to compare xs ys because of way OSA works... */
+static float *threadsafe_table_sphere(int test, int thread, int xs, int ys, int tot)
+{
+ static int xso[BLENDER_MAX_THREADS], yso[BLENDER_MAX_THREADS];
+ static int firsttime= 1;
+
+ if (firsttime) {
+ memset(xso, 255, sizeof(xso));
+ memset(yso, 255, sizeof(yso));
+ firsttime= 0;
+ }
+
+ if (xs==xso[thread] && ys==yso[thread]) return R.wrld.aotables+ thread*tot*3;
+ if (test) return NULL;
+ xso[thread]= xs; yso[thread]= ys;
+ return R.wrld.aotables+ thread*tot*3;
+}
+
+static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, int reset)
+{
+ int tot;
+ float *vec;
+
+ tot= 2*resol*resol;
+
+ if (type & WO_AORNDSMP) {
+ /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */
+ RNG *rng = BLI_rng_new(BLI_thread_rand(thread));
+ float *sphere;
+ int a;
+
+ /* always returns table */
+ sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
+
+ vec= sphere;
+ for (a=0; a<tot; a++, vec+=3) {
+ BLI_rng_get_float_unit_v3(rng, vec);
+ }
+
+ BLI_rng_free(rng);
+
+ return sphere;
+ }
+ else {
+ float *sphere;
+ float *vec1;
+
+ /* returns table if xs and ys were equal to last call, and not resetting */
+ sphere= (reset)? NULL: threadsafe_table_sphere(1, thread, xs, ys, tot);
+ if (sphere==NULL) {
+ float cosfi, sinfi, cost, sint;
+ float ang;
+ int a;
+
+ sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
+
+ /* random rotation */
+ ang = BLI_thread_frand(thread);
+ sinfi = sinf(ang); cosfi = cosf(ang);
+ ang = BLI_thread_frand(thread);
+ sint = sinf(ang); cost = cosf(ang);
+
+ vec= R.wrld.aosphere;
+ vec1= sphere;
+ for (a=0; a<tot; a++, vec+=3, vec1+=3) {
+ vec1[0]= cost*cosfi*vec[0] - sinfi*vec[1] + sint*cosfi*vec[2];
+ vec1[1]= cost*sinfi*vec[0] + cosfi*vec[1] + sint*sinfi*vec[2];
+ vec1[2]= -sint*vec[0] + cost*vec[2];
+ }
+ }
+ return sphere;
+ }
+}
+
+static void ray_ao_qmc(ShadeInput *shi, float ao[3], float env[3])
+{
+ Isect isec;
+ RayHint point_hint;
+ QMCSampler *qsa=NULL;
+ float samp3d[3];
+ float up[3], side[3], dir[3], nrm[3];
+
+ float maxdist = R.wrld.aodist;
+ float fac=0.0f, prev=0.0f;
+ float adapt_thresh = R.wrld.ao_adapt_thresh;
+ float adapt_speed_fac = R.wrld.ao_adapt_speed_fac;
+
+ int samples=0;
+ int max_samples = R.wrld.aosamp*R.wrld.aosamp;
+
+ float dxyview[3], skyadded=0;
+ int envcolor;
+
+ RE_RC_INIT(isec, *shi);
+ isec.orig.ob = shi->obi;
+ isec.orig.face = shi->vlr;
+ isec.check = RE_CHECK_VLR_NON_SOLID_MATERIAL;
+ isec.skip = RE_SKIP_VLR_NEIGHBOUR;
+ isec.hint = NULL;
+
+ isec.hit.ob = NULL;
+ isec.hit.face = NULL;
+
+ isec.last_hit = NULL;
+
+ isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
+ isec.lay= -1;
+
+ copy_v3_v3(isec.start, shi->co);
+
+ RE_instance_rotate_ray_start(shi->obi, &isec);
+
+ RE_rayobject_hint_bb(R.raytree, &point_hint, isec.start, isec.start);
+ isec.hint = &point_hint;
+
+ zero_v3(ao);
+ zero_v3(env);
+
+ /* prevent sky colors to be added for only shadow (shadow becomes alpha) */
+ envcolor= R.wrld.aocolor;
+ if (shi->mat->mode & MA_ONLYSHADOW)
+ envcolor= WO_AOPLAIN;
+
+ if (envcolor == WO_AOSKYTEX) {
+ dxyview[0]= 1.0f/(float)R.wrld.aosamp;
+ dxyview[1]= 1.0f/(float)R.wrld.aosamp;
+ dxyview[2]= 0.0f;
+ }
+
+ if (shi->vlr->flag & R_SMOOTH) {
+ copy_v3_v3(nrm, shi->vn);
+ }
+ else {
+ copy_v3_v3(nrm, shi->facenor);
+ }
+
+ ortho_basis_v3v3_v3(up, side, nrm);
+
+ /* sampling init */
+ if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) {
+ float speedfac;
+
+ speedfac = get_avg_speed(shi) * adapt_speed_fac;
+ CLAMP(speedfac, 1.0f, 1000.0f);
+ max_samples /= speedfac;
+ if (max_samples < 5) max_samples = 5;
+
+ qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, max_samples);
+ }
+ else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
+ qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples);
+
+ QMC_initPixel(qsa, shi->thread);
+
+ while (samples < max_samples) {
+
+ /* sampling, returns quasi-random vector in unit hemisphere */
+ QMC_sampleHemi(samp3d, qsa, shi->thread, samples);
+
+ dir[0] = (samp3d[0]*up[0] + samp3d[1]*side[0] + samp3d[2]*nrm[0]);
+ dir[1] = (samp3d[0]*up[1] + samp3d[1]*side[1] + samp3d[2]*nrm[1]);
+ dir[2] = (samp3d[0]*up[2] + samp3d[1]*side[2] + samp3d[2]*nrm[2]);
+
+ normalize_v3(dir);
+
+ isec.dir[0] = -dir[0];
+ isec.dir[1] = -dir[1];
+ isec.dir[2] = -dir[2];
+ isec.dist = maxdist;
+
+ RE_instance_rotate_ray_dir(shi->obi, &isec);
+
+ prev = fac;
+
+ if (RE_rayobject_raycast(R.raytree, &isec)) {
+ if (R.wrld.aomode & WO_AODIST) fac+= expf(-isec.dist*R.wrld.aodistfac);
+ else fac+= 1.0f;
+ }
+ else if (envcolor!=WO_AOPLAIN) {
+ float skycol[4];
+ float view[3];
+
+ view[0]= -dir[0];
+ view[1]= -dir[1];
+ view[2]= -dir[2];
+ normalize_v3(view);
+
+ if (envcolor==WO_AOSKYCOL) {
+ const float skyfac= 0.5f * (1.0f + dot_v3v3(view, R.grvec));
+ env[0]+= (1.0f-skyfac)*R.wrld.horr + skyfac*R.wrld.zenr;
+ env[1]+= (1.0f-skyfac)*R.wrld.horg + skyfac*R.wrld.zeng;
+ env[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb;
+ }
+ else { /* WO_AOSKYTEX */
+ shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
+ shadeSunView(skycol, shi->view);
+ env[0]+= skycol[0];
+ env[1]+= skycol[1];
+ env[2]+= skycol[2];
+ }
+ skyadded++;
+ }
+
+ samples++;
+
+ if (qsa && qsa->type == SAMP_TYPE_HALTON) {
+ /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */
+ if (adapt_thresh > 0.0f && (samples > max_samples/2) ) {
+
+ if (adaptive_sample_contrast_val(samples, prev, fac, adapt_thresh)) {
+ break;
+ }
+ }
+ }
+ }
+
+ /* average color times distances/hits formula */
+ ao[0]= ao[1]= ao[2]= 1.0f - fac/(float)samples;
+
+ if (envcolor!=WO_AOPLAIN && skyadded)
+ mul_v3_fl(env, (1.0f - fac/(float)samples)/((float)skyadded));
+ else
+ copy_v3_v3(env, ao);
+
+ if (qsa)
+ release_thread_qmcsampler(&R, shi->thread, qsa);
+}
+
+/* extern call from shade_lamp_loop, ambient occlusion calculus */
+static void ray_ao_spheresamp(ShadeInput *shi, float ao[3], float env[3])
+{
+ Isect isec;
+ RayHint point_hint;
+ float *vec, *nrm, bias, sh=0.0f;
+ float maxdist = R.wrld.aodist;
+ float dxyview[3];
+ int j= -1, tot, actual=0, skyadded=0, envcolor, resol= R.wrld.aosamp;
+
+ RE_RC_INIT(isec, *shi);
+ isec.orig.ob = shi->obi;
+ isec.orig.face = shi->vlr;
+ isec.check = RE_CHECK_VLR_RENDER;
+ isec.skip = RE_SKIP_VLR_NEIGHBOUR;
+ isec.hint = NULL;
+
+ isec.hit.ob = NULL;
+ isec.hit.face = NULL;
+
+ isec.last_hit = NULL;
+
+ isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
+ isec.lay= -1;
+
+ copy_v3_v3(isec.start, shi->co);
+ RE_instance_rotate_ray_start(shi->obi, &isec);
+
+ RE_rayobject_hint_bb(R.raytree, &point_hint, isec.start, isec.start);
+ isec.hint = &point_hint;
+
+ zero_v3(ao);
+ zero_v3(env);
+
+ /* bias prevents smoothed faces to appear flat */
+ if (shi->vlr->flag & R_SMOOTH) {
+ bias= R.wrld.aobias;
+ nrm= shi->vn;
+ }
+ else {
+ bias= 0.0f;
+ nrm= shi->facenor;
+ }
+
+ /* prevent sky colors to be added for only shadow (shadow becomes alpha) */
+ envcolor= R.wrld.aocolor;
+ if (shi->mat->mode & MA_ONLYSHADOW)
+ envcolor= WO_AOPLAIN;
+
+ if (resol>32) resol= 32;
+
+ /* get sphere samples. for faces we get the same samples for sample x/y values,
+ * for strand render we always require a new sampler because x/y are not set */
+ vec= sphere_sampler(R.wrld.aomode, resol, shi->thread, shi->xs, shi->ys, shi->strand != NULL);
+
+ /* warning: since we use full sphere now, and dotproduct is below, we do twice as much */
+ tot= 2*resol*resol;
+
+ if (envcolor == WO_AOSKYTEX) {
+ dxyview[0]= 1.0f/(float)resol;
+ dxyview[1]= 1.0f/(float)resol;
+ dxyview[2]= 0.0f;
+ }
+
+ while (tot--) {
+
+ if (dot_v3v3(vec, nrm) > bias) {
+ /* only ao samples for mask */
+ if (R.r.mode & R_OSA) {
+ j++;
+ if (j==R.osa) j= 0;
+ if (!(shi->mask & (1<<j))) {
+ vec+=3;
+ continue;
+ }
+ }
+
+ actual++;
+
+ /* always set start/vec/dist */
+ isec.dir[0] = -vec[0];
+ isec.dir[1] = -vec[1];
+ isec.dir[2] = -vec[2];
+ isec.dist = maxdist;
+
+ RE_instance_rotate_ray_dir(shi->obi, &isec);
+
+ /* do the trace */
+ if (RE_rayobject_raycast(R.raytree, &isec)) {
+ if (R.wrld.aomode & WO_AODIST) sh+= expf(-isec.dist*R.wrld.aodistfac);
+ else sh+= 1.0f;
+ }
+ else if (envcolor!=WO_AOPLAIN) {
+ float skycol[4];
+ float view[3];
+
+ view[0]= -vec[0];
+ view[1]= -vec[1];
+ view[2]= -vec[2];
+ normalize_v3(view);
+
+ if (envcolor==WO_AOSKYCOL) {
+ const float fac = 0.5f * (1.0f + dot_v3v3(view, R.grvec));
+ env[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr;
+ env[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng;
+ env[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb;
+ }
+ else { /* WO_AOSKYTEX */
+ shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
+ shadeSunView(skycol, shi->view);
+ env[0]+= skycol[0];
+ env[1]+= skycol[1];
+ env[2]+= skycol[2];
+ }
+ skyadded++;
+ }
+ }
+ /* samples */
+ vec+= 3;
+ }
+
+ if (actual==0) sh= 1.0f;
+ else sh = 1.0f - sh/((float)actual);
+
+ /* average color times distances/hits formula */
+ ao[0]= ao[1]= ao[2]= sh;
+
+ if (envcolor!=WO_AOPLAIN && skyadded)
+ mul_v3_fl(env, sh/((float)skyadded));
+ else
+ copy_v3_v3(env, ao);
+}
+
+void ray_ao(ShadeInput *shi, float ao[3], float env[3])
+{
+ /* Unfortunately, the unusual way that the sphere sampler calculates roughly twice as many
+ * samples as are actually traced, and skips them based on bias and OSA settings makes it very difficult
+ * to reuse code between these two functions. This is the easiest way I can think of to do it
+ * --broken */
+ if (ELEM(R.wrld.ao_samp_method, WO_AOSAMP_HAMMERSLEY, WO_AOSAMP_HALTON))
+ ray_ao_qmc(shi, ao, env);
+ else if (R.wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
+ ray_ao_spheresamp(shi, ao, env);
+}
+
+static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_MAX_OSA][3], int *totjitco)
+{
+ /* magic numbers for reordering sample positions to give better
+ * results with adaptive sample, when it usually only takes 4 samples */
+ int order8[8] = {0, 1, 5, 6, 2, 3, 4, 7};
+ int order11[11] = {1, 3, 8, 10, 0, 2, 4, 5, 6, 7, 9};
+ int order16[16] = {1, 3, 9, 12, 0, 6, 7, 8, 13, 2, 4, 5, 10, 11, 14, 15};
+ int count = count_mask(shi->mask);
+
+ /* for better antialising shadow samples are distributed over the subpixel
+ * sample coordinates, this only works for raytracing depth 0 though */
+ if (!shi->strand && shi->depth == 0 && count > 1 && count <= max) {
+ float xs, ys, zs, view[3];
+ int samp, ordsamp, tot= 0;
+
+ for (samp=0; samp<R.osa; samp++) {
+ if (R.osa == 8) ordsamp = order8[samp];
+ else if (R.osa == 11) ordsamp = order11[samp];
+ else if (R.osa == 16) ordsamp = order16[samp];
+ else ordsamp = samp;
+
+ if (shi->mask & (1<<ordsamp)) {
+ /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */
+ xs= (float)shi->scanco[0] + R.jit[ordsamp][0] + 0.5f;
+ ys= (float)shi->scanco[1] + R.jit[ordsamp][1] + 0.5f;
+ zs= shi->scanco[2];
+
+ shade_input_calc_viewco(shi, xs, ys, zs, view, NULL, jitco[tot], NULL, NULL);
+ tot++;
+ }
+ }
+
+ *totjitco= tot;
+ }
+ else {
+ copy_v3_v3(jitco[0], shi->co);
+ *totjitco= 1;
+ }
+}
+
+static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, const float lampco[3], float shadfac[4], Isect *isec)
+{
+ QMCSampler *qsa=NULL;
+ int samples=0;
+ float samp3d[3];
+
+ float fac=0.0f, vec[3], end[3];
+ float colsq[4];
+ float adapt_thresh = lar->adapt_thresh;
+ int min_adapt_samples=4, max_samples = lar->ray_totsamp;
+ float start[3];
+ bool do_soft = true, full_osa = false;
+ int i;
+
+ float min[3], max[3];
+ RayHint bb_hint;
+
+ float jitco[RE_MAX_OSA][3];
+ int totjitco;
+
+ colsq[0] = colsq[1] = colsq[2] = 0.0;
+ if (isec->mode==RE_RAY_SHADOW_TRA) {
+ shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;
+ }
+ else
+ shadfac[3]= 1.0f;
+
+ if (lar->ray_totsamp < 2) do_soft = false;
+ if ((R.r.mode & R_OSA) && (R.osa > 0) && (shi->vlr->flag & R_FULL_OSA)) full_osa = true;
+
+ if (full_osa) {
+ if (do_soft) max_samples = max_samples/R.osa + 1;
+ else max_samples = 1;
+ }
+ else {
+ if (do_soft) max_samples = lar->ray_totsamp;
+ else if (shi->depth == 0) max_samples = (R.osa > 4)?R.osa:5;
+ else max_samples = 1;
+ }
+
+ ray_shadow_jittered_coords(shi, max_samples, jitco, &totjitco);
+
+ /* sampling init */
+ if (lar->ray_samp_method==LA_SAMP_HALTON)
+ qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, max_samples);
+ else if (lar->ray_samp_method==LA_SAMP_HAMMERSLEY)
+ qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples);
+
+ QMC_initPixel(qsa, shi->thread);
+
+ INIT_MINMAX(min, max);
+ for (i = 0; i < totjitco; i++) {
+ minmax_v3v3_v3(min, max, jitco[i]);
+ }
+ if (shi->obi->flag & R_ENV_TRANSFORMED) {
+ mul_m4_v3(shi->obi->imat, min);
+ mul_m4_v3(shi->obi->imat, max);
+ }
+ RE_rayobject_hint_bb(R.raytree, &bb_hint, min, max);
+
+ isec->hint = &bb_hint;
+ isec->check = RE_CHECK_VLR_RENDER;
+ isec->skip = RE_SKIP_VLR_NEIGHBOUR;
+ copy_v3_v3(vec, lampco);
+
+ while (samples < max_samples) {
+
+ isec->orig.ob = shi->obi;
+ isec->orig.face = shi->vlr;
+
+ /* manually jitter the start shading co-ord per sample
+ * based on the pre-generated OSA texture sampling offsets,
+ * for anti-aliasing sharp shadow edges. */
+ copy_v3_v3(start, jitco[samples % totjitco]);
+
+ if (do_soft) {
+ /* sphere shadow source */
+ if (lar->type == LA_LOCAL) {
+ float ru[3], rv[3], v[3], s[3];
+
+ /* calc tangent plane vectors */
+ sub_v3_v3v3(v, start, lampco);
+ normalize_v3(v);
+ ortho_basis_v3v3_v3(ru, rv, v);
+
+ /* sampling, returns quasi-random vector in area_size disc */
+ QMC_sampleDisc(samp3d, qsa, shi->thread, samples, lar->area_size);
+
+ /* distribute disc samples across the tangent plane */
+ s[0] = samp3d[0]*ru[0] + samp3d[1]*rv[0];
+ s[1] = samp3d[0]*ru[1] + samp3d[1]*rv[1];
+ s[2] = samp3d[0]*ru[2] + samp3d[1]*rv[2];
+
+ copy_v3_v3(samp3d, s);
+ }
+ else {
+ /* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */
+ QMC_sampleRect(samp3d, qsa, shi->thread, samples, lar->area_size, lar->area_sizey);
+
+ /* align samples to lamp vector */
+ mul_m3_v3(lar->mat, samp3d);
+ }
+ end[0] = vec[0]+samp3d[0];
+ end[1] = vec[1]+samp3d[1];
+ end[2] = vec[2]+samp3d[2];
+ }
+ else {
+ copy_v3_v3(end, vec);
+ }
+
+ if (shi->strand) {
+ /* bias away somewhat to avoid self intersection */
+ float jitbias= 0.5f*(len_v3(shi->dxco) + len_v3(shi->dyco));
+ float v[3];
+
+ sub_v3_v3v3(v, start, end);
+ normalize_v3(v);
+
+ start[0] -= jitbias*v[0];
+ start[1] -= jitbias*v[1];
+ start[2] -= jitbias*v[2];
+ }
+
+ copy_v3_v3(isec->start, start);
+ sub_v3_v3v3(isec->dir, end, start);
+ isec->dist = normalize_v3(isec->dir);
+
+ RE_instance_rotate_ray(shi->obi, isec);
+
+ /* trace the ray */
+ if (isec->mode==RE_RAY_SHADOW_TRA) {
+ float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0, col);
+ shadfac[0] += col[0];
+ shadfac[1] += col[1];
+ shadfac[2] += col[2];
+ shadfac[3] += col[3];
+
+ /* for variance calc */
+ colsq[0] += col[0]*col[0];
+ colsq[1] += col[1]*col[1];
+ colsq[2] += col[2]*col[2];
+ }
+ else {
+ if ( RE_rayobject_raycast(R.raytree, isec) ) fac+= 1.0f;
+ }
+
+ samples++;
+
+ if (lar->ray_samp_method == LA_SAMP_HALTON) {
+
+ /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */
+ if ((max_samples > min_adapt_samples) && (adapt_thresh > 0.0f) && (samples > max_samples / 3)) {
+ if (isec->mode==RE_RAY_SHADOW_TRA) {
+ if ((shadfac[3] / samples > (1.0f-adapt_thresh)) || (shadfac[3] / samples < adapt_thresh))
+ break;
+ else if (adaptive_sample_variance(samples, shadfac, colsq, adapt_thresh))
+ break;
+ }
+ else {
+ if ((fac / samples > (1.0f-adapt_thresh)) || (fac / samples < adapt_thresh))
+ break;
+ }
+ }
+ }
+ }
+
+ if (isec->mode==RE_RAY_SHADOW_TRA) {
+ shadfac[0] /= samples;
+ shadfac[1] /= samples;
+ shadfac[2] /= samples;
+ shadfac[3] /= samples;
+ }
+ else
+ shadfac[3]= 1.0f-fac/samples;
+
+ if (qsa)
+ release_thread_qmcsampler(&R, shi->thread, qsa);
+}
+
+static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[3], float shadfac[4], Isect *isec)
+{
+ /* area soft shadow */
+ const float *jitlamp;
+ float fac=0.0f, div=0.0f, vec[3];
+ int a, j= -1, mask;
+ RayHint point_hint;
+
+ if (isec->mode==RE_RAY_SHADOW_TRA) {
+ shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;
+ }
+ else shadfac[3]= 1.0f;
+
+ fac= 0.0f;
+ jitlamp= give_jitter_plane(lar, shi->thread, shi->xs, shi->ys);
+
+ a= lar->ray_totsamp;
+
+ /* this correction to make sure we always take at least 1 sample */
+ mask= shi->mask;
+ if (a==4) mask |= (mask>>4)|(mask>>8);
+ else if (a==9) mask |= (mask>>9);
+
+ copy_v3_v3(isec->start, shi->co);
+ RE_instance_rotate_ray_start(shi->obi, isec);
+
+ isec->orig.ob = shi->obi;
+ isec->orig.face = shi->vlr;
+ RE_rayobject_hint_bb(R.raytree, &point_hint, isec->start, isec->start);
+ isec->hint = &point_hint;
+
+ while (a--) {
+
+ if (R.r.mode & R_OSA) {
+ j++;
+ if (j>=R.osa) j= 0;
+ if (!(mask & (1<<j))) {
+ jitlamp+= 2;
+ continue;
+ }
+ }
+
+ vec[0]= jitlamp[0];
+ vec[1]= jitlamp[1];
+ vec[2]= 0.0f;
+ mul_m3_v3(lar->mat, vec);
+
+ /* set start and vec */
+ isec->dir[0] = vec[0]+lampco[0]-shi->co[0];
+ isec->dir[1] = vec[1]+lampco[1]-shi->co[1];
+ isec->dir[2] = vec[2]+lampco[2]-shi->co[2];
+
+ RE_instance_rotate_ray_dir(shi->obi, isec);
+
+ isec->dist = 1.0f;
+ isec->check = RE_CHECK_VLR_RENDER;
+ isec->skip = RE_SKIP_VLR_NEIGHBOUR;
+
+ if (isec->mode==RE_RAY_SHADOW_TRA) {
+ /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */
+ float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ ray_trace_shadow_tra(isec, shi, DEPTH_SHADOW_TRA, 0, col);
+ shadfac[0] += col[0];
+ shadfac[1] += col[1];
+ shadfac[2] += col[2];
+ shadfac[3] += col[3];
+ }
+ else if ( RE_rayobject_raycast(R.raytree, isec) ) fac+= 1.0f;
+
+ div+= 1.0f;
+ jitlamp+= 2;
+ }
+
+ if (isec->mode==RE_RAY_SHADOW_TRA) {
+ shadfac[0] /= div;
+ shadfac[1] /= div;
+ shadfac[2] /= div;
+ shadfac[3] /= div;
+ }
+ else {
+ /* sqrt makes nice umbra effect */
+ if (lar->ray_samp_type & LA_SAMP_UMBRA)
+ shadfac[3] = sqrtf(1.0f - fac / div);
+ else
+ shadfac[3] = 1.0f - fac / div;
+ }
+}
+/* extern call from shade_lamp_loop */
+void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4])
+{
+ Isect isec;
+ float lampco[3];
+
+ /* setup isec */
+ RE_RC_INIT(isec, *shi);
+ if (shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA;
+ else isec.mode= RE_RAY_SHADOW;
+ isec.hint = NULL;
+
+ if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW))
+ isec.lay= lar->lay;
+ else
+ isec.lay= -1;
+
+ /* only when not mir tracing, first hit optimm */
+ if (shi->depth==0) {
+ isec.last_hit = lar->last_hit[shi->thread];
+ }
+ else {
+ isec.last_hit = NULL;
+ }
+
+ if (lar->type==LA_SUN || lar->type==LA_HEMI) {
+ /* jitter and QMC sampling add a displace vector to the lamp position
+ * that's incorrect because a SUN lamp does not has an exact position
+ * and the displace should be done at the ray vector instead of the
+ * lamp position.
+ * This is easily verified by noticing that shadows of SUN lights change
+ * with the scene BB.
+ *
+ * This was detected during SoC 2009 - Raytrace Optimization, but to keep
+ * consistency with older render code it wasn't removed.
+ *
+ * If the render code goes through some recode/serious bug-fix then this
+ * is something to consider!
+ */
+ lampco[0]= shi->co[0] - R.maxdist*lar->vec[0];
+ lampco[1]= shi->co[1] - R.maxdist*lar->vec[1];
+ lampco[2]= shi->co[2] - R.maxdist*lar->vec[2];
+ }
+ else {
+ copy_v3_v3(lampco, lar->co);
+ }
+
+ if (ELEM(lar->ray_samp_method, LA_SAMP_HALTON, LA_SAMP_HAMMERSLEY)) {
+
+ ray_shadow_qmc(shi, lar, lampco, shadfac, &isec);
+
+ }
+ else {
+ if (lar->ray_totsamp<2) {
+
+ isec.orig.ob = shi->obi;
+ isec.orig.face = shi->vlr;
+
+ shadfac[3]= 1.0f; /* 1.0=full light */
+
+ /* set up isec.dir */
+ copy_v3_v3(isec.start, shi->co);
+ sub_v3_v3v3(isec.dir, lampco, isec.start);
+ isec.dist = normalize_v3(isec.dir);
+
+ RE_instance_rotate_ray(shi->obi, &isec);
+
+ if (isec.mode==RE_RAY_SHADOW_TRA) {
+ /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */
+ float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ ray_trace_shadow_tra(&isec, shi, DEPTH_SHADOW_TRA, 0, col);
+ copy_v4_v4(shadfac, col);
+ }
+ else if (RE_rayobject_raycast(R.raytree, &isec))
+ shadfac[3]= 0.0f;
+ }
+ else {
+ ray_shadow_jitter(shi, lar, lampco, shadfac, &isec);
+ }
+ }
+
+ /* for first hit optim, set last interesected shadow face */
+ if (shi->depth==0) {
+ lar->last_hit[shi->thread] = isec.last_hit;
+ }
+
+}
+
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index a6f1ecd5405..e0cacdf4b8f 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -95,7 +95,7 @@ void render_result_free(RenderResult *res)
if (rl->acolrect) MEM_freeN(rl->acolrect);
if (rl->scolrect) MEM_freeN(rl->scolrect);
if (rl->display_buffer) MEM_freeN(rl->display_buffer);
-
+
while (rl->passes.first) {
RenderPass *rpass = rl->passes.first;
if (rpass->rect) MEM_freeN(rpass->rect);
@@ -128,13 +128,13 @@ void render_result_free(RenderResult *res)
void render_result_free_list(ListBase *lb, RenderResult *rr)
{
RenderResult *rrnext;
-
+
for (; rr; rr = rrnext) {
rrnext = rr->next;
-
+
if (lb && lb->first)
BLI_remlink(lb, rr);
-
+
render_result_free(rr);
}
}
@@ -206,7 +206,7 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int
const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
size_t rectsize = ((size_t)rr->rectx) * rr->recty * channels;
-
+
rpass->channels = channels;
rpass->rectx = rl->rectx;
rpass->recty = rl->recty;
@@ -216,7 +216,7 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int
BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
BLI_strncpy(rpass->view, viewname, sizeof(rpass->view));
set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id);
-
+
if (rl->exrhandle) {
int a;
for (a = 0; a < channels; a++) {
@@ -227,13 +227,13 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int
else {
float *rect;
int x;
-
+
rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, name);
if (rpass->rect == NULL) {
MEM_freeN(rpass);
return NULL;
}
-
+
if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
/* initialize to max speed */
rect = rpass->rect;
@@ -267,13 +267,13 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
RenderLayer *rl;
RenderView *rv;
int rectx, recty;
-
+
rectx = BLI_rcti_size_x(partrct);
recty = BLI_rcti_size_y(partrct);
-
+
if (rectx <= 0 || recty <= 0)
return NULL;
-
+
rr = MEM_callocN(sizeof(RenderResult), "new render result");
rr->rectx = rectx;
rr->recty = recty;
@@ -286,7 +286,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
-
+
if (savebuffers) {
rr->do_exr_tile = true;
}
@@ -304,14 +304,14 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
-
+
BLI_strncpy(rl->name, view_layer->name, sizeof(rl->name));
rl->layflag = view_layer->layflag;
rl->passflag = view_layer->passflag; /* for debugging: view_layer->passflag | SCE_PASS_RAYHITS; */
rl->pass_xor = view_layer->pass_xor;
rl->rectx = rectx;
rl->recty = recty;
-
+
if (rr->do_exr_tile) {
rl->display_buffer = MEM_mapallocN((size_t)rectx * recty * sizeof(unsigned int),
"Combined display space rgba");
@@ -412,7 +412,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) {
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
-
+
rl->rectx = rectx;
rl->recty = recty;
@@ -439,15 +439,15 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
/* note, this has to be in sync with scene.c */
rl->layflag = 0x7FFF; /* solid ztra halo strand */
rl->passflag = SCE_PASS_COMBINED;
-
+
re->active_view_layer = 0;
}
-
+
/* border render; calculate offset for use in compositor. compo is centralized coords */
/* XXX obsolete? I now use it for drawing border render offset (ton) */
rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2);
rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2);
-
+
return rr;
}
@@ -554,7 +554,7 @@ static void *ml_addlayer_cb(void *base, const char *str)
{
RenderResult *rr = base;
RenderLayer *rl;
-
+
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
@@ -676,7 +676,7 @@ RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace
rr->rectx = rectx;
rr->recty = recty;
-
+
IMB_exr_multilayer_convert(exrhandle, rr, ml_addview_cb, ml_addlayer_cb, ml_addpass_cb);
for (rl = rr->layers.first; rl; rl = rl->next) {
@@ -695,7 +695,7 @@ RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace
}
}
}
-
+
return rr;
}
@@ -740,16 +740,16 @@ static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target,
{
int y, tilex, tiley;
size_t ofs, copylen;
-
+
copylen = tilex = rrpart->rectx;
tiley = rrpart->recty;
-
+
if (rrpart->crop) { /* filters add pixel extra */
tile += pixsize * (rrpart->crop + ((size_t)rrpart->crop) * tilex);
-
+
copylen = tilex - 2 * rrpart->crop;
tiley -= 2 * rrpart->crop;
-
+
ofs = (((size_t)rrpart->tilerect.ymin) + rrpart->crop) * rr->rectx + (rrpart->tilerect.xmin + rrpart->crop);
target += pixsize * ofs;
}
@@ -776,7 +776,7 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
{
RenderLayer *rl, *rlp;
RenderPass *rpass, *rpassp;
-
+
for (rl = rr->layers.first; rl; rl = rl->next) {
rlp = RE_GetRenderLayer(rrpart, rl->name);
if (rlp) {
@@ -956,7 +956,7 @@ void render_result_single_layer_begin(Render *re)
/* officially pushed result should be NULL... error can happen with do_seq */
RE_FreeRenderResult(re->pushedresult);
-
+
re->pushedresult = re->result;
re->result = NULL;
}
@@ -980,10 +980,10 @@ void render_result_single_layer_end(Render *re)
if (re->pushedresult->rectx == re->result->rectx && re->pushedresult->recty == re->result->recty) {
/* find which layer in re->pushedresult should be replaced */
rl = re->result->layers.first;
-
+
/* render result should be empty after this */
BLI_remlink(&re->result->layers, rl);
-
+
/* reconstruct render result layers */
for (nr = 0, view_layer = re->view_layers.first; view_layer; view_layer = view_layer->next, nr++) {
if (nr == re->active_view_layer) {
@@ -1010,9 +1010,9 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons
RenderLayer *rlp, *rl;
RenderPass *rpassp;
int offs, partx, party;
-
+
BLI_thread_lock(LOCK_IMAGE);
-
+
for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
rl = RE_GetRenderLayer(rr, rlp->name);
@@ -1042,7 +1042,7 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons
xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs);
}
}
-
+
}
party = rrpart->tilerect.ymin + rrpart->crop;
@@ -1068,7 +1068,7 @@ void render_result_save_empty_result_tiles(Render *re)
RenderPart *pa;
RenderResult *rr;
RenderLayer *rl;
-
+
for (rr = re->result; rr; rr = rr->next) {
for (rl = rr->layers.first; rl; rl = rl->next) {
for (pa = re->parts.first; pa; pa = pa->next) {
@@ -1112,7 +1112,7 @@ void render_result_exr_file_end(Render *re)
rr->do_exr_tile = false;
}
-
+
render_result_free_list(&re->fullresult, re->result);
re->result = NULL;
@@ -1130,8 +1130,8 @@ void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart, const
void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
{
char name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100];
- const char *fi = BLI_path_basename(G.main->name);
-
+ const char *fi = BLI_path_basename(BKE_main_blendfile_path_from_global());
+
if (sample == 0) {
BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
}
@@ -1194,7 +1194,7 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c
for (rl = rr->layers.first; rl; rl = rl->next) {
if (rl_single && rl_single != rl)
continue;
-
+
/* passes are allocated in sync */
for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
const int xstride = rpass->channels;
@@ -1224,10 +1224,11 @@ static void render_result_exr_file_cache_path(Scene *sce, const char *root, char
char path_hexdigest[33];
/* If root is relative, use either current .blend file dir, or temp one if not saved. */
- if (G.main->name[0]) {
- BLI_split_dirfile(G.main->name, dirname, filename, sizeof(dirname), sizeof(filename));
+ const char *blendfile_path = BKE_main_blendfile_path_from_global();
+ if (blendfile_path[0] != '\0') {
+ BLI_split_dirfile(blendfile_path, dirname, filename, sizeof(dirname), sizeof(filename));
BLI_replace_extension(filename, sizeof(filename), ""); /* strip '.blend' */
- BLI_hash_md5_buffer(G.main->name, strlen(G.main->name), path_digest);
+ BLI_hash_md5_buffer(blendfile_path, strlen(blendfile_path), path_digest);
}
else {
BLI_strncpy(dirname, BKE_tempdir_base(), sizeof(dirname));
@@ -1291,7 +1292,7 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd, const int vi
/* float factor for random dither, imbuf takes care of it */
ibuf->dither = rd->dither_intensity;
-
+
/* prepare to gamma correct to sRGB color space
* note that sequence editor can generate 8bpc render buffers
*/
@@ -1332,7 +1333,7 @@ void RE_render_result_rect_from_ibuf(RenderResult *rr, RenderData *UNUSED(rd), I
if (!rv->rectf)
rv->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf");
-
+
memcpy(rv->rectf, ibuf->rect_float, 4 * sizeof(float) * rr->rectx * rr->recty);
/* TSK! Since sequence render doesn't free the *rr render result, the old rect32
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 79d13ecab5b..99da5b3ca01 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -95,7 +95,7 @@ static void tex_normal_derivate(Tex *tex, TexResult *texres)
float col[4];
if (BKE_colorband_evaluate(tex->coba, texres->tin, col)) {
float fac0, fac1, fac2, fac3;
-
+
fac0= (col[0]+col[1]+col[2]);
BKE_colorband_evaluate(tex->coba, texres->nor[0], col);
fac1= (col[0]+col[1]+col[2]);
@@ -103,11 +103,11 @@ static void tex_normal_derivate(Tex *tex, TexResult *texres)
fac2= (col[0]+col[1]+col[2]);
BKE_colorband_evaluate(tex->coba, texres->nor[2], col);
fac3= (col[0]+col[1]+col[2]);
-
+
texres->nor[0]= (fac0 - fac1) / 3.0f;
texres->nor[1]= (fac0 - fac2) / 3.0f;
texres->nor[2]= (fac0 - fac3) / 3.0f;
-
+
return;
}
}
@@ -173,7 +173,7 @@ static int blend(Tex *tex, const float texvec[3], TexResult *texres)
static int clouds(Tex *tex, const float texvec[3], TexResult *texres)
{
int rv = TEX_INT;
-
+
texres->tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
if (texres->nor!=NULL) {
@@ -181,7 +181,7 @@ static int clouds(Tex *tex, const float texvec[3], TexResult *texres)
texres->nor[0] = BLI_gTurbulence(tex->noisesize, texvec[0] + tex->nabla, texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
texres->nor[1] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1] + tex->nabla, texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
texres->nor[2] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2] + tex->nabla, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
-
+
tex_normal_derivate(tex, texres);
rv |= TEX_NOR;
}
@@ -215,7 +215,7 @@ static float tex_sin(float a)
static float tex_saw(float a)
{
const float b = 2*M_PI;
-
+
int n = (int)(a / b);
a -= n*b;
if (a < 0) a += b;
@@ -227,9 +227,9 @@ static float tex_tri(float a)
{
const float b = 2*M_PI;
const float rmax = 1.0;
-
+
a = rmax - 2.0f*fabsf(floorf((a*(1.0f/b))+0.5f) - (a*(1.0f/b)));
-
+
return a;
}
@@ -244,9 +244,9 @@ static float wood_int(Tex *tex, float x, float y, float z)
waveform[0] = tex_sin; /* assign address of tex_sin() function to pointer array */
waveform[1] = tex_saw;
waveform[2] = tex_tri;
-
+
if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 is initialized ahead of time */
-
+
if (wt==TEX_BAND) {
wi = waveform[wf]((x + y + z)*10.0f);
}
@@ -261,7 +261,7 @@ static float wood_int(Tex *tex, float x, float y, float z)
wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
wi = waveform[wf](sqrtf(x*x + y*y + z*z)*20.0f + wi);
}
-
+
return wi;
}
@@ -275,7 +275,7 @@ static int wood(Tex *tex, const float texvec[3], TexResult *texres)
texres->nor[0] = wood_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
texres->nor[1] = wood_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
texres->nor[2] = wood_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
-
+
tex_normal_derivate(tex, texres);
rv |= TEX_NOR;
}
@@ -291,16 +291,16 @@ static float marble_int(Tex *tex, float x, float y, float z)
float n, mi;
short wf = tex->noisebasis2; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */
short mt = tex->stype; /* marble type: TEX_SOFT=0, TEX_SHARP=1,TEX_SHAPER=2 */
-
+
float (*waveform[3])(float); /* create array of pointers to waveform functions */
waveform[0] = tex_sin; /* assign address of tex_sin() function to pointer array */
waveform[1] = tex_saw;
waveform[2] = tex_tri;
-
+
if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 isn't initialized ahead of time */
-
+
n = 5.0f * (x + y + z);
-
+
mi = n + tex->turbul * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
if (mt>=TEX_SOFT) { /* TEX_SOFT always true */
@@ -327,9 +327,9 @@ static int marble(Tex *tex, const float texvec[3], TexResult *texres)
texres->nor[0] = marble_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
texres->nor[1] = marble_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
texres->nor[2] = marble_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
-
+
tex_normal_derivate(tex, texres);
-
+
rv |= TEX_NOR;
}
@@ -397,8 +397,8 @@ static int magic(Tex *tex, const float texvec[3], TexResult *texres)
if (turb!=0.0f) {
turb*= 2.0f;
- x/= turb;
- y/= turb;
+ x/= turb;
+ y/= turb;
z/= turb;
}
texres->tr = 0.5f - x;
@@ -406,10 +406,10 @@ static int magic(Tex *tex, const float texvec[3], TexResult *texres)
texres->tb = 0.5f - z;
texres->tin= (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb);
-
+
BRICONTRGB;
texres->ta = 1.0f;
-
+
return TEX_RGB;
}
@@ -420,9 +420,9 @@ static int stucci(Tex *tex, const float texvec[3], TexResult *texres)
{
float nor[3], b2, ofs;
int retval= TEX_INT;
-
+
b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
-
+
ofs= tex->turbul/200.0f;
if (tex->stype) ofs*=(b2*b2);
@@ -431,27 +431,27 @@ static int stucci(Tex *tex, const float texvec[3], TexResult *texres)
nor[2] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
texres->tin= nor[2];
-
+
if (texres->nor) {
-
+
copy_v3_v3(texres->nor, nor);
tex_normal_derivate(tex, texres);
-
+
if (tex->stype==TEX_WALLOUT) {
texres->nor[0]= -texres->nor[0];
texres->nor[1]= -texres->nor[1];
texres->nor[2]= -texres->nor[2];
}
-
+
retval |= TEX_NOR;
}
-
+
if (tex->stype==TEX_WALLOUT)
texres->tin= 1.0f-texres->tin;
-
+
if (texres->tin<0.0f)
texres->tin= 0.0f;
-
+
return retval;
}
@@ -477,7 +477,7 @@ static float mg_mFractalOrfBmTex(Tex *tex, const float texvec[3], TexResult *tex
texres->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
texres->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
texres->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
-
+
tex_normal_derivate(tex, texres);
rv |= TEX_NOR;
}
@@ -507,7 +507,7 @@ static float mg_ridgedOrHybridMFTex(Tex *tex, const float texvec[3], TexResult *
texres->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
texres->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
texres->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
-
+
tex_normal_derivate(tex, texres);
rv |= TEX_NOR;
}
@@ -532,7 +532,7 @@ static float mg_HTerrainTex(Tex *tex, const float texvec[3], TexResult *texres)
texres->nor[0] = tex->ns_outscale*mg_HeteroTerrain(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
texres->nor[1] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
texres->nor[2] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
-
+
tex_normal_derivate(tex, texres);
rv |= TEX_NOR;
}
@@ -630,7 +630,7 @@ static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres)
texres->nor[1] = sc * fabsf(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp, tex->vn_distm);
texres->nor[2] = sc * fabsf(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
-
+
tex_normal_derivate(tex, texres);
rv |= TEX_NOR;
}
@@ -640,7 +640,7 @@ static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres)
texres->ta = 1.0;
return (rv | TEX_RGB);
}
-
+
BRICONT;
return rv;
@@ -653,20 +653,20 @@ static int texnoise(Tex *tex, TexResult *texres, int thread)
{
float div=3.0;
int val, ran, loop, shift = 29;
-
+
ran= BLI_rng_thread_rand(random_tex_array, thread);
-
+
loop= tex->noisedepth;
/* start from top bits since they have more variance */
val= ((ran >> shift) & 3);
-
+
while (loop--) {
- shift -= 2;
+ shift -= 2;
val *= ((ran >> shift) & 3);
div *= 3.0f;
}
-
+
texres->tin= ((float)val)/div;
BRICONT;
@@ -679,7 +679,7 @@ static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1
{
float x1, y1, z1, nor[3];
int ret;
-
+
if (n==NULL) {
nor[0]= x; nor[1]= y; nor[2]= z; /* use local render coord */
}
@@ -690,7 +690,7 @@ static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1
x1 = fabsf(nor[0]);
y1 = fabsf(nor[1]);
z1 = fabsf(nor[2]);
-
+
if (z1>=x1 && z1>=y1) {
*adr1 = (x + 1.0f) / 2.0f;
*adr2 = (y + 1.0f) / 2.0f;
@@ -719,13 +719,13 @@ static void do_2d_mapping(
Tex *tex;
float fx, fy, fac1, area[8];
int ok, proj, areaflag= 0, wrap;
-
+
/* mtex variables localized, only cubemap doesn't cooperate yet... */
wrap= mtex->mapping;
tex= mtex->tex;
if (!(dxt && dyt)) {
-
+
if (wrap==MTEX_FLAT) {
fx = (texvec[0] + 1.0f) / 2.0f;
fy = (texvec[1] + 1.0f) / 2.0f;
@@ -735,15 +735,15 @@ static void do_2d_mapping(
else {
cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy);
}
-
+
/* repeat */
if (tex->extend==TEX_REPEAT) {
if (tex->xrepeat>1) {
float origf= fx *= tex->xrepeat;
-
+
if (fx>1.0f) fx -= (int)(fx);
else if (fx<0.0f) fx+= 1-(int)(fx);
-
+
if (tex->flag & TEX_REPEAT_XMIR) {
int orig= (int)floor(origf);
if (orig & 1)
@@ -752,10 +752,10 @@ static void do_2d_mapping(
}
if (tex->yrepeat>1) {
float origf= fy *= tex->yrepeat;
-
+
if (fy>1.0f) fy -= (int)(fy);
else if (fy<0.0f) fy+= 1-(int)(fy);
-
+
if (tex->flag & TEX_REPEAT_YMIR) {
int orig= (int)floor(origf);
if (orig & 1)
@@ -777,7 +777,7 @@ static void do_2d_mapping(
texvec[1]= fy;
}
else {
-
+
if (wrap==MTEX_FLAT) {
fx= (texvec[0] + 1.0f) / 2.0f;
fy= (texvec[1] + 1.0f) / 2.0f;
@@ -854,55 +854,55 @@ static void do_2d_mapping(
dyt[2] *= 0.5f;
}
-
+
/* if area, then reacalculate dxt[] and dyt[] */
if (areaflag) {
- fx= area[0];
+ fx= area[0];
fy= area[1];
dxt[0]= area[2]-fx;
dxt[1]= area[3]-fy;
dyt[0]= area[4]-fx;
dyt[1]= area[5]-fy;
}
-
+
/* repeat */
if (tex->extend==TEX_REPEAT) {
float max= 1.0f;
if (tex->xrepeat>1) {
float origf= fx *= tex->xrepeat;
-
+
/* TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call */
if (tex->texfilter == TXF_BOX) {
if (fx>1.0f) fx -= (int)(fx);
else if (fx<0.0f) fx+= 1-(int)(fx);
-
+
if (tex->flag & TEX_REPEAT_XMIR) {
int orig= (int)floor(origf);
if (orig & 1)
fx= 1.0f-fx;
}
}
-
+
max= tex->xrepeat;
-
+
dxt[0]*= tex->xrepeat;
dyt[0]*= tex->xrepeat;
}
if (tex->yrepeat>1) {
float origf= fy *= tex->yrepeat;
-
+
/* TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call */
if (tex->texfilter == TXF_BOX) {
if (fy>1.0f) fy -= (int)(fy);
else if (fy<0.0f) fy+= 1-(int)(fy);
-
+
if (tex->flag & TEX_REPEAT_YMIR) {
int orig= (int)floor(origf);
if (orig & 1)
fy= 1.0f-fy;
}
}
-
+
if (max<tex->yrepeat)
max= tex->yrepeat;
@@ -913,7 +913,7 @@ static void do_2d_mapping(
dxt[2]*= max;
dyt[2]*= max;
}
-
+
}
/* crop */
if (tex->cropxmin!=0.0f || tex->cropxmax!=1.0f) {
@@ -928,7 +928,7 @@ static void do_2d_mapping(
dxt[1]*= fac1;
dyt[1]*= fac1;
}
-
+
texvec[0]= fx;
texvec[1]= fy;
@@ -953,7 +953,7 @@ static int multitex(Tex *tex,
int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */
texres->talpha = false; /* is set when image texture returns alpha (considered premul) */
-
+
if (use_nodes && tex->use_nodes && tex->nodetree) {
const float cfra = 1.0f; /* This was only set for Blender Internal render before. */
retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
@@ -1072,7 +1072,7 @@ static int multitex_nodes_intern(Tex *tex,
if (mtex)
which_output= mtex->which_output;
-
+
if (tex->type==TEX_IMAGE) {
int rgbnor;
@@ -1093,7 +1093,7 @@ static int multitex_nodes_intern(Tex *tex,
if (mtex->mapto & (MAP_COL)) {
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
-
+
/* don't linearize float buffers, assumed to be linear */
if (ibuf != NULL &&
ibuf->rect_float == NULL &&
@@ -1110,12 +1110,12 @@ static int multitex_nodes_intern(Tex *tex,
/* we don't have mtex, do default flat 2d projection */
MTex localmtex;
float texvec_l[3], dxt_l[3], dyt_l[3];
-
+
localmtex.mapping= MTEX_FLAT;
localmtex.tex= tex;
localmtex.object= NULL;
localmtex.texco= TEXCO_ORCO;
-
+
copy_v3_v3(texvec_l, texvec);
if (dxt && dyt) {
copy_v3_v3(dxt_l, dxt);
@@ -1125,7 +1125,7 @@ static int multitex_nodes_intern(Tex *tex,
zero_v3(dxt_l);
zero_v3(dyt_l);
}
-
+
do_2d_mapping(&localmtex, texvec_l, NULL, dxt_l, dyt_l);
rgbnor = multitex(tex,
texvec_l,
@@ -1244,7 +1244,7 @@ int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct Image
void texture_rgb_blend(float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype)
{
float facm;
-
+
switch (blendtype) {
case MTEX_BLEND:
fact*= facg;
@@ -1254,7 +1254,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
in[1]= (fact*tex[1] + facm*out[1]);
in[2]= (fact*tex[2] + facm*out[2]);
break;
-
+
case MTEX_MUL:
fact*= facg;
facm= 1.0f-fact;
@@ -1274,7 +1274,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_OVERLAY:
fact*= facg;
facm= 1.0f-fact;
-
+
if (out[0] < 0.5f)
in[0] = out[0] * (facm + 2.0f*fact*tex[0]);
else
@@ -1288,7 +1288,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
else
in[2] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[2])) * (1.0f - out[2]);
break;
-
+
case MTEX_SUB:
fact= -fact;
ATTR_FALLTHROUGH;
@@ -1302,7 +1302,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_DIV:
fact*= facg;
facm= 1.0f-fact;
-
+
if (tex[0]!=0.0f)
in[0]= facm*out[0] + fact*out[0]/tex[0];
if (tex[1]!=0.0f)
@@ -1323,7 +1323,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_DARK:
fact*= facg;
facm= 1.0f-fact;
-
+
in[0] = min_ff(out[0], tex[0])*fact + out[0]*facm;
in[1] = min_ff(out[1], tex[1])*fact + out[1]*facm;
in[2] = min_ff(out[2], tex[2])*fact + out[2]*facm;
@@ -1336,7 +1336,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
in[1] = max_ff(fact * tex[1], out[1]);
in[2] = max_ff(fact * tex[2], out[2]);
break;
-
+
case MTEX_BLEND_HUE:
fact*= facg;
copy_v3_v3(in, out);
@@ -1357,16 +1357,16 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
copy_v3_v3(in, out);
ramp_blend(MA_RAMP_COLOR, in, fact, tex);
break;
- case MTEX_SOFT_LIGHT:
- fact*= facg;
+ case MTEX_SOFT_LIGHT:
+ fact*= facg;
copy_v3_v3(in, out);
ramp_blend(MA_RAMP_SOFT, in, fact, tex);
- break;
- case MTEX_LIN_LIGHT:
- fact*= facg;
+ break;
+ case MTEX_LIN_LIGHT:
+ fact*= facg;
copy_v3_v3(in, out);
ramp_blend(MA_RAMP_LINEAR, in, fact, tex);
- break;
+ break;
}
}
@@ -1376,7 +1376,7 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen
int flip= (facg < 0.0f);
facg= fabsf(facg);
-
+
fact*= facg;
facm= 1.0f-fact;
if (flip) SWAP(float, fact, facm);
@@ -1429,19 +1429,19 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen
if (col > out) in= col; else in= out;
break;
- case MTEX_SOFT_LIGHT:
+ case MTEX_SOFT_LIGHT:
scf=1.0f - (1.0f - tex) * (1.0f - out);
in= facm*out + fact * ((1.0f - out) * tex * out) + (out * scf);
- break;
+ break;
- case MTEX_LIN_LIGHT:
+ case MTEX_LIN_LIGHT:
if (tex > 0.5f)
in = out + fact*(2.0f*(tex - 0.5f));
- else
+ else
in = out + fact*(2.0f*tex - 1.0f);
break;
}
-
+
return in;
}
@@ -1459,26 +1459,26 @@ int externtex(const MTex *mtex,
TexResult texr;
float dxt[3], dyt[3], texvec[3];
int rgb;
-
+
tex= mtex->tex;
if (tex==NULL) return 0;
texr.nor= NULL;
-
+
/* placement */
if (mtex->projx) texvec[0]= mtex->size[0]*(vec[mtex->projx-1]+mtex->ofs[0]);
else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
-
+
if (mtex->projy) texvec[1]= mtex->size[1]*(vec[mtex->projy-1]+mtex->ofs[1]);
else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
-
+
if (mtex->projz) texvec[2]= mtex->size[2]*(vec[mtex->projz-1]+mtex->ofs[2]);
else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
-
+
/* texture */
if (tex->type==TEX_IMAGE) {
do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
}
-
+
rgb = multitex(tex,
texvec,
dxt, dyt,
@@ -1489,7 +1489,7 @@ int externtex(const MTex *mtex,
skip_load_image,
texnode_preview,
true);
-
+
if (rgb) {
texr.tin = IMB_colormanagement_get_luminance(&texr.tr);
}
@@ -1498,7 +1498,7 @@ int externtex(const MTex *mtex,
texr.tg= mtex->g;
texr.tb= mtex->b;
}
-
+
*tin= texr.tin;
*tr= texr.tr;
*tg= texr.tg;
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
new file mode 100644
index 00000000000..99d2436d4bc
--- /dev/null
+++ b/source/blender/render/intern/source/rendercore.c
@@ -0,0 +1,2030 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributors: Hos, Robert Wenzlaff.
+ * Contributors: 2004/2005/2006 Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/rendercore.c
+ * \ingroup render
+ */
+
+
+/* system includes */
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <assert.h>
+
+/* External modules: */
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_rand.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_group_types.h"
+
+/* local include */
+#include "renderpipeline.h"
+#include "render_result.h"
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "occlusion.h"
+#include "pixelblending.h"
+#include "pixelshading.h"
+#include "shadbuf.h"
+#include "shading.h"
+#include "sss.h"
+#include "zbuf.h"
+
+/* own include */
+#include "rendercore.h"
+
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+/* x and y are current pixels in rect to be rendered */
+/* do not normalize! */
+void calc_view_vector(float view[3], float x, float y)
+{
+
+ view[2]= -ABS(R.clipsta);
+
+ if (R.r.mode & R_ORTHO) {
+ view[0]= view[1]= 0.0f;
+ }
+ else {
+
+ if (R.r.mode & R_PANORAMA) {
+ x-= R.panodxp;
+ }
+
+ /* move x and y to real viewplane coords */
+ x = (x / (float)R.winx);
+ view[0] = R.viewplane.xmin + x * BLI_rctf_size_x(&R.viewplane);
+
+ y = (y / (float)R.winy);
+ view[1] = R.viewplane.ymin + y * BLI_rctf_size_y(&R.viewplane);
+
+// if (R.flag & R_SEC_FIELD) {
+// if (R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
+// else view[1]= (y+R.ystart+1.0)*R.ycor;
+// }
+// else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
+
+ if (R.r.mode & R_PANORAMA) {
+ float u= view[0] + R.panodxv; float v= view[2];
+ view[0]= R.panoco*u + R.panosi*v;
+ view[2]= -R.panosi*u + R.panoco*v;
+ }
+ }
+}
+
+void calc_renderco_ortho(float co[3], float x, float y, int z)
+{
+ /* x and y 3d coordinate can be derived from pixel coord and winmat */
+ float fx= 2.0f/(R.winx*R.winmat[0][0]);
+ float fy= 2.0f/(R.winy*R.winmat[1][1]);
+ float zco;
+
+ co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
+ co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
+
+ zco= ((float)z)/2147483647.0f;
+ co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
+}
+
+void calc_renderco_zbuf(float co[3], const float view[3], int z)
+{
+ float fac, zco;
+
+ /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
+ zco= ((float)z)/2147483647.0f;
+ co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
+
+ fac= co[2]/view[2];
+ co[0]= fac*view[0];
+ co[1]= fac*view[1];
+}
+
+/* also used in zbuf.c and shadbuf.c */
+int count_mask(unsigned short mask)
+{
+ if (R.samples)
+ return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
+ return 0;
+}
+
+static int calchalo_z(HaloRen *har, int zz)
+{
+
+ if (har->type & HA_ONLYSKY) {
+ if (zz < 0x7FFFFFF0) zz= - 0x7FFFFF; /* edge render messes zvalues */
+ }
+ else {
+ zz= (zz>>8);
+ }
+ return zz;
+}
+
+
+
+static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps)
+{
+ float col[4], accol[4], fac;
+ int amount, amountm, zz, flarec, sample, fullsample, mask=0;
+
+ fullsample= (totsample > 1);
+ amount= 0;
+ accol[0] = accol[1] = accol[2] = accol[3]= 0.0f;
+ col[0] = col[1] = col[2] = col[3]= 0.0f;
+ flarec= har->flarec;
+
+ while (ps) {
+ amountm= count_mask(ps->mask);
+ amount+= amountm;
+
+ zz= calchalo_z(har, ps->z);
+ if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
+ if (shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) {
+ flarec= 0;
+
+ if (fullsample) {
+ for (sample=0; sample<totsample; sample++) {
+ if (ps->mask & (1 << sample)) {
+ float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+ addalphaAddfacFloat(pass + od*4, col, har->add);
+ }
+ }
+ }
+ else {
+ fac= ((float)amountm)/(float)R.osa;
+ accol[0]+= fac*col[0];
+ accol[1]+= fac*col[1];
+ accol[2]+= fac*col[2];
+ accol[3]+= fac*col[3];
+ }
+ }
+ }
+
+ mask |= ps->mask;
+ ps= ps->next;
+ }
+
+ /* now do the sky sub-pixels */
+ amount= R.osa-amount;
+ if (amount) {
+ if (shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) {
+ if (!fullsample) {
+ fac= ((float)amount)/(float)R.osa;
+ accol[0]+= fac*col[0];
+ accol[1]+= fac*col[1];
+ accol[2]+= fac*col[2];
+ accol[3]+= fac*col[3];
+ }
+ }
+ }
+
+ if (fullsample) {
+ for (sample=0; sample<totsample; sample++) {
+ if (!(mask & (1 << sample))) {
+ float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+ addalphaAddfacFloat(pass + od*4, col, har->add);
+ }
+ }
+ }
+ else {
+ col[0]= accol[0];
+ col[1]= accol[1];
+ col[2]= accol[2];
+ col[3]= accol[3];
+
+ for (sample=0; sample<totsample; sample++) {
+ float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+ addalphaAddfacFloat(pass + od*4, col, har->add);
+ }
+ }
+}
+
+static void halo_tile(RenderPart *pa, RenderLayer *rl)
+{
+ RenderLayer *rlpp[RE_MAX_OSA];
+ HaloRen *har;
+ rcti disprect= pa->disprect, testrect= pa->disprect;
+ float dist, xsq, ysq, xn, yn;
+ float col[4];
+ intptr_t *rd= NULL;
+ int a, *rz, zz, y, sample, totsample, od;
+ short minx, maxx, miny, maxy, x;
+ unsigned int lay= rl->lay;
+
+ /* we don't render halos in the cropped area, gives errors in flare counter */
+ if (pa->crop) {
+ testrect.xmin+= pa->crop;
+ testrect.xmax-= pa->crop;
+ testrect.ymin+= pa->crop;
+ testrect.ymax-= pa->crop;
+ }
+
+ totsample= get_sample_layers(pa, rl, rlpp);
+
+ for (a=0; a<R.tothalo; a++) {
+ har= R.sortedhalos[a];
+
+ /* layer test, clip halo with y */
+ if ((har->lay & lay) == 0) {
+ /* pass */
+ }
+ else if (testrect.ymin > har->maxy) {
+ /* pass */
+ }
+ else if (testrect.ymax < har->miny) {
+ /* pass */
+ }
+ else {
+
+ minx= floor(har->xs-har->rad);
+ maxx= ceil(har->xs+har->rad);
+
+ if (testrect.xmin > maxx) {
+ /* pass */
+ }
+ else if (testrect.xmax < minx) {
+ /* pass */
+ }
+ else {
+
+ minx = max_ii(minx, testrect.xmin);
+ maxx = min_ii(maxx, testrect.xmax);
+
+ miny = max_ii(har->miny, testrect.ymin);
+ maxy = min_ii(har->maxy, testrect.ymax);
+
+ for (y=miny; y<maxy; y++) {
+ int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
+ rz= pa->rectz + rectofs;
+ od= rectofs;
+
+ if (pa->rectdaps)
+ rd= pa->rectdaps + rectofs;
+
+ yn= (y-har->ys)*R.ycor;
+ ysq= yn*yn;
+
+ for (x=minx; x<maxx; x++, rz++, od++) {
+ xn= x- har->xs;
+ xsq= xn*xn;
+ dist= xsq+ysq;
+ if (dist<har->radsq) {
+ if (rd && *rd) {
+ halo_pixelstruct(har, rlpp, totsample, od, dist, xn, yn, (PixStr *)*rd);
+ }
+ else {
+ zz= calchalo_z(har, *rz);
+ if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
+ if (shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) {
+ for (sample=0; sample<totsample; sample++) {
+ float * rect= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+ addalphaAddfacFloat(rect + od*4, col, har->add);
+ }
+ }
+ }
+ }
+ }
+ if (rd) rd++;
+ }
+ }
+ }
+ }
+ if (R.test_break(R.tbh) ) break;
+ }
+}
+
+static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
+{
+ RenderLayer *rlpp[RE_MAX_OSA];
+ ShadeInput shi;
+ float *pass;
+ float fac, col[4];
+ intptr_t *rd= pa->rectdaps;
+ const int *rz= pa->rectz;
+ int x, y, sample, totsample, fullsample, od;
+
+ totsample= get_sample_layers(pa, rl, rlpp);
+ fullsample= (totsample > 1);
+
+ shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */
+
+ for (od=0, y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+ for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, od++) {
+
+ calc_view_vector(shi.view, x, y);
+
+ if (rd && *rd) {
+ PixStr *ps= (PixStr *)*rd;
+ int count, totsamp= 0, mask= 0;
+
+ while (ps) {
+ if (R.r.mode & R_ORTHO)
+ calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z);
+ else
+ calc_renderco_zbuf(shi.co, shi.view, ps->z);
+
+ totsamp+= count= count_mask(ps->mask);
+ mask |= ps->mask;
+
+ col[0]= col[1]= col[2]= col[3]= 0.0f;
+ renderspothalo(&shi, col, 1.0f);
+
+ if (fullsample) {
+ for (sample=0; sample<totsample; sample++) {
+ if (ps->mask & (1 << sample)) {
+ pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+ pass += od * 4;
+ pass[0]+= col[0];
+ pass[1]+= col[1];
+ pass[2]+= col[2];
+ pass[3]+= col[3];
+ if (pass[3]>1.0f) pass[3]= 1.0f;
+ }
+ }
+ }
+ else {
+ fac= ((float)count)/(float)R.osa;
+ pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
+ pass += od * 4;
+ pass[0]+= fac*col[0];
+ pass[1]+= fac*col[1];
+ pass[2]+= fac*col[2];
+ pass[3]+= fac*col[3];
+ if (pass[3]>1.0f) pass[3]= 1.0f;
+ }
+
+ ps= ps->next;
+ }
+
+ if (totsamp<R.osa) {
+ shi.co[2]= 0.0f;
+
+ col[0]= col[1]= col[2]= col[3]= 0.0f;
+ renderspothalo(&shi, col, 1.0f);
+
+ if (fullsample) {
+ for (sample=0; sample<totsample; sample++) {
+ if (!(mask & (1 << sample))) {
+
+ pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+ pass += od * 4;
+ pass[0]+= col[0];
+ pass[1]+= col[1];
+ pass[2]+= col[2];
+ pass[3]+= col[3];
+ if (pass[3]>1.0f) pass[3]= 1.0f;
+ }
+ }
+ }
+ else {
+ fac= ((float)R.osa-totsamp)/(float)R.osa;
+ pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
+ pass += od * 4;
+ pass[0]+= fac*col[0];
+ pass[1]+= fac*col[1];
+ pass[2]+= fac*col[2];
+ pass[3]+= fac*col[3];
+ if (pass[3]>1.0f) pass[3]= 1.0f;
+ }
+ }
+ }
+ else {
+ if (R.r.mode & R_ORTHO)
+ calc_renderco_ortho(shi.co, (float)x, (float)y, *rz);
+ else
+ calc_renderco_zbuf(shi.co, shi.view, *rz);
+
+ col[0]= col[1]= col[2]= col[3]= 0.0f;
+ renderspothalo(&shi, col, 1.0f);
+
+ for (sample=0; sample<totsample; sample++) {
+ pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+ pass += od * 4;
+ pass[0]+= col[0];
+ pass[1]+= col[1];
+ pass[2]+= col[2];
+ pass[3]+= col[3];
+ if (pass[3]>1.0f) pass[3]= 1.0f;
+ }
+ }
+
+ if (rd) rd++;
+ }
+ if (y&1)
+ if (R.test_break(R.tbh)) break;
+ }
+}
+
+
+/* ********************* MAINLOOPS ******************** */
+
+/* osa version */
+static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
+{
+ RenderPass *rpass;
+
+ for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ float *fp, *col= NULL;
+ int pixsize= 3;
+
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+ add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx);
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+ fp = rpass->rect + offset;
+ *fp = shr->z;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+ col = shr->col;
+ pixsize = 4;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+ col = shr->emit;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+ col = shr->diff;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+ col = shr->spec;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+ col = shr->shad;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+ col = shr->ao;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+ col = shr->env;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+ col = shr->indirect;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+ col = shr->refl;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+ col = shr->refr;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+ col = shr->nor;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_UV)) {
+ /* box filter only, gauss will screwup UV too much */
+ if (shi->totuv) {
+ float mult = (float)count_mask(curmask)/(float)R.osa;
+ fp = rpass->rect + 3*offset;
+ fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
+ fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
+ fp[2]+= mult;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) {
+ /* no filter */
+ if (shi->vlr) {
+ fp = rpass->rect + offset;
+ if (*fp==0.0f)
+ *fp = (float)shi->obr->ob->index;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) {
+ /* no filter */
+ if (shi->vlr) {
+ fp = rpass->rect + offset;
+ if (*fp==0.0f)
+ *fp = (float)shi->mat->index;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+ /* */
+ col = &shr->mist;
+ pixsize = 1;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
+ /* add minimum speed in pixel, no filter */
+ fp = rpass->rect + 4*offset;
+ if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
+ fp[0] = shr->winspeed[0];
+ fp[1] = shr->winspeed[1];
+ }
+ if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
+ fp[2] = shr->winspeed[2];
+ fp[3] = shr->winspeed[3];
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) {
+ /* */
+ col = shr->rayhits;
+ pixsize= 4;
+ }
+
+ if (col) {
+ fp= rpass->rect + pixsize*offset;
+ add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
+ }
+ }
+}
+
+/* non-osa version */
+static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
+{
+ RenderPass *rpass;
+ float *fp;
+
+ for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ float *col= NULL, uvcol[3];
+ int a, pixsize= 3;
+
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+ /* copy combined to use for preview */
+ copy_v4_v4(rpass->rect + 4*offset, shr->combined);
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+ fp = rpass->rect + offset;
+ *fp = shr->z;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+ col = shr->col;
+ pixsize = 4;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+ col = shr->emit;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+ col = shr->diff;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+ col = shr->spec;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+ col = shr->shad;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+ col = shr->ao;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+ col = shr->env;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+ col = shr->indirect;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+ col = shr->refl;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+ col = shr->refr;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+ col = shr->nor;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_UV)) {
+ if (shi->totuv) {
+ uvcol[0] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
+ uvcol[1] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
+ uvcol[2] = 1.0f;
+ col = uvcol;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
+ col = shr->winspeed;
+ pixsize = 4;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) {
+ if (shi->vlr) {
+ fp = rpass->rect + offset;
+ *fp = (float)shi->obr->ob->index;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) {
+ if (shi->vlr) {
+ fp = rpass->rect + offset;
+ *fp = (float)shi->mat->index;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+ fp = rpass->rect + offset;
+ *fp = shr->mist;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) {
+ col = shr->rayhits;
+ pixsize = 4;
+ }
+
+ if (col) {
+ fp = rpass->rect + pixsize*offset;
+ for (a=0; a<pixsize; a++)
+ fp[a] = col[a];
+ }
+ }
+}
+
+int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp)
+{
+
+ if (pa->fullresult.first) {
+ int sample, nr= BLI_findindex(&pa->result->layers, rl);
+
+ for (sample=0; sample<R.osa; sample++) {
+ RenderResult *rr= BLI_findlink(&pa->fullresult, sample);
+
+ rlpp[sample]= BLI_findlink(&rr->layers, nr);
+ }
+ return R.osa;
+ }
+ else {
+ rlpp[0]= rl;
+ return 1;
+ }
+}
+
+
+/* only do sky, is default in the solid layer (shade_tile) btw */
+static void sky_tile(RenderPart *pa, RenderLayer *rl)
+{
+ RenderLayer *rlpp[RE_MAX_OSA];
+ int x, y, od=0, totsample;
+
+ if (R.r.alphamode!=R_ADDSKY)
+ return;
+
+ totsample= get_sample_layers(pa, rl, rlpp);
+
+ for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+ for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) {
+ float col[4];
+ int sample;
+ bool done = false;
+
+ for (sample= 0; sample<totsample; sample++) {
+ float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+ pass += od;
+
+ if (pass[3]<1.0f) {
+
+ if (done==0) {
+ shadeSkyPixel(col, x, y, pa->thread);
+ done = true;
+ }
+
+ if (pass[3]==0.0f) {
+ copy_v4_v4(pass, col);
+ pass[3] = 1.0f;
+ }
+ else {
+ addAlphaUnderFloat(pass, col);
+ pass[3] = 1.0f;
+ }
+ }
+ }
+ }
+
+ if (y&1)
+ if (R.test_break(R.tbh)) break;
+ }
+}
+
+static void atm_tile(RenderPart *pa, RenderLayer *rl)
+{
+ RenderPass *zpass;
+ GroupObject *go;
+ LampRen *lar;
+ RenderLayer *rlpp[RE_MAX_OSA];
+ int totsample;
+ int x, y, od= 0;
+
+ totsample= get_sample_layers(pa, rl, rlpp);
+
+ /* check that z pass is enabled */
+ if (pa->rectz==NULL) return;
+ for (zpass= rl->passes.first; zpass; zpass= zpass->next)
+ if (STREQ(zpass->name, RE_PASSNAME_Z))
+ break;
+
+ if (zpass==NULL) return;
+
+ /* check for at least one sun lamp that its atmosphere flag is enabled */
+ for (go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if (lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_AP))
+ break;
+ }
+ /* do nothign and return if there is no sun lamp */
+ if (go==NULL)
+ return;
+
+ /* for each x,y and each sample, and each sun lamp*/
+ for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+ for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od++) {
+ int sample;
+
+ for (sample=0; sample<totsample; sample++) {
+ const float *zrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_Z, R.viewname) + od;
+ float *rgbrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname) + 4*od;
+ float rgb[3] = {0};
+ bool done = false;
+
+ for (go=R.lights.first; go; go= go->next) {
+
+
+ lar= go->lampren;
+ if (lar->type==LA_SUN && lar->sunsky) {
+
+ /* if it's sky continue and don't apply atmosphere effect on it */
+ if (*zrect >= 9.9e10f || rgbrect[3]==0.0f) {
+ continue;
+ }
+
+ if ((lar->sunsky->effect_type & LA_SUN_EFFECT_AP)) {
+ float tmp_rgb[3];
+
+ /* skip if worldspace lamp vector is below horizon */
+ if (go->ob->obmat[2][2] < 0.f) {
+ continue;
+ }
+
+ copy_v3_v3(tmp_rgb, rgbrect);
+ if (rgbrect[3]!=1.0f) { /* de-premul */
+ mul_v3_fl(tmp_rgb, 1.0f/rgbrect[3]);
+ }
+ shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
+ if (rgbrect[3]!=1.0f) { /* premul */
+ mul_v3_fl(tmp_rgb, rgbrect[3]);
+ }
+
+ if (done==0) {
+ copy_v3_v3(rgb, tmp_rgb);
+ done = true;
+ }
+ else {
+ rgb[0] = 0.5f*rgb[0] + 0.5f*tmp_rgb[0];
+ rgb[1] = 0.5f*rgb[1] + 0.5f*tmp_rgb[1];
+ rgb[2] = 0.5f*rgb[2] + 0.5f*tmp_rgb[2];
+ }
+ }
+ }
+ }
+
+ /* if at least for one sun lamp aerial perspective was applied*/
+ if (done) {
+ copy_v3_v3(rgbrect, rgb);
+ }
+ }
+ }
+ }
+}
+
+static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
+{
+ RenderResult *rr= pa->result;
+ ShadeSample ssamp;
+ intptr_t *rd, *rectdaps= pa->rectdaps;
+ int samp;
+ int x, y, seed, crop=0, offs=0, od;
+
+ if (R.test_break(R.tbh)) return;
+
+ /* irregular shadowb buffer creation */
+ if (R.r.mode & R_SHADOW)
+ ISB_create(pa, NULL);
+
+ /* we set per pixel a fixed seed, for random AO and shadow samples */
+ seed= pa->rectx*pa->disprect.ymin;
+
+ /* general shader info, passes */
+ shade_sample_initialize(&ssamp, pa, rl);
+
+ /* occlusion caching */
+ if (R.occlusiontree)
+ cache_occ_samples(&R, pa, &ssamp);
+
+ /* filtered render, for now we assume only 1 filter size */
+ if (pa->crop) {
+ crop= 1;
+ rectdaps+= pa->rectx + 1;
+ offs= pa->rectx + 1;
+ }
+
+ /* scanline updates have to be 2 lines behind */
+ rr->renrect.ymin = 0;
+ rr->renrect.ymax = -2*crop;
+ rr->renlay= rl;
+
+ for (y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
+ rd= rectdaps;
+ od= offs;
+
+ for (x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) {
+ BLI_thread_srandom(pa->thread, seed++);
+
+ if (*rd) {
+ if (shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
+
+ /* multisample buffers or filtered mask filling? */
+ if (pa->fullresult.first) {
+ int a;
+ for (samp=0; samp<ssamp.tot; samp++) {
+ int smask= ssamp.shi[samp].mask;
+ for (a=0; a<R.osa; a++) {
+ int mask= 1<<a;
+ if (smask & mask)
+ add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]);
+ }
+ }
+ }
+ else {
+ for (samp=0; samp<ssamp.tot; samp++)
+ add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
+ }
+ }
+ }
+ }
+
+ rectdaps+= pa->rectx;
+ offs+= pa->rectx;
+
+ if (y&1) if (R.test_break(R.tbh)) break;
+ }
+
+ /* disable scanline updating */
+ rr->renlay= NULL;
+
+ if (R.r.mode & R_SHADOW)
+ ISB_free(pa);
+
+ if (R.occlusiontree)
+ free_occ_samples(&R, pa);
+}
+
+/* ************* pixel struct ******** */
+
+
+static PixStrMain *addpsmain(ListBase *lb)
+{
+ PixStrMain *psm;
+
+ psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain), "pixstrMain");
+ BLI_addtail(lb, psm);
+
+ psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr), "pixstr");
+ psm->counter= 0;
+
+ return psm;
+}
+
+static void freeps(ListBase *lb)
+{
+ PixStrMain *psm, *psmnext;
+
+ for (psm= lb->first; psm; psm= psmnext) {
+ psmnext= psm->next;
+ if (psm->ps)
+ MEM_freeN(psm->ps);
+ MEM_freeN(psm);
+ }
+ BLI_listbase_clear(lb);
+}
+
+static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int maskz, unsigned short mask)
+{
+ PixStrMain *psm;
+ PixStr *ps, *last= NULL;
+
+ if (*rd) {
+ ps= (PixStr *)(*rd);
+
+ while (ps) {
+ if ( ps->obi == obi && ps->facenr == facenr ) {
+ ps->mask |= mask;
+ return;
+ }
+ last= ps;
+ ps= ps->next;
+ }
+ }
+
+ /* make new PS (pixel struct) */
+ psm= lb->last;
+
+ if (psm->counter==4095)
+ psm= addpsmain(lb);
+
+ ps= psm->ps + psm->counter++;
+
+ if (last) last->next= ps;
+ else *rd= (intptr_t)ps;
+
+ ps->next= NULL;
+ ps->obi= obi;
+ ps->facenr= facenr;
+ ps->z= z;
+ ps->maskz= maskz;
+ ps->mask = mask;
+ ps->shadfac= 0;
+}
+
+static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
+{
+ float addcol[4];
+ int pix;
+
+ if (arect==NULL)
+ return;
+
+ for (pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
+ if (*arect != 0.0f) {
+ addcol[0]= *arect * R.r.edgeR;
+ addcol[1]= *arect * R.r.edgeG;
+ addcol[2]= *arect * R.r.edgeB;
+ addcol[3]= *arect;
+ addAlphaOverFloat(rectf, addcol);
+ }
+ }
+}
+
+/* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */
+static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
+{
+ RenderLayer *rlpp[RE_MAX_OSA];
+ int y, sample, totsample;
+
+ totsample= get_sample_layers(pa, rl, rlpp);
+
+ /* not for full sample, there we clamp after compositing */
+ if (totsample > 1)
+ return;
+
+ for (sample= 0; sample<totsample; sample++) {
+ float *rectf = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
+
+ for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
+ rectf[0] = MAX2(rectf[0], 0.0f);
+ rectf[1] = MAX2(rectf[1], 0.0f);
+ rectf[2] = MAX2(rectf[2], 0.0f);
+ CLAMP(rectf[3], 0.0f, 1.0f);
+ }
+ }
+}
+
+/* adds only alpha values */
+static void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz)
+{
+ /* use zbuffer to define edges, add it to the image */
+ int y, x, col, *rz, *rz1, *rz2, *rz3;
+ int zval1, zval2, zval3;
+ float *rf;
+
+ /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
+ rz= rectz;
+ if (rz==NULL) return;
+
+ for (y=0; y<pa->recty; y++)
+ for (x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
+
+ rz1= rectz;
+ rz2= rz1+pa->rectx;
+ rz3= rz2+pa->rectx;
+
+ rf= rectf+pa->rectx+1;
+
+ for (y=0; y<pa->recty-2; y++) {
+ for (x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
+
+ /* prevent overflow with sky z values */
+ zval1= rz1[0] + 2*rz1[1] + rz1[2];
+ zval2= 2*rz2[0] + 2*rz2[2];
+ zval3= rz3[0] + 2*rz3[1] + rz3[2];
+
+ col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
+ if (col<0) col= -col;
+
+ col >>= 5;
+ if (col > (1<<16)) col= (1<<16);
+ else col= (R.r.edgeint*col)>>8;
+
+ if (col>0) {
+ float fcol;
+
+ if (col>255) fcol= 1.0f;
+ else fcol= (float)col/255.0f;
+
+ if (R.osa)
+ *rf+= fcol/(float)R.osa;
+ else
+ *rf= fcol;
+ }
+ }
+ rz1+= 2;
+ rz2+= 2;
+ rz3+= 2;
+ rf+= 2;
+ }
+
+ /* shift back zbuf values, we might need it still */
+ rz= rectz;
+ for (y=0; y<pa->recty; y++)
+ for (x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4;
+
+}
+
+static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
+{
+ /* for all pixels with max speed, set to zero */
+ RenderLayer *rlpp[RE_MAX_OSA];
+ float *fp;
+ int a, sample, totsample;
+
+ totsample= get_sample_layers(pa, rl, rlpp);
+
+ for (sample= 0; sample<totsample; sample++) {
+ fp= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_VECTOR, R.viewname);
+ if (fp==NULL) break;
+
+ for (a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
+ if (fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
+ }
+}
+
+static unsigned short *make_solid_mask(RenderPart *pa)
+{
+ intptr_t *rd= pa->rectdaps;
+ unsigned short *solidmask, *sp;
+ int x;
+
+ if (rd==NULL) return NULL;
+
+ sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask");
+
+ for (x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) {
+ if (*rd) {
+ PixStr *ps= (PixStr *)*rd;
+
+ *sp= ps->mask;
+ for (ps= ps->next; ps; ps= ps->next)
+ *sp |= ps->mask;
+ }
+ else
+ *sp= 0;
+ }
+
+ return solidmask;
+}
+
+static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask)
+{
+ unsigned short shared= dmask & smask;
+ float mul= 1.0f - source[3];
+
+ if (shared) { /* overlapping masks */
+
+ /* masks differ, we make a mixture of 'add' and 'over' */
+ if (shared!=dmask) {
+ float shared_bits= (float)count_mask(shared); /* alpha over */
+ float tot_bits= (float)count_mask(smask|dmask); /* alpha add */
+
+ float add= (tot_bits - shared_bits)/tot_bits; /* add level */
+ mul= add + (1.0f-add)*mul;
+ }
+ }
+ else if (dmask && smask) {
+ /* works for premul only, of course */
+ dest[0]+= source[0];
+ dest[1]+= source[1];
+ dest[2]+= source[2];
+ dest[3]+= source[3];
+
+ return;
+ }
+
+ dest[0]= (mul*dest[0]) + source[0];
+ dest[1]= (mul*dest[1]) + source[1];
+ dest[2]= (mul*dest[2]) + source[2];
+ dest[3]= (mul*dest[3]) + source[3];
+}
+
+typedef struct ZbufSolidData {
+ RenderLayer *rl;
+ ListBase *psmlist;
+ float *edgerect;
+} ZbufSolidData;
+
+static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
+{
+ ZbufSolidData *sdata = (ZbufSolidData *)data;
+ ListBase *lb= sdata->psmlist;
+ intptr_t *rd= pa->rectdaps;
+ const int *ro= zspan->recto;
+ const int *rp= zspan->rectp;
+ const int *rz= zspan->rectz;
+ const int *rm= zspan->rectmask;
+ int x, y;
+ int mask= 1<<sample;
+
+ for (y=0; y<pa->recty; y++) {
+ for (x=0; x<pa->rectx; x++, rd++, rp++, ro++, rz++, rm++) {
+ if (*rp) {
+ addps(lb, rd, *ro, *rp, *rz, (zspan->rectmask)? *rm: 0, mask);
+ }
+ }
+ }
+
+ if (sdata->rl->layflag & SCE_LAY_EDGE)
+ if (R.r.mode & R_EDGE)
+ edge_enhance_tile(pa, sdata->edgerect, zspan->rectz);
+}
+
+/* main call for shading Delta Accum, for OSA */
+/* supposed to be fully threadable! */
+void zbufshadeDA_tile(RenderPart *pa)
+{
+ RenderResult *rr= pa->result;
+ RenderLayer *rl;
+ ListBase psmlist= {NULL, NULL};
+ float *edgerect= NULL;
+
+ /* allocate the necessary buffers */
+ /* zbuffer inits these rects */
+ pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
+ pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
+ pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
+ for (rl= rr->layers.first; rl; rl= rl->next) {
+ float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
+
+ if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
+ pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
+
+ /* initialize pixelstructs and edge buffer */
+ addpsmain(&psmlist);
+ pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd");
+
+ if (rl->layflag & SCE_LAY_EDGE)
+ if (R.r.mode & R_EDGE)
+ edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
+
+ /* always fill visibility */
+ for (pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
+ ZbufSolidData sdata;
+
+ sdata.rl= rl;
+ sdata.psmlist= &psmlist;
+ sdata.edgerect= edgerect;
+ zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
+ if (R.test_break(R.tbh)) break;
+ }
+
+ /* shades solid */
+ if (rl->layflag & SCE_LAY_SOLID)
+ shadeDA_tile(pa, rl);
+
+ /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
+ if (R.flag & R_LAMPHALO)
+ if (rl->layflag & SCE_LAY_HALO)
+ lamphalo_tile(pa, rl);
+
+ /* halo before ztra, because ztra fills in zbuffer now */
+ if (R.flag & R_HALO)
+ if (rl->layflag & SCE_LAY_HALO)
+ halo_tile(pa, rl);
+
+ /* transp layer */
+ if (R.flag & R_ZTRA || R.totstrand) {
+ if (rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
+ if (pa->fullresult.first) {
+ zbuffer_transp_shade(pa, rl, rect, &psmlist);
+ }
+ else {
+ unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
+
+ /* allocate, but not free here, for asynchronous display of this rect in main thread */
+ rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
+
+ /* swap for live updates, and it is used in zbuf.c!!! */
+ SWAP(float *, rl->acolrect, rect);
+ ztramask = zbuffer_transp_shade(pa, rl, rect, &psmlist);
+ SWAP(float *, rl->acolrect, rect);
+
+ /* zbuffer transp only returns ztramask if there's solid rendered */
+ if (ztramask)
+ solidmask= make_solid_mask(pa);
+
+ if (ztramask && solidmask) {
+ unsigned short *sps= solidmask, *spz= ztramask;
+ unsigned short fullmask= (1<<R.osa)-1;
+ float *fcol= rect;
+ float *acol= rl->acolrect;
+ int x;
+
+ for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
+ if (*sps == fullmask)
+ addAlphaOverFloat(fcol, acol);
+ else
+ addAlphaOverFloatMask(fcol, acol, *sps, *spz);
+ }
+ }
+ else {
+ float *fcol= rect;
+ float *acol= rl->acolrect;
+ int x;
+ for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
+ addAlphaOverFloat(fcol, acol);
+ }
+ }
+ if (solidmask) MEM_freeN(solidmask);
+ if (ztramask) MEM_freeN(ztramask);
+ }
+ }
+ }
+
+ /* sun/sky */
+ if (rl->layflag & SCE_LAY_SKY)
+ atm_tile(pa, rl);
+
+ /* sky before edge */
+ if (rl->layflag & SCE_LAY_SKY)
+ sky_tile(pa, rl);
+
+ /* extra layers */
+ if (rl->layflag & SCE_LAY_EDGE)
+ if (R.r.mode & R_EDGE)
+ edge_enhance_add(pa, rect, edgerect);
+
+ if (rl->passflag & SCE_PASS_VECTOR)
+ reset_sky_speed(pa, rl);
+
+ /* clamp alpha to 0..1 range, can go outside due to filter */
+ clamp_alpha_rgb_range(pa, rl);
+
+ /* free stuff within loop! */
+ MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
+ freeps(&psmlist);
+
+ if (edgerect) MEM_freeN(edgerect);
+ edgerect= NULL;
+
+ if (pa->rectmask) {
+ MEM_freeN(pa->rectmask);
+ pa->rectmask= NULL;
+ }
+ }
+
+ /* free all */
+ MEM_freeN(pa->recto); pa->recto= NULL;
+ MEM_freeN(pa->rectp); pa->rectp= NULL;
+ MEM_freeN(pa->rectz); pa->rectz= NULL;
+
+ /* display active layer */
+ rr->renrect.ymin=rr->renrect.ymax = 0;
+ rr->renlay= render_get_active_layer(&R, rr);
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+/* non OSA case, full tile render */
+/* supposed to be fully threadable! */
+void zbufshade_tile(RenderPart *pa)
+{
+ ShadeSample ssamp;
+ RenderResult *rr= pa->result;
+ RenderLayer *rl;
+ PixStr ps;
+ float *edgerect= NULL;
+
+ /* fake pixel struct, to comply to osa render */
+ ps.next= NULL;
+ ps.mask= 0xFFFF;
+
+ /* zbuffer code clears/inits rects */
+ pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
+ pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
+ pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
+
+ for (rl= rr->layers.first; rl; rl= rl->next) {
+ float *rect= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
+ if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
+ pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
+
+ /* general shader info, passes */
+ shade_sample_initialize(&ssamp, pa, rl);
+
+ zbuffer_solid(pa, rl, NULL, NULL);
+
+ if (!R.test_break(R.tbh)) { /* NOTE: this if () is not consistent */
+
+ /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
+ if (rl->layflag & SCE_LAY_EDGE) {
+ if (R.r.mode & R_EDGE) {
+ edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
+ edge_enhance_tile(pa, edgerect, pa->rectz);
+ }
+ }
+
+ /* initialize scanline updates for main thread */
+ rr->renrect.ymin = 0;
+ rr->renlay= rl;
+
+ if (rl->layflag & SCE_LAY_SOLID) {
+ const float *fcol = rect;
+ const int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
+ int x, y, offs=0, seed;
+
+ /* we set per pixel a fixed seed, for random AO and shadow samples */
+ seed= pa->rectx*pa->disprect.ymin;
+
+ /* irregular shadowb buffer creation */
+ if (R.r.mode & R_SHADOW)
+ ISB_create(pa, NULL);
+
+ if (R.occlusiontree)
+ cache_occ_samples(&R, pa, &ssamp);
+
+ for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
+ for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
+ /* per pixel fixed seed */
+ BLI_thread_srandom(pa->thread, seed++);
+
+ if (*rp) {
+ ps.obi= *ro;
+ ps.facenr= *rp;
+ ps.z= *rz;
+ if (shade_samples(&ssamp, &ps, x, y)) {
+ /* combined and passes */
+ add_passes(rl, offs, ssamp.shi, ssamp.shr);
+ }
+ }
+ }
+ if (y&1)
+ if (R.test_break(R.tbh)) break;
+ }
+
+ if (R.occlusiontree)
+ free_occ_samples(&R, pa);
+
+ if (R.r.mode & R_SHADOW)
+ ISB_free(pa);
+ }
+
+ /* disable scanline updating */
+ rr->renlay= NULL;
+ }
+
+ /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
+ if (R.flag & R_LAMPHALO)
+ if (rl->layflag & SCE_LAY_HALO)
+ lamphalo_tile(pa, rl);
+
+ /* halo before ztra, because ztra fills in zbuffer now */
+ if (R.flag & R_HALO)
+ if (rl->layflag & SCE_LAY_HALO)
+ halo_tile(pa, rl);
+
+ if (R.flag & R_ZTRA || R.totstrand) {
+ if (rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
+ float *fcol, *acol;
+ int x;
+
+ /* allocate, but not free here, for asynchronous display of this rect in main thread */
+ rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
+
+ /* swap for live updates */
+ SWAP(float *, rl->acolrect, rect);
+ zbuffer_transp_shade(pa, rl, rect, NULL);
+ SWAP(float *, rl->acolrect, rect);
+
+ fcol= rect; acol= rl->acolrect;
+ for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
+ addAlphaOverFloat(fcol, acol);
+ }
+ }
+ }
+
+ /* sun/sky */
+ if (rl->layflag & SCE_LAY_SKY)
+ atm_tile(pa, rl);
+
+ /* sky before edge */
+ if (rl->layflag & SCE_LAY_SKY)
+ sky_tile(pa, rl);
+
+ if (!R.test_break(R.tbh)) {
+ if (rl->layflag & SCE_LAY_EDGE)
+ if (R.r.mode & R_EDGE)
+ edge_enhance_add(pa, rect, edgerect);
+ }
+
+ if (rl->passflag & SCE_PASS_VECTOR)
+ reset_sky_speed(pa, rl);
+
+ if (edgerect) MEM_freeN(edgerect);
+ edgerect= NULL;
+
+ if (pa->rectmask) {
+ MEM_freeN(pa->rectmask);
+ pa->rectmask= NULL;
+ }
+ }
+
+ /* display active layer */
+ rr->renrect.ymin=rr->renrect.ymax = 0;
+ rr->renlay= render_get_active_layer(&R, rr);
+
+ MEM_freeN(pa->recto); pa->recto= NULL;
+ MEM_freeN(pa->rectp); pa->rectp= NULL;
+ MEM_freeN(pa->rectz); pa->rectz= NULL;
+}
+
+/* SSS preprocess tile render, fully threadable */
+typedef struct ZBufSSSHandle {
+ RenderPart *pa;
+ ListBase psmlist;
+ int totps;
+} ZBufSSSHandle;
+
+static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
+{
+ ZBufSSSHandle *handle = cb_handle;
+ RenderPart *pa= handle->pa;
+
+ /* extra border for filter gives double samples on part edges,
+ * don't use those */
+ if (x<pa->crop || x>=pa->rectx-pa->crop)
+ return;
+ if (y<pa->crop || y>=pa->recty-pa->crop)
+ return;
+
+ if (pa->rectall) {
+ intptr_t *rs= pa->rectall + pa->rectx*y + x;
+
+ addps(&handle->psmlist, rs, obi, facenr, z, 0, 0);
+ handle->totps++;
+ }
+ if (pa->rectz) {
+ int *rz= pa->rectz + pa->rectx*y + x;
+ int *rp= pa->rectp + pa->rectx*y + x;
+ int *ro= pa->recto + pa->rectx*y + x;
+
+ if (z < *rz) {
+ if (*rp == 0)
+ handle->totps++;
+ *rz= z;
+ *rp= facenr;
+ *ro= obi;
+ }
+ }
+ if (pa->rectbackz) {
+ int *rz= pa->rectbackz + pa->rectx*y + x;
+ int *rp= pa->rectbackp + pa->rectx*y + x;
+ int *ro= pa->rectbacko + pa->rectx*y + x;
+
+ if (z >= *rz) {
+ if (*rp == 0)
+ handle->totps++;
+ *rz= z;
+ *rp= facenr;
+ *ro= obi;
+ }
+ }
+}
+
+static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRen *obi, VlakRen *vlr, int quad, float x, float y, float z, float *co, float color[3], float *area)
+{
+ ShadeInput *shi= ssamp->shi;
+ ShadeResult shr;
+ float /* texfac,*/ /* UNUSED */ orthoarea, nor[3], alpha, sx, sy;
+
+ /* cache for shadow */
+ shi->samplenr= R.shadowsamplenr[shi->thread]++;
+
+ if (quad)
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
+ else
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
+
+ /* center pixel */
+ sx = x + 0.5f;
+ sy = y + 0.5f;
+
+ /* we estimate the area here using shi->dxco and shi->dyco. we need to
+ * enabled shi->osatex these are filled. we compute two areas, one with
+ * the normal pointed at the camera and one with the original normal, and
+ * then clamp to avoid a too large contribution from a single pixel */
+ shi->osatex= 1;
+
+ copy_v3_v3(nor, shi->facenor);
+ calc_view_vector(shi->facenor, sx, sy);
+ normalize_v3(shi->facenor);
+ shade_input_set_viewco(shi, x, y, sx, sy, z);
+ orthoarea= len_v3(shi->dxco)*len_v3(shi->dyco);
+
+ copy_v3_v3(shi->facenor, nor);
+ shade_input_set_viewco(shi, x, y, sx, sy, z);
+ *area = min_ff(len_v3(shi->dxco) * len_v3(shi->dyco), 2.0f * orthoarea);
+
+ shade_input_set_uv(shi);
+ shade_input_set_normals(shi);
+
+ /* we don't want flipped normals, they screw up back scattering */
+ if (shi->flippednor)
+ shade_input_flip_normals(shi);
+
+ /* not a pretty solution, but fixes common cases */
+ if (shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
+ negate_v3(shi->vn);
+ negate_v3(shi->vno);
+ negate_v3(shi->nmapnorm);
+ }
+
+ /* if nodetree, use the material that we are currently preprocessing
+ * instead of the node material */
+ if (shi->mat->nodetree && shi->mat->use_nodes)
+ shi->mat= mat;
+
+ /* init material vars */
+ shade_input_init_material(shi);
+
+ /* render */
+ shade_input_set_shade_texco(shi);
+
+ shade_samples_do_AO(ssamp);
+ shade_material_loop(shi, &shr);
+
+ copy_v3_v3(co, shi->co);
+ copy_v3_v3(color, shr.combined);
+
+ /* texture blending */
+ /* texfac= shi->mat->sss_texfac; */ /* UNUSED */
+
+ alpha= shr.combined[3];
+ *area *= alpha;
+}
+
+static void zbufshade_sss_free(RenderPart *pa)
+{
+#if 0
+ MEM_freeN(pa->rectall); pa->rectall= NULL;
+ freeps(&handle.psmlist);
+#else
+ MEM_freeN(pa->rectz); pa->rectz= NULL;
+ MEM_freeN(pa->rectp); pa->rectp= NULL;
+ MEM_freeN(pa->recto); pa->recto= NULL;
+ MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
+ MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
+ MEM_freeN(pa->rectbacko); pa->rectbacko= NULL;
+#endif
+}
+
+void zbufshade_sss_tile(RenderPart *pa)
+{
+ Render *re= &R;
+ ShadeSample ssamp;
+ ZBufSSSHandle handle;
+ RenderResult *rr= pa->result;
+ RenderLayer *rl;
+ VlakRen *vlr;
+ Material *mat= re->sss_mat;
+ float (*co)[3], (*color)[3], *area, *fcol;
+ int x, y, seed, quad, totpoint;
+ const bool display = (re->r.scemode & (R_BUTS_PREVIEW | R_VIEWPORT_PREVIEW)) == 0;
+ int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay;
+#if 0
+ PixStr *ps;
+ intptr_t *rs;
+ int z;
+#endif
+
+ /* setup pixelstr list and buffer for zbuffering */
+ handle.pa= pa;
+ handle.totps= 0;
+
+#if 0
+ handle.psmlist.first= handle.psmlist.last= NULL;
+ addpsmain(&handle.psmlist);
+
+ pa->rectall= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "rectall");
+#else
+ pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
+ pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
+ pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
+ pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko");
+ pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
+ pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
+#endif
+
+ /* setup shade sample with correct passes */
+ memset(&ssamp, 0, sizeof(ssamp));
+ shade_sample_initialize(&ssamp, pa, rr->layers.first);
+ ssamp.tot= 1;
+
+ for (rl=rr->layers.first; rl; rl=rl->next) {
+ ssamp.shi[0].lay |= rl->lay;
+ ssamp.shi[0].layflag |= rl->layflag;
+ ssamp.shi[0].passflag |= rl->passflag;
+ ssamp.shi[0].combinedflag |= ~rl->pass_xor;
+ }
+
+ rl= rr->layers.first;
+ ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED;
+ ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC);
+ ssamp.shi[0].mat_override= NULL;
+ ssamp.shi[0].light_override= NULL;
+ lay= ssamp.shi[0].lay;
+
+ /* create the pixelstrs to be used later */
+ zbuffer_sss(pa, lay, &handle, addps_sss);
+
+ if (handle.totps==0) {
+ zbufshade_sss_free(pa);
+ return;
+ }
+
+ fcol= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
+
+ co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
+ color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
+ area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea");
+
+#if 0
+ /* create ISB (does not work currently!) */
+ if (re->r.mode & R_SHADOW)
+ ISB_create(pa, NULL);
+#endif
+
+ if (display) {
+ /* initialize scanline updates for main thread */
+ rr->renrect.ymin = 0;
+ rr->renlay= rl;
+ }
+
+ seed= pa->rectx*pa->disprect.ymin;
+#if 0
+ rs= pa->rectall;
+#else
+ rz= pa->rectz;
+ rp= pa->rectp;
+ ro= pa->recto;
+ rbz= pa->rectbackz;
+ rbp= pa->rectbackp;
+ rbo= pa->rectbacko;
+#endif
+ totpoint= 0;
+
+ for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
+ for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) {
+ /* per pixel fixed seed */
+ BLI_thread_srandom(pa->thread, seed++);
+
+#if 0
+ if (rs) {
+ /* for each sample in this pixel, shade it */
+ for (ps = (PixStr *)(*rs); ps; ps=ps->next) {
+ ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
+ ObjectRen *obr= obi->obr;
+ vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
+ quad= (ps->facenr & RE_QUAD_OFFS);
+ z= ps->z;
+
+ shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z,
+ co[totpoint], color[totpoint], &area[totpoint]);
+
+ totpoint++;
+
+ add_v3_v3(fcol, color);
+ fcol[3]= 1.0f;
+ }
+
+ rs++;
+ }
+#else
+ if (rp) {
+ if (*rp != 0) {
+ ObjectInstanceRen *obi= &re->objectinstance[*ro];
+ ObjectRen *obr= obi->obr;
+
+ /* shade front */
+ vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK);
+ quad= ((*rp) & RE_QUAD_OFFS);
+
+ shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz,
+ co[totpoint], color[totpoint], &area[totpoint]);
+
+ add_v3_v3(fcol, color[totpoint]);
+ fcol[3]= 1.0f;
+ totpoint++;
+ }
+
+ rp++; rz++; ro++;
+ }
+
+ if (rbp) {
+ if (*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) {
+ ObjectInstanceRen *obi= &re->objectinstance[*rbo];
+ ObjectRen *obr= obi->obr;
+
+ /* shade back */
+ vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK);
+ quad= ((*rbp) & RE_QUAD_OFFS);
+
+ shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz,
+ co[totpoint], color[totpoint], &area[totpoint]);
+
+ /* to indicate this is a back sample */
+ area[totpoint]= -area[totpoint];
+
+ add_v3_v3(fcol, color[totpoint]);
+ fcol[3]= 1.0f;
+ totpoint++;
+ }
+
+ rbz++; rbp++; rbo++;
+ }
+#endif
+ }
+
+ if (y&1)
+ if (re->test_break(re->tbh)) break;
+ }
+
+ /* note: after adding we do not free these arrays, sss keeps them */
+ if (totpoint > 0) {
+ sss_add_points(re, co, color, area, totpoint);
+ }
+ else {
+ MEM_freeN(co);
+ MEM_freeN(color);
+ MEM_freeN(area);
+ }
+
+#if 0
+ if (re->r.mode & R_SHADOW)
+ ISB_free(pa);
+#endif
+
+ if (display) {
+ /* display active layer */
+ rr->renrect.ymin=rr->renrect.ymax = 0;
+ rr->renlay= render_get_active_layer(&R, rr);
+ }
+
+ zbufshade_sss_free(pa);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* postprocess version */
+{
+ float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf;
+ float haloxs, haloys;
+ int minx, maxx, miny, maxy, x, y;
+
+ /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */
+ haloxs= har->xs - R.disprect.xmin;
+ haloys= har->ys - R.disprect.ymin;
+
+ har->miny= miny= haloys - har->rad/R.ycor;
+ har->maxy= maxy= haloys + har->rad/R.ycor;
+
+ if (maxy < 0) {
+ /* pass */
+ }
+ else if (rr->recty < miny) {
+ /* pass */
+ }
+ else {
+ minx = floor(haloxs - har->rad);
+ maxx = ceil(haloxs + har->rad);
+
+ if (maxx < 0) {
+ /* pass */
+ }
+ else if (rr->rectx < minx) {
+ /* pass */
+ }
+ else {
+ if (minx<0) minx= 0;
+ if (maxx>=rr->rectx) maxx= rr->rectx-1;
+ if (miny<0) miny= 0;
+ if (maxy>rr->recty) maxy= rr->recty;
+
+ rectft= rectf+ 4*rr->rectx*miny;
+
+ for (y=miny; y<maxy; y++) {
+
+ rtf= rectft+4*minx;
+
+ yn= (y - haloys)*R.ycor;
+ ysq= yn*yn;
+
+ for (x=minx; x<=maxx; x++) {
+ xn= x - haloxs;
+ xsq= xn*xn;
+ dist= xsq+ysq;
+ if (dist<har->radsq) {
+
+ if (shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec))
+ addalphaAddfacFloat(rtf, colf, har->add);
+ }
+ rtf+=4;
+ }
+
+ rectft+= 4*rr->rectx;
+
+ if (R.test_break(R.tbh)) break;
+ }
+ }
+ }
+}
+/* ------------------------------------------------------------------------ */
+
+static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
+{
+ extern const float hashvectf[];
+ HaloRen fla;
+ Material *ma;
+ const float *rc;
+ float rad, alfa, visifac, vec[3];
+ int b, type;
+
+ fla= *har;
+ fla.linec= fla.ringc= fla.flarec= 0;
+
+ rad= har->rad;
+ alfa= har->alfa;
+
+ visifac= R.ycor*(har->pixels);
+ /* all radials added / r^3 == 1.0f! */
+ visifac /= (har->rad*har->rad*har->rad);
+ visifac*= visifac;
+
+ ma= har->mat;
+
+ /* first halo: just do */
+
+ har->rad= rad*ma->flaresize*visifac;
+ har->radsq= har->rad*har->rad;
+ har->zs= fla.zs= 0;
+
+ har->alfa= alfa*visifac;
+
+ renderhalo_post(rr, rectf, har);
+
+ /* next halo's: the flares */
+ rc= hashvectf + ma->seed2;
+
+ for (b=1; b<har->flarec; b++) {
+
+ fla.r = fabsf(rc[0]);
+ fla.g = fabsf(rc[1]);
+ fla.b = fabsf(rc[2]);
+ fla.alfa= ma->flareboost*fabsf(alfa*visifac*rc[3]);
+ fla.hard= 20.0f + fabsf(70.0f*rc[7]);
+ fla.tex= 0;
+
+ type= (int)(fabsf(3.9f*rc[6]));
+
+ fla.rad = ma->subsize * sqrtf(fabsf(2.0f * har->rad * rc[4]));
+
+ if (type==3) {
+ fla.rad*= 3.0f;
+ fla.rad+= R.rectx/10;
+ }
+
+ fla.radsq= fla.rad*fla.rad;
+
+ vec[0]= 1.4f*rc[5]*(har->xs-R.winx/2);
+ vec[1]= 1.4f*rc[5]*(har->ys-R.winy/2);
+ vec[2]= 32.0f*sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f);
+
+ fla.xs= R.winx/2 + vec[0] + (1.2f+rc[8])*R.rectx*vec[0]/vec[2];
+ fla.ys= R.winy/2 + vec[1] + (1.2f+rc[8])*R.rectx*vec[1]/vec[2];
+
+ if (R.flag & R_SEC_FIELD) {
+ if (R.r.mode & R_ODDFIELD) fla.ys += 0.5f;
+ else fla.ys -= 0.5f;
+ }
+ if (type & 1) fla.type= HA_FLARECIRC;
+ else fla.type= 0;
+ renderhalo_post(rr, rectf, &fla);
+
+ fla.alfa*= 0.5f;
+ if (type & 2) fla.type= HA_FLARECIRC;
+ else fla.type= 0;
+ renderhalo_post(rr, rectf, &fla);
+
+ rc+= 7;
+ }
+}
+
+/* needs recode... integrate this better! */
+void add_halo_flare(Render *re)
+{
+ RenderResult *rr= re->result;
+ RenderLayer *rl;
+ HaloRen *har;
+ int a, mode;
+ float *rect;
+
+ /* for now, we get the first renderlayer in list with halos set */
+ for (rl= rr->layers.first; rl; rl= rl->next) {
+ bool do_draw = false;
+
+ if ((rl->layflag & SCE_LAY_HALO) == 0)
+ continue;
+
+ rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname);
+
+ if (rect==NULL)
+ continue;
+
+ mode= R.r.mode;
+ R.r.mode &= ~R_PANORAMA;
+
+ project_renderdata(&R, projectverto, 0, 0, 0);
+
+ for (a=0; a<R.tothalo; a++) {
+ har= R.sortedhalos[a];
+
+ if (har->flarec && (har->lay & rl->lay)) {
+ do_draw = true;
+ renderflare(rr, rect, har);
+ }
+ }
+
+ if (do_draw) {
+ /* weak... the display callback wants an active renderlayer pointer... */
+ rr->renlay= rl;
+ re->display_update(re->duh, rr, NULL);
+ }
+
+ R.r.mode= mode;
+ }
+}
+
+void render_internal_update_passes(RenderEngine *engine, Scene *scene, SceneRenderLayer *srl)
+{
+ int type;
+
+ RE_engine_register_pass(engine, scene, srl, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
+
+#define CHECK_PASS(name, channels, chanid) \
+ if (srl->passflag & (SCE_PASS_ ## name)) { \
+ if (channels == 4) type = SOCK_RGBA; \
+ else if (channels == 3) type = SOCK_VECTOR; \
+ else type = SOCK_FLOAT; \
+ RE_engine_register_pass(engine, scene, srl, RE_PASSNAME_ ## name, channels, chanid, type); \
+ }
+
+ CHECK_PASS(Z, 1, "Z");
+ CHECK_PASS(VECTOR, 4, "XYZW");
+ CHECK_PASS(NORMAL, 3, "XYZ");
+ CHECK_PASS(UV, 3, "UVA");
+ CHECK_PASS(RGBA, 4, "RGBA");
+ CHECK_PASS(EMIT, 3, "RGB");
+ CHECK_PASS(DIFFUSE, 3, "RGB");
+ CHECK_PASS(SPEC, 3, "RGB");
+ CHECK_PASS(AO, 3, "RGB");
+ CHECK_PASS(ENVIRONMENT, 3, "RGB");
+ CHECK_PASS(INDIRECT, 3, "RGB");
+ CHECK_PASS(SHADOW, 3, "RGB");
+ CHECK_PASS(REFLECT, 3, "RGB");
+ CHECK_PASS(REFRACT, 3, "RGB");
+ CHECK_PASS(INDEXOB, 1, "X");
+ CHECK_PASS(INDEXMA, 1, "X");
+ CHECK_PASS(MIST, 1, "Z");
+
+#undef CHECK_PASS
+}
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
new file mode 100644
index 00000000000..67bfd1bfdc7
--- /dev/null
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -0,0 +1,1603 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): 2004-2006, Blender Foundation, full recode
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/renderdatabase.c
+ * \ingroup render
+ */
+
+
+/*
+ * Storage, retrieval and query of render specific data.
+ *
+ * All data from a Blender scene is converted by the renderconverter/
+ * into a special format that is used by the render module to make
+ * images out of. These functions interface to the render-specific
+ * database.
+ *
+ * The blo{ha/ve/vl} arrays store pointers to blocks of 256 data
+ * entries each.
+ *
+ * The index of an entry is >>8 (the highest 24 * bits), to find an
+ * offset in a 256-entry block.
+ *
+ * - If the 256-entry block entry has an entry in the
+ * vertnodes/vlaknodes/bloha array of the current block, the i-th entry in
+ * that block is allocated to this entry.
+ *
+ * - If the entry has no block allocated for it yet, memory is
+ * allocated.
+ *
+ * The pointer to the correct entry is returned. Memory is guaranteed
+ * to exist (as long as the malloc does not break). Since guarded
+ * allocation is used, memory _must_ be available. Otherwise, an
+ * exit(0) would occur.
+ *
+ */
+
+#include <limits.h>
+#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+#include "BLI_hash.h"
+
+#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_listBase.h"
+#include "DNA_particle_types.h"
+
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+
+#include "RE_render_ext.h" /* externtex */
+
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "zbuf.h"
+
+/* ------------------------------------------------------------------------- */
+
+/* More dynamic allocation of options for render vertices and faces, so we don't
+ * have to reserve this space inside vertices.
+ * Important; vertices and faces, should have been created already (to get tables
+ * checked) that's a reason why the calls demand VertRen/VlakRen * as arg, not
+ * the index */
+
+/* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */
+#define RE_STRESS_ELEMS 1
+#define RE_RAD_ELEMS 4
+#define RE_STRAND_ELEMS 1
+#define RE_TANGENT_ELEMS 3
+#define RE_WINSPEED_ELEMS 4
+#define RE_MTFACE_ELEMS 1
+#define RE_MCOL_ELEMS 4
+#define RE_UV_ELEMS 2
+#define RE_VLAK_ORIGINDEX_ELEMS 1
+#define RE_VERT_ORIGINDEX_ELEMS 1
+#define RE_SURFNOR_ELEMS 3
+#define RE_RADFACE_ELEMS 1
+#define RE_SIMPLIFY_ELEMS 2
+#define RE_FACE_ELEMS 1
+#define RE_NMAP_TANGENT_ELEMS 16
+
+float *RE_vertren_get_stress(ObjectRen *obr, VertRen *ver, int verify)
+{
+ float *stress;
+ int nr= ver->index>>8;
+
+ stress= obr->vertnodes[nr].stress;
+ if (stress==NULL) {
+ if (verify)
+ stress= obr->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
+ else
+ return NULL;
+ }
+ return stress + (ver->index & 255)*RE_STRESS_ELEMS;
+}
+
+/* this one callocs! */
+float *RE_vertren_get_rad(ObjectRen *obr, VertRen *ver, int verify)
+{
+ float *rad;
+ int nr= ver->index>>8;
+
+ rad= obr->vertnodes[nr].rad;
+ if (rad==NULL) {
+ if (verify)
+ rad= obr->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
+ else
+ return NULL;
+ }
+ return rad + (ver->index & 255)*RE_RAD_ELEMS;
+}
+
+float *RE_vertren_get_strand(ObjectRen *obr, VertRen *ver, int verify)
+{
+ float *strand;
+ int nr= ver->index>>8;
+
+ strand= obr->vertnodes[nr].strand;
+ if (strand==NULL) {
+ if (verify)
+ strand= obr->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
+ else
+ return NULL;
+ }
+ return strand + (ver->index & 255)*RE_STRAND_ELEMS;
+}
+
+/* needs calloc */
+float *RE_vertren_get_tangent(ObjectRen *obr, VertRen *ver, int verify)
+{
+ float *tangent;
+ int nr= ver->index>>8;
+
+ tangent= obr->vertnodes[nr].tangent;
+ if (tangent==NULL) {
+ if (verify)
+ tangent= obr->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
+ else
+ return NULL;
+ }
+ return tangent + (ver->index & 255)*RE_TANGENT_ELEMS;
+}
+
+/* needs calloc! not all renderverts have them */
+/* also winspeed is exception, it is stored per instance */
+float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify)
+{
+ float *winspeed;
+ int totvector;
+
+ winspeed= obi->vectors;
+ if (winspeed==NULL) {
+ if (verify) {
+ totvector= obi->obr->totvert + obi->obr->totstrand;
+ winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
+ }
+ else
+ return NULL;
+ }
+ return winspeed + ver->index*RE_WINSPEED_ELEMS;
+}
+
+int *RE_vertren_get_origindex(ObjectRen *obr, VertRen *ver, int verify)
+{
+ int *origindex;
+ int nr= ver->index>>8;
+
+ origindex= obr->vertnodes[nr].origindex;
+ if (origindex==NULL) {
+ if (verify)
+ origindex= obr->vertnodes[nr].origindex= MEM_mallocN(256*RE_VERT_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
+ else
+ return NULL;
+ }
+ return origindex + (ver->index & 255)*RE_VERT_ORIGINDEX_ELEMS;
+}
+
+VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
+{
+ VertRen *v1= RE_findOrAddVert(obr, obr->totvert++);
+ float *fp1, *fp2;
+ int *int1, *int2;
+ int index= v1->index;
+
+ *v1= *ver;
+ v1->index= index;
+
+ fp1= RE_vertren_get_stress(obr, ver, 0);
+ if (fp1) {
+ fp2= RE_vertren_get_stress(obr, v1, 1);
+ memcpy(fp2, fp1, RE_STRESS_ELEMS*sizeof(float));
+ }
+ fp1= RE_vertren_get_rad(obr, ver, 0);
+ if (fp1) {
+ fp2= RE_vertren_get_rad(obr, v1, 1);
+ memcpy(fp2, fp1, RE_RAD_ELEMS*sizeof(float));
+ }
+ fp1= RE_vertren_get_strand(obr, ver, 0);
+ if (fp1) {
+ fp2= RE_vertren_get_strand(obr, v1, 1);
+ memcpy(fp2, fp1, RE_STRAND_ELEMS*sizeof(float));
+ }
+ fp1= RE_vertren_get_tangent(obr, ver, 0);
+ if (fp1) {
+ fp2= RE_vertren_get_tangent(obr, v1, 1);
+ memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float));
+ }
+ int1= RE_vertren_get_origindex(obr, ver, 0);
+ if (int1) {
+ int2= RE_vertren_get_origindex(obr, v1, 1);
+ memcpy(int2, int1, RE_VERT_ORIGINDEX_ELEMS*sizeof(int));
+ }
+ return v1;
+}
+
+VertRen *RE_findOrAddVert(ObjectRen *obr, int nr)
+{
+ VertTableNode *temp;
+ VertRen *v;
+ int a;
+
+ if (nr<0) {
+ printf("error in findOrAddVert: %d\n", nr);
+ return NULL;
+ }
+ a= nr>>8;
+
+ if (a>=obr->vertnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */
+ temp= obr->vertnodes;
+
+ obr->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(obr->vertnodeslen+TABLEINITSIZE), "vertnodes");
+ if (temp) memcpy(obr->vertnodes, temp, obr->vertnodeslen*sizeof(VertTableNode));
+ memset(obr->vertnodes+obr->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
+
+ obr->vertnodeslen+=TABLEINITSIZE;
+ if (temp) MEM_freeN(temp);
+ }
+
+ v= obr->vertnodes[a].vert;
+ if (v==NULL) {
+ int i;
+
+ v= (VertRen *)MEM_callocN(256*sizeof(VertRen), "findOrAddVert");
+ obr->vertnodes[a].vert= v;
+
+ for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) {
+ v[a].index= i;
+ }
+ }
+ v+= (nr & 255);
+ return v;
+}
+
+/* ------------------------------------------------------------------------ */
+
+MTFace *RE_vlakren_get_tface(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
+{
+ VlakTableNode *node;
+ int nr= vlr->index>>8, vlakindex= (vlr->index&255);
+ int index= (n<<8) + vlakindex;
+
+ node= &obr->vlaknodes[nr];
+
+ if (verify) {
+ if (n>=node->totmtface) {
+ MTFace *mtface= node->mtface;
+ int size= (n+1)*256;
+
+ node->mtface= MEM_callocN(size*sizeof(MTFace), "Vlak mtface");
+
+ if (mtface) {
+ size= node->totmtface*256;
+ memcpy(node->mtface, mtface, size*sizeof(MTFace));
+ MEM_freeN(mtface);
+ }
+
+ node->totmtface= n+1;
+ }
+ }
+ else {
+ if (n>=node->totmtface)
+ return NULL;
+
+ if (name) *name= obr->mtface[n];
+ }
+
+ return node->mtface + index;
+}
+
+MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
+{
+ VlakTableNode *node;
+ int nr= vlr->index>>8, vlakindex= (vlr->index&255);
+ int index= (n<<8) + vlakindex;
+
+ node= &obr->vlaknodes[nr];
+
+ if (verify) {
+ if (n>=node->totmcol) {
+ MCol *mcol= node->mcol;
+ int size= (n+1)*256;
+
+ node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Vlak mcol");
+
+ if (mcol) {
+ size= node->totmcol*256;
+ memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
+ MEM_freeN(mcol);
+ }
+
+ node->totmcol= n+1;
+ }
+ }
+ else {
+ if (n>=node->totmcol)
+ return NULL;
+
+ if (name) *name= obr->mcol[n];
+ }
+
+ return node->mcol + index*RE_MCOL_ELEMS;
+}
+
+int *RE_vlakren_get_origindex(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+ int *origindex;
+ int nr= vlak->index>>8;
+
+ origindex= obr->vlaknodes[nr].origindex;
+ if (origindex==NULL) {
+ if (verify)
+ origindex= obr->vlaknodes[nr].origindex= MEM_callocN(256*RE_VLAK_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
+ else
+ return NULL;
+ }
+ return origindex + (vlak->index & 255)*RE_VLAK_ORIGINDEX_ELEMS;
+}
+
+float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+ float *surfnor;
+ int nr= vlak->index>>8;
+
+ surfnor= obr->vlaknodes[nr].surfnor;
+ if (surfnor==NULL) {
+ if (verify)
+ surfnor= obr->vlaknodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table");
+ else
+ return NULL;
+ }
+ return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
+}
+
+float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int index, bool verify)
+{
+ float **tangents;
+ int nr= vlak->index>>8;
+
+ tangents = obr->vlaknodes[nr].tangent_arrays;
+
+ if (index + 1 > 8) {
+ return NULL;
+ }
+
+ index = index < 0 ? 0: index;
+
+ if (tangents[index] == NULL) {
+ if (verify) {
+ tangents[index] = MEM_callocN(256*RE_NMAP_TANGENT_ELEMS*sizeof(float), "tangent table");
+ }
+ else
+ return NULL;
+ }
+
+ return tangents[index] + (vlak->index & 255)*RE_NMAP_TANGENT_ELEMS;
+}
+
+RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+ RadFace **radface;
+ int nr= vlak->index>>8;
+
+ radface= obr->vlaknodes[nr].radface;
+ if (radface==NULL) {
+ if (verify)
+ radface = obr->vlaknodes[nr].radface= MEM_callocN(256 * RE_RADFACE_ELEMS * sizeof(void *), "radface table");
+ else
+ return NULL;
+ }
+ return radface + (vlak->index & 255)*RE_RADFACE_ELEMS;
+}
+
+VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
+{
+ VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
+ MTFace *mtface, *mtface1;
+ MCol *mcol, *mcol1;
+ float *surfnor, *surfnor1;
+ float *tangent, *tangent1;
+ int *origindex, *origindex1;
+ RadFace **radface, **radface1;
+ int i, index = vlr1->index;
+ char *name;
+
+ *vlr1= *vlr;
+ vlr1->index= index;
+
+ for (i=0; (mtface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)) != NULL; i++) {
+ mtface1= RE_vlakren_get_tface(obr, vlr1, i, &name, 1);
+ memcpy(mtface1, mtface, sizeof(MTFace)*RE_MTFACE_ELEMS);
+ }
+
+ for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)) != NULL; i++) {
+ mcol1= RE_vlakren_get_mcol(obr, vlr1, i, &name, 1);
+ memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS);
+ }
+
+ origindex= RE_vlakren_get_origindex(obr, vlr, 0);
+ if (origindex) {
+ origindex1= RE_vlakren_get_origindex(obr, vlr1, 1);
+ /* Just an int, but memcpy for consistency. */
+ memcpy(origindex1, origindex, sizeof(int)*RE_VLAK_ORIGINDEX_ELEMS);
+ }
+
+ surfnor= RE_vlakren_get_surfnor(obr, vlr, 0);
+ if (surfnor) {
+ surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1);
+ copy_v3_v3(surfnor1, surfnor);
+ }
+
+ for (i=0; i < MAX_MTFACE; i++) {
+ tangent = RE_vlakren_get_nmap_tangent(obr, vlr, i, false);
+ if (!tangent)
+ continue;
+ tangent1 = RE_vlakren_get_nmap_tangent(obr, vlr1, i, true);
+ memcpy(tangent1, tangent, sizeof(float)*RE_NMAP_TANGENT_ELEMS);
+ }
+
+ radface= RE_vlakren_get_radface(obr, vlr, 0);
+ if (radface) {
+ radface1= RE_vlakren_get_radface(obr, vlr1, 1);
+ *radface1= *radface;
+ }
+
+ return vlr1;
+}
+
+void RE_vlakren_get_normal(Render *UNUSED(re), ObjectInstanceRen *obi, VlakRen *vlr, float r_nor[3])
+{
+ float (*nmat)[3]= obi->nmat;
+
+ if (obi->flag & R_TRANSFORMED) {
+ mul_v3_m3v3(r_nor, nmat, vlr->n);
+ normalize_v3(r_nor);
+ }
+ else {
+ copy_v3_v3(r_nor, vlr->n);
+ }
+}
+
+void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
+{
+ /* CustomData layer names are stored per object here, because the
+ * DerivedMesh which stores the layers is freed */
+
+ CustomDataLayer *layer;
+ int numtf = 0, numcol = 0, i, mtfn, mcn;
+
+ if (CustomData_has_layer(data, CD_MTFACE)) {
+ numtf= CustomData_number_of_layers(data, CD_MTFACE);
+ obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numtf, "mtfacenames");
+ }
+
+ if (CustomData_has_layer(data, CD_MCOL)) {
+ numcol= CustomData_number_of_layers(data, CD_MCOL);
+ obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numcol, "mcolnames");
+ }
+
+ for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) {
+ layer= &data->layers[i];
+
+ if (layer->type == CD_MTFACE) {
+ BLI_strncpy(obr->mtface[mtfn++], layer->name, sizeof(layer->name));
+ obr->actmtface= CLAMPIS(layer->active_rnd, 0, numtf);
+ obr->bakemtface= layer->active;
+ }
+ else if (layer->type == CD_MCOL) {
+ BLI_strncpy(obr->mcol[mcn++], layer->name, sizeof(layer->name));
+ obr->actmcol= CLAMPIS(layer->active_rnd, 0, numcol);
+ }
+ }
+}
+
+VlakRen *RE_findOrAddVlak(ObjectRen *obr, int nr)
+{
+ VlakTableNode *temp;
+ VlakRen *v;
+ int a;
+
+ if (nr<0) {
+ printf("error in findOrAddVlak: %d\n", nr);
+ return obr->vlaknodes[0].vlak;
+ }
+ a= nr>>8;
+
+ if (a>=obr->vlaknodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */
+ temp= obr->vlaknodes;
+
+ obr->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(obr->vlaknodeslen+TABLEINITSIZE), "vlaknodes");
+ if (temp) memcpy(obr->vlaknodes, temp, obr->vlaknodeslen*sizeof(VlakTableNode));
+ memset(obr->vlaknodes+obr->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode));
+
+ obr->vlaknodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
+ if (temp) MEM_freeN(temp);
+ }
+
+ v= obr->vlaknodes[a].vlak;
+
+ if (v==NULL) {
+ int i;
+
+ v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen), "findOrAddVlak");
+ obr->vlaknodes[a].vlak= v;
+
+ for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
+ v[a].index= i;
+ }
+ v+= (nr & 255);
+ return v;
+}
+
+/* ------------------------------------------------------------------------ */
+
+float *RE_strandren_get_surfnor(ObjectRen *obr, StrandRen *strand, int verify)
+{
+ float *surfnor;
+ int nr= strand->index>>8;
+
+ surfnor= obr->strandnodes[nr].surfnor;
+ if (surfnor==NULL) {
+ if (verify)
+ surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor strand table");
+ else
+ return NULL;
+ }
+ return surfnor + (strand->index & 255)*RE_SURFNOR_ELEMS;
+}
+
+float *RE_strandren_get_uv(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
+{
+ StrandTableNode *node;
+ int nr= strand->index>>8, strandindex= (strand->index&255);
+ int index= (n<<8) + strandindex;
+
+ node= &obr->strandnodes[nr];
+
+ if (verify) {
+ if (n>=node->totuv) {
+ float *uv= node->uv;
+ int size= (n+1)*256;
+
+ node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "strand uv table");
+
+ if (uv) {
+ size= node->totuv*256;
+ memcpy(node->uv, uv, size*sizeof(float)*RE_UV_ELEMS);
+ MEM_freeN(uv);
+ }
+
+ node->totuv= n+1;
+ }
+ }
+ else {
+ if (n>=node->totuv)
+ return NULL;
+
+ if (name) *name= obr->mtface[n];
+ }
+
+ return node->uv + index*RE_UV_ELEMS;
+}
+
+MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
+{
+ StrandTableNode *node;
+ int nr= strand->index>>8, strandindex= (strand->index&255);
+ int index= (n<<8) + strandindex;
+
+ node= &obr->strandnodes[nr];
+
+ if (verify) {
+ if (n>=node->totmcol) {
+ MCol *mcol= node->mcol;
+ int size= (n+1)*256;
+
+ node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "strand mcol table");
+
+ if (mcol) {
+ size= node->totmcol*256;
+ memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
+ MEM_freeN(mcol);
+ }
+
+ node->totmcol= n+1;
+ }
+ }
+ else {
+ if (n>=node->totmcol)
+ return NULL;
+
+ if (name) *name= obr->mcol[n];
+ }
+
+ return node->mcol + index*RE_MCOL_ELEMS;
+}
+
+float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify)
+{
+ float *simplify;
+ int nr= strand->index>>8;
+
+ simplify= obr->strandnodes[nr].simplify;
+ if (simplify==NULL) {
+ if (verify)
+ simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify strand table");
+ else
+ return NULL;
+ }
+ return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS;
+}
+
+int *RE_strandren_get_face(ObjectRen *obr, StrandRen *strand, int verify)
+{
+ int *face;
+ int nr= strand->index>>8;
+
+ face= obr->strandnodes[nr].face;
+ if (face==NULL) {
+ if (verify)
+ face= obr->strandnodes[nr].face= MEM_callocN(256*RE_FACE_ELEMS*sizeof(int), "face strand table");
+ else
+ return NULL;
+ }
+ return face + (strand->index & 255)*RE_FACE_ELEMS;
+}
+
+/* winspeed is exception, it is stored per instance */
+float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify)
+{
+ float *winspeed;
+ int totvector;
+
+ winspeed= obi->vectors;
+ if (winspeed==NULL) {
+ if (verify) {
+ totvector= obi->obr->totvert + obi->obr->totstrand;
+ winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed strand table");
+ }
+ else
+ return NULL;
+ }
+ return winspeed + (obi->obr->totvert + strand->index)*RE_WINSPEED_ELEMS;
+}
+
+StrandRen *RE_findOrAddStrand(ObjectRen *obr, int nr)
+{
+ StrandTableNode *temp;
+ StrandRen *v;
+ int a;
+
+ if (nr<0) {
+ printf("error in findOrAddStrand: %d\n", nr);
+ return obr->strandnodes[0].strand;
+ }
+ a= nr>>8;
+
+ if (a>=obr->strandnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */
+ temp= obr->strandnodes;
+
+ obr->strandnodes= MEM_mallocN(sizeof(StrandTableNode)*(obr->strandnodeslen+TABLEINITSIZE), "strandnodes");
+ if (temp) memcpy(obr->strandnodes, temp, obr->strandnodeslen*sizeof(StrandTableNode));
+ memset(obr->strandnodes+obr->strandnodeslen, 0, TABLEINITSIZE*sizeof(StrandTableNode));
+
+ obr->strandnodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
+ if (temp) MEM_freeN(temp);
+ }
+
+ v= obr->strandnodes[a].strand;
+
+ if (v==NULL) {
+ int i;
+
+ v= (StrandRen *)MEM_callocN(256*sizeof(StrandRen), "findOrAddStrand");
+ obr->strandnodes[a].strand= v;
+
+ for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
+ v[a].index= i;
+ }
+ v+= (nr & 255);
+ return v;
+}
+
+StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
+{
+ StrandBuffer *strandbuf;
+
+ strandbuf= MEM_callocN(sizeof(StrandBuffer), "StrandBuffer");
+ strandbuf->vert= MEM_callocN(sizeof(StrandVert)*totvert, "StrandVert");
+ strandbuf->totvert= totvert;
+ strandbuf->obr= obr;
+
+ obr->strandbuf= strandbuf;
+
+ return strandbuf;
+}
+
+/* ------------------------------------------------------------------------ */
+
+ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay)
+{
+ ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct");
+
+ BLI_addtail(&re->objecttable, obr);
+ obr->ob= ob;
+ obr->par= par;
+ obr->index= index;
+ obr->psysindex= psysindex;
+ obr->lay= lay;
+
+ return obr;
+}
+
+void free_renderdata_vertnodes(VertTableNode *vertnodes)
+{
+ int a;
+
+ if (vertnodes==NULL) return;
+
+ for (a=0; vertnodes[a].vert; a++) {
+ MEM_freeN(vertnodes[a].vert);
+
+ if (vertnodes[a].rad)
+ MEM_freeN(vertnodes[a].rad);
+ if (vertnodes[a].strand)
+ MEM_freeN(vertnodes[a].strand);
+ if (vertnodes[a].tangent)
+ MEM_freeN(vertnodes[a].tangent);
+ if (vertnodes[a].stress)
+ MEM_freeN(vertnodes[a].stress);
+ if (vertnodes[a].winspeed)
+ MEM_freeN(vertnodes[a].winspeed);
+ if (vertnodes[a].origindex)
+ MEM_freeN(vertnodes[a].origindex);
+ }
+
+ MEM_freeN(vertnodes);
+}
+
+void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
+{
+ int a;
+
+ if (vlaknodes==NULL) return;
+
+ for (a=0; vlaknodes[a].vlak; a++) {
+ MEM_freeN(vlaknodes[a].vlak);
+
+ if (vlaknodes[a].mtface)
+ MEM_freeN(vlaknodes[a].mtface);
+ if (vlaknodes[a].mcol)
+ MEM_freeN(vlaknodes[a].mcol);
+ if (vlaknodes[a].origindex)
+ MEM_freeN(vlaknodes[a].origindex);
+ if (vlaknodes[a].surfnor)
+ MEM_freeN(vlaknodes[a].surfnor);
+ for (int b = 0; b < MAX_MTFACE; b++) {
+ if (vlaknodes[a].tangent_arrays[b])
+ MEM_freeN(vlaknodes[a].tangent_arrays[b]);
+ }
+ if (vlaknodes[a].radface)
+ MEM_freeN(vlaknodes[a].radface);
+ }
+
+ MEM_freeN(vlaknodes);
+}
+
+static void free_renderdata_strandnodes(StrandTableNode *strandnodes)
+{
+ int a;
+
+ if (strandnodes==NULL) return;
+
+ for (a=0; strandnodes[a].strand; a++) {
+ MEM_freeN(strandnodes[a].strand);
+
+ if (strandnodes[a].uv)
+ MEM_freeN(strandnodes[a].uv);
+ if (strandnodes[a].mcol)
+ MEM_freeN(strandnodes[a].mcol);
+ if (strandnodes[a].winspeed)
+ MEM_freeN(strandnodes[a].winspeed);
+ if (strandnodes[a].surfnor)
+ MEM_freeN(strandnodes[a].surfnor);
+ if (strandnodes[a].simplify)
+ MEM_freeN(strandnodes[a].simplify);
+ if (strandnodes[a].face)
+ MEM_freeN(strandnodes[a].face);
+ }
+
+ MEM_freeN(strandnodes);
+}
+
+void free_renderdata_tables(Render *re)
+{
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ StrandBuffer *strandbuf;
+ int a=0;
+
+ for (obr=re->objecttable.first; obr; obr=obr->next) {
+ if (obr->vertnodes) {
+ free_renderdata_vertnodes(obr->vertnodes);
+ obr->vertnodes= NULL;
+ obr->vertnodeslen= 0;
+ }
+
+ if (obr->vlaknodes) {
+ free_renderdata_vlaknodes(obr->vlaknodes);
+ obr->vlaknodes= NULL;
+ obr->vlaknodeslen= 0;
+ obr->totvlak= 0;
+ }
+
+ if (obr->bloha) {
+ for (a=0; obr->bloha[a]; a++)
+ MEM_freeN(obr->bloha[a]);
+
+ MEM_freeN(obr->bloha);
+ obr->bloha= NULL;
+ obr->blohalen= 0;
+ }
+
+ if (obr->strandnodes) {
+ free_renderdata_strandnodes(obr->strandnodes);
+ obr->strandnodes= NULL;
+ obr->strandnodeslen= 0;
+ }
+
+ strandbuf= obr->strandbuf;
+ if (strandbuf) {
+ if (strandbuf->vert) MEM_freeN(strandbuf->vert);
+ if (strandbuf->bound) MEM_freeN(strandbuf->bound);
+ MEM_freeN(strandbuf);
+ }
+
+ if (obr->mtface)
+ MEM_freeN(obr->mtface);
+
+ if (obr->mcol)
+ MEM_freeN(obr->mcol);
+
+ if (obr->rayfaces) {
+ MEM_freeN(obr->rayfaces);
+ obr->rayfaces = NULL;
+ }
+
+ if (obr->rayprimitives) {
+ MEM_freeN(obr->rayprimitives);
+ obr->rayprimitives = NULL;
+ }
+
+ if (obr->raytree) {
+ RE_rayobject_free(obr->raytree);
+ obr->raytree = NULL;
+ }
+ }
+
+ if (re->objectinstance) {
+ for (obi=re->instancetable.first; obi; obi=obi->next) {
+ if (obi->vectors)
+ MEM_freeN(obi->vectors);
+
+ if (obi->raytree)
+ RE_rayobject_free(obi->raytree);
+ }
+
+ MEM_freeN(re->objectinstance);
+ re->objectinstance= NULL;
+ re->totinstance= 0;
+ re->instancetable.first= re->instancetable.last= NULL;
+ }
+
+ if (re->sortedhalos) {
+ MEM_freeN(re->sortedhalos);
+ re->sortedhalos= NULL;
+ }
+
+ BLI_freelistN(&re->customdata_names);
+ BLI_freelistN(&re->objecttable);
+ BLI_freelistN(&re->instancetable);
+}
+
+/* ------------------------------------------------------------------------ */
+
+HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr)
+{
+ HaloRen *h, **temp;
+ int a;
+
+ if (nr<0) {
+ printf("error in findOrAddHalo: %d\n", nr);
+ return NULL;
+ }
+ a= nr>>8;
+
+ if (a>=obr->blohalen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */
+ //printf("Allocating %i more halo groups. %i total.\n",
+ // TABLEINITSIZE, obr->blohalen+TABLEINITSIZE );
+ temp=obr->bloha;
+
+ obr->bloha = (HaloRen **)MEM_callocN(sizeof(void *) * (obr->blohalen + TABLEINITSIZE), "Bloha");
+ if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void *));
+ memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE * sizeof(void *));
+ obr->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
+ if (temp) MEM_freeN(temp);
+ }
+
+ h= obr->bloha[a];
+ if (h==NULL) {
+ h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen), "findOrAdHalo");
+ obr->bloha[a]= h;
+ }
+ h+= (nr & 255);
+ return h;
+}
+
+/* ------------------------------------------------------------------------- */
+
+HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
+ const float vec[3], const float vec1[3],
+ const float *orco, float hasize, float vectsize, int seed)
+{
+ const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
+ const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0;
+ HaloRen *har;
+ MTex *mtex;
+ float tin, tr, tg, tb, ta;
+ float xn, yn, zn, texvec[3], hoco[4], hoco1[4];
+
+ if (hasize==0.0f) return NULL;
+
+ projectverto(vec, re->winmat, hoco);
+ if (hoco[3]==0.0f) return NULL;
+ if (vec1) {
+ projectverto(vec1, re->winmat, hoco1);
+ if (hoco1[3]==0.0f) return NULL;
+ }
+
+ har= RE_findOrAddHalo(obr, obr->tothalo++);
+ copy_v3_v3(har->co, vec);
+ har->hasize= hasize;
+
+ /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
+ /* we do it here for sorting of halos */
+ zn= hoco[3];
+ har->xs= 0.5f*re->winx*(hoco[0]/zn);
+ har->ys= 0.5f*re->winy*(hoco[1]/zn);
+ har->zs= 0x7FFFFF*(hoco[2]/zn);
+
+ har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
+
+ /* halovect */
+ if (vec1) {
+
+ har->type |= HA_VECT;
+
+ xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]);
+ yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]);
+ if (yn == 0.0f && xn >= 0.0f) zn = 0.0f;
+ else zn = atan2f(yn, xn);
+
+ har->sin = sinf(zn);
+ har->cos = cosf(zn);
+ zn= len_v3v3(vec1, vec);
+
+ har->hasize= vectsize*zn + (1.0f-vectsize)*hasize;
+
+ sub_v3_v3v3(har->no, vec, vec1);
+ normalize_v3(har->no);
+ }
+
+ if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
+
+ har->alfa= ma->alpha;
+ har->r= ma->r;
+ har->g= ma->g;
+ har->b= ma->b;
+ har->add= (255.0f*ma->add);
+ har->mat= ma;
+ har->hard= ma->har;
+ har->seed= seed % 256;
+
+ if (ma->mode & MA_STAR) har->starpoints= ma->starc;
+ if (ma->mode & MA_HALO_LINES) har->linec= ma->linec;
+ if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
+ if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
+
+
+ if (ma->mtex[0]) {
+
+ if (ma->mode & MA_HALOTEX) {
+ har->tex = 1;
+ }
+ else if (har->mat->septex & (1 << 0)) {
+ /* only 1 level textures */
+ }
+ else {
+ mtex= ma->mtex[0];
+ copy_v3_v3(texvec, vec);
+
+ if (mtex->texco & TEXCO_NORM) {
+ ;
+ }
+ else if (mtex->texco & TEXCO_OBJECT) {
+ /* texvec[0]+= imatbase->ivec[0]; */
+ /* texvec[1]+= imatbase->ivec[1]; */
+ /* texvec[2]+= imatbase->ivec[2]; */
+ /* mul_m3_v3(imatbase->imat, texvec); */
+ }
+ else {
+ if (orco) {
+ copy_v3_v3(texvec, orco);
+ }
+ }
+
+ externtex(mtex,
+ texvec,
+ &tin, &tr, &tg, &tb, &ta,
+ 0,
+ re->pool,
+ skip_load_image,
+ texnode_preview);
+
+ yn= tin*mtex->colfac;
+ //zn= tin*mtex->alphafac;
+
+ if (mtex->mapto & MAP_COL) {
+ zn= 1.0f-yn;
+ har->r= (yn*tr+ zn*ma->r);
+ har->g= (yn*tg+ zn*ma->g);
+ har->b= (yn*tb+ zn*ma->b);
+ }
+ if (mtex->texco & TEXCO_UV) {
+ har->alfa= tin;
+ }
+ if (mtex->mapto & MAP_ALPHA)
+ har->alfa= tin;
+ }
+ }
+
+ har->pool = re->pool;
+ har->skip_load_image = skip_load_image;
+ har->texnode_preview = texnode_preview;
+
+ return har;
+}
+
+HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma,
+ const float vec[3], const float vec1[3],
+ const float *orco, const float *uvco, float hasize, float vectsize, int seed, const float pa_co[3])
+{
+ const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
+ const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0;
+ HaloRen *har;
+ MTex *mtex;
+ float tin, tr, tg, tb, ta;
+ float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3], tex[3], out[3];
+ int i, hasrgb;
+
+ if (hasize==0.0f) return NULL;
+
+ projectverto(vec, re->winmat, hoco);
+ if (hoco[3]==0.0f) return NULL;
+ if (vec1) {
+ projectverto(vec1, re->winmat, hoco1);
+ if (hoco1[3]==0.0f) return NULL;
+ }
+
+ har= RE_findOrAddHalo(obr, obr->tothalo++);
+ copy_v3_v3(har->co, vec);
+ har->hasize= hasize;
+
+ /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
+ /* we do it here for sorting of halos */
+ zn= hoco[3];
+ har->xs= 0.5f*re->winx*(hoco[0]/zn);
+ har->ys= 0.5f*re->winy*(hoco[1]/zn);
+ har->zs= 0x7FFFFF*(hoco[2]/zn);
+
+ har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
+
+ /* halovect */
+ if (vec1) {
+
+ har->type |= HA_VECT;
+
+ xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]);
+ yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]);
+ if (yn == 0.0f && xn >= 0.0f) zn = 0.0f;
+ else zn = atan2f(yn, xn);
+
+ har->sin = sinf(zn);
+ har->cos = cosf(zn);
+ zn= len_v3v3(vec1, vec)*0.5f;
+
+ har->hasize= vectsize*zn + (1.0f-vectsize)*hasize;
+
+ sub_v3_v3v3(har->no, vec, vec1);
+ normalize_v3(har->no);
+ }
+
+ if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
+
+ har->alfa= ma->alpha;
+ har->r= ma->r;
+ har->g= ma->g;
+ har->b= ma->b;
+ har->add= (255.0f*ma->add);
+ har->mat= ma;
+ har->hard= ma->har;
+ har->seed= seed % 256;
+
+ if (ma->mode & MA_STAR) har->starpoints= ma->starc;
+ if (ma->mode & MA_HALO_LINES) har->linec= ma->linec;
+ if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
+ if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
+
+ if ((ma->mode & MA_HALOTEX) && ma->mtex[0])
+ har->tex= 1;
+
+ for (i=0; i<MAX_MTEX; i++)
+ if (ma->mtex[i] && (ma->septex & (1<<i))==0) {
+ mtex= ma->mtex[i];
+ copy_v3_v3(texvec, vec);
+
+ if (mtex->texco & TEXCO_NORM) {
+ ;
+ }
+ else if (mtex->texco & TEXCO_OBJECT) {
+ if (mtex->object)
+ mul_m4_v3(mtex->object->imat_ren, texvec);
+ }
+ else if (mtex->texco & TEXCO_GLOB) {
+ copy_v3_v3(texvec, vec);
+ }
+ else if (mtex->texco & TEXCO_UV && uvco) {
+ int uv_index=CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, mtex->uvname);
+ if (uv_index<0)
+ uv_index=CustomData_get_active_layer_index(&dm->faceData, CD_MTFACE);
+
+ uv_index-=CustomData_get_layer_index(&dm->faceData, CD_MTFACE);
+
+ texvec[0]=2.0f*uvco[2*uv_index]-1.0f;
+ texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f;
+ texvec[2]=0.0f;
+ }
+ else if (mtex->texco & TEXCO_PARTICLE) {
+ /* particle coordinates in range [0, 1] */
+ texvec[0] = 2.f * pa_co[0] - 1.f;
+ texvec[1] = 2.f * pa_co[1] - 1.f;
+ texvec[2] = pa_co[2];
+ }
+ else if (orco) {
+ copy_v3_v3(texvec, orco);
+ }
+
+ hasrgb = externtex(mtex,
+ texvec,
+ &tin, &tr, &tg, &tb, &ta,
+ 0,
+ re->pool,
+ skip_load_image,
+ texnode_preview);
+
+ //yn= tin*mtex->colfac;
+ //zn= tin*mtex->alphafac;
+ if (mtex->mapto & MAP_COL) {
+ tex[0]=tr;
+ tex[1]=tg;
+ tex[2]=tb;
+ out[0]=har->r;
+ out[1]=har->g;
+ out[2]=har->b;
+
+ texture_rgb_blend(in, tex, out, tin, mtex->colfac, mtex->blendtype);
+ // zn= 1.0-yn;
+ //har->r= (yn*tr+ zn*ma->r);
+ //har->g= (yn*tg+ zn*ma->g);
+ //har->b= (yn*tb+ zn*ma->b);
+ har->r= in[0];
+ har->g= in[1];
+ har->b= in[2];
+ }
+
+ /* alpha returned, so let's use it instead of intensity */
+ if (hasrgb)
+ tin = ta;
+
+ if (mtex->mapto & MAP_ALPHA)
+ har->alfa = texture_value_blend(mtex->def_var, har->alfa, tin, mtex->alphafac, mtex->blendtype);
+ if (mtex->mapto & MAP_HAR)
+ har->hard = 1.0f+126.0f*texture_value_blend(mtex->def_var, ((float)har->hard)/127.0f, tin, mtex->hardfac, mtex->blendtype);
+ if (mtex->mapto & MAP_RAYMIRR)
+ har->hasize = 100.0f*texture_value_blend(mtex->def_var, har->hasize/100.0f, tin, mtex->raymirrfac, mtex->blendtype);
+ if (mtex->mapto & MAP_TRANSLU) {
+ float add = texture_value_blend(mtex->def_var, (float)har->add/255.0f, tin, mtex->translfac, mtex->blendtype);
+ CLAMP(add, 0.f, 1.f);
+ har->add = 255.0f*add;
+ }
+ /* now what on earth is this good for?? */
+ //if (mtex->texco & 16) {
+ // har->alfa= tin;
+ //}
+ }
+
+ har->pool = re->pool;
+ har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
+ har->texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0;
+
+ return har;
+}
+
+/* -------------------------- operations on entire database ----------------------- */
+
+/* ugly function for halos in panorama */
+static int panotestclip(Render *re, bool do_pano, float v[4])
+{
+ /* part size (ensure we run RE_parts_clamp first) */
+ BLI_assert(re->partx == min_ii(re->r.tilex, re->rectx));
+ BLI_assert(re->party == min_ii(re->r.tiley, re->recty));
+
+ if (do_pano == false) {
+ return testclip(v);
+ }
+ else {
+ /* to be used for halos en infos */
+ float abs4;
+ short c = 0;
+
+ int xparts = (re->rectx + re->partx - 1) / re->partx;
+
+ abs4= fabsf(v[3]);
+
+ if (v[2]< -abs4) c=16; /* this used to be " if (v[2]<0) ", see clippz() */
+ else if (v[2]> abs4) c+= 32;
+
+ if ( v[1]>abs4) c+=4;
+ else if ( v[1]< -abs4) c+=8;
+
+ abs4*= xparts;
+ if ( v[0]>abs4) c+=2;
+ else if ( v[0]< -abs4) c+=1;
+
+ return c;
+ }
+}
+
+/**
+ * This adds the hcs coordinates to vertices. It iterates over all
+ * vertices, halos and faces. After the conversion, we clip in hcs.
+ *
+ * Elsewhere, all primites are converted to vertices.
+ * Called in
+ * - envmapping (envmap.c)
+ * - shadow buffering (shadbuf.c)
+ */
+
+void project_renderdata(Render *re,
+ void (*projectfunc)(const float *, float mat[4][4], float *),
+ bool do_pano, float xoffs, bool UNUSED(do_buckets))
+{
+ ObjectRen *obr;
+ HaloRen *har = NULL;
+ float zn, vec[3], hoco[4];
+ int a;
+
+ if (do_pano) {
+ float panophi= xoffs;
+
+ re->panosi = sinf(panophi);
+ re->panoco = cosf(panophi);
+ }
+
+ for (obr=re->objecttable.first; obr; obr=obr->next) {
+ /* calculate view coordinates (and zbuffer value) */
+ for (a=0; a<obr->tothalo; a++) {
+ if ((a & 255)==0) har= obr->bloha[a>>8];
+ else har++;
+
+ if (do_pano) {
+ vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2];
+ vec[1]= har->co[1];
+ vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2];
+ }
+ else {
+ copy_v3_v3(vec, har->co);
+ }
+
+ projectfunc(vec, re->winmat, hoco);
+
+ /* we clip halos less critical, but not for the Z */
+ hoco[0]*= 0.5f;
+ hoco[1]*= 0.5f;
+
+ if ( panotestclip(re, do_pano, hoco) ) {
+ har->miny= har->maxy= -10000; /* that way render clips it */
+ }
+ else if (hoco[3]<0.0f) {
+ har->miny= har->maxy= -10000; /* render clips it */
+ }
+ else { /* do the projection...*/
+ /* bring back hocos */
+ hoco[0]*= 2.0f;
+ hoco[1]*= 2.0f;
+
+ zn= hoco[3];
+ har->xs= 0.5f*re->winx*(1.0f+hoco[0]/zn); /* the 0.5 negates the previous 2...*/
+ har->ys= 0.5f*re->winy*(1.0f+hoco[1]/zn);
+
+ /* this should be the zbuffer coordinate */
+ har->zs= 0x7FFFFF*(hoco[2]/zn);
+ /* taking this from the face clip functions? seems ok... */
+ har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
+
+ vec[0]+= har->hasize;
+ projectfunc(vec, re->winmat, hoco);
+ vec[0]-= har->hasize;
+ zn= hoco[3];
+ har->rad= fabsf(har->xs- 0.5f*re->winx*(1.0f+hoco[0]/zn));
+
+ /* this clip is not really OK, to prevent stars to become too large */
+ if (har->type & HA_ONLYSKY) {
+ if (har->rad>3.0f) har->rad= 3.0f;
+ }
+
+ har->radsq= har->rad*har->rad;
+
+ har->miny= har->ys - har->rad/re->ycor;
+ har->maxy= har->ys + har->rad/re->ycor;
+
+ /* the Zd value is still not really correct for pano */
+
+ vec[2] -= har->hasize; /* z negative, otherwise it's clipped */
+ projectfunc(vec, re->winmat, hoco);
+ zn = hoco[3];
+ zn = fabsf((float)har->zs - 0x7FFFFF * (hoco[2] / zn));
+ har->zd = CLAMPIS(zn, 0, INT_MAX);
+
+ }
+
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+void RE_updateRenderInstance(Render *re, ObjectInstanceRen *obi, int flag)
+{
+ /* flag specifies what things have changed. */
+ if (flag & RE_OBJECT_INSTANCES_UPDATE_OBMAT) {
+ copy_m4_m4(obi->obmat, obi->ob->obmat);
+ invert_m4_m4(obi->obinvmat, obi->obmat);
+ }
+ if (flag & RE_OBJECT_INSTANCES_UPDATE_VIEW) {
+ mul_m4_m4m4(obi->localtoviewmat, re->viewmat, obi->obmat);
+ mul_m4_m4m4(obi->localtoviewinvmat, obi->obinvmat, re->viewinv);
+ }
+}
+
+void RE_updateRenderInstances(Render *re, int flag)
+{
+ int i = 0;
+ for (i = 0; i < re->totinstance; i++)
+ RE_updateRenderInstance(re, &re->objectinstance[i], flag);
+}
+
+ObjectInstanceRen *RE_addRenderInstance(
+ Render *re, ObjectRen *obr, Object *ob, Object *par,
+ int index, int psysindex, float mat[4][4], int lay, const DupliObject *dob)
+{
+ ObjectInstanceRen *obi;
+ float mat3[3][3];
+
+ obi= MEM_callocN(sizeof(ObjectInstanceRen), "ObjectInstanceRen");
+ obi->obr= obr;
+ obi->ob= ob;
+ obi->par= par;
+ obi->index= index;
+ obi->psysindex= psysindex;
+ obi->lay= lay;
+
+ /* Fill particle info */
+ if (par && dob) {
+ const ParticleSystem *psys = dob->particle_system;
+ if (psys) {
+ int part_index;
+ if (obi->index < psys->totpart) {
+ part_index = obi->index;
+ }
+ else if (psys->child) {
+ part_index = psys->child[obi->index - psys->totpart].parent;
+ }
+ else {
+ part_index = -1;
+ }
+
+ if (part_index >= 0) {
+ const ParticleData *p = &psys->particles[part_index];
+ obi->part_index = part_index;
+ obi->part_size = p->size;
+ obi->part_age = RE_GetStats(re)->cfra - p->time;
+ obi->part_lifetime = p->lifetime;
+
+ copy_v3_v3(obi->part_co, p->state.co);
+ copy_v3_v3(obi->part_vel, p->state.vel);
+ copy_v3_v3(obi->part_avel, p->state.ave);
+ }
+ }
+ }
+
+ /* Fill object info */
+ if (dob) {
+ obi->random_id = dob->random_id;
+ }
+ else {
+ obi->random_id = BLI_hash_int_2d(BLI_hash_string(obi->ob->id.name + 2), 0);
+ }
+
+ RE_updateRenderInstance(re, obi, RE_OBJECT_INSTANCES_UPDATE_OBMAT | RE_OBJECT_INSTANCES_UPDATE_VIEW);
+
+ if (mat) {
+ copy_m4_m4(obi->mat, mat);
+ copy_m3_m4(mat3, mat);
+ invert_m3_m3(obi->nmat, mat3);
+ transpose_m3(obi->nmat);
+ obi->flag |= R_DUPLI_TRANSFORMED;
+ }
+
+ BLI_addtail(&re->instancetable, obi);
+
+ return obi;
+}
+
+void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3])
+{
+ *index = obi->part_index;
+ *random = BLI_hash_int_01(obi->part_index);
+ *age = obi->part_age;
+ *lifetime = obi->part_lifetime;
+ copy_v3_v3(co, obi->part_co);
+ *size = obi->part_size;
+ copy_v3_v3(vel, obi->part_vel);
+ copy_v3_v3(angvel, obi->part_avel);
+}
+
+
+void RE_makeRenderInstances(Render *re)
+{
+ ObjectInstanceRen *obi, *oldobi;
+ ListBase newlist;
+ int tot;
+
+ /* convert list of object instances to an array for index based lookup */
+ tot= BLI_listbase_count(&re->instancetable);
+ re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance");
+ re->totinstance= tot;
+ newlist.first= newlist.last= NULL;
+
+ obi= re->objectinstance;
+ for (oldobi=re->instancetable.first; oldobi; oldobi=oldobi->next) {
+ *obi= *oldobi;
+
+ if (obi->obr) {
+ obi->prev= obi->next= NULL;
+ BLI_addtail(&newlist, obi);
+ obi++;
+ }
+ else
+ re->totinstance--;
+ }
+
+ BLI_freelistN(&re->instancetable);
+ re->instancetable= newlist;
+}
+
+/* four functions to facilitate envmap rotation for raytrace */
+void RE_instance_rotate_ray_start(ObjectInstanceRen *obi, Isect *is)
+{
+ if (obi && (obi->flag & R_ENV_TRANSFORMED)) {
+ copy_v3_v3(is->origstart, is->start);
+ mul_m4_v3(obi->imat, is->start);
+ }
+}
+
+void RE_instance_rotate_ray_dir(ObjectInstanceRen *obi, Isect *is)
+{
+ if (obi && (obi->flag & R_ENV_TRANSFORMED)) {
+ float end[3];
+
+ copy_v3_v3(is->origdir, is->dir);
+ add_v3_v3v3(end, is->origstart, is->dir);
+
+ mul_m4_v3(obi->imat, end);
+ sub_v3_v3v3(is->dir, end, is->start);
+ }
+}
+
+void RE_instance_rotate_ray(ObjectInstanceRen *obi, Isect *is)
+{
+ RE_instance_rotate_ray_start(obi, is);
+ RE_instance_rotate_ray_dir(obi, is);
+}
+
+void RE_instance_rotate_ray_restore(ObjectInstanceRen *obi, Isect *is)
+{
+ if (obi && (obi->flag & R_ENV_TRANSFORMED)) {
+ copy_v3_v3(is->start, is->origstart);
+ copy_v3_v3(is->dir, is->origdir);
+ }
+}
+
+int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4])
+{
+ float mat[4][4], vec[4];
+ int a, fl, flag = -1;
+
+ copy_m4_m4(mat, winmat);
+
+ for (a=0; a < 8; a++) {
+ vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0];
+ vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1];
+ vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2];
+ vec[3]= 1.0;
+ mul_m4_v4(mat, vec);
+
+ fl = 0;
+ if (bounds) {
+ if (vec[0] < bounds[0] * vec[3]) fl |= 1;
+ else if (vec[0] > bounds[1] * vec[3]) fl |= 2;
+
+ if (vec[1] > bounds[3] * vec[3]) fl |= 4;
+ else if (vec[1] < bounds[2] * vec[3]) fl |= 8;
+ }
+ else {
+ if (vec[0] < -vec[3]) fl |= 1;
+ else if (vec[0] > vec[3]) fl |= 2;
+
+ if (vec[1] > vec[3]) fl |= 4;
+ else if (vec[1] < -vec[3]) fl |= 8;
+ }
+ if (vec[2] < -vec[3]) fl |= 16;
+ else if (vec[2] > vec[3]) fl |= 32;
+
+ flag &= fl;
+ if (flag == 0) {
+ return 0;
+ }
+ }
+
+ return flag;
+}
+
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
new file mode 100644
index 00000000000..04e9177241b
--- /dev/null
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -0,0 +1,2647 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): 2004-2006, Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/shadbuf.c
+ * \ingroup render
+ */
+
+
+#include <math.h>
+#include <string.h>
+
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_group_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_jitter_2d.h"
+#include "BLI_memarena.h"
+#include "BLI_rand.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_global.h"
+#include "BKE_scene.h"
+
+#include "PIL_time.h"
+
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "rendercore.h"
+#include "shadbuf.h"
+#include "shading.h"
+#include "zbuf.h"
+
+/* XXX, could be better implemented... this is for endian issues */
+#ifdef __BIG_ENDIAN__
+//# define RCOMP 3
+# define GCOMP 2
+# define BCOMP 1
+# define ACOMP 0
+#else
+//# define RCOMP 0
+# define GCOMP 1
+# define BCOMP 2
+# define ACOMP 3
+#endif
+
+#define RCT_SIZE_X(rct) ((rct)->xmax - (rct)->xmin)
+#define RCT_SIZE_Y(rct) ((rct)->ymax - (rct)->ymin)
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+/* ------------------------------------------------------------------------- */
+
+/* initshadowbuf() in convertBlenderScene.c */
+
+/* ------------------------------------------------------------------------- */
+
+static void copy_to_ztile(int *rectz, int size, int x1, int y1, int tile, char *r1)
+{
+ int len4, *rz;
+ int x2, y2;
+
+ x2= x1+tile;
+ y2= y1+tile;
+ if (x2>=size) x2= size-1;
+ if (y2>=size) y2= size-1;
+
+ if (x1>=x2 || y1>=y2) return;
+
+ len4= 4*(x2- x1);
+ rz= rectz + size*y1 + x1;
+ for (; y1<y2; y1++) {
+ memcpy(r1, rz, len4);
+ rz+= size;
+ r1+= len4;
+ }
+}
+
+#if 0
+static int sizeoflampbuf(ShadBuf *shb)
+{
+ int num, count=0;
+ char *cp;
+
+ cp= shb->cbuf;
+ num= (shb->size*shb->size)/256;
+
+ while (num--) count+= *(cp++);
+
+ return 256*count;
+}
+#endif
+
+/* not threadsafe... */
+static float *give_jitter_tab(int samp)
+{
+ /* these are all possible jitter tables, takes up some
+ * 12k, not really bad!
+ * For soft shadows, it saves memory and render time
+ */
+ static int tab[17]={1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256};
+ static float jit[1496][2];
+ static char ctab[17]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ int a, offset=0;
+
+ if (samp<2) samp= 2;
+ else if (samp>16) samp= 16;
+
+ for (a=0; a<samp-1; a++) offset+= tab[a];
+
+ if (ctab[samp]==0) {
+ ctab[samp]= 1;
+ BLI_jitter_init((float (*)[2])jit[offset], samp*samp);
+ }
+
+ return jit[offset];
+
+}
+
+static void make_jitter_weight_tab(Render *re, ShadBuf *shb, short filtertype)
+{
+ float *jit, totw= 0.0f;
+ int samp= get_render_shadow_samples(&re->r, shb->samp);
+ int a, tot=samp*samp;
+
+ shb->weight= MEM_mallocN(sizeof(float)*tot, "weight tab lamp");
+
+ for (jit= shb->jit, a=0; a<tot; a++, jit+=2) {
+ if (filtertype==LA_SHADBUF_TENT)
+ shb->weight[a] = 0.71f - sqrtf(jit[0] * jit[0] + jit[1] * jit[1]);
+ else if (filtertype==LA_SHADBUF_GAUSS)
+ shb->weight[a] = RE_filter_value(R_FILTER_GAUSS, 1.8f * sqrtf(jit[0] * jit[0] + jit[1] * jit[1]));
+ else
+ shb->weight[a]= 1.0f;
+
+ totw+= shb->weight[a];
+ }
+
+ totw= 1.0f/totw;
+ for (a=0; a<tot; a++) {
+ shb->weight[a]*= totw;
+ }
+}
+
+static int verg_deepsample(const void *poin1, const void *poin2)
+{
+ const DeepSample *ds1= (const DeepSample*)poin1;
+ const DeepSample *ds2= (const DeepSample*)poin2;
+
+ if (ds1->z < ds2->z) return -1;
+ else if (ds1->z == ds2->z) return 0;
+ else return 1;
+}
+
+static int compress_deepsamples(DeepSample *dsample, int tot, float epsilon)
+{
+ /* uses doubles to avoid overflows and other numerical issues,
+ * could be improved */
+ DeepSample *ds, *newds;
+ float v;
+ double slope, slopemin, slopemax, min, max, div, newmin, newmax;
+ int a, first, z, newtot= 0;
+
+#if 0
+ if (print) {
+ for (a=0, ds=dsample; a<tot; a++, ds++)
+ printf("%lf, %f ", ds->z/(double)0x7FFFFFFF, ds->v);
+ printf("\n");
+ }
+#endif
+
+ /* read from and write into same array */
+ ds= dsample;
+ newds= dsample;
+ a= 0;
+
+ /* as long as we are not at the end of the array */
+ for (a++, ds++; a<tot; a++, ds++) {
+ slopemin= 0.0f;
+ slopemax= 0.0f;
+ first= 1;
+
+ for (; a<tot; a++, ds++) {
+ //dz= ds->z - newds->z;
+ if (ds->z == newds->z) {
+ /* still in same z position, simply check
+ * visibility difference against epsilon */
+ if (!(fabsf(newds->v - ds->v) <= epsilon)) {
+ break;
+ }
+ }
+ else {
+ /* compute slopes */
+ div= (double)0x7FFFFFFF / ((double)ds->z - (double)newds->z);
+ min= (double)((ds->v - epsilon) - newds->v) * div;
+ max= (double)((ds->v + epsilon) - newds->v) * div;
+
+ /* adapt existing slopes */
+ if (first) {
+ newmin= min;
+ newmax= max;
+ first= 0;
+ }
+ else {
+ newmin= MAX2(slopemin, min);
+ newmax= MIN2(slopemax, max);
+
+ /* verify if there is still space between the slopes */
+ if (newmin > newmax) {
+ ds--;
+ a--;
+ break;
+ }
+ }
+
+ slopemin= newmin;
+ slopemax= newmax;
+ }
+ }
+
+ if (a == tot) {
+ ds--;
+ a--;
+ }
+
+ /* always previous z */
+ z= ds->z;
+
+ if (first || a==tot-1) {
+ /* if slopes were not initialized, use last visibility */
+ v= ds->v;
+ }
+ else {
+ /* compute visibility at center between slopes at z */
+ slope = (slopemin + slopemax) * 0.5;
+ v = (double)newds->v + slope * ((double)(z - newds->z) / (double)0x7FFFFFFF);
+ }
+
+ newds++;
+ newtot++;
+
+ newds->z= z;
+ newds->v= v;
+ }
+
+ if (newtot == 0 || (newds->v != (newds-1)->v))
+ newtot++;
+
+#if 0
+ if (print) {
+ for (a=0, ds=dsample; a<newtot; a++, ds++)
+ printf("%lf, %f ", ds->z/(double)0x7FFFFFFF, ds->v);
+ printf("\n");
+ }
+#endif
+
+ return newtot;
+}
+
+static float deep_alpha(Render *re, int obinr, int facenr, bool use_strand)
+{
+ ObjectInstanceRen *obi= &re->objectinstance[obinr];
+ Material *ma;
+
+ if (use_strand) {
+ StrandRen *strand= RE_findOrAddStrand(obi->obr, facenr-1);
+ ma= strand->buffer->ma;
+ }
+ else {
+ VlakRen *vlr= RE_findOrAddVlak(obi->obr, (facenr-1) & RE_QUAD_MASK);
+ ma= vlr->mat;
+ }
+
+ return ma->shad_alpha;
+}
+
+static void compress_deepshadowbuf(Render *re, ShadBuf *shb, APixstr *apixbuf, APixstrand *apixbufstrand)
+{
+ ShadSampleBuf *shsample;
+ DeepSample *ds[RE_MAX_OSA], *sampleds[RE_MAX_OSA], *dsb, *newbuf;
+ APixstr *ap, *apn;
+ APixstrand *aps, *apns;
+ float visibility;
+
+ const int totbuf= shb->totbuf;
+ const float totbuf_f= (float)shb->totbuf;
+ const float totbuf_f_inv= 1.0f/totbuf_f;
+ const int size= shb->size;
+
+ int a, b, c, tot, minz, found, prevtot, newtot;
+ int sampletot[RE_MAX_OSA], totsample = 0, totsamplec = 0;
+
+ shsample= MEM_callocN(sizeof(ShadSampleBuf), "shad sample buf");
+ BLI_addtail(&shb->buffers, shsample);
+
+ shsample->totbuf = MEM_callocN(sizeof(int) * size * size, "deeptotbuf");
+ shsample->deepbuf = MEM_callocN(sizeof(DeepSample *) * size * size, "deepbuf");
+
+ ap= apixbuf;
+ aps= apixbufstrand;
+ for (a=0; a<size*size; a++, ap++, aps++) {
+ /* count number of samples */
+ for (c=0; c<totbuf; c++)
+ sampletot[c]= 0;
+
+ tot= 0;
+ for (apn=ap; apn; apn=apn->next)
+ for (b=0; b<4; b++)
+ if (apn->p[b])
+ for (c=0; c<totbuf; c++)
+ if (apn->mask[b] & (1<<c))
+ sampletot[c]++;
+
+ if (apixbufstrand) {
+ for (apns=aps; apns; apns=apns->next)
+ for (b=0; b<4; b++)
+ if (apns->p[b])
+ for (c=0; c<totbuf; c++)
+ if (apns->mask[b] & (1<<c))
+ sampletot[c]++;
+ }
+
+ for (c=0; c<totbuf; c++)
+ tot += sampletot[c];
+
+ if (tot == 0) {
+ shsample->deepbuf[a]= NULL;
+ shsample->totbuf[a]= 0;
+ continue;
+ }
+
+ /* fill samples */
+ ds[0]= sampleds[0]= MEM_callocN(sizeof(DeepSample)*tot*2, "deepsample");
+ for (c=1; c<totbuf; c++)
+ ds[c]= sampleds[c]= sampleds[c-1] + sampletot[c-1]*2;
+
+ for (apn=ap; apn; apn=apn->next) {
+ for (b=0; b<4; b++) {
+ if (apn->p[b]) {
+ for (c=0; c<totbuf; c++) {
+ if (apn->mask[b] & (1<<c)) {
+ /* two entries to create step profile */
+ ds[c]->z= apn->z[b];
+ ds[c]->v= 1.0f; /* not used */
+ ds[c]++;
+ ds[c]->z= apn->z[b];
+ ds[c]->v= deep_alpha(re, apn->obi[b], apn->p[b], 0);
+ ds[c]++;
+ }
+ }
+ }
+ }
+ }
+
+ if (apixbufstrand) {
+ for (apns=aps; apns; apns=apns->next) {
+ for (b=0; b<4; b++) {
+ if (apns->p[b]) {
+ for (c=0; c<totbuf; c++) {
+ if (apns->mask[b] & (1<<c)) {
+ /* two entries to create step profile */
+ ds[c]->z= apns->z[b];
+ ds[c]->v= 1.0f; /* not used */
+ ds[c]++;
+ ds[c]->z= apns->z[b];
+ ds[c]->v= deep_alpha(re, apns->obi[b], apns->p[b], 1);
+ ds[c]++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ for (c=0; c<totbuf; c++) {
+ /* sort by increasing z */
+ qsort(sampleds[c], sampletot[c], sizeof(DeepSample)*2, verg_deepsample);
+
+ /* sum visibility, replacing alpha values */
+ visibility= 1.0f;
+ ds[c]= sampleds[c];
+
+ for (b=0; b<sampletot[c]; b++) {
+ /* two entries creating step profile */
+ ds[c]->v= visibility;
+ ds[c]++;
+
+ visibility *= 1.0f-ds[c]->v;
+ ds[c]->v= visibility;
+ ds[c]++;
+ }
+
+ /* halfway trick, probably won't work well for volumes? */
+ ds[c]= sampleds[c];
+ for (b=0; b<sampletot[c]; b++) {
+ if (b+1 < sampletot[c]) {
+ ds[c]->z= (ds[c]->z>>1) + ((ds[c]+2)->z>>1);
+ ds[c]++;
+ ds[c]->z= (ds[c]->z>>1) + ((ds[c]+2)->z>>1);
+ ds[c]++;
+ }
+ else {
+ ds[c]->z= (ds[c]->z>>1) + (0x7FFFFFFF>>1);
+ ds[c]++;
+ ds[c]->z= (ds[c]->z>>1) + (0x7FFFFFFF>>1);
+ ds[c]++;
+ }
+ }
+
+ /* init for merge loop */
+ ds[c]= sampleds[c];
+ sampletot[c] *= 2;
+ }
+
+ shsample->deepbuf[a]= MEM_callocN(sizeof(DeepSample)*tot*2, "deepsample");
+ shsample->totbuf[a]= 0;
+
+ /* merge buffers */
+ dsb= shsample->deepbuf[a];
+ while (1) {
+ minz= 0;
+ found= 0;
+
+ for (c=0; c<totbuf; c++) {
+ if (sampletot[c] && (!found || ds[c]->z < minz)) {
+ minz= ds[c]->z;
+ found= 1;
+ }
+ }
+
+ if (!found)
+ break;
+
+ dsb->z= minz;
+ dsb->v= 0.0f;
+
+ visibility= 0.0f;
+ for (c=0; c<totbuf; c++) {
+ if (sampletot[c] && ds[c]->z == minz) {
+ ds[c]++;
+ sampletot[c]--;
+ }
+
+ if (sampleds[c] == ds[c])
+ visibility += totbuf_f_inv;
+ else
+ visibility += (ds[c]-1)->v / totbuf_f;
+ }
+
+ dsb->v= visibility;
+ dsb++;
+ shsample->totbuf[a]++;
+ }
+
+ prevtot= shsample->totbuf[a];
+ totsample += prevtot;
+
+ newtot= compress_deepsamples(shsample->deepbuf[a], prevtot, shb->compressthresh);
+ shsample->totbuf[a]= newtot;
+ totsamplec += newtot;
+
+ if (newtot < prevtot) {
+ newbuf= MEM_mallocN(sizeof(DeepSample)*newtot, "cdeepsample");
+ memcpy(newbuf, shsample->deepbuf[a], sizeof(DeepSample)*newtot);
+ MEM_freeN(shsample->deepbuf[a]);
+ shsample->deepbuf[a]= newbuf;
+ }
+
+ MEM_freeN(sampleds[0]);
+ }
+
+ //printf("%d -> %d, ratio %f\n", totsample, totsamplec, (float)totsamplec/(float)totsample);
+}
+
+/* create Z tiles (for compression): this system is 24 bits!!! */
+static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
+{
+ ShadSampleBuf *shsample;
+ float dist;
+ uintptr_t *ztile;
+ int *rz, *rz1, verg, verg1, size= shb->size;
+ int a, x, y, minx, miny, byt1, byt2;
+ char *rc, *rcline, *ctile, *zt;
+
+ shsample= MEM_callocN(sizeof(ShadSampleBuf), "shad sample buf");
+ BLI_addtail(&shb->buffers, shsample);
+
+ shsample->zbuf= MEM_mallocN(sizeof(uintptr_t)*(size*size)/256, "initshadbuf2");
+ shsample->cbuf= MEM_callocN((size*size)/256, "initshadbuf3");
+
+ ztile= (uintptr_t *)shsample->zbuf;
+ ctile= shsample->cbuf;
+
+ /* help buffer */
+ rcline= MEM_mallocN(256*4+sizeof(int), "makeshadbuf2");
+
+ for (y=0; y<size; y+=16) {
+ if (y< size/2) miny= y+15-size/2;
+ else miny= y-size/2;
+
+ for (x=0; x<size; x+=16) {
+
+ /* is tile within spotbundle? */
+ a= size/2;
+ if (x< a) minx= x+15-a;
+ else minx= x-a;
+
+ dist = sqrtf((float)(minx * minx + miny * miny));
+
+ if (square==0 && dist>(float)(a+12)) { /* 12, tested with a onlyshadow lamp */
+ a= 256; verg= 0; /* 0x80000000; */ /* 0x7FFFFFFF; */
+ rz1= (&verg)+1;
+ }
+ else {
+ copy_to_ztile(rectz, size, x, y, 16, rcline);
+ rz1= (int *)rcline;
+
+ verg= (*rz1 & 0xFFFFFF00);
+
+ for (a=0;a<256;a++, rz1++) {
+ if ( (*rz1 & 0xFFFFFF00) !=verg) break;
+ }
+ }
+ if (a==256) { /* complete empty tile */
+ *ctile= 0;
+ *ztile= *(rz1-1);
+ }
+ else {
+
+ /* ACOMP etc. are defined to work L/B endian */
+
+ rc= rcline;
+ rz1= (int *)rcline;
+ verg= rc[ACOMP];
+ verg1= rc[BCOMP];
+ rc+= 4;
+ byt1= 1; byt2= 1;
+ for (a=1;a<256;a++, rc+=4) {
+ byt1 &= (verg==rc[ACOMP]);
+ byt2 &= (verg1==rc[BCOMP]);
+
+ if (byt1==0) break;
+ }
+ if (byt1 && byt2) { /* only store byte */
+ *ctile= 1;
+ *ztile= (uintptr_t)MEM_mallocN(256+4, "tile1");
+ rz= (int *)*ztile;
+ *rz= *rz1;
+
+ zt= (char *)(rz+1);
+ rc= rcline;
+ for (a=0; a<256; a++, zt++, rc+=4) *zt= rc[GCOMP];
+ }
+ else if (byt1) { /* only store short */
+ *ctile= 2;
+ *ztile= (uintptr_t)MEM_mallocN(2*256+4, "Tile2");
+ rz= (int *)*ztile;
+ *rz= *rz1;
+
+ zt= (char *)(rz+1);
+ rc= rcline;
+ for (a=0; a<256; a++, zt+=2, rc+=4) {
+ zt[0]= rc[BCOMP];
+ zt[1]= rc[GCOMP];
+ }
+ }
+ else { /* store triple */
+ *ctile= 3;
+ *ztile= (uintptr_t)MEM_mallocN(3*256, "Tile3");
+
+ zt= (char *)*ztile;
+ rc= rcline;
+ for (a=0; a<256; a++, zt+=3, rc+=4) {
+ zt[0]= rc[ACOMP];
+ zt[1]= rc[BCOMP];
+ zt[2]= rc[GCOMP];
+ }
+ }
+ }
+ ztile++;
+ ctile++;
+ }
+ }
+
+ MEM_freeN(rcline);
+}
+
+/* sets start/end clipping. lar->shb should be initialized */
+static void shadowbuf_autoclip(Render *re, LampRen *lar)
+{
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ VlakRen *vlr= NULL;
+ VertRen *ver= NULL;
+ Material *ma= NULL;
+ float minz, maxz, vec[3], viewmat[4][4], obviewmat[4][4];
+ unsigned int lay = -1;
+ int i, a, maxtotvert, ok= 1;
+ char *clipflag;
+
+ minz= 1.0e30f; maxz= -1.0e30f;
+ copy_m4_m4(viewmat, lar->shb->viewmat);
+
+ if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay;
+
+ maxtotvert= 0;
+ for (obr=re->objecttable.first; obr; obr=obr->next)
+ maxtotvert = max_ii(obr->totvert, maxtotvert);
+
+ clipflag= MEM_callocN(sizeof(char)*maxtotvert, "autoclipflag");
+
+ /* set clip in vertices when face visible */
+ for (i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_m4m4(obviewmat, viewmat, obi->mat);
+ else
+ copy_m4_m4(obviewmat, viewmat);
+
+ memset(clipflag, 0, sizeof(char)*obr->totvert);
+
+ /* clear clip, is being set if face is visible (clip is calculated for real later) */
+ for (a=0; a<obr->totvlak; a++) {
+ if ((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ /* note; these conditions are copied from zbuffer_shadow() */
+ if (vlr->mat!= ma) {
+ ma= vlr->mat;
+ ok= 1;
+ if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0;
+ }
+
+ if (ok && (obi->lay & lay)) {
+ clipflag[vlr->v1->index]= 1;
+ clipflag[vlr->v2->index]= 1;
+ clipflag[vlr->v3->index]= 1;
+ if (vlr->v4) clipflag[vlr->v4->index]= 1;
+ }
+ }
+
+ /* calculate min and max */
+ for (a=0; a< obr->totvert;a++) {
+ if ((a & 255)==0) ver= RE_findOrAddVert(obr, a);
+ else ver++;
+
+ if (clipflag[a]) {
+ copy_v3_v3(vec, ver->co);
+ mul_m4_v3(obviewmat, vec);
+ /* Z on visible side of lamp space */
+ if (vec[2] < 0.0f) {
+ float inpr, z= -vec[2];
+
+ /* since vec is rotated in lampspace, this is how to get the cosine of angle */
+ /* precision is set 20% larger */
+ vec[2]*= 1.2f;
+ normalize_v3(vec);
+ inpr= - vec[2];
+
+ if (inpr>=lar->spotsi) {
+ if (z<minz) minz= z;
+ if (z>maxz) maxz= z;
+ }
+ }
+ }
+ }
+ }
+
+ MEM_freeN(clipflag);
+
+ /* set clipping min and max */
+ if (minz < maxz) {
+ float delta= (maxz - minz); /* threshold to prevent precision issues */
+
+ //printf("minz %f maxz %f delta %f\n", minz, maxz, delta);
+ if (lar->bufflag & LA_SHADBUF_AUTO_START)
+ lar->shb->d= minz - delta*0.02f; /* 0.02 is arbitrary... needs more thinking! */
+ if (lar->bufflag & LA_SHADBUF_AUTO_END)
+ lar->shb->clipend= maxz + delta*0.1f;
+
+ /* bias was calculated as percentage, we scale it to prevent animation issues */
+ delta= (lar->clipend-lar->clipsta)/(lar->shb->clipend-lar->shb->d);
+ //printf("bias delta %f\n", delta);
+ lar->shb->bias= (int) (delta*(float)lar->shb->bias);
+ }
+}
+
+static void makeflatshadowbuf(Render *re, LampRen *lar, float *jitbuf)
+{
+ ShadBuf *shb= lar->shb;
+ int *rectz, samples;
+
+ /* zbuffering */
+ rectz= MEM_mapallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf");
+
+ for (samples=0; samples<shb->totbuf; samples++) {
+ zbuffer_shadow(re, shb->persmat, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]);
+ /* create Z tiles (for compression): this system is 24 bits!!! */
+ compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE);
+
+ if (re->test_break(re->tbh))
+ break;
+ }
+
+ MEM_freeN(rectz);
+}
+
+static void makedeepshadowbuf(Render *re, LampRen *lar, float *jitbuf)
+{
+ ShadBuf *shb= lar->shb;
+ APixstr *apixbuf;
+ APixstrand *apixbufstrand= NULL;
+ ListBase apsmbase= {NULL, NULL};
+
+ /* zbuffering */
+ apixbuf= MEM_callocN(sizeof(APixstr)*shb->size*shb->size, "APixbuf");
+ if (re->totstrand)
+ apixbufstrand= MEM_callocN(sizeof(APixstrand)*shb->size*shb->size, "APixbufstrand");
+
+ zbuffer_abuf_shadow(re, lar, shb->persmat, apixbuf, apixbufstrand, &apsmbase, shb->size,
+ shb->totbuf, (float(*)[2])jitbuf);
+
+ /* create Z tiles (for compression): this system is 24 bits!!! */
+ compress_deepshadowbuf(re, shb, apixbuf, apixbufstrand);
+
+ MEM_freeN(apixbuf);
+ if (apixbufstrand)
+ MEM_freeN(apixbufstrand);
+ freepsA(&apsmbase);
+}
+
+void makeshadowbuf(Render *re, LampRen *lar)
+{
+ ShadBuf *shb= lar->shb;
+ float wsize, *jitbuf, twozero[2]= {0.0f, 0.0f}, angle, temp;
+
+ if (lar->bufflag & (LA_SHADBUF_AUTO_START|LA_SHADBUF_AUTO_END))
+ shadowbuf_autoclip(re, lar);
+
+ /* just to enforce identical behavior of all irregular buffers */
+ if (lar->buftype==LA_SHADBUF_IRREGULAR)
+ shb->size= 1024;
+
+ /* matrices and window: in winmat the transformation is being put,
+ * transforming from observer view to lamp view, including lamp window matrix */
+
+ angle= saacos(lar->spotsi);
+ temp = 0.5f * shb->size * cosf(angle) / sinf(angle);
+ shb->pixsize= (shb->d)/temp;
+ wsize= shb->pixsize*(shb->size/2.0f);
+
+ perspective_m4(shb->winmat, -wsize, wsize, -wsize, wsize, shb->d, shb->clipend);
+ mul_m4_m4m4(shb->persmat, shb->winmat, shb->viewmat);
+
+ if (ELEM(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) {
+ shb->totbuf= lar->buffers;
+
+ /* jitter, weights - not threadsafe! */
+ BLI_thread_lock(LOCK_CUSTOM1);
+ shb->jit= give_jitter_tab(get_render_shadow_samples(&re->r, shb->samp));
+ make_jitter_weight_tab(re, shb, lar->filtertype);
+ BLI_thread_unlock(LOCK_CUSTOM1);
+
+ if (shb->totbuf==4) jitbuf= give_jitter_tab(2);
+ else if (shb->totbuf==9) jitbuf= give_jitter_tab(3);
+ else jitbuf= twozero;
+
+ /* zbuffering */
+ if (lar->buftype == LA_SHADBUF_DEEP) {
+ makedeepshadowbuf(re, lar, jitbuf);
+ shb->totbuf= 1;
+ }
+ else
+ makeflatshadowbuf(re, lar, jitbuf);
+
+ /* printf("lampbuf %d\n", sizeoflampbuf(shb)); */
+ }
+}
+
+static void *do_shadow_thread(void *re_v)
+{
+ Render *re = (Render *)re_v;
+ LampRen *lar;
+
+ do {
+ BLI_thread_lock(LOCK_CUSTOM1);
+ for (lar=re->lampren.first; lar; lar=lar->next) {
+ if (lar->shb && !lar->thread_assigned) {
+ lar->thread_assigned= 1;
+ break;
+ }
+ }
+ BLI_thread_unlock(LOCK_CUSTOM1);
+
+ /* if type is irregular, this only sets the perspective matrix and autoclips */
+ if (lar) {
+ makeshadowbuf(re, lar);
+ BLI_thread_lock(LOCK_CUSTOM1);
+ lar->thread_ready= 1;
+ BLI_thread_unlock(LOCK_CUSTOM1);
+ }
+ } while (lar && !re->test_break(re->tbh));
+
+ return NULL;
+}
+
+static volatile int g_break= 0;
+static int thread_break(void *UNUSED(arg))
+{
+ return g_break;
+}
+
+void threaded_makeshadowbufs(Render *re)
+{
+ ListBase threads;
+ LampRen *lar;
+ int a, totthread= 0;
+ int (*test_break)(void *);
+
+ /* count number of threads to use */
+ if (G.is_rendering) {
+ for (lar=re->lampren.first; lar; lar= lar->next)
+ if (lar->shb)
+ totthread++;
+
+ totthread = min_ii(totthread, re->r.threads);
+ }
+ else
+ totthread = 1; /* preview render */
+
+ if (totthread <= 1) {
+ for (lar=re->lampren.first; lar; lar= lar->next) {
+ if (re->test_break(re->tbh)) break;
+ if (lar->shb) {
+ /* if type is irregular, this only sets the perspective matrix and autoclips */
+ makeshadowbuf(re, lar);
+ }
+ }
+ }
+ else {
+ /* swap test break function */
+ test_break= re->test_break;
+ re->test_break= thread_break;
+
+ for (lar=re->lampren.first; lar; lar= lar->next) {
+ lar->thread_assigned= 0;
+ lar->thread_ready= 0;
+ }
+
+ BLI_threadpool_init(&threads, do_shadow_thread, totthread);
+
+ for (a=0; a<totthread; a++)
+ BLI_threadpool_insert(&threads, re);
+
+ /* keep rendering as long as there are shadow buffers not ready */
+ do {
+ if ((g_break=test_break(re->tbh)))
+ break;
+
+ PIL_sleep_ms(50);
+
+ BLI_thread_lock(LOCK_CUSTOM1);
+ for (lar=re->lampren.first; lar; lar= lar->next)
+ if (lar->shb && !lar->thread_ready)
+ break;
+ BLI_thread_unlock(LOCK_CUSTOM1);
+ } while (lar);
+
+ BLI_threadpool_end(&threads);
+
+ /* unset threadsafety */
+ re->test_break= test_break;
+ g_break= 0;
+ }
+}
+
+void freeshadowbuf(LampRen *lar)
+{
+ if (lar->shb) {
+ ShadBuf *shb= lar->shb;
+ ShadSampleBuf *shsample;
+ int b, v;
+
+ for (shsample= shb->buffers.first; shsample; shsample= shsample->next) {
+ if (shsample->deepbuf) {
+ v= shb->size*shb->size;
+ for (b=0; b<v; b++)
+ if (shsample->deepbuf[b])
+ MEM_freeN(shsample->deepbuf[b]);
+
+ MEM_freeN(shsample->deepbuf);
+ MEM_freeN(shsample->totbuf);
+ }
+ else {
+ intptr_t *ztile= shsample->zbuf;
+ const char *ctile= shsample->cbuf;
+
+ v= (shb->size*shb->size)/256;
+ for (b=0; b<v; b++, ztile++, ctile++)
+ if (*ctile) MEM_freeN((void *) *ztile);
+
+ MEM_freeN(shsample->zbuf);
+ MEM_freeN(shsample->cbuf);
+ }
+ }
+ BLI_freelistN(&shb->buffers);
+
+ if (shb->weight) MEM_freeN(shb->weight);
+ MEM_freeN(lar->shb);
+
+ lar->shb= NULL;
+ }
+}
+
+
+static int firstreadshadbuf(ShadBuf *shb, ShadSampleBuf *shsample, int **rz, int xs, int ys, int nr)
+{
+ /* return a 1 if fully compressed shadbuf-tile && z==const */
+ int ofs;
+ const char *ct;
+
+ if (shsample->deepbuf)
+ return 0;
+
+ /* always test borders of shadowbuffer */
+ if (xs<0) xs= 0; else if (xs>=shb->size) xs= shb->size-1;
+ if (ys<0) ys= 0; else if (ys>=shb->size) ys= shb->size-1;
+
+ /* calc z */
+ ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
+ ct= shsample->cbuf+ofs;
+ if (*ct==0) {
+ if (nr==0) {
+ *rz= *( (int **)(shsample->zbuf+ofs) );
+ return 1;
+ }
+ else if (*rz!= *( (int **)(shsample->zbuf+ofs) )) return 0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static float readdeepvisibility(DeepSample *dsample, int tot, int z, int bias, float *biast)
+{
+ DeepSample *ds, *prevds;
+ float t;
+ int a;
+
+ /* tricky stuff here; we use ints which can overflow easily with bias values */
+
+ ds= dsample;
+ for (a=0; a<tot && (z-bias > ds->z); a++, ds++) {}
+
+ if (a == tot) {
+ if (biast)
+ *biast= 0.0f;
+ return (ds-1)->v; /* completely behind all samples */
+ }
+
+ /* check if this read needs bias blending */
+ if (biast) {
+ if (z > ds->z)
+ *biast= (float)(z - ds->z)/(float)bias;
+ else
+ *biast= 0.0f;
+ }
+
+ if (a == 0)
+ return 1.0f; /* completely in front of all samples */
+
+ /* converting to float early here because ds->z - prevds->z can overflow */
+ prevds= ds-1;
+ t= ((float)(z-bias) - (float)prevds->z)/((float)ds->z - (float)prevds->z);
+ return t*ds->v + (1.0f-t)*prevds->v;
+}
+
+static float readdeepshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs)
+{
+ float v, biasv, biast;
+ int ofs, tot;
+
+ if (zs < - 0x7FFFFE00 + bias)
+ return 1.0; /* extreme close to clipstart */
+
+ /* calc z */
+ ofs= ys*shb->size + xs;
+ tot= shsample->totbuf[ofs];
+ if (tot == 0)
+ return 1.0f;
+
+ v= readdeepvisibility(shsample->deepbuf[ofs], tot, zs, bias, &biast);
+
+ if (biast != 0.0f) {
+ /* in soft bias area */
+ biasv = readdeepvisibility(shsample->deepbuf[ofs], tot, zs, 0, NULL);
+
+ biast= biast*biast;
+ return (1.0f-biast)*v + biast*biasv;
+ }
+
+ return v;
+}
+
+/* return 1.0 : fully in light */
+static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs)
+{
+ float temp;
+ int *rz, ofs;
+ int zsamp=0;
+ char *ct, *cz;
+
+ /* simpleclip */
+ /* if (xs<0 || ys<0) return 1.0; */
+ /* if (xs>=shb->size || ys>=shb->size) return 1.0; */
+
+ /* always test borders of shadowbuffer */
+ if (xs<0) xs= 0; else if (xs>=shb->size) xs= shb->size-1;
+ if (ys<0) ys= 0; else if (ys>=shb->size) ys= shb->size-1;
+
+ if (shsample->deepbuf)
+ return readdeepshadowbuf(shb, shsample, bias, xs, ys, zs);
+
+ /* calc z */
+ ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
+ ct= shsample->cbuf+ofs;
+ rz= *( (int **)(shsample->zbuf+ofs) );
+
+ if (*ct==3) {
+ ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15);
+ cz= (char *)&zsamp;
+ cz[ACOMP]= ct[0];
+ cz[BCOMP]= ct[1];
+ cz[GCOMP]= ct[2];
+ }
+ else if (*ct==2) {
+ ct= ((char *)rz);
+ ct+= 4+2*16*(ys & 15)+2*(xs & 15);
+ zsamp= *rz;
+
+ cz= (char *)&zsamp;
+ cz[BCOMP]= ct[0];
+ cz[GCOMP]= ct[1];
+ }
+ else if (*ct==1) {
+ ct= ((char *)rz);
+ ct+= 4+16*(ys & 15)+(xs & 15);
+ zsamp= *rz;
+
+ cz= (char *)&zsamp;
+ cz[GCOMP]= ct[0];
+
+ }
+ else {
+ /* got warning on this for 64 bits.... */
+ /* but it's working code! in this case rz is not a pointer but zvalue (ton) */
+ zsamp= GET_INT_FROM_POINTER(rz);
+ }
+
+ /* tricky stuff here; we use ints which can overflow easily with bias values */
+
+ if (zsamp > zs) return 1.0; /* absolute no shadow */
+ else if (zs < - 0x7FFFFE00 + bias) return 1.0; /* extreme close to clipstart */
+ else if (zsamp < zs-bias) return 0.0; /* absolute in shadow */
+ else { /* soft area */
+
+ temp= ( (float)(zs- zsamp) )/(float)bias;
+ return 1.0f - temp*temp;
+
+ }
+}
+
+static void shadowbuf_project_co(float *x, float *y, float *z, ShadBuf *shb, const float co[3])
+{
+ float hco[4], size= 0.5f*(float)shb->size;
+
+ copy_v3_v3(hco, co);
+ hco[3]= 1.0f;
+
+ mul_m4_v4(shb->persmat, hco);
+
+ *x= size*(1.0f+hco[0]/hco[3]);
+ *y= size*(1.0f+hco[1]/hco[3]);
+ if (z) *z= (hco[2]/hco[3]);
+}
+
+/* the externally called shadow testing (reading) function */
+/* return 1.0: no shadow at all */
+float testshadowbuf(Render *re, ShadBuf *shb, const float co[3], const float dxco[3], const float dyco[3], float inp, float mat_bias)
+{
+ ShadSampleBuf *shsample;
+ float fac, dco[3], dx[3], dy[3], shadfac=0.0f;
+ float xs1, ys1, zs1, *jit, *weight, xres, yres, biasf;
+ int xs, ys, zs, bias, *rz;
+ short a, num;
+
+ /* crash preventer */
+ if (shb->buffers.first==NULL)
+ return 1.0f;
+
+ /* when facing away, assume fully in shadow */
+ if (inp <= 0.0f)
+ return 0.0f;
+
+ /* project coordinate to pixel space */
+ shadowbuf_project_co(&xs1, &ys1, &zs1, shb, co);
+
+ /* clip z coordinate, z is projected so that (-1.0, 1.0) matches
+ * (clipstart, clipend), so we can do this simple test */
+ if (zs1>=1.0f)
+ return 0.0f;
+ else if (zs1<= -1.0f)
+ return 1.0f;
+
+ zs= ((float)0x7FFFFFFF)*zs1;
+
+ /* take num*num samples, increase area with fac */
+ num= get_render_shadow_samples(&re->r, shb->samp);
+ num= num*num;
+ fac= shb->soft;
+
+ /* compute z bias */
+ if (mat_bias!=0.0f) biasf= shb->bias*mat_bias;
+ else biasf= shb->bias;
+ /* with inp==1.0, bias is half the size. correction value was 1.1, giving errors
+ * on cube edges, with one side being almost frontal lighted (ton) */
+ bias= (1.5f-inp*inp)*biasf;
+
+ /* in case of no filtering we can do things simpler */
+ if (num==1) {
+ for (shsample= shb->buffers.first; shsample; shsample= shsample->next)
+ shadfac += readshadowbuf(shb, shsample, bias, (int)xs1, (int)ys1, zs);
+
+ return shadfac/(float)shb->totbuf;
+ }
+
+ /* calculate filter size */
+ add_v3_v3v3(dco, co, dxco);
+ shadowbuf_project_co(&dx[0], &dx[1], NULL, shb, dco);
+ dx[0]= xs1 - dx[0];
+ dx[1]= ys1 - dx[1];
+
+ add_v3_v3v3(dco, co, dyco);
+ shadowbuf_project_co(&dy[0], &dy[1], NULL, shb, dco);
+ dy[0]= xs1 - dy[0];
+ dy[1]= ys1 - dy[1];
+
+ xres = fac * (fabsf(dx[0]) + fabsf(dy[0]));
+ yres = fac * (fabsf(dx[1]) + fabsf(dy[1]));
+ if (xres<1.0f) xres= 1.0f;
+ if (yres<1.0f) yres= 1.0f;
+
+ /* make xs1/xs1 corner of sample area */
+ xs1 -= xres*0.5f;
+ ys1 -= yres*0.5f;
+
+ /* in case we have a constant value in a tile, we can do quicker lookup */
+ if (xres<16.0f && yres<16.0f) {
+ shsample= shb->buffers.first;
+ if (firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)ys1, 0)) {
+ if (firstreadshadbuf(shb, shsample, &rz, (int)(xs1+xres), (int)ys1, 1)) {
+ if (firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)(ys1+yres), 1)) {
+ if (firstreadshadbuf(shb, shsample, &rz, (int)(xs1+xres), (int)(ys1+yres), 1)) {
+ return readshadowbuf(shb, shsample, bias, (int)xs1, (int)ys1, zs);
+ }
+ }
+ }
+ }
+ }
+
+ /* full jittered shadow buffer lookup */
+ for (shsample= shb->buffers.first; shsample; shsample= shsample->next) {
+ jit= shb->jit;
+ weight= shb->weight;
+
+ for (a=num; a>0; a--, jit+=2, weight++) {
+ /* instead of jit i tried random: ugly! */
+ /* note: the plus 0.5 gives best sampling results, jit goes from -0.5 to 0.5 */
+ /* xs1 and ys1 are already corrected to be corner of sample area */
+ xs= xs1 + xres*(jit[0] + 0.5f);
+ ys= ys1 + yres*(jit[1] + 0.5f);
+
+ shadfac+= *weight * readshadowbuf(shb, shsample, bias, xs, ys, zs);
+ }
+ }
+
+ /* Renormalizes for the sample number: */
+ return shadfac/(float)shb->totbuf;
+}
+
+/* different function... sampling behind clipend can be LIGHT, bias is negative! */
+/* return: light */
+static float readshadowbuf_halo(ShadBuf *shb, ShadSampleBuf *shsample, int xs, int ys, int zs)
+{
+ float temp;
+ int *rz, ofs;
+ int bias, zbias, zsamp;
+ char *ct, *cz;
+
+ /* negative! The other side is more important */
+ bias= -shb->bias;
+
+ /* simpleclip */
+ if (xs<0 || ys<0) return 0.0;
+ if (xs>=shb->size || ys>=shb->size) return 0.0;
+
+ /* calc z */
+ ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
+ ct= shsample->cbuf+ofs;
+ rz= *( (int **)(shsample->zbuf+ofs) );
+
+ if (*ct==3) {
+ ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15);
+ cz= (char *)&zsamp;
+ zsamp= 0;
+ cz[ACOMP]= ct[0];
+ cz[BCOMP]= ct[1];
+ cz[GCOMP]= ct[2];
+ }
+ else if (*ct==2) {
+ ct= ((char *)rz);
+ ct+= 4+2*16*(ys & 15)+2*(xs & 15);
+ zsamp= *rz;
+
+ cz= (char *)&zsamp;
+ cz[BCOMP]= ct[0];
+ cz[GCOMP]= ct[1];
+ }
+ else if (*ct==1) {
+ ct= ((char *)rz);
+ ct+= 4+16*(ys & 15)+(xs & 15);
+ zsamp= *rz;
+
+ cz= (char *)&zsamp;
+ cz[GCOMP]= ct[0];
+
+ }
+ else {
+ /* same as before */
+ /* still working code! (ton) */
+ zsamp= GET_INT_FROM_POINTER(rz);
+ }
+
+ /* NO schadow when sampled at 'eternal' distance */
+
+ if (zsamp >= 0x7FFFFE00) return 1.0;
+
+ if (zsamp > zs) return 1.0; /* absolute no shadww */
+ else {
+ /* bias is negative, so the (zs-bias) can be beyond 0x7fffffff */
+ zbias= 0x7fffffff - zs;
+ if (zbias > -bias) {
+ if ( zsamp < zs-bias) return 0.0; /* absolute in shadow */
+ }
+ else return 0.0; /* absolute shadow */
+ }
+
+ /* soft area */
+
+ temp= ( (float)(zs- zsamp) )/(float)bias;
+ return 1.0f - temp*temp;
+}
+
+
+float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
+{
+ /* p1 p2 already are rotated in spot-space */
+ ShadBuf *shb= lar->shb;
+ ShadSampleBuf *shsample;
+ float co[4], siz;
+ float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy;
+ float zf, xf1, yf1, zf1, xf2, yf2, zf2;
+ float count, lightcount;
+ int x, y, z, xs1, ys1;
+ int dx = 0, dy = 0;
+
+ siz= 0.5f*(float)shb->size;
+
+ co[0]= p1[0];
+ co[1]= p1[1];
+ co[2]= p1[2]/lar->sh_zfac;
+ co[3]= 1.0;
+ mul_m4_v4(shb->winmat, co); /* rational hom co */
+ xf1= siz*(1.0f+co[0]/co[3]);
+ yf1= siz*(1.0f+co[1]/co[3]);
+ zf1= (co[2]/co[3]);
+
+
+ co[0]= p2[0];
+ co[1]= p2[1];
+ co[2]= p2[2]/lar->sh_zfac;
+ co[3]= 1.0;
+ mul_m4_v4(shb->winmat, co); /* rational hom co */
+ xf2= siz*(1.0f+co[0]/co[3]);
+ yf2= siz*(1.0f+co[1]/co[3]);
+ zf2= (co[2]/co[3]);
+
+ /* the 2dda (a pixel line formula) */
+
+ xs1= (int)xf1;
+ ys1= (int)yf1;
+
+ if (xf1 != xf2) {
+ if (xf2-xf1 > 0.0f) {
+ lambda_x= (xf1-xs1-1.0f)/(xf1-xf2);
+ ldx= -shb->shadhalostep/(xf1-xf2);
+ dx= shb->shadhalostep;
+ }
+ else {
+ lambda_x= (xf1-xs1)/(xf1-xf2);
+ ldx= shb->shadhalostep/(xf1-xf2);
+ dx= -shb->shadhalostep;
+ }
+ }
+ else {
+ lambda_x= 1.0;
+ ldx= 0.0;
+ }
+
+ if (yf1 != yf2) {
+ if (yf2-yf1 > 0.0f) {
+ lambda_y= (yf1-ys1-1.0f)/(yf1-yf2);
+ ldy= -shb->shadhalostep/(yf1-yf2);
+ dy= shb->shadhalostep;
+ }
+ else {
+ lambda_y= (yf1-ys1)/(yf1-yf2);
+ ldy= shb->shadhalostep/(yf1-yf2);
+ dy= -shb->shadhalostep;
+ }
+ }
+ else {
+ lambda_y= 1.0;
+ ldy= 0.0;
+ }
+
+ x= xs1;
+ y= ys1;
+ lambda= count= lightcount= 0.0;
+
+/* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */
+
+ do {
+ lambda_o= lambda;
+
+ if (lambda_x==lambda_y) {
+ lambda_x+= ldx;
+ x+= dx;
+ lambda_y+= ldy;
+ y+= dy;
+ }
+ else {
+ if (lambda_x<lambda_y) {
+ lambda_x+= ldx;
+ x+= dx;
+ }
+ else {
+ lambda_y+= ldy;
+ y+= dy;
+ }
+ }
+
+ lambda = min_ff(lambda_x, lambda_y);
+
+ /* not making any progress? */
+ if (lambda==lambda_o) break;
+
+ /* clip to end of volume */
+ lambda = min_ff(lambda, 1.0f);
+
+ zf= zf1 + lambda*(zf2-zf1);
+ count+= (float)shb->totbuf;
+
+ if (zf<= -1.0f) lightcount += 1.0f; /* close to the spot */
+ else {
+
+ /* make sure, behind the clipend we extend halolines. */
+ if (zf>=1.0f) z= 0x7FFFF000;
+ else z= (int)(0x7FFFF000*zf);
+
+ for (shsample= shb->buffers.first; shsample; shsample= shsample->next)
+ lightcount+= readshadowbuf_halo(shb, shsample, x, y, z);
+
+ }
+ }
+ while (lambda < 1.0f);
+
+ if (count!=0.0f) return (lightcount/count);
+ return 0.0f;
+
+}
+
+
+/* ********************* Irregular Shadow Buffer (ISB) ************* */
+/* ********** storage of all view samples in a raster of lists ***** */
+
+/* based on several articles describing this method, like:
+ * The Irregular Z-Buffer and its Application to Shadow Mapping
+ * Gregory S. Johnson - William R. Mark - Christopher A. Burns
+ * and
+ * Alias-Free Shadow Maps
+ * Timo Aila and Samuli Laine
+ */
+
+/* bsp structure (actually kd tree) */
+
+#define BSPMAX_SAMPLE 128
+#define BSPMAX_DEPTH 32
+
+/* aligned with struct rctf */
+typedef struct Boxf {
+ float xmin, xmax;
+ float ymin, ymax;
+ float zmin, zmax;
+} Boxf;
+
+typedef struct ISBBranch {
+ struct ISBBranch *left, *right;
+ float divider[2];
+ Boxf box;
+ short totsamp, index, full, unused;
+ ISBSample **samples;
+} ISBBranch;
+
+typedef struct BSPFace {
+ Boxf box;
+ const float *v1, *v2, *v3, *v4;
+ int obi; /* object for face lookup */
+ int facenr; /* index to retrieve VlakRen */
+ int type; /* only for strand now */
+ short shad_alpha, is_full;
+
+ /* strand caching data, optimize for point_behind_strand() */
+ float radline, radline_end, len;
+ float vec1[3], vec2[3], rc[3];
+} BSPFace;
+
+/* boxes are in lamp projection */
+static void init_box(Boxf *box)
+{
+ box->xmin = 1000000.0f;
+ box->xmax = 0;
+ box->ymin = 1000000.0f;
+ box->ymax = 0;
+ box->zmin= 0x7FFFFFFF;
+ box->zmax= - 0x7FFFFFFF;
+}
+
+/* use v1 to calculate boundbox */
+static void bound_boxf(Boxf *box, const float v1[3])
+{
+ if (v1[0] < box->xmin) box->xmin = v1[0];
+ if (v1[0] > box->xmax) box->xmax = v1[0];
+ if (v1[1] < box->ymin) box->ymin = v1[1];
+ if (v1[1] > box->ymax) box->ymax = v1[1];
+ if (v1[2] < box->zmin) box->zmin= v1[2];
+ if (v1[2] > box->zmax) box->zmax= v1[2];
+}
+
+/* use v1 to calculate boundbox */
+static void bound_rectf(rctf *box, const float v1[2])
+{
+ if (v1[0] < box->xmin) box->xmin = v1[0];
+ if (v1[0] > box->xmax) box->xmax = v1[0];
+ if (v1[1] < box->ymin) box->ymin = v1[1];
+ if (v1[1] > box->ymax) box->ymax = v1[1];
+}
+
+
+/* halfway splitting, for initializing a more regular tree */
+static void isb_bsp_split_init(ISBBranch *root, MemArena *mem, int level)
+{
+
+ /* if level > 0 we create new branches and go deeper */
+ if (level > 0) {
+ ISBBranch *left, *right;
+ int i;
+
+ /* splitpoint */
+ root->divider[0]= 0.5f*(root->box.xmin+root->box.xmax);
+ root->divider[1]= 0.5f*(root->box.ymin+root->box.ymax);
+
+ /* find best splitpoint */
+ if (RCT_SIZE_X(&root->box) > RCT_SIZE_Y(&root->box))
+ i = root->index = 0;
+ else
+ i = root->index = 1;
+
+ left= root->left= BLI_memarena_alloc(mem, sizeof(ISBBranch));
+ right= root->right= BLI_memarena_alloc(mem, sizeof(ISBBranch));
+
+ /* box info */
+ left->box= root->box;
+ right->box= root->box;
+ if (i==0) {
+ left->box.xmax = root->divider[0];
+ right->box.xmin = root->divider[0];
+ }
+ else {
+ left->box.ymax = root->divider[1];
+ right->box.ymin = root->divider[1];
+ }
+ isb_bsp_split_init(left, mem, level-1);
+ isb_bsp_split_init(right, mem, level-1);
+ }
+ else {
+ /* we add sample array */
+ root->samples= BLI_memarena_alloc(mem, BSPMAX_SAMPLE*sizeof(void *));
+ }
+}
+
+/* note; if all samples on same location we just spread them over 2 new branches */
+static void isb_bsp_split(ISBBranch *root, MemArena *mem)
+{
+ ISBBranch *left, *right;
+ ISBSample *samples[BSPMAX_SAMPLE];
+ int a, i;
+
+ /* splitpoint */
+ root->divider[0]= root->divider[1]= 0.0f;
+ for (a=BSPMAX_SAMPLE-1; a>=0; a--) {
+ root->divider[0]+= root->samples[a]->zco[0];
+ root->divider[1]+= root->samples[a]->zco[1];
+ }
+ root->divider[0]/= BSPMAX_SAMPLE;
+ root->divider[1]/= BSPMAX_SAMPLE;
+
+ /* find best splitpoint */
+ if (RCT_SIZE_X(&root->box) > RCT_SIZE_Y(&root->box))
+ i = root->index = 0;
+ else
+ i = root->index = 1;
+
+ /* new branches */
+ left= root->left= BLI_memarena_alloc(mem, sizeof(ISBBranch));
+ right= root->right= BLI_memarena_alloc(mem, sizeof(ISBBranch));
+
+ /* new sample array */
+ left->samples = BLI_memarena_alloc(mem, BSPMAX_SAMPLE*sizeof(void *));
+ right->samples = samples; /* tmp */
+
+ /* split samples */
+ for (a=BSPMAX_SAMPLE-1; a>=0; a--) {
+ int comp= 0;
+ /* this prevents adding samples all to 1 branch when divider is equal to samples */
+ if (root->samples[a]->zco[i] == root->divider[i])
+ comp= a & 1;
+ else if (root->samples[a]->zco[i] < root->divider[i])
+ comp= 1;
+
+ if (comp==1) {
+ left->samples[left->totsamp]= root->samples[a];
+ left->totsamp++;
+ }
+ else {
+ right->samples[right->totsamp]= root->samples[a];
+ right->totsamp++;
+ }
+ }
+
+ /* copy samples from tmp */
+ memcpy(root->samples, samples, right->totsamp*(sizeof(void *)));
+ right->samples= root->samples;
+ root->samples= NULL;
+
+ /* box info */
+ left->box= root->box;
+ right->box= root->box;
+ if (i==0) {
+ left->box.xmax = root->divider[0];
+ right->box.xmin = root->divider[0];
+ }
+ else {
+ left->box.ymax = root->divider[1];
+ right->box.ymin = root->divider[1];
+ }
+}
+
+/* inserts sample in main tree, also splits on threshold */
+/* returns 1 if error */
+static int isb_bsp_insert(ISBBranch *root, MemArena *memarena, ISBSample *sample)
+{
+ ISBBranch *bspn= root;
+ const float *zco= sample->zco;
+ int i= 0;
+
+ /* debug counter, also used to check if something was filled in ever */
+ root->totsamp++;
+
+ /* going over branches until last one found */
+ while (bspn->left) {
+ if (zco[bspn->index] <= bspn->divider[bspn->index])
+ bspn= bspn->left;
+ else
+ bspn= bspn->right;
+ i++;
+ }
+ /* bspn now is the last branch */
+
+ if (bspn->totsamp==BSPMAX_SAMPLE) {
+ printf("error in bsp branch\n"); /* only for debug, cannot happen */
+ return 1;
+ }
+
+ /* insert */
+ bspn->samples[bspn->totsamp]= sample;
+ bspn->totsamp++;
+
+ /* split if allowed and needed */
+ if (bspn->totsamp==BSPMAX_SAMPLE) {
+ if (i==BSPMAX_DEPTH) {
+ bspn->totsamp--; /* stop filling in... will give errors */
+ return 1;
+ }
+ isb_bsp_split(bspn, memarena);
+ }
+ return 0;
+}
+
+/* initialize vars in face, for optimal point-in-face test */
+static void bspface_init_strand(BSPFace *face)
+{
+
+ face->radline= 0.5f* len_v2v2(face->v1, face->v2);
+
+ mid_v3_v3v3(face->vec1, face->v1, face->v2);
+ if (face->v4)
+ mid_v3_v3v3(face->vec2, face->v3, face->v4);
+ else
+ copy_v3_v3(face->vec2, face->v3);
+
+ face->rc[0]= face->vec2[0]-face->vec1[0];
+ face->rc[1]= face->vec2[1]-face->vec1[1];
+ face->rc[2]= face->vec2[2]-face->vec1[2];
+
+ face->len= face->rc[0]*face->rc[0]+ face->rc[1]*face->rc[1];
+
+ if (face->len != 0.0f) {
+ face->radline_end = face->radline / sqrtf(face->len);
+ face->len = 1.0f / face->len;
+ }
+}
+
+/* brought back to a simple 2d case */
+static int point_behind_strand(const float p[3], BSPFace *face)
+{
+ /* v1 - v2 is radius, v1 - v3 length */
+ float dist, rc[2], pt[2];
+
+ /* using code from dist_to_line_segment_v2(), distance vec to line-piece */
+
+ if (face->len==0.0f) {
+ rc[0]= p[0]-face->vec1[0];
+ rc[1]= p[1]-face->vec1[1];
+ dist = len_v2(rc);
+
+ if (dist < face->radline)
+ return 1;
+ }
+ else {
+ float lambda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len;
+
+ if (lambda > -face->radline_end && lambda < 1.0f+face->radline_end) {
+ /* hesse for dist: */
+ //dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len);
+
+ pt[0]= lambda*face->rc[0]+face->vec1[0];
+ pt[1]= lambda*face->rc[1]+face->vec1[1];
+
+ rc[0]= pt[0]-p[0];
+ rc[1]= pt[1]-p[1];
+ dist = len_v2(rc);
+
+ if (dist < face->radline) {
+ float zval= face->vec1[2] + lambda*face->rc[2];
+ if (p[2] > zval)
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/* return 1 if inside. code derived from src/parametrizer.c */
+static int point_behind_tria2d(const float p[3], const float v1[3], const float v2[3], const float v3[3])
+{
+ float a[2], c[2], h[2], div;
+ float u, v;
+
+ a[0] = v2[0] - v1[0];
+ a[1] = v2[1] - v1[1];
+ c[0] = v3[0] - v1[0];
+ c[1] = v3[1] - v1[1];
+
+ div = a[0]*c[1] - a[1]*c[0];
+ if (div==0.0f)
+ return 0;
+
+ h[0] = p[0] - v1[0];
+ h[1] = p[1] - v1[1];
+
+ div = 1.0f/div;
+
+ u = (h[0]*c[1] - h[1]*c[0])*div;
+ if (u >= 0.0f) {
+ v = (a[0]*h[1] - a[1]*h[0])*div;
+ if (v >= 0.0f) {
+ if ( u + v <= 1.0f) {
+ /* inside, now check if point p is behind */
+ float z= (1.0f-u-v)*v1[2] + u*v2[2] + v*v3[2];
+ if (z <= p[2])
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#if 0
+/* tested these calls, but it gives inaccuracy, 'side' cannot be found reliably using v3 */
+
+/* check if line v1-v2 has all rect points on other side of point v3 */
+static int rect_outside_line(rctf *rect, const float v1[3], const float v2[3], const float v3[3])
+{
+ float a, b, c;
+ int side;
+
+ /* line formula for v1-v2 */
+ a= v2[1]-v1[1];
+ b= v1[0]-v2[0];
+ c= -a*v1[0] - b*v1[1];
+ side= a*v3[0] + b*v3[1] + c < 0.0f;
+
+ /* the four quad points */
+ if ( side==(rect->xmin*a + rect->ymin*b + c >= 0.0f) )
+ if ( side==(rect->xmax*a + rect->ymin*b + c >= 0.0f) )
+ if ( side==(rect->xmax*a + rect->ymax*b + c >= 0.0f) )
+ if ( side==(rect->xmin*a + rect->ymax*b + c >= 0.0f) )
+ return 1;
+ return 0;
+}
+
+/* check if one of the triangle edges separates all rect points on 1 side */
+static int rect_isect_tria(rctf *rect, const float v1[3], const float v2[3], const float v3[3])
+{
+ if (rect_outside_line(rect, v1, v2, v3))
+ return 0;
+ if (rect_outside_line(rect, v2, v3, v1))
+ return 0;
+ if (rect_outside_line(rect, v3, v1, v2))
+ return 0;
+ return 1;
+}
+#endif
+
+/* if face overlaps a branch, it executes func. recursive */
+static void isb_bsp_face_inside(ISBBranch *bspn, BSPFace *face)
+{
+
+ /* are we descending? */
+ if (bspn->left) {
+ /* hrmf, the box struct cannot be addressed with index */
+ if (bspn->index==0) {
+ if (face->box.xmin <= bspn->divider[0])
+ isb_bsp_face_inside(bspn->left, face);
+ if (face->box.xmax > bspn->divider[0])
+ isb_bsp_face_inside(bspn->right, face);
+ }
+ else {
+ if (face->box.ymin <= bspn->divider[1])
+ isb_bsp_face_inside(bspn->left, face);
+ if (face->box.ymax > bspn->divider[1])
+ isb_bsp_face_inside(bspn->right, face);
+ }
+ }
+ else {
+ /* else: end branch reached */
+ int a;
+
+ if (bspn->totsamp==0) return;
+
+ /* check for nodes entirely in shadow, can be skipped */
+ if (bspn->totsamp==bspn->full)
+ return;
+
+ /* if bsp node is entirely in front of face, give up */
+ if (bspn->box.zmax < face->box.zmin)
+ return;
+
+ /* if face boundbox is outside of branch rect, give up */
+ if (0==BLI_rctf_isect((rctf *)&face->box, (rctf *)&bspn->box, NULL))
+ return;
+
+ /* test all points inside branch */
+ for (a=bspn->totsamp-1; a>=0; a--) {
+ ISBSample *samp= bspn->samples[a];
+
+ if ((samp->facenr!=face->facenr || samp->obi!=face->obi) && samp->shadfac) {
+ if (face->box.zmin < samp->zco[2]) {
+ if (BLI_rctf_isect_pt_v((rctf *)&face->box, samp->zco)) {
+ int inshadow= 0;
+
+ if (face->type) {
+ if (point_behind_strand(samp->zco, face))
+ inshadow= 1;
+ }
+ else if ( point_behind_tria2d(samp->zco, face->v1, face->v2, face->v3))
+ inshadow= 1;
+ else if (face->v4 && point_behind_tria2d(samp->zco, face->v1, face->v3, face->v4))
+ inshadow= 1;
+
+ if (inshadow) {
+ *(samp->shadfac) += face->shad_alpha;
+ /* optimize; is_full means shad_alpha==4096 */
+ if (*(samp->shadfac) >= 4096 || face->is_full) {
+ bspn->full++;
+ samp->shadfac= NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/* based on available samples, recalculate the bounding box for bsp nodes, recursive */
+static void isb_bsp_recalc_box(ISBBranch *root)
+{
+ if (root->left) {
+ isb_bsp_recalc_box(root->left);
+ isb_bsp_recalc_box(root->right);
+ }
+ else if (root->totsamp) {
+ int a;
+
+ init_box(&root->box);
+ for (a=root->totsamp-1; a>=0; a--)
+ bound_boxf(&root->box, root->samples[a]->zco);
+ }
+}
+
+/* callback function for zbuf clip */
+static void isb_bsp_test_strand(ZSpan *zspan, int obi, int zvlnr,
+ const float *v1, const float *v2, const float *v3, const float *v4)
+{
+ BSPFace face;
+
+ face.v1= v1;
+ face.v2= v2;
+ face.v3= v3;
+ face.v4= v4;
+ face.obi= obi;
+ face.facenr= zvlnr & ~RE_QUAD_OFFS;
+ face.type= R_STRAND;
+ if (R.osa)
+ face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha/(float)R.osa);
+ else
+ face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha);
+
+ face.is_full= (zspan->shad_alpha==1.0f);
+
+ /* setup boundbox */
+ init_box(&face.box);
+ bound_boxf(&face.box, v1);
+ bound_boxf(&face.box, v2);
+ bound_boxf(&face.box, v3);
+ if (v4)
+ bound_boxf(&face.box, v4);
+
+ /* optimize values */
+ bspface_init_strand(&face);
+
+ isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face);
+
+}
+
+/* callback function for zbuf clip */
+static void isb_bsp_test_face(ZSpan *zspan, int obi, int zvlnr,
+ const float *v1, const float *v2, const float *v3, const float *v4)
+{
+ BSPFace face;
+
+ face.v1= v1;
+ face.v2= v2;
+ face.v3= v3;
+ face.v4= v4;
+ face.obi= obi;
+ face.facenr= zvlnr & ~RE_QUAD_OFFS;
+ face.type= 0;
+ if (R.osa)
+ face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha/(float)R.osa);
+ else
+ face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha);
+
+ face.is_full= (zspan->shad_alpha==1.0f);
+
+ /* setup boundbox */
+ init_box(&face.box);
+ bound_boxf(&face.box, v1);
+ bound_boxf(&face.box, v2);
+ bound_boxf(&face.box, v3);
+ if (v4)
+ bound_boxf(&face.box, v4);
+
+ isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face);
+}
+
+static int testclip_minmax(const float ho[4], const float minmax[4])
+{
+ float wco= ho[3];
+ int flag= 0;
+
+ if ( ho[0] > minmax[1]*wco) flag = 1;
+ else if ( ho[0]< minmax[0]*wco) flag = 2;
+
+ if ( ho[1] > minmax[3]*wco) flag |= 4;
+ else if ( ho[1]< minmax[2]*wco) flag |= 8;
+
+ return flag;
+}
+
+/* main loop going over all faces and check in bsp overlaps, fill in shadfac values */
+static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
+{
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ ShadBuf *shb= lar->shb;
+ ZSpan zspan, zspanstrand;
+ VlakRen *vlr= NULL;
+ Material *ma= NULL;
+ float minmaxf[4], winmat[4][4];
+ int size= shb->size;
+ int i, a, ok=1, lay= -1;
+
+ /* further optimize, also sets minz maxz */
+ isb_bsp_recalc_box(root);
+
+ /* extra clipping for minmax */
+ minmaxf[0]= (2.0f*root->box.xmin - size-2.0f)/size;
+ minmaxf[1]= (2.0f*root->box.xmax - size+2.0f)/size;
+ minmaxf[2]= (2.0f*root->box.ymin - size-2.0f)/size;
+ minmaxf[3]= (2.0f*root->box.ymax - size+2.0f)/size;
+
+ if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay;
+
+ /* (ab)use zspan, since we use zbuffer clipping code */
+ zbuf_alloc_span(&zspan, size, size, re->clipcrop);
+
+ zspan.zmulx= ((float)size)/2.0f;
+ zspan.zmuly= ((float)size)/2.0f;
+ zspan.zofsx= -0.5f;
+ zspan.zofsy= -0.5f;
+
+ /* pass on bsp root to zspan */
+ zspan.rectz= (int *)root;
+
+ /* filling methods */
+ zspanstrand= zspan;
+ // zspan.zbuflinefunc= zbufline_onlyZ;
+ zspan.zbuffunc= isb_bsp_test_face;
+ zspanstrand.zbuffunc= isb_bsp_test_strand;
+
+ for (i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_m4m4(winmat, shb->persmat, obi->mat);
+ else
+ copy_m4_m4(winmat, shb->persmat);
+
+ for (a=0; a<obr->totvlak; a++) {
+
+ if ((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ /* note, these conditions are copied in shadowbuf_autoclip() */
+ if (vlr->mat!= ma) {
+ ma= vlr->mat;
+ ok= 1;
+ if ((ma->mode2 & MA_CASTSHADOW)==0 || (ma->mode & MA_SHADBUF)==0) ok= 0;
+ if (ma->material_type == MA_TYPE_WIRE) ok= 0;
+ zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
+ }
+
+ if (ok && (obi->lay & lay)) {
+ float hoco[4][4];
+ int c1, c2, c3, c4=0;
+ int d1, d2, d3, d4=0;
+ int partclip;
+
+ /* create hocos per face, it is while render */
+ projectvert(vlr->v1->co, winmat, hoco[0]); d1= testclip_minmax(hoco[0], minmaxf);
+ projectvert(vlr->v2->co, winmat, hoco[1]); d2= testclip_minmax(hoco[1], minmaxf);
+ projectvert(vlr->v3->co, winmat, hoco[2]); d3= testclip_minmax(hoco[2], minmaxf);
+ if (vlr->v4) {
+ projectvert(vlr->v4->co, winmat, hoco[3]); d4= testclip_minmax(hoco[3], minmaxf);
+ }
+
+ /* minmax clipping */
+ if (vlr->v4) partclip= d1 & d2 & d3 & d4;
+ else partclip= d1 & d2 & d3;
+
+ if (partclip==0) {
+
+ /* window clipping */
+ c1= testclip(hoco[0]);
+ c2= testclip(hoco[1]);
+ c3= testclip(hoco[2]);
+ if (vlr->v4)
+ c4= testclip(hoco[3]);
+
+ /* ***** NO WIRE YET */
+ if (ma->material_type == MA_TYPE_WIRE) {
+ if (vlr->v4)
+ zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ else
+ zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], NULL, c1, c2, c3, 0);
+ }
+ else if (vlr->v4) {
+ if (vlr->flag & R_STRAND)
+ zbufclip4(&zspanstrand, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ else
+ zbufclip4(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ }
+ else
+ zbufclip(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], c1, c2, c3);
+
+ }
+ }
+ }
+ }
+
+ zbuf_free_span(&zspan);
+}
+
+/* returns 1 when the viewpixel is visible in lampbuffer */
+static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *vlr, float x, float y, float co_r[3])
+{
+ float hoco[4], v1[3], nor[3];
+ float dface, fac, siz;
+
+ RE_vlakren_get_normal(&R, obi, vlr, nor);
+ copy_v3_v3(v1, vlr->v1->co);
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_v3(obi->mat, v1);
+
+ /* from shadepixel() */
+ dface = dot_v3v3(v1, nor);
+ hoco[3]= 1.0f;
+
+ /* ortho viewplane cannot intersect using view vector originating in (0, 0, 0) */
+ if (R.r.mode & R_ORTHO) {
+ /* x and y 3d coordinate can be derived from pixel coord and winmat */
+ float fx= 2.0f/(R.winx*R.winmat[0][0]);
+ float fy= 2.0f/(R.winy*R.winmat[1][1]);
+
+ hoco[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
+ hoco[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
+
+ /* using a*x + b*y + c*z = d equation, (a b c) is normal */
+ if (nor[2]!=0.0f)
+ hoco[2]= (dface - nor[0]*hoco[0] - nor[1]*hoco[1])/nor[2];
+ else
+ hoco[2]= 0.0f;
+ }
+ else {
+ float div, view[3];
+
+ calc_view_vector(view, x, y);
+
+ div = dot_v3v3(nor, view);
+ if (div==0.0f)
+ return 0;
+
+ fac= dface/div;
+
+ hoco[0]= fac*view[0];
+ hoco[1]= fac*view[1];
+ hoco[2]= fac*view[2];
+ }
+
+ /* move 3d vector to lampbuf */
+ mul_m4_v4(shb->persmat, hoco); /* rational hom co */
+
+ /* clip We can test for -1.0/1.0 because of the properties of the
+ * coordinate transformations. */
+ fac = fabsf(hoco[3]);
+ if (hoco[0]<-fac || hoco[0]>fac)
+ return 0;
+ if (hoco[1]<-fac || hoco[1]>fac)
+ return 0;
+ if (hoco[2]<-fac || hoco[2]>fac)
+ return 0;
+
+ siz= 0.5f*(float)shb->size;
+ co_r[0]= siz*(1.0f+hoco[0]/hoco[3]) -0.5f;
+ co_r[1]= siz*(1.0f+hoco[1]/hoco[3]) -0.5f;
+ co_r[2]= ((float)0x7FFFFFFF)*(hoco[2]/hoco[3]);
+
+ /* XXXX bias, much less than normal shadbuf, or do we need a constant? */
+ co_r[2] -= 0.05f*shb->bias;
+
+ return 1;
+}
+
+/* storage of shadow results, solid osa and transp case */
+static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int obi, int facenr, short shadfac, short samples)
+{
+ ISBShadfacA *new;
+ float shadfacf;
+
+ /* in osa case, the samples were filled in with factor 1.0/R.osa. if fewer samples we have to correct */
+ if (R.osa)
+ shadfacf= ((float)shadfac*R.osa)/(4096.0f*samples);
+ else
+ shadfacf= ((float)shadfac)/(4096.0f);
+
+ new= BLI_memarena_alloc(mem, sizeof(ISBShadfacA));
+ new->obi= obi;
+ new->facenr= facenr & ~RE_QUAD_OFFS;
+ new->shadfac= shadfacf;
+ if (*isbsapp)
+ new->next= (*isbsapp);
+ else
+ new->next= NULL;
+
+ *isbsapp= new;
+}
+
+/* adding samples, solid case */
+static int isb_add_samples(RenderPart *pa, ISBBranch *root, MemArena *memarena, ISBSample **samplebuf)
+{
+ int xi, yi, *xcos, *ycos;
+ int sample, bsp_err= 0;
+
+ /* bsp split doesn't like to handle regular sequences */
+ xcos= MEM_mallocN(pa->rectx*sizeof(int), "xcos");
+ ycos= MEM_mallocN(pa->recty*sizeof(int), "ycos");
+ for (xi=0; xi<pa->rectx; xi++)
+ xcos[xi]= xi;
+ for (yi=0; yi<pa->recty; yi++)
+ ycos[yi]= yi;
+ BLI_array_randomize(xcos, sizeof(int), pa->rectx, 12345);
+ BLI_array_randomize(ycos, sizeof(int), pa->recty, 54321);
+
+ for (sample=0; sample<(R.osa?R.osa:1); sample++) {
+ ISBSample *samp= samplebuf[sample], *samp1;
+
+ for (yi=0; yi<pa->recty; yi++) {
+ int y= ycos[yi];
+ for (xi=0; xi<pa->rectx; xi++) {
+ int x= xcos[xi];
+ samp1= samp + y*pa->rectx + x;
+ if (samp1->facenr)
+ bsp_err |= isb_bsp_insert(root, memarena, samp1);
+ }
+ if (bsp_err) break;
+ }
+ }
+
+ MEM_freeN(xcos);
+ MEM_freeN(ycos);
+
+ return bsp_err;
+}
+
+/* solid version */
+/* lar->shb, pa->rectz and pa->rectp should exist */
+static void isb_make_buffer(RenderPart *pa, LampRen *lar)
+{
+ ShadBuf *shb= lar->shb;
+ ISBData *isbdata;
+ ISBSample *samp, *samplebuf[16]; /* should be RE_MAX_OSA */
+ ISBBranch root;
+ MemArena *memarena;
+ intptr_t *rd;
+ int *recto, *rectp, x, y, sindex, sample, bsp_err=0;
+
+ /* storage for shadow, per thread */
+ isbdata= shb->isb_result[pa->thread];
+
+ /* to map the shi->xs and ys coordinate */
+ isbdata->minx= pa->disprect.xmin;
+ isbdata->miny= pa->disprect.ymin;
+ isbdata->rectx= pa->rectx;
+ isbdata->recty= pa->recty;
+
+ /* branches are added using memarena (32k branches) */
+ memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena");
+ BLI_memarena_use_calloc(memarena);
+
+ /* samplebuf is in camera view space (pixels) */
+ for (sample=0; sample<(R.osa?R.osa:1); sample++)
+ samplebuf[sample]= MEM_callocN(sizeof(ISBSample)*pa->rectx*pa->recty, "isb samplebuf");
+
+ /* for end result, ISBSamples point to this in non OSA case, otherwise to pixstruct->shadfac */
+ if (R.osa==0)
+ isbdata->shadfacs= MEM_callocN(pa->rectx*pa->recty*sizeof(short), "isb shadfacs");
+
+ /* setup bsp root */
+ memset(&root, 0, sizeof(ISBBranch));
+ root.box.xmin = (float)shb->size;
+ root.box.ymin = (float)shb->size;
+
+ /* create the sample buffers */
+ for (sindex=0, y=0; y<pa->recty; y++) {
+ for (x=0; x<pa->rectx; x++, sindex++) {
+
+ /* this makes it a long function, but splitting it out would mean 10+ arguments */
+ /* first check OSA case */
+ if (R.osa) {
+ rd= pa->rectdaps + sindex;
+ if (*rd) {
+ float xs= (float)(x + pa->disprect.xmin);
+ float ys= (float)(y + pa->disprect.ymin);
+
+ for (sample=0; sample<R.osa; sample++) {
+ PixStr *ps= (PixStr *)(*rd);
+ int mask= (1<<sample);
+
+ while (ps) {
+ if (ps->mask & mask)
+ break;
+ ps= ps->next;
+ }
+ if (ps && ps->facenr>0) {
+ ObjectInstanceRen *obi= &R.objectinstance[ps->obi];
+ ObjectRen *obr= obi->obr;
+ VlakRen *vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
+
+ samp= samplebuf[sample] + sindex;
+ /* convert image plane pixel location to lamp buffer space */
+ if (viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], samp->zco)) {
+ samp->obi= ps->obi;
+ samp->facenr= ps->facenr & ~RE_QUAD_OFFS;
+ ps->shadfac= 0;
+ samp->shadfac= &ps->shadfac;
+ bound_rectf((rctf *)&root.box, samp->zco);
+ }
+ }
+ }
+ }
+ }
+ else {
+ rectp= pa->rectp + sindex;
+ recto= pa->recto + sindex;
+ if (*rectp>0) {
+ ObjectInstanceRen *obi= &R.objectinstance[*recto];
+ ObjectRen *obr= obi->obr;
+ VlakRen *vlr= RE_findOrAddVlak(obr, (*rectp-1) & RE_QUAD_MASK);
+ float xs= (float)(x + pa->disprect.xmin);
+ float ys= (float)(y + pa->disprect.ymin);
+
+ samp= samplebuf[0] + sindex;
+ /* convert image plane pixel location to lamp buffer space */
+ if (viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, samp->zco)) {
+ samp->obi= *recto;
+ samp->facenr= *rectp & ~RE_QUAD_OFFS;
+ samp->shadfac= isbdata->shadfacs + sindex;
+ bound_rectf((rctf *)&root.box, samp->zco);
+ }
+ }
+ }
+ }
+ }
+
+ /* simple method to see if we have samples */
+ if (root.box.xmin != (float)shb->size) {
+ /* now create a regular split, root.box has the initial bounding box of all pixels */
+ /* split bsp 8 levels deep, in regular grid (16 x 16) */
+ isb_bsp_split_init(&root, memarena, 8);
+
+ /* insert all samples in BSP now */
+ bsp_err= isb_add_samples(pa, &root, memarena, samplebuf);
+
+ if (bsp_err==0) {
+ /* go over all faces and fill in shadow values */
+
+ isb_bsp_fillfaces(&R, lar, &root); /* shb->persmat should have been calculated */
+
+ /* copy shadow samples to persistent buffer, reduce memory overhead */
+ if (R.osa) {
+ ISBShadfacA **isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs");
+
+ isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena");
+ BLI_memarena_use_calloc(isbdata->memarena);
+
+ for (rd= pa->rectdaps, x=pa->rectx*pa->recty; x>0; x--, rd++, isbsa++) {
+
+ if (*rd) {
+ PixStr *ps= (PixStr *)(*rd);
+ while (ps) {
+ if (ps->shadfac)
+ isb_add_shadfac(isbsa, isbdata->memarena, ps->obi, ps->facenr, ps->shadfac, count_mask(ps->mask));
+ ps= ps->next;
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ if (isbdata->shadfacs) {
+ MEM_freeN(isbdata->shadfacs);
+ isbdata->shadfacs= NULL;
+ }
+ }
+
+ /* free BSP */
+ BLI_memarena_free(memarena);
+
+ /* free samples */
+ for (x=0; x<(R.osa?R.osa:1); x++)
+ MEM_freeN(samplebuf[x]);
+
+ if (bsp_err) printf("error in filling bsp\n");
+}
+
+/* add sample to buffer, isbsa is the root sample in a buffer */
+static ISBSampleA *isb_alloc_sample_transp(ISBSampleA **isbsa, MemArena *mem)
+{
+ ISBSampleA *new;
+
+ new= BLI_memarena_alloc(mem, sizeof(ISBSampleA));
+ if (*isbsa)
+ new->next= (*isbsa);
+ else
+ new->next= NULL;
+
+ *isbsa= new;
+ return new;
+}
+
+/* adding samples in BSP, transparent case */
+static int isb_add_samples_transp(RenderPart *pa, ISBBranch *root, MemArena *memarena, ISBSampleA ***samplebuf)
+{
+ int xi, yi, *xcos, *ycos;
+ int sample, bsp_err= 0;
+
+ /* bsp split doesn't like to handle regular sequences */
+ xcos= MEM_mallocN(pa->rectx*sizeof(int), "xcos");
+ ycos= MEM_mallocN(pa->recty*sizeof(int), "ycos");
+ for (xi=0; xi<pa->rectx; xi++)
+ xcos[xi]= xi;
+ for (yi=0; yi<pa->recty; yi++)
+ ycos[yi]= yi;
+ BLI_array_randomize(xcos, sizeof(int), pa->rectx, 12345);
+ BLI_array_randomize(ycos, sizeof(int), pa->recty, 54321);
+
+ for (sample=0; sample<(R.osa?R.osa:1); sample++) {
+ ISBSampleA **samp= samplebuf[sample], *samp1;
+
+ for (yi=0; yi<pa->recty; yi++) {
+ int y= ycos[yi];
+ for (xi=0; xi<pa->rectx; xi++) {
+ int x= xcos[xi];
+
+ samp1= *(samp + y*pa->rectx + x);
+ while (samp1) {
+ bsp_err |= isb_bsp_insert(root, memarena, (ISBSample *)samp1);
+ samp1= samp1->next;
+ }
+ }
+ if (bsp_err) break;
+ }
+ }
+
+ MEM_freeN(xcos);
+ MEM_freeN(ycos);
+
+ return bsp_err;
+}
+
+
+/* Ztransp version */
+/* lar->shb, pa->rectz and pa->rectp should exist */
+static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *lar)
+{
+ ShadBuf *shb= lar->shb;
+ ISBData *isbdata;
+ ISBSampleA *samp, **samplebuf[16]; /* MAX_OSA */
+ ISBBranch root;
+ MemArena *memarena;
+ APixstr *ap;
+ int x, y, sindex, sample, bsp_err=0;
+
+ /* storage for shadow, per thread */
+ isbdata= shb->isb_result[pa->thread];
+
+ /* to map the shi->xs and ys coordinate */
+ isbdata->minx= pa->disprect.xmin;
+ isbdata->miny= pa->disprect.ymin;
+ isbdata->rectx= pa->rectx;
+ isbdata->recty= pa->recty;
+
+ /* branches are added using memarena (32k branches) */
+ memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena");
+ BLI_memarena_use_calloc(memarena);
+
+ /* samplebuf is in camera view space (pixels) */
+ for (sample=0; sample<(R.osa?R.osa:1); sample++)
+ samplebuf[sample]= MEM_callocN(sizeof(void *)*pa->rectx*pa->recty, "isb alpha samplebuf");
+
+ /* setup bsp root */
+ memset(&root, 0, sizeof(ISBBranch));
+ root.box.xmin = (float)shb->size;
+ root.box.ymin = (float)shb->size;
+
+ /* create the sample buffers */
+ for (ap= apixbuf, sindex=0, y=0; y<pa->recty; y++) {
+ for (x=0; x<pa->rectx; x++, sindex++, ap++) {
+
+ if (ap->p[0]) {
+ APixstr *apn;
+ float xs= (float)(x + pa->disprect.xmin);
+ float ys= (float)(y + pa->disprect.ymin);
+
+ for (apn=ap; apn; apn= apn->next) {
+ int a;
+ for (a=0; a<4; a++) {
+ if (apn->p[a]) {
+ ObjectInstanceRen *obi= &R.objectinstance[apn->obi[a]];
+ ObjectRen *obr= obi->obr;
+ VlakRen *vlr= RE_findOrAddVlak(obr, (apn->p[a]-1) & RE_QUAD_MASK);
+ float zco[3];
+
+ /* here we store shadfac, easier to create the end storage buffer. needs zero'ed, multiple shadowbufs use it */
+ apn->shadfac[a]= 0;
+
+ if (R.osa) {
+ for (sample=0; sample<R.osa; sample++) {
+ int mask= (1<<sample);
+
+ if (apn->mask[a] & mask) {
+
+ /* convert image plane pixel location to lamp buffer space */
+ if (viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], zco)) {
+ samp= isb_alloc_sample_transp(samplebuf[sample] + sindex, memarena);
+ samp->obi= apn->obi[a];
+ samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
+ samp->shadfac= &apn->shadfac[a];
+
+ copy_v3_v3(samp->zco, zco);
+ bound_rectf((rctf *)&root.box, samp->zco);
+ }
+ }
+ }
+ }
+ else {
+
+ /* convert image plane pixel location to lamp buffer space */
+ if (viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, zco)) {
+
+ samp= isb_alloc_sample_transp(samplebuf[0] + sindex, memarena);
+ samp->obi= apn->obi[a];
+ samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
+ samp->shadfac= &apn->shadfac[a];
+
+ copy_v3_v3(samp->zco, zco);
+ bound_rectf((rctf *)&root.box, samp->zco);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* simple method to see if we have samples */
+ if (root.box.xmin != (float)shb->size) {
+ /* now create a regular split, root.box has the initial bounding box of all pixels */
+ /* split bsp 8 levels deep, in regular grid (16 x 16) */
+ isb_bsp_split_init(&root, memarena, 8);
+
+ /* insert all samples in BSP now */
+ bsp_err= isb_add_samples_transp(pa, &root, memarena, samplebuf);
+
+ if (bsp_err==0) {
+ ISBShadfacA **isbsa;
+
+ /* go over all faces and fill in shadow values */
+ isb_bsp_fillfaces(&R, lar, &root); /* shb->persmat should have been calculated */
+
+ /* copy shadow samples to persistent buffer, reduce memory overhead */
+ isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs");
+
+ isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena");
+
+ for (ap= apixbuf, x=pa->rectx*pa->recty; x>0; x--, ap++, isbsa++) {
+
+ if (ap->p[0]) {
+ APixstr *apn;
+ for (apn=ap; apn; apn= apn->next) {
+ int a;
+ for (a=0; a<4; a++) {
+ if (apn->p[a] && apn->shadfac[a]) {
+ if (R.osa)
+ isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], count_mask(apn->mask[a]));
+ else
+ isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], 0);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* free BSP */
+ BLI_memarena_free(memarena);
+
+ /* free samples */
+ for (x=0; x<(R.osa?R.osa:1); x++)
+ MEM_freeN(samplebuf[x]);
+
+ if (bsp_err) printf("error in filling bsp\n");
+}
+
+
+
+/* exported */
+
+/* returns amount of light (1.0 = no shadow) */
+/* note, shadepixel() rounds the coordinate, not the real sample info */
+float ISB_getshadow(ShadeInput *shi, ShadBuf *shb)
+{
+ /* if raytracing, we can't accept irregular shadow */
+ if (shi->depth==0) {
+ ISBData *isbdata= shb->isb_result[shi->thread];
+
+ if (isbdata) {
+ if (isbdata->shadfacs || isbdata->shadfaca) {
+ int x= shi->xs - isbdata->minx;
+
+ if (x >= 0 && x < isbdata->rectx) {
+ int y= shi->ys - isbdata->miny;
+
+ if (y >= 0 && y < isbdata->recty) {
+ if (isbdata->shadfacs) {
+ const short *sp= isbdata->shadfacs + y*isbdata->rectx + x;
+ return *sp>=4096?0.0f:1.0f - ((float)*sp)/4096.0f;
+ }
+ else {
+ int sindex= y*isbdata->rectx + x;
+ int obi= shi->obi - R.objectinstance;
+ ISBShadfacA *isbsa= *(isbdata->shadfaca + sindex);
+
+ while (isbsa) {
+ if (isbsa->facenr==shi->facenr+1 && isbsa->obi==obi)
+ return isbsa->shadfac>=1.0f?0.0f:1.0f - isbsa->shadfac;
+ isbsa= isbsa->next;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return 1.0f;
+}
+
+/* part is supposed to be solid zbuffered (apixbuf==NULL) or transparent zbuffered */
+void ISB_create(RenderPart *pa, APixstr *apixbuf)
+{
+ GroupObject *go;
+
+ /* go over all lamps, and make the irregular buffers */
+ for (go=R.lights.first; go; go= go->next) {
+ LampRen *lar= go->lampren;
+
+ if (lar->type==LA_SPOT && lar->shb && lar->buftype==LA_SHADBUF_IRREGULAR) {
+
+ /* create storage for shadow, per thread */
+ lar->shb->isb_result[pa->thread]= MEM_callocN(sizeof(ISBData), "isb data");
+
+ if (apixbuf)
+ isb_make_buffer_transp(pa, apixbuf, lar);
+ else
+ isb_make_buffer(pa, lar);
+ }
+ }
+}
+
+
+/* end of part rendering, free stored shadow data for this thread from all lamps */
+void ISB_free(RenderPart *pa)
+{
+ GroupObject *go;
+
+ /* go over all lamps, and free the irregular buffers */
+ for (go=R.lights.first; go; go= go->next) {
+ LampRen *lar= go->lampren;
+
+ if (lar->type==LA_SPOT && lar->shb && lar->buftype==LA_SHADBUF_IRREGULAR) {
+ ISBData *isbdata= lar->shb->isb_result[pa->thread];
+
+ if (isbdata) {
+ if (isbdata->shadfacs)
+ MEM_freeN(isbdata->shadfacs);
+ if (isbdata->shadfaca)
+ MEM_freeN(isbdata->shadfaca);
+
+ if (isbdata->memarena)
+ BLI_memarena_free(isbdata->memarena);
+
+ MEM_freeN(isbdata);
+ lar->shb->isb_result[pa->thread]= NULL;
+ }
+ }
+ }
+}
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
new file mode 100644
index 00000000000..d79749871c3
--- /dev/null
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -0,0 +1,1490 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation
+ * All rights reserved.
+ *
+ * Contributors: Hos, Robert Wenzlaff.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/shadeinput.c
+ * \ingroup render
+ */
+
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_lamp_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_material_types.h"
+#include "DNA_particle_types.h"
+
+#include "BKE_scene.h"
+
+#include "BKE_node.h"
+
+/* local include */
+#include "raycounter.h"
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "rendercore.h"
+#include "shading.h"
+#include "strand.h"
+#include "texture.h"
+#include "volumetric.h"
+#include "zbuf.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+/* Shade Sample order:
+ *
+ * - shade_samples_fill_with_ps()
+ * - for each sample
+ * - shade_input_set_triangle() <- if prev sample-face is same, use shade_input_copy_triangle()
+ * - if vlr
+ * - shade_input_set_viewco() <- not for ray or bake
+ * - shade_input_set_uv() <- not for ray or bake
+ * - shade_input_set_normals()
+ * - shade_samples()
+ * - if AO
+ * - shade_samples_do_AO()
+ * - if shading happens
+ * - for each sample
+ * - shade_input_set_shade_texco()
+ * - shade_samples_do_shade()
+ * - OSA: distribute sample result with filter masking
+ *
+ */
+
+/* initialize material variables in shadeinput,
+ * doing inverse gamma correction where applicable */
+void shade_input_init_material(ShadeInput *shi)
+{
+ /* note, keep this synced with render_types.h */
+ memcpy(&shi->r, &shi->mat->r, 23 * sizeof(float));
+ shi->har = shi->mat->har;
+}
+
+/* also used as callback for nodes */
+/* delivers a fully filled in ShadeResult, for all passes */
+void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
+{
+
+ shade_lamp_loop(shi, shr); /* clears shr */
+
+ if (shi->translucency != 0.0f) {
+ ShadeResult shr_t;
+ float fac = shi->translucency;
+
+ shade_input_init_material(shi);
+ negate_v3_v3(shi->vn, shi->vno);
+ negate_v3(shi->facenor);
+ shi->depth++; /* hack to get real shadow now */
+ shade_lamp_loop(shi, &shr_t);
+ shi->depth--;
+
+ /* a couple of passes */
+ madd_v3_v3fl(shr->combined, shr_t.combined, fac);
+ if (shi->passflag & SCE_PASS_SPEC)
+ madd_v3_v3fl(shr->spec, shr_t.spec, fac);
+ if (shi->passflag & SCE_PASS_DIFFUSE) {
+ madd_v3_v3fl(shr->diff, shr_t.diff, fac);
+ madd_v3_v3fl(shr->diffshad, shr_t.diffshad, fac);
+ }
+ if (shi->passflag & SCE_PASS_SHADOW)
+ madd_v3_v3fl(shr->shad, shr_t.shad, fac);
+
+ negate_v3(shi->vn);
+ negate_v3(shi->facenor);
+ }
+
+ /* depth >= 1 when ray-shading */
+ if (shi->depth == 0 || shi->volume_depth > 0) {
+ if (R.r.mode & R_RAYTRACE) {
+ if (shi->ray_mirror != 0.0f || ((shi->mode & MA_TRANSP) && (shi->mode & MA_RAYTRANSP) && shr->alpha != 1.0f)) {
+ /* ray trace works on combined, but gives pass info */
+ ray_trace(shi, shr);
+ }
+ }
+ /* disable adding of sky for raytransp */
+ if ((shi->mode & MA_TRANSP) && (shi->mode & MA_RAYTRANSP))
+ if ((shi->layflag & SCE_LAY_SKY) && (R.r.alphamode == R_ADDSKY))
+ shr->alpha = 1.0f;
+ }
+
+ if (R.r.mode & R_RAYTRACE) {
+ if (R.render_volumes_inside.first)
+ shade_volume_inside(shi, shr);
+ }
+}
+
+
+/* do a shade, finish up some passes, apply mist */
+void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
+{
+ bool compat = false;
+ float alpha;
+
+ /* ------ main shading loop -------- */
+#ifdef RE_RAYCOUNTER
+ memset(&shi->raycounter, 0, sizeof(shi->raycounter));
+#endif
+
+ if (shi->mat->nodetree && shi->mat->use_nodes) {
+ compat = ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
+ }
+
+ /* also run this when node shaders fail, due to incompatible shader nodes */
+ if (compat == false) {
+ /* copy all relevant material vars, note, keep this synced with render_types.h */
+ shade_input_init_material(shi);
+
+ if (shi->mat->material_type == MA_TYPE_VOLUME) {
+ if (R.r.mode & R_RAYTRACE) {
+ shade_volume_outside(shi, shr);
+ }
+ }
+ else { /* MA_TYPE_SURFACE, MA_TYPE_WIRE */
+ shade_material_loop(shi, shr);
+ }
+ }
+
+ /* copy additional passes */
+ if (shi->passflag & (SCE_PASS_VECTOR | SCE_PASS_NORMAL)) {
+ copy_v4_v4(shr->winspeed, shi->winspeed);
+ copy_v3_v3(shr->nor, shi->vn);
+ }
+
+ /* MIST */
+ if ((shi->passflag & SCE_PASS_MIST) || ((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST) == 0)) {
+ if (R.r.mode & R_ORTHO)
+ shr->mist = mistfactor(-shi->co[2], shi->co);
+ else
+ shr->mist = mistfactor(len_v3(shi->co), shi->co);
+ }
+ else shr->mist = 0.0f;
+
+ if ((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST) == 0) {
+ alpha = shr->mist;
+ }
+ else alpha = 1.0f;
+
+ /* add mist and premul color */
+ if (shr->alpha != 1.0f || alpha != 1.0f) {
+ float fac = alpha * (shr->alpha);
+ shr->combined[3] = fac;
+
+ if (shi->mat->material_type != MA_TYPE_VOLUME)
+ mul_v3_fl(shr->combined, fac);
+ }
+ else
+ shr->combined[3] = 1.0f;
+
+ /* add z */
+ shr->z = -shi->co[2];
+
+ /* RAYHITS */
+#if 0
+ if (1 || shi->passflag & SCE_PASS_RAYHITS) {
+ shr->rayhits[0] = (float)shi->raycounter.faces.test;
+ shr->rayhits[1] = (float)shi->raycounter.bb.hit;
+ shr->rayhits[2] = 0.0;
+ shr->rayhits[3] = 1.0;
+ }
+#endif
+
+ RE_RC_MERGE(&re_rc_counter[shi->thread], &shi->raycounter);
+}
+
+/* **************************************************************************** */
+/* ShadeInput */
+/* **************************************************************************** */
+
+
+void vlr_set_uv_indices(VlakRen *vlr, int *i1, int *i2, int *i3)
+{
+ /* to prevent storing new tfaces or vcols, we check a split runtime */
+ /* 4---3 4---3 */
+ /* |\ 1| or |1 /| */
+ /* |0\ | |/ 0| */
+ /* 1---2 1---2 0 = orig face, 1 = new face */
+
+ /* Update vert nums to point to correct verts of original face */
+ if (vlr->flag & R_DIVIDE_24) {
+ if (vlr->flag & R_FACE_SPLIT) {
+ (*i1)++; (*i2)++; (*i3)++;
+ }
+ else {
+ (*i3)++;
+ }
+ }
+ else if (vlr->flag & R_FACE_SPLIT) {
+ (*i2)++; (*i3)++;
+ }
+}
+
+/* copy data from face to ShadeInput, general case */
+/* indices 0 1 2 3 only */
+void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen *vlr, short i1, short i2, short i3)
+{
+ VertRen **vpp = &vlr->v1;
+
+ shi->vlr = vlr;
+ shi->obi = obi;
+ shi->obr = obi->obr;
+
+ shi->v1 = vpp[i1];
+ shi->v2 = vpp[i2];
+ shi->v3 = vpp[i3];
+
+ shi->i1 = i1;
+ shi->i2 = i2;
+ shi->i3 = i3;
+
+ /* note, shi->mat is set in node shaders */
+ shi->mat = shi->mat_override ? shi->mat_override : vlr->mat;
+
+ shi->osatex = (shi->mat->texco & TEXCO_OSA);
+ shi->mode = shi->mat->mode_l; /* or-ed result for all nodes */
+ shi->mode2 = shi->mat->mode2_l;
+
+ /* facenormal copy, can get flipped */
+ shi->flippednor = 0;
+ RE_vlakren_get_normal(&R, obi, vlr, shi->facenor);
+
+ /* calculate vertexnormals */
+ if (vlr->flag & R_SMOOTH) {
+ copy_v3_v3(shi->n1, shi->v1->n);
+ copy_v3_v3(shi->n2, shi->v2->n);
+ copy_v3_v3(shi->n3, shi->v3->n);
+
+ if (obi->flag & R_TRANSFORMED) {
+ mul_m3_v3(obi->nmat, shi->n1); normalize_v3(shi->n1);
+ mul_m3_v3(obi->nmat, shi->n2); normalize_v3(shi->n2);
+ mul_m3_v3(obi->nmat, shi->n3); normalize_v3(shi->n3);
+ }
+ }
+}
+
+/* copy data from face to ShadeInput, scanline case */
+void shade_input_set_triangle(ShadeInput *shi, int obi, int facenr, int UNUSED(normal_flip))
+{
+ if (facenr > 0) {
+ shi->obi = &R.objectinstance[obi];
+ shi->obr = shi->obi->obr;
+ shi->facenr = (facenr - 1) & RE_QUAD_MASK;
+ if (shi->facenr < shi->obr->totvlak) {
+ VlakRen *vlr = RE_findOrAddVlak(shi->obr, shi->facenr);
+
+ if (facenr & RE_QUAD_OFFS)
+ shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 2, 3);
+ else
+ shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 1, 2);
+ }
+ else
+ shi->vlr = NULL; /* general signal we got sky */
+ }
+ else
+ shi->vlr = NULL; /* general signal we got sky */
+}
+
+/* full osa case: copy static info */
+void shade_input_copy_triangle(ShadeInput *shi, ShadeInput *from)
+{
+ /* not so nice, but works... warning is in RE_shader_ext.h */
+ memcpy(shi, from, sizeof(struct ShadeInputCopy));
+}
+
+/* copy data from strand to shadeinput */
+void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spoint)
+{
+ /* note, shi->mat is set in node shaders */
+ shi->mat = shi->mat_override ? shi->mat_override : strand->buffer->ma;
+
+ shi->osatex = (shi->mat->texco & TEXCO_OSA);
+ shi->mode = shi->mat->mode_l; /* or-ed result for all nodes */
+
+ /* shade_input_set_viewco equivalent */
+ copy_v3_v3(shi->co, spoint->co);
+ copy_v3_v3(shi->view, shi->co);
+ normalize_v3(shi->view);
+
+ shi->xs = (int)spoint->x;
+ shi->ys = (int)spoint->y;
+
+ if (shi->osatex || (R.r.mode & R_SHADOW)) {
+ copy_v3_v3(shi->dxco, spoint->dtco);
+ copy_v3_v3(shi->dyco, spoint->dsco);
+ }
+
+ /* dxview, dyview, not supported */
+
+ /* facenormal, simply viewco flipped */
+ copy_v3_v3(shi->facenor, spoint->nor);
+
+ /* shade_input_set_normals equivalent */
+ if (shi->mat->mode & MA_TANGENT_STR) {
+ copy_v3_v3(shi->vn, spoint->tan);
+ }
+ else {
+ float cross[3];
+
+ cross_v3_v3v3(cross, spoint->co, spoint->tan);
+ cross_v3_v3v3(shi->vn, cross, spoint->tan);
+ normalize_v3(shi->vn);
+
+ if (dot_v3v3(shi->vn, shi->view) < 0.0f)
+ negate_v3(shi->vn);
+ }
+
+ copy_v3_v3(shi->vno, shi->vn);
+}
+
+void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert *svert, StrandPoint *spoint)
+{
+ StrandBuffer *strandbuf = strand->buffer;
+ ObjectRen *obr = strandbuf->obr;
+ StrandVert *sv;
+ int mode = shi->mode; /* or-ed result for all nodes */
+ short texco = shi->mat->texco;
+
+ if ((shi->mat->texco & TEXCO_REFL)) {
+ /* shi->dxview, shi->dyview, not supported */
+ }
+
+ if (shi->osatex && (texco & (TEXCO_NORM | TEXCO_REFL))) {
+ /* not supported */
+ }
+
+ if (mode & (MA_TANGENT_V | MA_NORMAP_TANG)) {
+ copy_v3_v3(shi->tang, spoint->tan);
+ copy_v3_v3(shi->nmaptang, spoint->tan);
+ }
+
+ if (mode & MA_STR_SURFDIFF) {
+ const float *surfnor = RE_strandren_get_surfnor(obr, strand, 0);
+
+ if (surfnor)
+ copy_v3_v3(shi->surfnor, surfnor);
+ else
+ copy_v3_v3(shi->surfnor, shi->vn);
+
+ if (shi->mat->strand_surfnor > 0.0f) {
+ shi->surfdist = 0.0f;
+ for (sv = strand->vert; sv != svert; sv++)
+ shi->surfdist += len_v3v3(sv->co, (sv + 1)->co);
+ shi->surfdist += spoint->t * len_v3v3(sv->co, (sv + 1)->co);
+ }
+ }
+
+ if (R.r.mode & R_SPEED) {
+ const float *speed;
+
+ speed = RE_strandren_get_winspeed(shi->obi, strand, 0);
+ if (speed)
+ copy_v4_v4(shi->winspeed, speed);
+ else
+ shi->winspeed[0] = shi->winspeed[1] = shi->winspeed[2] = shi->winspeed[3] = 0.0f;
+ }
+
+ /* shade_input_set_shade_texco equivalent */
+ if (texco & NEED_UV) {
+ if (texco & TEXCO_ORCO) {
+ copy_v3_v3(shi->lo, strand->orco);
+ /* no shi->osatex, orco derivatives are zero */
+ }
+
+ if (texco & TEXCO_GLOB) {
+ mul_v3_m4v3(shi->gl, R.viewinv, shi->co);
+
+ if (shi->osatex) {
+ mul_v3_mat3_m4v3(shi->dxgl, R.viewinv, shi->dxco);
+ mul_v3_mat3_m4v3(shi->dygl, R.viewinv, shi->dyco);
+ }
+ }
+
+ if (texco & TEXCO_STRAND) {
+ shi->strandco = spoint->strandco;
+
+ if (shi->osatex) {
+ shi->dxstrand = spoint->dtstrandco;
+ shi->dystrand = 0.0f;
+ }
+ }
+
+ if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE))) {
+ MCol *mcol;
+ const float *uv;
+ char *name;
+ int i;
+
+ shi->totuv = 0;
+ shi->totcol = 0;
+ shi->actuv = obr->actmtface;
+ shi->actcol = obr->actmcol;
+
+ if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) {
+ for (i = 0; (mcol = RE_strandren_get_mcol(obr, strand, i, &name, 0)); i++) {
+ ShadeInputCol *scol = &shi->col[i];
+ const char *cp = (char *)mcol;
+
+ shi->totcol++;
+ scol->name = name;
+
+ scol->col[0] = cp[3] / 255.0f;
+ scol->col[1] = cp[2] / 255.0f;
+ scol->col[2] = cp[1] / 255.0f;
+ scol->col[3] = cp[0] / 255.0f;
+ }
+
+ if (shi->totcol) {
+ shi->vcol[0] = shi->col[shi->actcol].col[0];
+ shi->vcol[1] = shi->col[shi->actcol].col[1];
+ shi->vcol[2] = shi->col[shi->actcol].col[2];
+ shi->vcol[3] = shi->col[shi->actcol].col[3];
+ }
+ else {
+ shi->vcol[0] = 0.0f;
+ shi->vcol[1] = 0.0f;
+ shi->vcol[2] = 0.0f;
+ shi->vcol[3] = 0.0f;
+ }
+ }
+
+ for (i = 0; (uv = RE_strandren_get_uv(obr, strand, i, &name, 0)); i++) {
+ ShadeInputUV *suv = &shi->uv[i];
+
+ shi->totuv++;
+ suv->name = name;
+
+ if (strandbuf->overrideuv == i) {
+ suv->uv[0] = -1.0f;
+ suv->uv[1] = spoint->strandco;
+ suv->uv[2] = 0.0f;
+ }
+ else {
+ suv->uv[0] = -1.0f + 2.0f * uv[0];
+ suv->uv[1] = -1.0f + 2.0f * uv[1];
+ suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
+ }
+
+ if (shi->osatex) {
+ suv->dxuv[0] = 0.0f;
+ suv->dxuv[1] = 0.0f;
+ suv->dyuv[0] = 0.0f;
+ suv->dyuv[1] = 0.0f;
+ }
+
+ if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
+ if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) {
+ shi->vcol[0] = 1.0f;
+ shi->vcol[1] = 1.0f;
+ shi->vcol[2] = 1.0f;
+ shi->vcol[3] = 1.0f;
+ }
+ }
+ }
+
+ if (shi->totuv == 0) {
+ ShadeInputUV *suv = &shi->uv[0];
+
+ suv->uv[0] = 0.0f;
+ suv->uv[1] = spoint->strandco;
+ suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
+
+ if (mode & MA_FACETEXTURE) {
+ /* no tface? set at 1.0f */
+ shi->vcol[0] = 1.0f;
+ shi->vcol[1] = 1.0f;
+ shi->vcol[2] = 1.0f;
+ shi->vcol[3] = 1.0f;
+ }
+ }
+
+ }
+
+ if (texco & TEXCO_NORM) {
+ shi->orn[0] = -shi->vn[0];
+ shi->orn[1] = -shi->vn[1];
+ shi->orn[2] = -shi->vn[2];
+ }
+
+ if (texco & TEXCO_STRESS) {
+ /* not supported */
+ }
+
+ if (texco & TEXCO_TANGENT) {
+ if ((mode & MA_TANGENT_V) == 0) {
+ /* just prevent surprises */
+ shi->tang[0] = shi->tang[1] = shi->tang[2] = 0.0f;
+ shi->nmaptang[0] = shi->nmaptang[1] = shi->nmaptang[2] = 0.0f;
+ }
+ }
+ }
+
+ /* this only avalailable for scanline renders */
+ if (shi->depth == 0) {
+ if (texco & TEXCO_WINDOW) {
+ shi->winco[0] = -1.0f + 2.0f * spoint->x / (float)R.winx;
+ shi->winco[1] = -1.0f + 2.0f * spoint->y / (float)R.winy;
+ shi->winco[2] = 0.0f;
+
+ /* not supported */
+ if (shi->osatex) {
+ shi->dxwin[0] = 0.0f;
+ shi->dywin[1] = 0.0f;
+ shi->dxwin[0] = 0.0f;
+ shi->dywin[1] = 0.0f;
+ }
+ }
+ }
+
+ if (shi->do_manage) {
+ if (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) {
+ srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
+ }
+ }
+
+}
+
+/* from scanline pixel coordinates to 3d coordinates, requires set_triangle */
+void shade_input_calc_viewco(ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3])
+{
+ /* returns not normalized, so is in viewplane coords */
+ calc_view_vector(view, x, y);
+
+ if (shi->mat->material_type == MA_TYPE_WIRE) {
+ /* wire cannot use normal for calculating shi->co, so
+ * we reconstruct the coordinate less accurate */
+ if (R.r.mode & R_ORTHO)
+ calc_renderco_ortho(co, x, y, z);
+ else
+ calc_renderco_zbuf(co, view, z);
+ }
+ else {
+ /* for non-wire, intersect with the triangle to get the exact coord */
+ float fac, dface, v1[3];
+
+ copy_v3_v3(v1, shi->v1->co);
+ if (shi->obi->flag & R_TRANSFORMED)
+ mul_m4_v3(shi->obi->mat, v1);
+
+ dface = dot_v3v3(v1, shi->facenor);
+
+ /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */
+ if (R.r.mode & R_ORTHO) {
+ /* x and y 3d coordinate can be derived from pixel coord and winmat */
+ float fx = 2.0f / (R.winx * R.winmat[0][0]);
+ float fy = 2.0f / (R.winy * R.winmat[1][1]);
+
+ co[0] = (x - 0.5f * R.winx) * fx - R.winmat[3][0] / R.winmat[0][0];
+ co[1] = (y - 0.5f * R.winy) * fy - R.winmat[3][1] / R.winmat[1][1];
+
+ /* using a*x + b*y + c*z = d equation, (a b c) is normal */
+ if (shi->facenor[2] != 0.0f)
+ co[2] = (dface - shi->facenor[0] * co[0] - shi->facenor[1] * co[1]) / shi->facenor[2];
+ else
+ co[2] = 0.0f;
+
+ if (dxco && dyco) {
+ dxco[0] = fx;
+ dxco[1] = 0.0f;
+ if (shi->facenor[2] != 0.0f)
+ dxco[2] = -(shi->facenor[0] * fx) / shi->facenor[2];
+ else
+ dxco[2] = 0.0f;
+
+ dyco[0] = 0.0f;
+ dyco[1] = fy;
+ if (shi->facenor[2] != 0.0f)
+ dyco[2] = -(shi->facenor[1] * fy) / shi->facenor[2];
+ else
+ dyco[2] = 0.0f;
+
+ if (dxyview) {
+ fac = (co[2] != 0.0f) ? (1.0f / co[2]) : 0.0f;
+ dxyview[0] = -R.viewdx * fac;
+ dxyview[1] = -R.viewdy * fac;
+ }
+ }
+ }
+ else {
+ float div;
+
+ div = dot_v3v3(shi->facenor, view);
+ if (div != 0.0f) fac = dface / div;
+ else fac = 0.0f;
+
+ co[0] = fac * view[0];
+ co[1] = fac * view[1];
+ co[2] = fac * view[2];
+
+ /* pixel dx/dy for render coord */
+ if (dxco && dyco) {
+ float u = dface / (div - R.viewdx * shi->facenor[0]);
+ float v = dface / (div - R.viewdy * shi->facenor[1]);
+
+ dxco[0] = co[0] - (view[0] - R.viewdx) * u;
+ dxco[1] = co[1] - (view[1]) * u;
+ dxco[2] = co[2] - (view[2]) * u;
+
+ dyco[0] = co[0] - (view[0]) * v;
+ dyco[1] = co[1] - (view[1] - R.viewdy) * v;
+ dyco[2] = co[2] - (view[2]) * v;
+
+ if (dxyview) {
+ if (fac != 0.0f) fac = 1.0f / fac;
+ dxyview[0] = -R.viewdx * fac;
+ dxyview[1] = -R.viewdy * fac;
+ }
+ }
+ }
+ }
+
+ /* set camera coords - for scanline, it's always 0.0,0.0,0.0 (render is in camera space)
+ * however for raytrace it can be different - the position of the last intersection */
+ shi->camera_co[0] = shi->camera_co[1] = shi->camera_co[2] = 0.0f;
+
+ /* cannot normalize earlier, code above needs it at viewplane level */
+ normalize_v3(view);
+}
+
+/* from scanline pixel coordinates to 3d coordinates, requires set_triangle */
+void shade_input_set_viewco(ShadeInput *shi, float x, float y, float xs, float ys, float z)
+{
+ float *dxyview = NULL, *dxco = NULL, *dyco = NULL;
+
+ /* currently in use for dithering (soft shadow), node preview, irregular shad */
+ shi->xs = (int)xs;
+ shi->ys = (int)ys;
+
+ /* original scanline coordinate without jitter */
+ shi->scanco[0] = x;
+ shi->scanco[1] = y;
+ shi->scanco[2] = z;
+
+ /* check if we need derivatives */
+ if (shi->osatex || (R.r.mode & R_SHADOW)) {
+ dxco = shi->dxco;
+ dyco = shi->dyco;
+
+ if ((shi->mat->texco & TEXCO_REFL))
+ dxyview = &shi->dxview;
+ }
+
+ shade_input_calc_viewco(shi, xs, ys, z, shi->view, dxyview, shi->co, dxco, dyco);
+}
+
+void barycentric_differentials_from_position(
+ const float co[3], const float v1[3], const float v2[3], const float v3[3],
+ const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials,
+ float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v)
+{
+ /* find most stable axis to project */
+ int axis1, axis2;
+ axis_dominant_v3(&axis1, &axis2, facenor);
+
+ /* compute u,v and derivatives */
+ float t00 = v3[axis1] - v1[axis1];
+ float t01 = v3[axis2] - v1[axis2];
+ float t10 = v3[axis1] - v2[axis1];
+ float t11 = v3[axis2] - v2[axis2];
+
+ float detsh = (t00 * t11 - t10 * t01);
+ detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f;
+ t00 *= detsh; t01 *= detsh;
+ t10 *= detsh; t11 *= detsh;
+
+ *u = (v3[axis1] - co[axis1]) * t11 - (v3[axis2] - co[axis2]) * t10;
+ *v = (v3[axis2] - co[axis2]) * t00 - (v3[axis1] - co[axis1]) * t01;
+ if (differentials) {
+ *dx_u = dxco[axis1] * t11 - dxco[axis2] * t10;
+ *dx_v = dxco[axis2] * t00 - dxco[axis1] * t01;
+ *dy_u = dyco[axis1] * t11 - dyco[axis2] * t10;
+ *dy_v = dyco[axis2] * t00 - dyco[axis1] * t01;
+ }
+}
+/* calculate U and V, for scanline (silly render face u and v are in range -1 to 0) */
+void shade_input_set_uv(ShadeInput *shi)
+{
+ VlakRen *vlr = shi->vlr;
+
+ if ((vlr->flag & R_SMOOTH) || (shi->mat->texco & NEED_UV) || (shi->passflag & SCE_PASS_UV)) {
+ float v1[3], v2[3], v3[3];
+
+ copy_v3_v3(v1, shi->v1->co);
+ copy_v3_v3(v2, shi->v2->co);
+ copy_v3_v3(v3, shi->v3->co);
+
+ if (shi->obi->flag & R_TRANSFORMED) {
+ mul_m4_v3(shi->obi->mat, v1);
+ mul_m4_v3(shi->obi->mat, v2);
+ mul_m4_v3(shi->obi->mat, v3);
+ }
+
+ /* exception case for wire render of edge */
+ if (vlr->v2 == vlr->v3) {
+ float lend, lenc;
+
+ lend = len_v3v3(v2, v1);
+ lenc = len_v3v3(shi->co, v1);
+
+ if (lend == 0.0f) {
+ shi->u = shi->v = 0.0f;
+ }
+ else {
+ shi->u = -(1.0f - lenc / lend);
+ shi->v = 0.0f;
+ }
+
+ if (shi->osatex) {
+ shi->dx_u = 0.0f;
+ shi->dx_v = 0.0f;
+ shi->dy_u = 0.0f;
+ shi->dy_v = 0.0f;
+ }
+ }
+ else {
+ barycentric_differentials_from_position(
+ shi->co, v1, v2, v3, shi->dxco, shi->dyco, shi->facenor, shi->osatex,
+ &shi->u, &shi->v, &shi->dx_u, &shi->dx_v, &shi->dy_u, &shi->dy_v);
+
+ shi->u = -shi->u;
+ shi->v = -shi->v;
+
+ /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
+ CLAMP(shi->u, -2.0f, 1.0f);
+ CLAMP(shi->v, -2.0f, 1.0f);
+ }
+ }
+}
+
+void shade_input_set_normals(ShadeInput *shi)
+{
+ float u = shi->u, v = shi->v;
+ float l = 1.0f + u + v;
+
+ shi->flippednor = 0;
+
+ /* test flip normals to viewing direction */
+ if (!(shi->vlr->flag & R_TANGENT)) {
+ if (dot_v3v3(shi->facenor, shi->view) < 0.0f) {
+ negate_v3(shi->facenor);
+ shi->flippednor = 1;
+ }
+ }
+
+ /* calculate vertexnormals */
+ if (shi->vlr->flag & R_SMOOTH) {
+ float *n1 = shi->n1, *n2 = shi->n2, *n3 = shi->n3;
+
+ if (shi->flippednor) {
+ negate_v3(n1);
+ negate_v3(n2);
+ negate_v3(n3);
+ }
+
+ shi->vn[0] = l * n3[0] - u * n1[0] - v * n2[0];
+ shi->vn[1] = l * n3[1] - u * n1[1] - v * n2[1];
+ shi->vn[2] = l * n3[2] - u * n1[2] - v * n2[2];
+
+ /* use unnormalized normal (closer to games) */
+ copy_v3_v3(shi->nmapnorm, shi->vn);
+
+ normalize_v3(shi->vn);
+ }
+ else {
+ copy_v3_v3(shi->vn, shi->facenor);
+ copy_v3_v3(shi->nmapnorm, shi->vn);
+ }
+
+ /* used in nodes */
+ copy_v3_v3(shi->vno, shi->vn);
+
+ /* flip normals to viewing direction */
+ if (!(shi->vlr->flag & R_TANGENT))
+ if (dot_v3v3(shi->facenor, shi->view) < 0.0f)
+ shade_input_flip_normals(shi);
+}
+
+/* XXX shi->flippednor messes up otherwise */
+void shade_input_set_vertex_normals(ShadeInput *shi)
+{
+ float u = shi->u, v = shi->v;
+ float l = 1.0f + u + v;
+
+ /* calculate vertexnormals */
+ if (shi->vlr->flag & R_SMOOTH) {
+ const float *n1 = shi->n1, *n2 = shi->n2, *n3 = shi->n3;
+
+ shi->vn[0] = l * n3[0] - u * n1[0] - v * n2[0];
+ shi->vn[1] = l * n3[1] - u * n1[1] - v * n2[1];
+ shi->vn[2] = l * n3[2] - u * n1[2] - v * n2[2];
+
+ /* use unnormalized normal (closer to games) */
+ copy_v3_v3(shi->nmapnorm, shi->vn);
+
+ normalize_v3(shi->vn);
+ }
+ else {
+ copy_v3_v3(shi->vn, shi->facenor);
+ copy_v3_v3(shi->nmapnorm, shi->vn);
+ }
+
+ /* used in nodes */
+ copy_v3_v3(shi->vno, shi->vn);
+}
+
+
+/* use by raytrace, sss, bake to flip into the right direction */
+void shade_input_flip_normals(ShadeInput *shi)
+{
+ negate_v3(shi->facenor);
+ negate_v3(shi->vn);
+ negate_v3(shi->vno);
+ negate_v3(shi->nmapnorm);
+ shi->flippednor = !shi->flippednor;
+}
+
+void shade_input_set_shade_texco(ShadeInput *shi)
+{
+ ObjectInstanceRen *obi = shi->obi;
+ ObjectRen *obr = shi->obr;
+ VertRen *v1 = shi->v1, *v2 = shi->v2, *v3 = shi->v3;
+ float u = shi->u, v = shi->v;
+ float l = 1.0f + u + v, dl;
+ int mode = shi->mode; /* or-ed result for all nodes */
+ int mode2 = shi->mode2;
+ short texco = shi->mat->texco;
+ const bool need_mikk_tangent = (mode & MA_NORMAP_TANG || R.flag & R_NEED_TANGENT);
+ const bool need_mikk_tangent_concrete = (mode2 & MA_TANGENT_CONCRETE) != 0;
+
+ /* calculate dxno */
+ if (shi->vlr->flag & R_SMOOTH) {
+
+ if (shi->osatex && (texco & (TEXCO_NORM | TEXCO_REFL)) ) {
+ const float *n1 = shi->n1, *n2 = shi->n2, *n3 = shi->n3;
+
+ dl = shi->dx_u + shi->dx_v;
+ shi->dxno[0] = dl * n3[0] - shi->dx_u * n1[0] - shi->dx_v * n2[0];
+ shi->dxno[1] = dl * n3[1] - shi->dx_u * n1[1] - shi->dx_v * n2[1];
+ shi->dxno[2] = dl * n3[2] - shi->dx_u * n1[2] - shi->dx_v * n2[2];
+ dl = shi->dy_u + shi->dy_v;
+ shi->dyno[0] = dl * n3[0] - shi->dy_u * n1[0] - shi->dy_v * n2[0];
+ shi->dyno[1] = dl * n3[1] - shi->dy_u * n1[1] - shi->dy_v * n2[1];
+ shi->dyno[2] = dl * n3[2] - shi->dy_u * n1[2] - shi->dy_v * n2[2];
+
+ }
+ }
+
+ /* calc tangents */
+ if (mode & (MA_TANGENT_V | MA_NORMAP_TANG) || mode2 & MA_TANGENT_CONCRETE || R.flag & R_NEED_TANGENT) {
+ const float *s1, *s2, *s3;
+ float tl, tu, tv;
+
+ if (shi->vlr->flag & R_SMOOTH) {
+ tl = l;
+ tu = u;
+ tv = v;
+ }
+ else {
+ /* qdn: flat faces have tangents too,
+ * could pick either one, using average here */
+ tl = 1.0f / 3.0f;
+ tu = -1.0f / 3.0f;
+ tv = -1.0f / 3.0f;
+ }
+
+ shi->tang[0] = shi->tang[1] = shi->tang[2] = 0.0f;
+ shi->nmaptang[0] = shi->nmaptang[1] = shi->nmaptang[2] = 0.0f;
+
+ if (mode & MA_TANGENT_V) {
+ s1 = RE_vertren_get_tangent(obr, v1, 0);
+ s2 = RE_vertren_get_tangent(obr, v2, 0);
+ s3 = RE_vertren_get_tangent(obr, v3, 0);
+
+ if (s1 && s2 && s3) {
+ shi->tang[0] = (tl * s3[0] - tu * s1[0] - tv * s2[0]);
+ shi->tang[1] = (tl * s3[1] - tu * s1[1] - tv * s2[1]);
+ shi->tang[2] = (tl * s3[2] - tu * s1[2] - tv * s2[2]);
+
+ if (obi->flag & R_TRANSFORMED)
+ mul_m3_v3(obi->nmat, shi->tang);
+
+ normalize_v3(shi->tang);
+ copy_v3_v3(shi->nmaptang, shi->tang);
+ }
+ }
+
+ if (need_mikk_tangent || need_mikk_tangent_concrete) {
+ int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
+ float c0[3], c1[3], c2[3];
+ int acttang = obr->actmtface;
+
+ vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
+
+ /* cycle through all tangent in vlakren */
+ for (int i = 0; i < MAX_MTFACE; i++) {
+ const float *tangent = RE_vlakren_get_nmap_tangent(obr, shi->vlr, i, false);
+ if (!tangent)
+ continue;
+
+ copy_v3_v3(c0, &tangent[j1 * 4]);
+ copy_v3_v3(c1, &tangent[j2 * 4]);
+ copy_v3_v3(c2, &tangent[j3 * 4]);
+
+ /* keeping tangents normalized at vertex level
+ * corresponds better to how it's done in game engines */
+ if (obi->flag & R_TRANSFORMED) {
+ mul_mat3_m4_v3(obi->mat, c0); normalize_v3(c0);
+ mul_mat3_m4_v3(obi->mat, c1); normalize_v3(c1);
+ mul_mat3_m4_v3(obi->mat, c2); normalize_v3(c2);
+ }
+
+ /* we don't normalize the interpolated TBN tangent
+ * corresponds better to how it's done in game engines */
+ shi->tangents[i][0] = (tl * c2[0] - tu * c0[0] - tv * c1[0]);
+ shi->tangents[i][1] = (tl * c2[1] - tu * c0[1] - tv * c1[1]);
+ shi->tangents[i][2] = (tl * c2[2] - tu * c0[2] - tv * c1[2]);
+
+ /* the sign is the same for all 3 vertices of any
+ * non degenerate triangle. */
+ shi->tangents[i][3] = tangent[j1 * 4 + 3];
+
+ if (acttang == i && need_mikk_tangent) {
+ for (int m = 0; m < 4; m++) {
+ shi->nmaptang[m] = shi->tangents[i][m];
+ }
+ }
+ }
+ }
+ }
+
+ if (mode & MA_STR_SURFDIFF) {
+ const float *surfnor = RE_vlakren_get_surfnor(obr, shi->vlr, 0);
+
+ if (surfnor) {
+ copy_v3_v3(shi->surfnor, surfnor);
+ if (obi->flag & R_TRANSFORMED)
+ mul_m3_v3(obi->nmat, shi->surfnor);
+ }
+ else
+ copy_v3_v3(shi->surfnor, shi->vn);
+
+ shi->surfdist = 0.0f;
+ }
+
+ if (R.r.mode & R_SPEED) {
+ const float *s1, *s2, *s3;
+
+ s1 = RE_vertren_get_winspeed(obi, v1, 0);
+ s2 = RE_vertren_get_winspeed(obi, v2, 0);
+ s3 = RE_vertren_get_winspeed(obi, v3, 0);
+ if (s1 && s2 && s3) {
+ shi->winspeed[0] = (l * s3[0] - u * s1[0] - v * s2[0]);
+ shi->winspeed[1] = (l * s3[1] - u * s1[1] - v * s2[1]);
+ shi->winspeed[2] = (l * s3[2] - u * s1[2] - v * s2[2]);
+ shi->winspeed[3] = (l * s3[3] - u * s1[3] - v * s2[3]);
+ }
+ else {
+ shi->winspeed[0] = shi->winspeed[1] = shi->winspeed[2] = shi->winspeed[3] = 0.0f;
+ }
+ }
+
+ /* pass option forces UV calc */
+ if ((shi->passflag & SCE_PASS_UV) || (R.flag & R_NEED_VCOL))
+ texco |= (NEED_UV | TEXCO_UV);
+
+ /* texture coordinates. shi->dxuv shi->dyuv have been set */
+ if (texco & NEED_UV) {
+
+ if (texco & TEXCO_ORCO) {
+ if (v1->orco) {
+ const float *o1, *o2, *o3;
+
+ o1 = v1->orco;
+ o2 = v2->orco;
+ o3 = v3->orco;
+
+ shi->lo[0] = l * o3[0] - u * o1[0] - v * o2[0];
+ shi->lo[1] = l * o3[1] - u * o1[1] - v * o2[1];
+ shi->lo[2] = l * o3[2] - u * o1[2] - v * o2[2];
+
+ if (shi->osatex) {
+ dl = shi->dx_u + shi->dx_v;
+ shi->dxlo[0] = dl * o3[0] - shi->dx_u * o1[0] - shi->dx_v * o2[0];
+ shi->dxlo[1] = dl * o3[1] - shi->dx_u * o1[1] - shi->dx_v * o2[1];
+ shi->dxlo[2] = dl * o3[2] - shi->dx_u * o1[2] - shi->dx_v * o2[2];
+ dl = shi->dy_u + shi->dy_v;
+ shi->dylo[0] = dl * o3[0] - shi->dy_u * o1[0] - shi->dy_v * o2[0];
+ shi->dylo[1] = dl * o3[1] - shi->dy_u * o1[1] - shi->dy_v * o2[1];
+ shi->dylo[2] = dl * o3[2] - shi->dy_u * o1[2] - shi->dy_v * o2[2];
+ }
+ }
+
+ copy_v3_v3(shi->duplilo, obi->dupliorco);
+ }
+
+ if (texco & TEXCO_GLOB) {
+ copy_v3_v3(shi->gl, shi->co);
+ mul_m4_v3(R.viewinv, shi->gl);
+ if (shi->osatex) {
+ copy_v3_v3(shi->dxgl, shi->dxco);
+ mul_mat3_m4_v3(R.viewinv, shi->dxgl);
+ copy_v3_v3(shi->dygl, shi->dyco);
+ mul_mat3_m4_v3(R.viewinv, shi->dygl);
+ }
+ }
+
+ if (texco & TEXCO_STRAND) {
+ shi->strandco = (l * v3->accum - u * v1->accum - v * v2->accum);
+ if (shi->osatex) {
+ dl = shi->dx_u + shi->dx_v;
+ shi->dxstrand = dl * v3->accum - shi->dx_u * v1->accum - shi->dx_v * v2->accum;
+ dl = shi->dy_u + shi->dy_v;
+ shi->dystrand = dl * v3->accum - shi->dy_u * v1->accum - shi->dy_v * v2->accum;
+ }
+ }
+
+ if ((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) || (R.flag & R_NEED_VCOL)) {
+ VlakRen *vlr = shi->vlr;
+ MTFace *tface;
+ MCol *mcol;
+ char *name;
+ int i, j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
+
+ /* uv and vcols are not copied on split, so set them according vlr divide flag */
+ vlr_set_uv_indices(vlr, &j1, &j2, &j3);
+
+ shi->totuv = 0;
+ shi->totcol = 0;
+ shi->actuv = obr->actmtface;
+ shi->actcol = obr->actmcol;
+
+ if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) || (R.flag & R_NEED_VCOL)) {
+ for (i = 0; (mcol = RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) {
+ ShadeInputCol *scol = &shi->col[i];
+ const char *cp1, *cp2, *cp3;
+ float a[3];
+
+ shi->totcol++;
+ scol->name = name;
+
+ cp1 = (char *)(mcol + j1);
+ cp2 = (char *)(mcol + j2);
+ cp3 = (char *)(mcol + j3);
+
+ /* alpha values */
+ a[0] = ((float)cp1[0]) / 255.f;
+ a[1] = ((float)cp2[0]) / 255.f;
+ a[2] = ((float)cp3[0]) / 255.f;
+ scol->col[3] = l * a[2] - u * a[0] - v * a[1];
+
+ /* sample premultiplied color value */
+ scol->col[0] = (l * ((float)cp3[3]) * a[2] - u * ((float)cp1[3]) * a[0] - v * ((float)cp2[3]) * a[1]) / 255.f;
+ scol->col[1] = (l * ((float)cp3[2]) * a[2] - u * ((float)cp1[2]) * a[0] - v * ((float)cp2[2]) * a[1]) / 255.f;
+ scol->col[2] = (l * ((float)cp3[1]) * a[2] - u * ((float)cp1[1]) * a[0] - v * ((float)cp2[1]) * a[1]) / 255.f;
+
+ /* if not zero alpha, restore non-multiplied color */
+ if (scol->col[3]) {
+ mul_v3_fl(scol->col, 1.0f / scol->col[3]);
+ }
+ }
+
+ if (shi->totcol) {
+ shi->vcol[0] = shi->col[shi->actcol].col[0];
+ shi->vcol[1] = shi->col[shi->actcol].col[1];
+ shi->vcol[2] = shi->col[shi->actcol].col[2];
+ shi->vcol[3] = shi->col[shi->actcol].col[3];
+ }
+ else {
+ shi->vcol[0] = 0.0f;
+ shi->vcol[1] = 0.0f;
+ shi->vcol[2] = 0.0f;
+ shi->vcol[3] = 1.0f;
+ }
+ }
+
+ for (i = 0; (tface = RE_vlakren_get_tface(obr, vlr, i, &name, 0)); i++) {
+ ShadeInputUV *suv = &shi->uv[i];
+ const float *uv1 = tface->uv[j1];
+ const float *uv2 = tface->uv[j2];
+ const float *uv3 = tface->uv[j3];
+
+ shi->totuv++;
+ suv->name = name;
+
+ if ((shi->mat->mapflag & MA_MAPFLAG_UVPROJECT) && (shi->depth == 0)) {
+ float x = shi->xs;
+ float y = shi->ys;
+
+ float s1[2] = {-1.0f + 2.0f * uv1[0], -1.0f + 2.0f * uv1[1]};
+ float s2[2] = {-1.0f + 2.0f * uv2[0], -1.0f + 2.0f * uv2[1]};
+ float s3[2] = {-1.0f + 2.0f * uv3[0], -1.0f + 2.0f * uv3[1]};
+
+
+ float obwinmat[4][4], winmat[4][4], ho1[4], ho2[4], ho3[4];
+ float Zmulx, Zmuly;
+ float hox, hoy, l_proj, dl_proj, u_proj, v_proj;
+ float s00, s01, s10, s11, detsh;
+
+ /* old globals, localized now */
+ Zmulx = ((float)R.winx) / 2.0f;
+ Zmuly = ((float)R.winy) / 2.0f;
+
+ zbuf_make_winmat(&R, winmat);
+ if (shi->obi->flag & R_TRANSFORMED)
+ mul_m4_m4m4(obwinmat, winmat, obi->mat);
+ else
+ copy_m4_m4(obwinmat, winmat);
+
+ zbuf_render_project(obwinmat, v1->co, ho1);
+ zbuf_render_project(obwinmat, v2->co, ho2);
+ zbuf_render_project(obwinmat, v3->co, ho3);
+
+ s00 = ho3[0] / ho3[3] - ho1[0] / ho1[3];
+ s01 = ho3[1] / ho3[3] - ho1[1] / ho1[3];
+ s10 = ho3[0] / ho3[3] - ho2[0] / ho2[3];
+ s11 = ho3[1] / ho3[3] - ho2[1] / ho2[3];
+
+ detsh = s00 * s11 - s10 * s01;
+ detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f;
+ s00 *= detsh; s01 *= detsh;
+ s10 *= detsh; s11 *= detsh;
+
+ /* recalc u and v again */
+ hox = x / Zmulx - 1.0f;
+ hoy = y / Zmuly - 1.0f;
+ u_proj = (hox - ho3[0] / ho3[3]) * s11 - (hoy - ho3[1] / ho3[3]) * s10;
+ v_proj = (hoy - ho3[1] / ho3[3]) * s00 - (hox - ho3[0] / ho3[3]) * s01;
+ l_proj = 1.0f + u_proj + v_proj;
+
+ suv->uv[0] = l_proj * s3[0] - u_proj * s1[0] - v_proj * s2[0];
+ suv->uv[1] = l_proj * s3[1] - u_proj * s1[1] - v_proj * s2[1];
+ suv->uv[2] = 0.0f;
+
+ if (shi->osatex) {
+ float dxuv[2], dyuv[2];
+ dxuv[0] = s11 / Zmulx;
+ dxuv[1] = -s01 / Zmulx;
+ dyuv[0] = -s10 / Zmuly;
+ dyuv[1] = s00 / Zmuly;
+
+ dl_proj = dxuv[0] + dxuv[1];
+ suv->dxuv[0] = dl_proj * s3[0] - dxuv[0] * s1[0] - dxuv[1] * s2[0];
+ suv->dxuv[1] = dl_proj * s3[1] - dxuv[0] * s1[1] - dxuv[1] * s2[1];
+ dl_proj = dyuv[0] + dyuv[1];
+ suv->dyuv[0] = dl_proj * s3[0] - dyuv[0] * s1[0] - dyuv[1] * s2[0];
+ suv->dyuv[1] = dl_proj * s3[1] - dyuv[0] * s1[1] - dyuv[1] * s2[1];
+ }
+ }
+ else {
+
+ suv->uv[0] = -1.0f + 2.0f * (l * uv3[0] - u * uv1[0] - v * uv2[0]);
+ suv->uv[1] = -1.0f + 2.0f * (l * uv3[1] - u * uv1[1] - v * uv2[1]);
+ suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
+
+ if (shi->osatex) {
+ float duv[2];
+
+ dl = shi->dx_u + shi->dx_v;
+ duv[0] = shi->dx_u;
+ duv[1] = shi->dx_v;
+
+ suv->dxuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]);
+ suv->dxuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]);
+
+ dl = shi->dy_u + shi->dy_v;
+ duv[0] = shi->dy_u;
+ duv[1] = shi->dy_v;
+
+ suv->dyuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]);
+ suv->dyuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]);
+ }
+
+ if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
+ if (((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) && ((R.flag & R_NEED_VCOL) == 0)) {
+ shi->vcol[0] = 1.0f;
+ shi->vcol[1] = 1.0f;
+ shi->vcol[2] = 1.0f;
+ shi->vcol[3] = 1.0f;
+ }
+ if (tface->tpage) {
+ render_realtime_texture(shi, tface->tpage);
+ }
+ }
+ }
+ }
+
+ shi->dupliuv[0] = -1.0f + 2.0f * obi->dupliuv[0];
+ shi->dupliuv[1] = -1.0f + 2.0f * obi->dupliuv[1];
+ shi->dupliuv[2] = 0.0f;
+
+ if (shi->totuv == 0) {
+ ShadeInputUV *suv = &shi->uv[0];
+
+ suv->uv[0] = 2.0f * (u + .5f);
+ suv->uv[1] = 2.0f * (v + .5f);
+ suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
+
+ if (mode & MA_FACETEXTURE) {
+ /* no tface? set at 1.0f */
+ shi->vcol[0] = 1.0f;
+ shi->vcol[1] = 1.0f;
+ shi->vcol[2] = 1.0f;
+ shi->vcol[3] = 1.0f;
+ }
+ }
+ }
+
+ if (texco & TEXCO_NORM) {
+ shi->orn[0] = -shi->vn[0];
+ shi->orn[1] = -shi->vn[1];
+ shi->orn[2] = -shi->vn[2];
+ }
+
+ if (texco & TEXCO_STRESS) {
+ const float *s1, *s2, *s3;
+
+ s1 = RE_vertren_get_stress(obr, v1, 0);
+ s2 = RE_vertren_get_stress(obr, v2, 0);
+ s3 = RE_vertren_get_stress(obr, v3, 0);
+ if (s1 && s2 && s3) {
+ shi->stress = l * s3[0] - u * s1[0] - v * s2[0];
+ if (shi->stress < 1.0f) shi->stress -= 1.0f;
+ else shi->stress = (shi->stress - 1.0f) / shi->stress;
+ }
+ else shi->stress = 0.0f;
+ }
+
+ if (texco & TEXCO_TANGENT) {
+ if ((mode & MA_TANGENT_V) == 0) {
+ /* just prevent surprises */
+ shi->tang[0] = shi->tang[1] = shi->tang[2] = 0.0f;
+ shi->nmaptang[0] = shi->nmaptang[1] = shi->nmaptang[2] = 0.0f;
+ }
+ }
+ }
+
+ /* this only avalailable for scanline renders */
+ if (shi->depth == 0) {
+ float x = shi->xs;
+ float y = shi->ys;
+
+ if (texco & TEXCO_WINDOW) {
+ shi->winco[0] = -1.0f + 2.0f * x / (float)R.winx;
+ shi->winco[1] = -1.0f + 2.0f * y / (float)R.winy;
+ shi->winco[2] = 0.0f;
+ if (shi->osatex) {
+ shi->dxwin[0] = 2.0f / (float)R.winx;
+ shi->dywin[1] = 2.0f / (float)R.winy;
+ shi->dxwin[1] = shi->dxwin[2] = 0.0f;
+ shi->dywin[0] = shi->dywin[2] = 0.0f;
+ }
+ }
+ }
+ /* else {
+ * Note! For raytracing winco is not set,
+ * important because thus means all shader input's need to have their variables set to zero
+ * else un-initialized values are used
+ */
+ if (shi->do_manage) {
+ if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP | MA_FACETEXTURE)) || (R.flag & R_NEED_VCOL)) {
+ srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
+ }
+ }
+
+}
+
+/* ****************** ShadeSample ************************************** */
+
+/* initialize per part, not per pixel! */
+void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, int sample)
+{
+
+ memset(shi, 0, sizeof(ShadeInput));
+
+ shi->sample = sample;
+ shi->thread = pa->thread;
+ shi->do_preview = (R.r.scemode & R_MATNODE_PREVIEW) != 0;
+
+ shi->do_manage = BKE_scene_check_color_management_enabled(R.scene);
+ shi->use_world_space_shading = BKE_scene_use_world_space_shading(R.scene);
+
+ shi->lay = rl->lay;
+ shi->layflag = rl->layflag;
+ shi->passflag = rl->passflag;
+ shi->combinedflag = ~rl->pass_xor;
+ shi->mat_override = rl->mat_override;
+ shi->light_override = rl->light_override;
+// shi->rl= rl;
+ /* note shi.depth==0 means first hit, not raytracing */
+
+}
+
+/* initialize per part, not per pixel! */
+void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl)
+{
+ int a, tot;
+
+ tot = R.osa == 0 ? 1 : R.osa;
+
+ for (a = 0; a < tot; a++) {
+ shade_input_initialize(&ssamp->shi[a], pa, rl, a);
+ memset(&ssamp->shr[a], 0, sizeof(ShadeResult));
+ }
+
+ get_sample_layers(pa, rl, ssamp->rlpp);
+}
+
+/* Do AO or (future) GI */
+void shade_samples_do_AO(ShadeSample *ssamp)
+{
+ if (!(R.r.mode & R_SHADOW))
+ return;
+ if (!(R.r.mode & R_RAYTRACE) && !(R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
+ return;
+
+ if (R.wrld.mode & (WO_AMB_OCC | WO_ENV_LIGHT | WO_INDIRECT_LIGHT)) {
+ ShadeInput *shi = &ssamp->shi[0];
+ int sample;
+
+ if (((shi->passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO | SCE_PASS_ENVIRONMENT | SCE_PASS_INDIRECT))) ||
+ (shi->passflag & (SCE_PASS_AO | SCE_PASS_ENVIRONMENT | SCE_PASS_INDIRECT)))
+ {
+ for (sample = 0; sample < ssamp->tot; shi++, sample++)
+ if (!(shi->mode & MA_SHLESS))
+ ambient_occlusion(shi); /* stores in shi->ao[] */
+ }
+ }
+}
+
+
+void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y)
+{
+ ShadeInput *shi;
+ float xs, ys;
+
+ ssamp->tot = 0;
+
+ for (shi = ssamp->shi; ps; ps = ps->next) {
+ shade_input_set_triangle(shi, ps->obi, ps->facenr, 1);
+
+ if (shi->vlr) { /* NULL happens for env material or for 'all z' */
+ unsigned short curmask = ps->mask;
+
+ /* full osa is only set for OSA renders */
+ if (shi->vlr->flag & R_FULL_OSA) {
+ short shi_cp = 0, samp;
+
+ for (samp = 0; samp < R.osa; samp++) {
+ if (curmask & (1 << samp)) {
+ /* zbuffer has this inverse corrected, ensures xs,ys are inside pixel */
+ xs = (float)x + R.jit[samp][0] + 0.5f;
+ ys = (float)y + R.jit[samp][1] + 0.5f;
+
+ if (shi_cp)
+ shade_input_copy_triangle(shi, shi - 1);
+
+ shi->mask = (1 << samp);
+// shi->rl= ssamp->rlpp[samp];
+ shi->samplenr = R.shadowsamplenr[shi->thread]++; /* this counter is not being reset per pixel */
+ shade_input_set_viewco(shi, x, y, xs, ys, (float)ps->z);
+ shade_input_set_uv(shi);
+ if (shi_cp == 0)
+ shade_input_set_normals(shi);
+ else /* XXX shi->flippednor messes up otherwise */
+ shade_input_set_vertex_normals(shi);
+
+ shi_cp = 1;
+ shi++;
+ }
+ }
+ }
+ else {
+ if (R.osa) {
+ short b = R.samples->centmask[curmask];
+ xs = (float)x + R.samples->centLut[b & 15] + 0.5f;
+ ys = (float)y + R.samples->centLut[b >> 4] + 0.5f;
+ }
+ else if (R.i.curblur) {
+ xs= (float)x + R.mblur_jit[R.i.curblur-1][0] + 0.5f;
+ ys= (float)y + R.mblur_jit[R.i.curblur-1][1] + 0.5f;
+ }
+ else {
+ xs = (float)x + 0.5f;
+ ys = (float)y + 0.5f;
+ }
+
+ shi->mask = curmask;
+ shi->samplenr = R.shadowsamplenr[shi->thread]++;
+ shade_input_set_viewco(shi, x, y, xs, ys, (float)ps->z);
+ shade_input_set_uv(shi);
+ shade_input_set_normals(shi);
+ shi++;
+ }
+
+ /* total sample amount, shi->sample is static set in initialize */
+ if (shi != ssamp->shi)
+ ssamp->tot = (shi - 1)->sample + 1;
+ }
+ }
+}
+
+/* shades samples, returns true if anything happened */
+int shade_samples(ShadeSample *ssamp, PixStr *ps, int x, int y)
+{
+ shade_samples_fill_with_ps(ssamp, ps, x, y);
+
+ if (ssamp->tot) {
+ ShadeInput *shi = ssamp->shi;
+ ShadeResult *shr = ssamp->shr;
+ int samp;
+
+ /* if shadow or AO? */
+ shade_samples_do_AO(ssamp);
+
+ /* if shade (all shadepinputs have same passflag) */
+ if (ssamp->shi[0].passflag & ~(SCE_PASS_Z | SCE_PASS_INDEXOB | SCE_PASS_INDEXMA)) {
+
+ for (samp = 0; samp < ssamp->tot; samp++, shi++, shr++) {
+ shade_input_set_shade_texco(shi);
+ shade_input_do_shade(shi, shr);
+ }
+ }
+ else if (shi->passflag & SCE_PASS_Z) {
+ for (samp = 0; samp < ssamp->tot; samp++, shi++, shr++)
+ shr->z = -shi->co[2];
+ }
+
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
new file mode 100644
index 00000000000..090c249defb
--- /dev/null
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -0,0 +1,2182 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation
+ * All rights reserved.
+ *
+ * Contributors: Hos, Robert Wenzlaff.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/shadeoutput.c
+ * \ingroup render
+ */
+
+#include <stdio.h>
+#include <float.h>
+#include <math.h>
+#include <string.h>
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_colorband.h"
+#include "BKE_colortools.h"
+#include "BKE_material.h"
+
+#include "DNA_group_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+
+/* local include */
+#include "occlusion.h"
+#include "render_types.h"
+#include "rendercore.h"
+#include "shadbuf.h"
+#include "sss.h"
+#include "texture.h"
+
+#include "shading.h" /* own include */
+
+#include "IMB_colormanagement.h"
+
+/* could enable at some point but for now there are far too many conversions */
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+ListBase *get_lights(ShadeInput *shi)
+{
+
+ if (R.r.scemode & R_BUTS_PREVIEW)
+ return &R.lights;
+ if (shi->light_override)
+ return &shi->light_override->gobject;
+ if (shi->mat && shi->mat->group)
+ return &shi->mat->group->gobject;
+
+ return &R.lights;
+}
+
+#if 0
+static void fogcolor(const float colf[3], float *rco, float *view)
+{
+ float alpha, stepsize, startdist, dist, hor[4], zen[3], vec[3], dview[3];
+ float div=0.0f, distfac;
+
+ hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb;
+ zen[0]= R.wrld.zenr; zen[1]= R.wrld.zeng; zen[2]= R.wrld.zenb;
+
+ copy_v3_v3(vec, rco);
+
+ /* we loop from cur coord to mist start in steps */
+ stepsize= 1.0f;
+
+ div= ABS(view[2]);
+ dview[0]= view[0]/(stepsize*div);
+ dview[1]= view[1]/(stepsize*div);
+ dview[2]= -stepsize;
+
+ startdist= -rco[2] + BLI_frand();
+ for (dist= startdist; dist>R.wrld.miststa; dist-= stepsize) {
+
+ hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb;
+ alpha= 1.0f;
+ do_sky_tex(vec, vec, NULL, hor, zen, &alpha);
+
+ distfac= (dist-R.wrld.miststa)/R.wrld.mistdist;
+
+ hor[3]= hor[0]*distfac*distfac;
+
+ /* premul! */
+ alpha= hor[3];
+ hor[0]= hor[0]*alpha;
+ hor[1]= hor[1]*alpha;
+ hor[2]= hor[2]*alpha;
+ addAlphaOverFloat(colf, hor);
+
+ sub_v3_v3(vec, dview);
+ }
+}
+#endif
+
+/* zcor is distance, co the 3d coordinate in eye space, return alpha */
+float mistfactor(float zcor, float const co[3])
+{
+ float fac, hi;
+
+ fac = zcor - R.wrld.miststa; /* zcor is calculated per pixel */
+
+ /* fac= -co[2]-R.wrld.miststa; */
+
+ if (fac > 0.0f) {
+ if (fac < R.wrld.mistdist) {
+
+ fac = (fac / R.wrld.mistdist);
+
+ if (R.wrld.mistype == 0) {
+ fac *= fac;
+ }
+ else if (R.wrld.mistype == 1) {
+ /* pass */
+ }
+ else {
+ fac = sqrtf(fac);
+ }
+ }
+ else {
+ fac = 1.0f;
+ }
+ }
+ else {
+ fac = 0.0f;
+ }
+
+ /* height switched off mist */
+ if (R.wrld.misthi!=0.0f && fac!=0.0f) {
+ /* at height misthi the mist is completely gone */
+
+ hi = R.viewinv[0][2] * co[0] +
+ R.viewinv[1][2] * co[1] +
+ R.viewinv[2][2] * co[2] +
+ R.viewinv[3][2];
+
+ if (hi > R.wrld.misthi) {
+ fac = 0.0f;
+ }
+ else if (hi>0.0f) {
+ hi= (R.wrld.misthi-hi)/R.wrld.misthi;
+ fac*= hi*hi;
+ }
+ }
+
+ return (1.0f-fac)* (1.0f-R.wrld.misi);
+}
+
+static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
+{
+ double a, b, c, disc, nray[3], npos[3];
+ double t0, t1 = 0.0f, t2= 0.0f, t3;
+ float p1[3], p2[3], ladist, maxz = 0.0f, maxy = 0.0f, haint;
+ int cuts;
+ bool do_clip = true, use_yco = false;
+
+ *intens= 0.0f;
+ haint= lar->haint;
+
+ if (R.r.mode & R_ORTHO) {
+ /* camera pos (view vector) cannot be used... */
+ /* camera position (cox,coy,0) rotate around lamp */
+ p1[0]= shi->co[0]-lar->co[0];
+ p1[1]= shi->co[1]-lar->co[1];
+ p1[2]= -lar->co[2];
+ mul_m3_v3(lar->imat, p1);
+ copy_v3db_v3fl(npos, p1); /* npos is double! */
+
+ /* pre-scale */
+ npos[2] *= (double)lar->sh_zfac;
+ }
+ else {
+ copy_v3db_v3fl(npos, lar->sh_invcampos); /* in initlamp calculated */
+ }
+
+ /* rotate view */
+ copy_v3db_v3fl(nray, shi->view);
+ mul_m3_v3_double(lar->imat, nray);
+
+ if (R.wrld.mode & WO_MIST) {
+ /* patchy... */
+ haint *= mistfactor(-lar->co[2], lar->co);
+ if (haint==0.0f) {
+ return;
+ }
+ }
+
+
+ /* rotate maxz */
+ if (shi->co[2]==0.0f) {
+ do_clip = false; /* for when halo at sky */
+ }
+ else {
+ p1[0]= shi->co[0]-lar->co[0];
+ p1[1]= shi->co[1]-lar->co[1];
+ p1[2]= shi->co[2]-lar->co[2];
+
+ maxz= lar->imat[0][2]*p1[0]+lar->imat[1][2]*p1[1]+lar->imat[2][2]*p1[2];
+ maxz*= lar->sh_zfac;
+ maxy= lar->imat[0][1]*p1[0]+lar->imat[1][1]*p1[1]+lar->imat[2][1]*p1[2];
+
+ if (fabs(nray[2]) < FLT_EPSILON) {
+ use_yco = true;
+ }
+ }
+
+ /* scale z to make sure volume is normalized */
+ nray[2] *= (double)lar->sh_zfac;
+ /* nray does not need normalization */
+
+ ladist= lar->sh_zfac*lar->dist;
+
+ /* solve */
+ a = nray[0] * nray[0] + nray[1] * nray[1] - nray[2]*nray[2];
+ b = nray[0] * npos[0] + nray[1] * npos[1] - nray[2]*npos[2];
+ c = npos[0] * npos[0] + npos[1] * npos[1] - npos[2]*npos[2];
+
+ cuts= 0;
+ if (fabs(a) < DBL_EPSILON) {
+ /*
+ * Only one intersection point...
+ */
+ return;
+ }
+ else {
+ disc = b*b - a*c;
+
+ if (disc==0.0) {
+ t1=t2= (-b)/ a;
+ cuts= 2;
+ }
+ else if (disc > 0.0) {
+ disc = sqrt(disc);
+ t1 = (-b + disc) / a;
+ t2 = (-b - disc) / a;
+ cuts= 2;
+ }
+ }
+ if (cuts==2) {
+ int ok1=0, ok2=0;
+
+ /* sort */
+ if (t1>t2) {
+ a= t1; t1= t2; t2= a;
+ }
+
+ /* z of intersection points with diabolo */
+ p1[2]= npos[2] + t1*nray[2];
+ p2[2]= npos[2] + t2*nray[2];
+
+ /* evaluate both points */
+ if (p1[2]<=0.0f) ok1= 1;
+ if (p2[2]<=0.0f && t1!=t2) ok2= 1;
+
+ /* at least 1 point with negative z */
+ if (ok1==0 && ok2==0) return;
+
+ /* intersction point with -ladist, the bottom of the cone */
+ if (use_yco == false) {
+ t3= ((double)(-ladist)-npos[2])/nray[2];
+
+ /* de we have to replace one of the intersection points? */
+ if (ok1) {
+ if (p1[2]<-ladist) t1= t3;
+ }
+ else {
+ t1= t3;
+ }
+ if (ok2) {
+ if (p2[2]<-ladist) t2= t3;
+ }
+ else {
+ t2= t3;
+ }
+ }
+ else if (ok1==0 || ok2==0) return;
+
+ /* at least 1 visible interesction point */
+ if (t1<0.0 && t2<0.0) return;
+
+ if (t1<0.0) t1= 0.0;
+ if (t2<0.0) t2= 0.0;
+
+ if (t1==t2) return;
+
+ /* sort again to be sure */
+ if (t1>t2) {
+ a= t1; t1= t2; t2= a;
+ }
+
+ /* calculate t0: is the maximum visible z (when halo is intersected by face) */
+ if (do_clip) {
+ if (use_yco == false) t0 = ((double)maxz - npos[2]) / nray[2];
+ else t0 = ((double)maxy - npos[1]) / nray[1];
+
+ if (t0 < t1) return;
+ if (t0 < t2) t2= t0;
+ }
+
+ /* calc points */
+ p1[0]= npos[0] + t1*nray[0];
+ p1[1]= npos[1] + t1*nray[1];
+ p1[2]= npos[2] + t1*nray[2];
+ p2[0]= npos[0] + t2*nray[0];
+ p2[1]= npos[1] + t2*nray[1];
+ p2[2]= npos[2] + t2*nray[2];
+
+
+ /* now we have 2 points, make three lengths with it */
+
+ a = len_v3(p1);
+ b = len_v3(p2);
+ c = len_v3v3(p1, p2);
+
+ a/= ladist;
+ a= sqrt(a);
+ b/= ladist;
+ b= sqrt(b);
+ c/= ladist;
+
+ *intens= c*( (1.0-a)+(1.0-b) );
+
+ /* WATCH IT: do not clip a,b en c at 1.0, this gives nasty little overflows
+ * at the edges (especially with narrow halos) */
+ if (*intens<=0.0f) return;
+
+ /* soft area */
+ /* not needed because t0 has been used for p1/p2 as well */
+ /* if (doclip && t0<t2) { */
+ /* *intens *= (t0-t1)/(t2-t1); */
+ /* } */
+
+ *intens *= haint;
+
+ if (lar->shb && lar->shb->shadhalostep) {
+ *intens *= shadow_halo(lar, p1, p2);
+ }
+
+ }
+}
+
+void renderspothalo(ShadeInput *shi, float col[4], float alpha)
+{
+ ListBase *lights;
+ GroupObject *go;
+ LampRen *lar;
+ float i;
+
+ if (alpha==0.0f) return;
+
+ lights= get_lights(shi);
+ for (go=lights->first; go; go= go->next) {
+ lar= go->lampren;
+ if (lar==NULL) continue;
+
+ if (lar->type==LA_SPOT && (lar->mode & LA_HALO) && (lar->buftype != LA_SHADBUF_DEEP) && lar->haint>0) {
+
+ if (lar->mode & LA_LAYER)
+ if (shi->vlr && (lar->lay & shi->obi->lay)==0)
+ continue;
+ if ((lar->lay & shi->lay)==0)
+ continue;
+
+ spothalo(lar, shi, &i);
+ if (i > 0.0f) {
+ const float i_alpha = i * alpha;
+ col[0] += i_alpha * lar->r;
+ col[1] += i_alpha * lar->g;
+ col[2] += i_alpha * lar->b;
+ col[3] += i_alpha; /* all premul */
+ }
+ }
+ }
+ /* clip alpha, is needed for unified 'alpha threshold' (vanillaRenderPipe.c) */
+ if (col[3]>1.0f) col[3]= 1.0f;
+}
+
+
+
+/* ---------------- shaders ----------------------- */
+
+static double Normalize_d(double *n)
+{
+ double d;
+
+ d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
+
+ if (d>0.00000000000000001) {
+ d= sqrt(d);
+
+ n[0]/=d;
+ n[1]/=d;
+ n[2]/=d;
+ }
+ else {
+ n[0]=n[1]=n[2]= 0.0;
+ d= 0.0;
+ }
+ return d;
+}
+
+/* mix of 'real' fresnel and allowing control. grad defines blending gradient */
+float fresnel_fac(const float view[3], const float vn[3], float grad, float fac)
+{
+ float t1, t2;
+
+ if (fac==0.0f) return 1.0f;
+
+ t1 = dot_v3v3(view, vn);
+ if (t1>0.0f) t2= 1.0f+t1;
+ else t2= 1.0f-t1;
+
+ t2= grad + (1.0f-grad)*powf(t2, fac);
+
+ if (t2<0.0f) return 0.0f;
+ else if (t2>1.0f) return 1.0f;
+ return t2;
+}
+
+static double saacos_d(double fac)
+{
+ if (fac<= -1.0) return M_PI;
+ else if (fac>=1.0) return 0.0;
+ else return acos(fac);
+}
+
+/* Stoke's form factor. Need doubles here for extreme small area sizes */
+static float area_lamp_energy(float (*area)[3], const float co[3], const float vn[3])
+{
+ double fac;
+ double vec[4][3]; /* vectors of rendered co to vertices lamp */
+ double cross[4][3]; /* cross products of this */
+ double rad[4]; /* angles between vecs */
+
+ VECSUB(vec[0], co, area[0]);
+ VECSUB(vec[1], co, area[1]);
+ VECSUB(vec[2], co, area[2]);
+ VECSUB(vec[3], co, area[3]);
+
+ Normalize_d(vec[0]);
+ Normalize_d(vec[1]);
+ Normalize_d(vec[2]);
+ Normalize_d(vec[3]);
+
+ /* cross product */
+#define CROSS(dest, a, b) \
+ { \
+ dest[0]= a[1] * b[2] - a[2] * b[1]; \
+ dest[1]= a[2] * b[0] - a[0] * b[2]; \
+ dest[2]= a[0] * b[1] - a[1] * b[0]; \
+ } (void)0
+
+ CROSS(cross[0], vec[0], vec[1]);
+ CROSS(cross[1], vec[1], vec[2]);
+ CROSS(cross[2], vec[2], vec[3]);
+ CROSS(cross[3], vec[3], vec[0]);
+
+#undef CROSS
+
+ Normalize_d(cross[0]);
+ Normalize_d(cross[1]);
+ Normalize_d(cross[2]);
+ Normalize_d(cross[3]);
+
+ /* angles */
+ rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2];
+ rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2];
+ rad[2]= vec[2][0]*vec[3][0]+ vec[2][1]*vec[3][1]+ vec[2][2]*vec[3][2];
+ rad[3]= vec[3][0]*vec[0][0]+ vec[3][1]*vec[0][1]+ vec[3][2]*vec[0][2];
+
+ rad[0]= saacos_d(rad[0]);
+ rad[1]= saacos_d(rad[1]);
+ rad[2]= saacos_d(rad[2]);
+ rad[3]= saacos_d(rad[3]);
+
+ /* Stoke formula */
+ fac= rad[0]*(vn[0]*cross[0][0]+ vn[1]*cross[0][1]+ vn[2]*cross[0][2]);
+ fac+= rad[1]*(vn[0]*cross[1][0]+ vn[1]*cross[1][1]+ vn[2]*cross[1][2]);
+ fac+= rad[2]*(vn[0]*cross[2][0]+ vn[1]*cross[2][1]+ vn[2]*cross[2][2]);
+ fac+= rad[3]*(vn[0]*cross[3][0]+ vn[1]*cross[3][1]+ vn[2]*cross[3][2]);
+
+ if (fac<=0.0) return 0.0;
+ return fac;
+}
+
+static float area_lamp_energy_multisample(LampRen *lar, const float co[3], float *vn)
+{
+ /* corner vectors are moved around according lamp jitter */
+ float *jitlamp= lar->jitter, vec[3];
+ float area[4][3], intens= 0.0f;
+ int a= lar->ray_totsamp;
+
+ /* test if co is behind lamp */
+ sub_v3_v3v3(vec, co, lar->co);
+ if (dot_v3v3(vec, lar->vec) < 0.0f)
+ return 0.0f;
+
+ while (a--) {
+ vec[0]= jitlamp[0];
+ vec[1]= jitlamp[1];
+ vec[2]= 0.0f;
+ mul_m3_v3(lar->mat, vec);
+
+ add_v3_v3v3(area[0], lar->area[0], vec);
+ add_v3_v3v3(area[1], lar->area[1], vec);
+ add_v3_v3v3(area[2], lar->area[2], vec);
+ add_v3_v3v3(area[3], lar->area[3], vec);
+
+ intens+= area_lamp_energy(area, co, vn);
+
+ jitlamp+= 2;
+ }
+ intens /= (float)lar->ray_totsamp;
+
+ return pow(intens * lar->areasize, lar->k); /* corrected for buttons size and lar->dist^2 */
+}
+
+static float spec(float inp, int hard)
+{
+ float b1;
+
+ if (inp>=1.0f) return 1.0f;
+ else if (inp<=0.0f) return 0.0f;
+
+ b1= inp*inp;
+ /* avoid FPE */
+ if (b1<0.01f) b1= 0.01f;
+
+ if ((hard & 1)==0) inp= 1.0f;
+ if (hard & 2) inp*= b1;
+ b1*= b1;
+ if (hard & 4) inp*= b1;
+ b1*= b1;
+ if (hard & 8) inp*= b1;
+ b1*= b1;
+ if (hard & 16) inp*= b1;
+ b1*= b1;
+
+ /* avoid FPE */
+ if (b1<0.001f) b1= 0.0f;
+
+ if (hard & 32) inp*= b1;
+ b1*= b1;
+ if (hard & 64) inp*=b1;
+ b1*= b1;
+ if (hard & 128) inp*=b1;
+
+ if (b1<0.001f) b1= 0.0f;
+
+ if (hard & 256) {
+ b1*= b1;
+ inp*=b1;
+ }
+
+ return inp;
+}
+
+static float Phong_Spec(const float n[3], const float l[3], const float v[3], int hard, int tangent )
+{
+ float h[3];
+ float rslt;
+
+ h[0] = l[0] + v[0];
+ h[1] = l[1] + v[1];
+ h[2] = l[2] + v[2];
+ normalize_v3(h);
+
+ rslt = h[0]*n[0] + h[1]*n[1] + h[2]*n[2];
+ if (tangent) rslt= sasqrt(1.0f - rslt*rslt);
+
+ if ( rslt > 0.0f ) rslt= spec(rslt, hard);
+ else rslt = 0.0f;
+
+ return rslt;
+}
+
+
+/* reduced cook torrance spec (for off-specular peak) */
+static float CookTorr_Spec(const float n[3], const float l[3], const float v[3], int hard, int tangent)
+{
+ float i, nh, nv, h[3];
+
+ h[0]= v[0]+l[0];
+ h[1]= v[1]+l[1];
+ h[2]= v[2]+l[2];
+ normalize_v3(h);
+
+ nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2];
+ if (tangent) nh= sasqrt(1.0f - nh*nh);
+ else if (nh<0.0f) return 0.0f;
+
+ nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2];
+ if (tangent) nv= sasqrt(1.0f - nv*nv);
+ else if (nv<0.0f) nv= 0.0f;
+
+ i= spec(nh, hard);
+
+ i= i/(0.1f+nv);
+ return i;
+}
+
+/* Blinn spec */
+static float Blinn_Spec(const float n[3], const float l[3], const float v[3], float refrac, float spec_power, int tangent)
+{
+ float i, nh, nv, nl, vh, h[3];
+ float a, b, c, g=0.0f, p, f, ang;
+
+ if (refrac < 1.0f) return 0.0f;
+ if (spec_power == 0.0f) return 0.0f;
+
+ /* conversion from 'hardness' (1-255) to 'spec_power' (50 maps at 0.1) */
+ if (spec_power<100.0f)
+ spec_power = sqrtf(1.0f / spec_power);
+ else spec_power= 10.0f/spec_power;
+
+ h[0]= v[0]+l[0];
+ h[1]= v[1]+l[1];
+ h[2]= v[2]+l[2];
+ normalize_v3(h);
+
+ nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface normal and half-way vector */
+ if (tangent) nh= sasqrt(1.0f - nh*nh);
+ else if (nh<0.0f) return 0.0f;
+
+ nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */
+ if (tangent) nv= sasqrt(1.0f - nv*nv);
+ if (nv<=0.01f) nv= 0.01f; /* hrms... */
+
+ nl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */
+ if (tangent) nl= sasqrt(1.0f - nl*nl);
+ if (nl<=0.01f) {
+ return 0.0f;
+ }
+
+ vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; /* Dot product between view vector and half-way vector */
+ if (vh<=0.0f) vh= 0.01f;
+
+ a = 1.0f;
+ b = (2.0f*nh*nv)/vh;
+ c = (2.0f*nh*nl)/vh;
+
+ if ( a < b && a < c ) g = a;
+ else if ( b < a && b < c ) g = b;
+ else if ( c < a && c < b ) g = c;
+
+ p = sqrt((double)((refrac * refrac)+(vh * vh) - 1.0f));
+ f = (((p-vh)*(p-vh))/((p+vh)*(p+vh)))*(1+((((vh*(p+vh))-1.0f)*((vh*(p+vh))-1.0f))/(((vh*(p-vh))+1.0f)*((vh*(p-vh))+1.0f))));
+ ang = saacos(nh);
+
+ i= f * g * exp((double)(-(ang*ang) / (2.0f*spec_power*spec_power)));
+ if (i<0.0f) i= 0.0f;
+
+ return i;
+}
+
+/* cartoon render spec */
+static float Toon_Spec(const float n[3], const float l[3], const float v[3], float size, float smooth, int tangent)
+{
+ float h[3];
+ float ang;
+ float rslt;
+
+ h[0] = l[0] + v[0];
+ h[1] = l[1] + v[1];
+ h[2] = l[2] + v[2];
+ normalize_v3(h);
+
+ rslt = h[0]*n[0] + h[1]*n[1] + h[2]*n[2];
+ if (tangent) rslt = sasqrt(1.0f - rslt*rslt);
+
+ ang = saacos( rslt );
+
+ if ( ang < size ) rslt = 1.0f;
+ else if ( ang >= (size + smooth) || smooth == 0.0f ) rslt = 0.0f;
+ else rslt = 1.0f - ((ang - size) / smooth);
+
+ return rslt;
+}
+
+/* Ward isotropic gaussian spec */
+static float WardIso_Spec(const float n[3], const float l[3], const float v[3], float rms, int tangent)
+{
+ float i, nh, nv, nl, h[3], angle, alpha;
+
+
+ /* half-way vector */
+ h[0] = l[0] + v[0];
+ h[1] = l[1] + v[1];
+ h[2] = l[2] + v[2];
+ normalize_v3(h);
+
+ nh = n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface normal and half-way vector */
+ if (tangent) nh = sasqrt(1.0f - nh*nh);
+ if (nh<=0.0f) nh = 0.001f;
+
+ nv = n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */
+ if (tangent) nv = sasqrt(1.0f - nv*nv);
+ if (nv<=0.0f) nv = 0.001f;
+
+ nl = n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */
+ if (tangent) nl = sasqrt(1.0f - nl*nl);
+ if (nl<=0.0f) nl = 0.001f;
+
+ angle = tanf(saacos(nh));
+ alpha = MAX2(rms, 0.001f);
+
+ i= nl * (1.0f/(4.0f*(float)M_PI*alpha*alpha)) * (expf( -(angle*angle)/(alpha*alpha))/(sqrtf(nv*nl)));
+
+ return i;
+}
+
+/* cartoon render diffuse */
+static float Toon_Diff(const float n[3], const float l[3], const float UNUSED(v[3]), float size, float smooth)
+{
+ float rslt, ang;
+
+ rslt = n[0]*l[0] + n[1]*l[1] + n[2]*l[2];
+
+ ang = saacos(rslt);
+
+ if ( ang < size ) rslt = 1.0f;
+ else if ( ang >= (size + smooth) || smooth == 0.0f ) rslt = 0.0f;
+ else rslt = 1.0f - ((ang - size) / smooth);
+
+ return rslt;
+}
+
+/* Oren Nayar diffuse */
+
+/* 'nl' is either dot product, or return value of area light */
+/* in latter case, only last multiplication uses 'nl' */
+static float OrenNayar_Diff(float nl, const float n[3], const float l[3], const float v[3], float rough )
+{
+ float i/*, nh*/, nv /*, vh */, realnl, h[3];
+ float a, b, t, A, B;
+ float Lit_A, View_A, Lit_B[3], View_B[3];
+
+ h[0]= v[0]+l[0];
+ h[1]= v[1]+l[1];
+ h[2]= v[2]+l[2];
+ normalize_v3(h);
+
+ /* nh= n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; */ /* Dot product between surface normal and half-way vector */
+ /* if (nh<0.0f) nh = 0.0f; */
+
+ nv= n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */
+ if (nv<=0.0f) nv= 0.0f;
+
+ realnl= n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */
+ if (realnl<=0.0f) return 0.0f;
+ if (nl<0.0f) return 0.0f; /* value from area light */
+
+ /* vh= v[0]*h[0]+v[1]*h[1]+v[2]*h[2]; */ /* Dot product between view vector and halfway vector */
+ /* if (vh<=0.0f) vh= 0.0f; */
+
+ Lit_A = saacos(realnl);
+ View_A = saacos( nv );
+
+ Lit_B[0] = l[0] - (realnl * n[0]);
+ Lit_B[1] = l[1] - (realnl * n[1]);
+ Lit_B[2] = l[2] - (realnl * n[2]);
+ normalize_v3(Lit_B);
+
+ View_B[0] = v[0] - (nv * n[0]);
+ View_B[1] = v[1] - (nv * n[1]);
+ View_B[2] = v[2] - (nv * n[2]);
+ normalize_v3(View_B);
+
+ t = Lit_B[0]*View_B[0] + Lit_B[1]*View_B[1] + Lit_B[2]*View_B[2];
+ if ( t < 0 ) t = 0;
+
+ if ( Lit_A > View_A ) {
+ a = Lit_A;
+ b = View_A;
+ }
+ else {
+ a = View_A;
+ b = Lit_A;
+ }
+
+ A = 1.0f - (0.5f * ((rough * rough) / ((rough * rough) + 0.33f)));
+ B = 0.45f * ((rough * rough) / ((rough * rough) + 0.09f));
+
+ b*= 0.95f; /* prevent tangens from shooting to inf, 'nl' can be not a dot product here. */
+ /* overflow only happens with extreme size area light, and higher roughness */
+ i = nl * ( A + ( B * t * sinf(a) * tanf(b) ) );
+
+ return i;
+}
+
+/* Minnaert diffuse */
+static float Minnaert_Diff(float nl, const float n[3], const float v[3], float darkness)
+{
+ float i, nv;
+
+ /* nl = dot product between surface normal and light vector */
+ if (nl <= 0.0f)
+ return 0.0f;
+
+ /* nv = dot product between surface normal and view vector */
+ nv = dot_v3v3(n, v);
+ if (nv < 0.0f)
+ nv = 0.0f;
+
+ if (darkness <= 1.0f)
+ i = nl * pow(max_ff(nv * nl, 0.1f), (darkness - 1.0f) ); /*The Real model*/
+ else
+ i = nl * pow( (1.001f - nv), (darkness - 1.0f) ); /*Nvidia model*/
+
+ return i;
+}
+
+static float Fresnel_Diff(float *vn, float *lv, float *UNUSED(view), float fac_i, float fac)
+{
+ return fresnel_fac(lv, vn, fac_i, fac);
+}
+
+/* --------------------------------------------- */
+/* also called from texture.c */
+void calc_R_ref(ShadeInput *shi)
+{
+ float i;
+
+ /* shi->vn dot shi->view */
+ i= -2*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]);
+
+ shi->ref[0]= (shi->view[0]+i*shi->vn[0]);
+ shi->ref[1]= (shi->view[1]+i*shi->vn[1]);
+ shi->ref[2]= (shi->view[2]+i*shi->vn[2]);
+ if (shi->osatex) {
+ if (shi->vlr->flag & R_SMOOTH) {
+ i= -2*( (shi->vn[0]+shi->dxno[0])*(shi->view[0]+shi->dxview) +
+ (shi->vn[1]+shi->dxno[1])*shi->view[1]+ (shi->vn[2]+shi->dxno[2])*shi->view[2] );
+
+ shi->dxref[0]= shi->ref[0]- ( shi->view[0]+shi->dxview+i*(shi->vn[0]+shi->dxno[0]));
+ shi->dxref[1]= shi->ref[1]- (shi->view[1]+ i*(shi->vn[1]+shi->dxno[1]));
+ shi->dxref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+shi->dxno[2]));
+
+ i= -2*( (shi->vn[0]+shi->dyno[0])*shi->view[0]+
+ (shi->vn[1]+shi->dyno[1])*(shi->view[1]+shi->dyview)+ (shi->vn[2]+shi->dyno[2])*shi->view[2] );
+
+ shi->dyref[0]= shi->ref[0]- (shi->view[0]+ i*(shi->vn[0]+shi->dyno[0]));
+ shi->dyref[1]= shi->ref[1]- (shi->view[1]+shi->dyview+i*(shi->vn[1]+shi->dyno[1]));
+ shi->dyref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+shi->dyno[2]));
+
+ }
+ else {
+
+ i= -2*( shi->vn[0]*(shi->view[0]+shi->dxview) +
+ shi->vn[1]*shi->view[1]+ shi->vn[2]*shi->view[2] );
+
+ shi->dxref[0]= shi->ref[0]- (shi->view[0]+shi->dxview+i*shi->vn[0]);
+ shi->dxref[1]= shi->ref[1]- (shi->view[1]+ i*shi->vn[1]);
+ shi->dxref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]);
+
+ i= -2*( shi->vn[0]*shi->view[0]+
+ shi->vn[1]*(shi->view[1]+shi->dyview)+ shi->vn[2]*shi->view[2] );
+
+ shi->dyref[0]= shi->ref[0]- (shi->view[0]+ i*shi->vn[0]);
+ shi->dyref[1]= shi->ref[1]- (shi->view[1]+shi->dyview+i*shi->vn[1]);
+ shi->dyref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]);
+ }
+ }
+
+}
+
+/* called from rayshade.c */
+void shade_color(ShadeInput *shi, ShadeResult *shr)
+{
+ Material *ma= shi->mat;
+
+ if (ma->mode & (MA_FACETEXTURE)) {
+ shi->r= shi->vcol[0];
+ shi->g= shi->vcol[1];
+ shi->b= shi->vcol[2];
+ if (ma->mode & (MA_FACETEXTURE_ALPHA))
+ shi->alpha= shi->vcol[3];
+ }
+ else if (ma->mode & (MA_VERTEXCOLP)) {
+ float neg_alpha = 1.0f - shi->vcol[3];
+ shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3];
+ shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3];
+ shi->b= shi->b*neg_alpha + shi->vcol[2]*shi->vcol[3];
+ }
+
+ if (ma->texco)
+ do_material_tex(shi, &R);
+
+ if (ma->fresnel_tra!=0.0f)
+ shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
+
+ if (!(shi->mode & MA_TRANSP)) shi->alpha= 1.0f;
+
+ shr->diff[0]= shi->r;
+ shr->diff[1]= shi->g;
+ shr->diff[2]= shi->b;
+ shr->alpha= shi->alpha;
+
+ /* modulate by the object color */
+ if ((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) {
+ float obcol[4];
+
+ copy_v4_v4(obcol, shi->obr->ob->col);
+ CLAMP(obcol[3], 0.0f, 1.0f);
+
+ shr->diff[0] *= obcol[0];
+ shr->diff[1] *= obcol[1];
+ shr->diff[2] *= obcol[2];
+ if (shi->mode & MA_TRANSP) shr->alpha *= obcol[3];
+ }
+
+ copy_v3_v3(shr->diffshad, shr->diff);
+}
+
+/* ramp for at end of shade */
+static void ramp_diffuse_result(float *diff, ShadeInput *shi)
+{
+ Material *ma= shi->mat;
+ float col[4];
+
+ if (ma->ramp_col) {
+ if (ma->rampin_col==MA_RAMP_IN_RESULT) {
+ float fac = IMB_colormanagement_get_luminance(diff);
+ BKE_colorband_evaluate(ma->ramp_col, fac, col);
+
+ /* blending method */
+ fac= col[3]*ma->rampfac_col;
+
+ ramp_blend(ma->rampblend_col, diff, fac, col);
+ }
+ }
+}
+
+/* r,g,b denote energy, ramp is used with different values to make new material color */
+static void add_to_diffuse(float diff[3], const ShadeInput *shi, const float is, const float rgb[3])
+{
+ Material *ma= shi->mat;
+
+ if (ma->ramp_col && (ma->mode & MA_RAMP_COL)) {
+
+ /* MA_RAMP_IN_RESULT is exceptional */
+ if (ma->rampin_col==MA_RAMP_IN_RESULT) {
+ /* normal add */
+ diff[0] += rgb[0] * shi->r;
+ diff[1] += rgb[1] * shi->g;
+ diff[2] += rgb[2] * shi->b;
+ }
+ else {
+ float colt[3], col[4];
+ float fac;
+
+ /* input */
+ switch (ma->rampin_col) {
+ case MA_RAMP_IN_ENERGY:
+ fac = IMB_colormanagement_get_luminance(rgb);
+ break;
+ case MA_RAMP_IN_SHADER:
+ fac = is;
+ break;
+ case MA_RAMP_IN_NOR:
+ fac = dot_v3v3(shi->view, shi->vn);
+ break;
+ default:
+ fac = 0.0f;
+ break;
+ }
+
+ BKE_colorband_evaluate(ma->ramp_col, fac, col);
+
+ /* blending method */
+ fac = col[3] * ma->rampfac_col;
+ copy_v3_v3(colt, &shi->r);
+
+ ramp_blend(ma->rampblend_col, colt, fac, col);
+
+ /* output to */
+ diff[0] += rgb[0] * colt[0];
+ diff[1] += rgb[1] * colt[1];
+ diff[2] += rgb[2] * colt[2];
+ }
+ }
+ else {
+ diff[0] += rgb[0] * shi->r;
+ diff[1] += rgb[1] * shi->g;
+ diff[2] += rgb[2] * shi->b;
+ }
+}
+
+static void ramp_spec_result(float spec_col[3], ShadeInput *shi)
+{
+ Material *ma= shi->mat;
+
+ if (ma->ramp_spec && (ma->rampin_spec==MA_RAMP_IN_RESULT)) {
+ float col[4];
+ float fac = IMB_colormanagement_get_luminance(spec_col);
+
+ BKE_colorband_evaluate(ma->ramp_spec, fac, col);
+
+ /* blending method */
+ fac= col[3]*ma->rampfac_spec;
+
+ ramp_blend(ma->rampblend_spec, spec_col, fac, col);
+
+ }
+}
+
+/* is = dot product shade, t = spec energy */
+static void do_specular_ramp(ShadeInput *shi, float is, float t, float spec[3])
+{
+ Material *ma= shi->mat;
+
+ spec[0]= shi->specr;
+ spec[1]= shi->specg;
+ spec[2]= shi->specb;
+
+ /* MA_RAMP_IN_RESULT is exception */
+ if (ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) {
+ float fac;
+ float col[4];
+
+ /* input */
+ switch (ma->rampin_spec) {
+ case MA_RAMP_IN_ENERGY:
+ fac= t;
+ break;
+ case MA_RAMP_IN_SHADER:
+ fac= is;
+ break;
+ case MA_RAMP_IN_NOR:
+ fac= shi->view[0]*shi->vn[0] + shi->view[1]*shi->vn[1] + shi->view[2]*shi->vn[2];
+ break;
+ default:
+ fac= 0.0f;
+ break;
+ }
+
+ BKE_colorband_evaluate(ma->ramp_spec, fac, col);
+
+ /* blending method */
+ fac= col[3]*ma->rampfac_spec;
+
+ ramp_blend(ma->rampblend_spec, spec, fac, col);
+ }
+}
+
+/* pure AO, check for raytrace and world should have been done */
+/* preprocess, textures were not done, don't use shi->amb for that reason */
+void ambient_occlusion(ShadeInput *shi)
+{
+ if ((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f) {
+ sample_occ(&R, shi);
+ }
+ else if ((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f) {
+ ray_ao(shi, shi->ao, shi->env);
+ }
+ else {
+ shi->ao[0]= shi->ao[1]= shi->ao[2]= 1.0f;
+ zero_v3(shi->env);
+ zero_v3(shi->indirect);
+ }
+}
+
+
+/* wrld mode was checked for */
+static void ambient_occlusion_apply(ShadeInput *shi, ShadeResult *shr)
+{
+ float f= R.wrld.aoenergy;
+ float tmp[3], tmpspec[3];
+
+ if (!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
+ return;
+ if (f == 0.0f)
+ return;
+
+ if (R.wrld.aomix==WO_AOADD) {
+ shr->combined[0] += shi->ao[0]*shi->r*shi->refl*f;
+ shr->combined[1] += shi->ao[1]*shi->g*shi->refl*f;
+ shr->combined[2] += shi->ao[2]*shi->b*shi->refl*f;
+ }
+ else if (R.wrld.aomix==WO_AOMUL) {
+ mul_v3_v3v3(tmp, shr->combined, shi->ao);
+ mul_v3_v3v3(tmpspec, shr->spec, shi->ao);
+
+ if (f == 1.0f) {
+ copy_v3_v3(shr->combined, tmp);
+ copy_v3_v3(shr->spec, tmpspec);
+ }
+ else {
+ interp_v3_v3v3(shr->combined, shr->combined, tmp, f);
+ interp_v3_v3v3(shr->spec, shr->spec, tmpspec, f);
+ }
+ }
+}
+
+void environment_lighting_apply(ShadeInput *shi, ShadeResult *shr)
+{
+ float f= R.wrld.ao_env_energy*shi->amb;
+
+ if (!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
+ return;
+ if (f == 0.0f)
+ return;
+
+ shr->combined[0] += shi->env[0]*shi->r*shi->refl*f;
+ shr->combined[1] += shi->env[1]*shi->g*shi->refl*f;
+ shr->combined[2] += shi->env[2]*shi->b*shi->refl*f;
+}
+
+static void indirect_lighting_apply(ShadeInput *shi, ShadeResult *shr)
+{
+ float f= R.wrld.ao_indirect_energy;
+
+ if (!((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
+ return;
+ if (f == 0.0f)
+ return;
+
+ shr->combined[0] += shi->indirect[0]*shi->r*shi->refl*f;
+ shr->combined[1] += shi->indirect[1]*shi->g*shi->refl*f;
+ shr->combined[2] += shi->indirect[2]*shi->b*shi->refl*f;
+}
+
+/* result written in shadfac */
+void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float shadfac[4], int do_real)
+{
+ LampShadowSubSample *lss= &(lar->shadsamp[shi->thread].s[shi->sample]);
+
+ if (do_real || lss->samplenr!=shi->samplenr) {
+
+ shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 1.0f;
+
+ if (lar->shb) {
+ if (lar->buftype==LA_SHADBUF_IRREGULAR)
+ shadfac[3]= ISB_getshadow(shi, lar->shb);
+ else
+ shadfac[3] = testshadowbuf(&R, lar->shb, shi->co, shi->dxco, shi->dyco, inp, shi->mat->lbias);
+ }
+ else if (lar->mode & LA_SHAD_RAY) {
+ ray_shadow(shi, lar, shadfac);
+ }
+
+ if (shi->depth==0) {
+ copy_v4_v4(lss->shadfac, shadfac);
+ lss->samplenr= shi->samplenr;
+ }
+ }
+ else {
+ copy_v4_v4(shadfac, lss->shadfac);
+ }
+}
+
+/* lampdistance and spot angle, writes in lv and dist */
+float lamp_get_visibility(LampRen *lar, const float co[3], float lv[3], float *dist)
+{
+ if (lar->type==LA_SUN || lar->type==LA_HEMI) {
+ *dist= 1.0f;
+ copy_v3_v3(lv, lar->vec);
+ return 1.0f;
+ }
+ else {
+ float visifac= 1.0f, visifac_r;
+
+ sub_v3_v3v3(lv, co, lar->co);
+ mul_v3_fl(lv, 1.0f / (*dist = len_v3(lv)));
+
+ /* area type has no quad or sphere option */
+ if (lar->type==LA_AREA) {
+ /* area is single sided */
+ //if (dot_v3v3(lv, lar->vec) > 0.0f)
+ // visifac= 1.0f;
+ //else
+ // visifac= 0.0f;
+ }
+ else {
+ switch (lar->falloff_type) {
+ case LA_FALLOFF_CONSTANT:
+ visifac = 1.0f;
+ break;
+ case LA_FALLOFF_INVLINEAR:
+ visifac = lar->dist/(lar->dist + dist[0]);
+ break;
+ case LA_FALLOFF_INVSQUARE:
+ /* NOTE: This seems to be a hack since commit r12045 says this
+ * option is similar to old Quad, but with slight changes.
+ * Correct inv square would be (which would be old Quad):
+ * visifac = lar->distkw / (lar->distkw + dist[0]*dist[0]);
+ */
+ visifac = lar->dist / (lar->dist + dist[0]*dist[0]);
+ break;
+ case LA_FALLOFF_SLIDERS:
+ if (lar->ld1>0.0f)
+ visifac= lar->dist/(lar->dist+lar->ld1*dist[0]);
+ if (lar->ld2>0.0f)
+ visifac*= lar->distkw/(lar->distkw+lar->ld2*dist[0]*dist[0]);
+ break;
+ case LA_FALLOFF_INVCOEFFICIENTS:
+ visifac_r = lar->coeff_const +
+ lar->coeff_lin * dist[0] +
+ lar->coeff_quad * dist[0] * dist[0];
+ if (visifac_r > 0.0)
+ visifac = 1.0 / visifac_r;
+ else
+ visifac = 0.0;
+ break;
+ case LA_FALLOFF_CURVE:
+ /* curvemapping_initialize is called from #add_render_lamp */
+ visifac = curvemapping_evaluateF(lar->curfalloff, 0, dist[0]/lar->dist);
+ break;
+ }
+
+ if (lar->mode & LA_SPHERE) {
+ float t= lar->dist - dist[0];
+ if (t<=0.0f)
+ visifac= 0.0f;
+ else
+ visifac*= t/lar->dist;
+ }
+
+ if (visifac > 0.0f) {
+ if (lar->type==LA_SPOT) {
+ float inpr, t;
+
+ if (lar->mode & LA_SQUARE) {
+ if (dot_v3v3(lv, lar->vec) > 0.0f) {
+ float lvrot[3], x;
+
+ /* rotate view to lampspace */
+ copy_v3_v3(lvrot, lv);
+ mul_m3_v3(lar->imat, lvrot);
+
+ x = max_ff(fabsf(lvrot[0]/lvrot[2]), fabsf(lvrot[1]/lvrot[2]));
+ /* 1.0f/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
+
+ inpr = 1.0f / (sqrtf(1.0f + x * x));
+ }
+ else inpr= 0.0f;
+ }
+ else {
+ inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
+ }
+
+ t= lar->spotsi;
+ if (inpr<=t)
+ visifac= 0.0f;
+ else {
+ t= inpr-t;
+ if (t<lar->spotbl && lar->spotbl!=0.0f) {
+ /* soft area */
+ float i= t/lar->spotbl;
+ t= i*i;
+ inpr*= (3.0f*t-2.0f*t*i);
+ }
+ visifac*= inpr;
+ }
+ }
+ }
+ }
+ if (visifac <= 0.001f) visifac = 0.0f;
+ return visifac;
+ }
+}
+
+/* function returns raw diff, spec and full shadowed diff in the 'shad' pass */
+static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int passflag)
+{
+ Material *ma= shi->mat;
+ VlakRen *vlr= shi->vlr;
+ float lv[3], lampdist, lacol[3], shadfac[4], lashdw[3];
+ float i, is, i_noshad, inp, *vn, *view, vnor[3], phongcorr=1.0f;
+ float visifac;
+
+ vn= shi->vn;
+ view= shi->view;
+
+
+ if (lar->energy == 0.0f) return;
+ /* only shadow lamps shouldn't affect shadow-less materials at all */
+ if ((lar->mode & LA_ONLYSHADOW) && (!(ma->mode & MA_SHADOW) || !(R.r.mode & R_SHADOW)))
+ return;
+ /* optimization, don't render fully black lamps */
+ if (!(lar->mode & LA_TEXTURE) && (lar->r + lar->g + lar->b == 0.0f))
+ return;
+
+ /* lampdist, spot angle, area side, ... */
+ visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist);
+ if (visifac==0.0f)
+ return;
+
+ if (lar->type==LA_SPOT) {
+ if (lar->mode & LA_OSATEX) {
+ shi->osatex= 1; /* signal for multitex() */
+
+ shi->dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dxco[0])/lampdist;
+ shi->dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dxco[1])/lampdist;
+ shi->dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dxco[2])/lampdist;
+
+ shi->dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dyco[0])/lampdist;
+ shi->dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dyco[1])/lampdist;
+ shi->dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dyco[2])/lampdist;
+ }
+ }
+
+ /* lamp color texture */
+ lacol[0]= lar->r;
+ lacol[1]= lar->g;
+ lacol[2]= lar->b;
+
+ lashdw[0]= lar->shdwr;
+ lashdw[1]= lar->shdwg;
+ lashdw[2]= lar->shdwb;
+
+ if (lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE);
+ if (lar->mode & LA_SHAD_TEX) do_lamp_tex(lar, lv, shi, lashdw, LA_SHAD_TEX);
+
+ /* tangent case; calculate fake face normal, aligned with lampvector */
+ /* note, vnor==vn is used as tangent trigger for buffer shadow */
+ if (vlr->flag & R_TANGENT) {
+ float cross[3], nstrand[3], blend;
+
+ if (ma->mode & MA_STR_SURFDIFF) {
+ cross_v3_v3v3(cross, shi->surfnor, vn);
+ cross_v3_v3v3(nstrand, vn, cross);
+
+ blend= dot_v3v3(nstrand, shi->surfnor);
+ blend= 1.0f - blend;
+ CLAMP(blend, 0.0f, 1.0f);
+
+ interp_v3_v3v3(vnor, nstrand, shi->surfnor, blend);
+ normalize_v3(vnor);
+ }
+ else {
+ cross_v3_v3v3(cross, lv, vn);
+ cross_v3_v3v3(vnor, cross, vn);
+ normalize_v3(vnor);
+ }
+
+ if (ma->strand_surfnor > 0.0f) {
+ if (ma->strand_surfnor > shi->surfdist) {
+ blend= (ma->strand_surfnor - shi->surfdist)/ma->strand_surfnor;
+ interp_v3_v3v3(vnor, vnor, shi->surfnor, blend);
+ normalize_v3(vnor);
+ }
+ }
+
+ vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
+ vn= vnor;
+ }
+ else if (ma->mode & MA_TANGENT_V) {
+ float cross[3];
+ cross_v3_v3v3(cross, lv, shi->tang);
+ cross_v3_v3v3(vnor, cross, shi->tang);
+ normalize_v3(vnor);
+ vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
+ vn= vnor;
+ }
+
+ /* dot product and reflectivity */
+ /* inp = dotproduct, is = shader result, i = lamp energy (with shadow), i_noshad = i without shadow */
+ inp= dot_v3v3(vn, lv);
+
+ /* phong threshold to prevent backfacing faces having artifacts on ray shadow (terminator problem) */
+ /* this complex construction screams for a nicer implementation! (ton) */
+ if (R.r.mode & R_SHADOW) {
+ if (ma->mode & MA_SHADOW) {
+ if (lar->type == LA_HEMI || lar->type == LA_AREA) {
+ /* pass */
+ }
+ else if ((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
+ float thresh= shi->obr->ob->smoothresh;
+ if (inp>thresh)
+ phongcorr= (inp-thresh)/(inp*(1.0f-thresh));
+ else
+ phongcorr= 0.0f;
+ }
+ else if (ma->sbias!=0.0f && ((lar->mode & LA_SHAD_RAY) || lar->shb)) {
+ if (inp>ma->sbias)
+ phongcorr= (inp-ma->sbias)/(inp*(1.0f-ma->sbias));
+ else
+ phongcorr= 0.0f;
+ }
+ }
+ }
+
+ /* diffuse shaders */
+ if (lar->mode & LA_NO_DIFF) {
+ is = 0.0f; /* skip shaders */
+ }
+ else if (lar->type==LA_HEMI) {
+ is = 0.5f * inp + 0.5f;
+ }
+ else {
+
+ if (lar->type==LA_AREA)
+ inp= area_lamp_energy_multisample(lar, shi->co, vn);
+
+ /* diffuse shaders (oren nayer gets inp from area light) */
+ if (ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
+ else if (ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]);
+ else if (ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness);
+ else if (ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]);
+ else is= inp; /* Lambert */
+ }
+
+ /* 'is' is diffuse */
+ if ((ma->shade_flag & MA_CUBIC) && is > 0.0f && is < 1.0f) {
+ is= 3.0f * is * is - 2.0f * is * is * is; /* nicer termination of shades */
+ }
+
+ i= is*phongcorr;
+
+ if (i>0.0f) {
+ i*= visifac*shi->refl;
+ }
+ i_noshad= i;
+
+ vn = shi->vn; /* bring back original vector, we use special specular shaders for tangent */
+ if (ma->mode & MA_TANGENT_V)
+ vn= shi->tang;
+
+ /* init transp shadow */
+ shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 1.0f;
+
+ /* shadow and spec, (visifac==0 outside spot) */
+ if (visifac> 0.0f) {
+
+ if ((R.r.mode & R_SHADOW)) {
+ if (ma->mode & MA_SHADOW) {
+ if (lar->shb || (lar->mode & LA_SHAD_RAY)) {
+
+ if (vn==vnor) /* tangent trigger */
+ lamp_get_shadow(lar, shi, dot_v3v3(shi->vn, lv), shadfac, shi->depth);
+ else
+ lamp_get_shadow(lar, shi, inp, shadfac, shi->depth);
+
+ /* warning, here it skips the loop */
+ if ((lar->mode & LA_ONLYSHADOW) && i>0.0f) {
+
+ shadfac[3]= i*lar->energy*(1.0f-shadfac[3]);
+ shr->shad[0] -= shadfac[3]*shi->r*(1.0f-lashdw[0]);
+ shr->shad[1] -= shadfac[3]*shi->g*(1.0f-lashdw[1]);
+ shr->shad[2] -= shadfac[3]*shi->b*(1.0f-lashdw[2]);
+
+ if (!(lar->mode & LA_NO_SPEC)) {
+ shr->spec[0] -= shadfac[3]*shi->specr*(1.0f-lashdw[0]);
+ shr->spec[1] -= shadfac[3]*shi->specg*(1.0f-lashdw[1]);
+ shr->spec[2] -= shadfac[3]*shi->specb*(1.0f-lashdw[2]);
+ }
+
+ return;
+ }
+
+ i*= shadfac[3];
+ shr->shad[3] = shadfac[3]; /* store this for possible check in troublesome cases */
+ }
+ else {
+ shr->shad[3] = 1.0f; /* No shadow at all! */
+ }
+ }
+ }
+
+ /* in case 'no diffuse' we still do most calculus, spec can be in shadow.*/
+ if (!(lar->mode & LA_NO_DIFF)) {
+ if (i>0.0f) {
+ if (ma->mode & MA_SHADOW_TRA) {
+ const float tcol[3] = {
+ i * shadfac[0] * lacol[0],
+ i * shadfac[1] * lacol[1],
+ i * shadfac[2] * lacol[2],
+ };
+ add_to_diffuse(shr->shad, shi, is, tcol);
+ }
+ else {
+ const float tcol[3] = {
+ i * lacol[0],
+ i * lacol[1],
+ i * lacol[2],
+ };
+ add_to_diffuse(shr->shad, shi, is, tcol);
+ }
+ }
+ /* add light for colored shadow */
+ if (i_noshad>i && !(lashdw[0]==0 && lashdw[1]==0 && lashdw[2]==0)) {
+ const float tcol[3] = {
+ lashdw[0] * (i_noshad - i) * lacol[0],
+ lashdw[1] * (i_noshad - i) * lacol[1],
+ lashdw[2] * (i_noshad - i) * lacol[2],
+ };
+ add_to_diffuse(shr->shad, shi, is, tcol);
+ }
+ if (i_noshad>0.0f) {
+ if (passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW) ||
+ ((passflag & SCE_PASS_COMBINED) && !(shi->combinedflag & SCE_PASS_SHADOW)))
+ {
+ const float tcol[3] = {
+ i_noshad * lacol[0],
+ i_noshad * lacol[1],
+ i_noshad * lacol[2]
+ };
+ add_to_diffuse(shr->diff, shi, is, tcol);
+ }
+ else {
+ copy_v3_v3(shr->diff, shr->shad);
+ }
+ }
+ }
+
+ /* specularity */
+ shadfac[3]*= phongcorr; /* note, shadfac not allowed to be stored nonlocal */
+
+ if (shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC) && !(lar->mode & LA_ONLYSHADOW)) {
+
+ if (!(passflag & (SCE_PASS_COMBINED | SCE_PASS_SPEC))) {
+ /* pass */
+ }
+ else if (lar->type == LA_HEMI) {
+ float t;
+ /* hemi uses no spec shaders (yet) */
+
+ lv[0]+= view[0];
+ lv[1]+= view[1];
+ lv[2]+= view[2];
+
+ normalize_v3(lv);
+
+ t= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2];
+
+ if (lar->type==LA_HEMI) {
+ t= 0.5f*t+0.5f;
+ }
+
+ t= shadfac[3]*shi->spec*spec(t, shi->har);
+
+ shr->spec[0]+= t*(lacol[0] * shi->specr);
+ shr->spec[1]+= t*(lacol[1] * shi->specg);
+ shr->spec[2]+= t*(lacol[2] * shi->specb);
+ }
+ else {
+ /* specular shaders */
+ float specfac, t;
+
+ if (ma->spec_shader==MA_SPEC_PHONG)
+ specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if (ma->spec_shader==MA_SPEC_COOKTORR)
+ specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if (ma->spec_shader==MA_SPEC_BLINN)
+ specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else if (ma->spec_shader==MA_SPEC_WARDISO)
+ specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+ else
+ specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V));
+
+ /* area lamp correction */
+ if (lar->type==LA_AREA) specfac*= inp;
+
+ t= shadfac[3]*shi->spec*visifac*specfac;
+
+ if (ma->mode & MA_RAMP_SPEC) {
+ float spec[3];
+ do_specular_ramp(shi, specfac, t, spec);
+ shr->spec[0]+= t*(lacol[0] * spec[0]);
+ shr->spec[1]+= t*(lacol[1] * spec[1]);
+ shr->spec[2]+= t*(lacol[2] * spec[2]);
+ }
+ else {
+ shr->spec[0]+= t*(lacol[0] * shi->specr);
+ shr->spec[1]+= t*(lacol[1] * shi->specg);
+ shr->spec[2]+= t*(lacol[2] * shi->specb);
+ }
+ }
+ }
+ }
+}
+
+static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
+{
+
+ if (R.r.mode & R_SHADOW) {
+ ListBase *lights;
+ LampRen *lar;
+ GroupObject *go;
+ float inpr, lv[3];
+ float /* *view, */ shadfac[4];
+ float ir, accum, visifac, lampdist;
+ float shaded = 0.0f, lightness = 0.0f;
+
+
+ /* view= shi->view; */ /* UNUSED */
+ accum= ir= 0.0f;
+
+ lights= get_lights(shi);
+ for (go=lights->first; go; go= go->next) {
+ lar= go->lampren;
+ if (lar==NULL) continue;
+
+ if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay)==0) continue;
+ if ((lar->lay & shi->lay)==0) continue;
+
+ if (lar->shb || (lar->mode & LA_SHAD_RAY)) {
+ visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist);
+ ir+= 1.0f;
+
+ if (visifac <= 0.0f) {
+ if (shi->mat->shadowonly_flag == MA_SO_OLD)
+ accum+= 1.0f;
+
+ continue;
+ }
+ inpr= dot_v3v3(shi->vn, lv);
+ if (inpr <= 0.0f) {
+ if (shi->mat->shadowonly_flag == MA_SO_OLD)
+ accum+= 1.0f;
+
+ continue;
+ }
+
+ lamp_get_shadow(lar, shi, inpr, shadfac, shi->depth);
+
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ /* Old "Shadows Only" */
+ accum+= (1.0f-visifac) + (visifac)*IMB_colormanagement_get_luminance(shadfac)*shadfac[3];
+ }
+ else {
+ shaded += IMB_colormanagement_get_luminance(shadfac)*shadfac[3] * visifac * lar->energy;
+
+ if (shi->mat->shadowonly_flag == MA_SO_SHADOW) {
+ lightness += visifac * lar->energy;
+ }
+ }
+ }
+ }
+
+ /* Apply shadows as alpha */
+ if (ir>0.0f) {
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ accum = 1.0f - accum/ir;
+ }
+ else {
+ if (shi->mat->shadowonly_flag == MA_SO_SHADOW) {
+ if (lightness > 0.0f) {
+ /* Get shadow value from between 0.0f and non-shadowed lightness */
+ accum = (lightness - shaded) / (lightness);
+ }
+ else {
+ accum = 0.0f;
+ }
+ }
+ else { /* shadowonly_flag == MA_SO_SHADED */
+ /* Use shaded value */
+ accum = 1.0f - shaded;
+ }
+ }
+
+ shr->alpha= (shi->alpha)*(accum);
+ if (shr->alpha<0.0f) shr->alpha=0.0f;
+ }
+ else {
+ /* If "fully shaded", use full alpha even on areas that have no lights */
+ if (shi->mat->shadowonly_flag == MA_SO_SHADED) shr->alpha=shi->alpha;
+ else shr->alpha= 0.f;
+ }
+ }
+
+ /* quite disputable this... also note it doesn't mirror-raytrace */
+ if ((R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT)) && shi->amb!=0.0f) {
+ float f;
+
+ if (R.wrld.mode & WO_AMB_OCC) {
+ f= R.wrld.aoenergy*shi->amb;
+
+ if (R.wrld.aomix==WO_AOADD) {
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ f= f*(1.0f - IMB_colormanagement_get_luminance(shi->ao));
+ shr->alpha= (shr->alpha + f)*f;
+ }
+ else {
+ shr->alpha -= f*IMB_colormanagement_get_luminance(shi->ao);
+ if (shr->alpha<0.0f) shr->alpha=0.0f;
+ }
+ }
+ else /* AO Multiply */
+ shr->alpha= (1.0f - f)*shr->alpha + f*(1.0f - (1.0f - shr->alpha)*IMB_colormanagement_get_luminance(shi->ao));
+ }
+
+ if (R.wrld.mode & WO_ENV_LIGHT) {
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ f= R.wrld.ao_env_energy*shi->amb*(1.0f - IMB_colormanagement_get_luminance(shi->env));
+ shr->alpha= (shr->alpha + f)*f;
+ }
+ else {
+ f= R.wrld.ao_env_energy*shi->amb;
+ shr->alpha -= f*IMB_colormanagement_get_luminance(shi->env);
+ if (shr->alpha<0.0f) shr->alpha=0.0f;
+ }
+ }
+ }
+}
+
+/* let's map negative light as if it mirrors positive light, otherwise negative values disappear */
+static void wrld_exposure_correct(float diff[3])
+{
+
+ diff[0]= R.wrld.linfac*(1.0f-expf( diff[0]*R.wrld.logfac) );
+ diff[1]= R.wrld.linfac*(1.0f-expf( diff[1]*R.wrld.logfac) );
+ diff[2]= R.wrld.linfac*(1.0f-expf( diff[2]*R.wrld.logfac) );
+}
+
+void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
+{
+ /* Passes which might need to know material color.
+ *
+ * It seems to be faster to just calculate material color
+ * even if the pass doesn't really need it than trying to
+ * figure out whether color is really needed or not.
+ */
+ const int color_passes =
+ SCE_PASS_COMBINED | SCE_PASS_RGBA | SCE_PASS_DIFFUSE | SCE_PASS_SPEC |
+ SCE_PASS_REFLECT | SCE_PASS_NORMAL | SCE_PASS_REFRACT | SCE_PASS_EMIT | SCE_PASS_SHADOW;
+
+ Material *ma= shi->mat;
+ int passflag= shi->passflag;
+
+ memset(shr, 0, sizeof(ShadeResult));
+
+ if (!(shi->mode & MA_TRANSP)) shi->alpha = 1.0f;
+
+ /* separate loop */
+ if (ma->mode & MA_ONLYSHADOW) {
+ shade_lamp_loop_only_shadow(shi, shr);
+ return;
+ }
+
+ /* envmap hack, always reset */
+ shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0f;
+
+ /* material color itself */
+ if (passflag & color_passes) {
+ if (ma->mode & (MA_FACETEXTURE)) {
+ shi->r= shi->vcol[0];
+ shi->g= shi->vcol[1];
+ shi->b= shi->vcol[2];
+ if (ma->mode & (MA_FACETEXTURE_ALPHA))
+ shi->alpha= shi->vcol[3];
+ }
+#ifdef WITH_FREESTYLE
+ else if (ma->vcol_alpha) {
+ shi->r= shi->vcol[0];
+ shi->g= shi->vcol[1];
+ shi->b= shi->vcol[2];
+ shi->alpha= shi->vcol[3];
+ }
+#endif
+ else if (ma->mode & (MA_VERTEXCOLP)) {
+ float neg_alpha = 1.0f - shi->vcol[3];
+ shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3];
+ shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3];
+ shi->b= shi->b*neg_alpha + shi->vcol[2]*shi->vcol[3];
+ }
+ if (ma->texco) {
+ do_material_tex(shi, &R);
+ if (!(shi->mode & MA_TRANSP)) shi->alpha = 1.0f;
+ }
+
+ shr->col[0]= shi->r*shi->alpha;
+ shr->col[1]= shi->g*shi->alpha;
+ shr->col[2]= shi->b*shi->alpha;
+ shr->col[3]= shi->alpha;
+
+ if ((ma->sss_flag & MA_DIFF_SSS) && !sss_pass_done(&R, ma)) {
+ if (ma->sss_texfac == 0.0f) {
+ shi->r= shi->g= shi->b= shi->alpha= 1.0f;
+ shr->col[0]= shr->col[1]= shr->col[2]= shr->col[3]= 1.0f;
+ }
+ else {
+ shi->r= pow(max_ff(shi->r, 0.0f), ma->sss_texfac);
+ shi->g= pow(max_ff(shi->g, 0.0f), ma->sss_texfac);
+ shi->b= pow(max_ff(shi->b, 0.0f), ma->sss_texfac);
+ shi->alpha= pow(max_ff(shi->alpha, 0.0f), ma->sss_texfac);
+
+ shr->col[0]= pow(max_ff(shr->col[0], 0.0f), ma->sss_texfac);
+ shr->col[1]= pow(max_ff(shr->col[1], 0.0f), ma->sss_texfac);
+ shr->col[2]= pow(max_ff(shr->col[2], 0.0f), ma->sss_texfac);
+ shr->col[3]= pow(max_ff(shr->col[3], 0.0f), ma->sss_texfac);
+ }
+ }
+ }
+
+ if (ma->mode & MA_SHLESS) {
+ shr->combined[0]= shi->r;
+ shr->combined[1]= shi->g;
+ shr->combined[2]= shi->b;
+ shr->alpha= shi->alpha;
+ goto finally_shadeless;
+ }
+
+ if ( (ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL ) { /* vertexcolor light */
+ shr->emit[0]= shi->r*(shi->emit+shi->vcol[0]*shi->vcol[3]);
+ shr->emit[1]= shi->g*(shi->emit+shi->vcol[1]*shi->vcol[3]);
+ shr->emit[2]= shi->b*(shi->emit+shi->vcol[2]*shi->vcol[3]);
+ }
+ else {
+ shr->emit[0]= shi->r*shi->emit;
+ shr->emit[1]= shi->g*shi->emit;
+ shr->emit[2]= shi->b*shi->emit;
+ }
+
+ /* AO pass */
+ if (((passflag & SCE_PASS_COMBINED) && (shi->combinedflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) ||
+ (passflag & (SCE_PASS_AO|SCE_PASS_ENVIRONMENT|SCE_PASS_INDIRECT))) {
+ if ((R.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && (R.r.mode & R_SHADOW)) {
+ /* AO was calculated for scanline already */
+ if (shi->depth || shi->volume_depth)
+ ambient_occlusion(shi);
+ copy_v3_v3(shr->ao, shi->ao);
+ copy_v3_v3(shr->env, shi->env); /* XXX multiply */
+ copy_v3_v3(shr->indirect, shi->indirect); /* XXX multiply */
+ }
+ else {
+ shr->ao[0]= shr->ao[1]= shr->ao[2]= 1.0f;
+ zero_v3(shr->env);
+ zero_v3(shr->indirect);
+ }
+ }
+
+ /* lighting pass */
+ if (passflag & (SCE_PASS_COMBINED|SCE_PASS_DIFFUSE|SCE_PASS_SPEC|SCE_PASS_SHADOW)) {
+ GroupObject *go;
+ ListBase *lights;
+ LampRen *lar;
+
+ lights= get_lights(shi);
+ for (go=lights->first; go; go= go->next) {
+ lar= go->lampren;
+ if (lar==NULL) continue;
+
+ /* test for lamp layer */
+ if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay)==0) continue;
+ if ((lar->lay & shi->lay)==0) continue;
+
+ /* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */
+ shade_one_light(lar, shi, shr, passflag);
+ }
+
+ /* this check is to prevent only shadow lamps from producing negative
+ * colors.*/
+ if (shr->spec[0] < 0) shr->spec[0] = 0;
+ if (shr->spec[1] < 0) shr->spec[1] = 0;
+ if (shr->spec[2] < 0) shr->spec[2] = 0;
+
+ if (shr->shad[0] < 0) shr->shad[0] = 0;
+ if (shr->shad[1] < 0) shr->shad[1] = 0;
+ if (shr->shad[2] < 0) shr->shad[2] = 0;
+
+ if (ma->sss_flag & MA_DIFF_SSS) {
+ float sss[3], col[3], invalpha, texfac= ma->sss_texfac;
+
+ /* this will return false in the preprocess stage */
+ if (sample_sss(&R, ma, shi->co, sss)) {
+ invalpha= (shr->col[3] > FLT_EPSILON)? 1.0f/shr->col[3]: 1.0f;
+
+ if (texfac==0.0f) {
+ copy_v3_v3(col, shr->col);
+ mul_v3_fl(col, invalpha);
+ }
+ else if (texfac==1.0f) {
+ col[0]= col[1]= col[2]= 1.0f;
+ mul_v3_fl(col, invalpha);
+ }
+ else {
+ copy_v3_v3(col, shr->col);
+ mul_v3_fl(col, invalpha);
+ col[0]= pow(max_ff(col[0], 0.0f), 1.0f-texfac);
+ col[1]= pow(max_ff(col[1], 0.0f), 1.0f-texfac);
+ col[2]= pow(max_ff(col[2], 0.0f), 1.0f-texfac);
+ }
+
+ shr->diff[0]= sss[0]*col[0];
+ shr->diff[1]= sss[1]*col[1];
+ shr->diff[2]= sss[2]*col[2];
+
+ if (shi->combinedflag & SCE_PASS_SHADOW) {
+ shr->shad[0]= shr->diff[0];
+ shr->shad[1]= shr->diff[1];
+ shr->shad[2]= shr->diff[2];
+ }
+ }
+ }
+
+ if (shi->combinedflag & SCE_PASS_SHADOW)
+ copy_v3_v3(shr->diffshad, shr->shad);
+ else
+ copy_v3_v3(shr->diffshad, shr->diff);
+
+ copy_v3_v3(shr->combined, shr->diffshad);
+
+ /* calculate shadow pass, we use a multiplication mask */
+ /* Even if diff = 0,0,0, it does matter what the shadow pass is, since we may want it 'for itself'! */
+ if (passflag & SCE_PASS_SHADOW) {
+ if (shr->diff[0]!=0.0f) shr->shad[0]= shr->shad[0]/shr->diff[0];
+ /* can't determine proper shadow from shad/diff (0/0), so use shadow intensity */
+ else if (shr->shad[0]==0.0f) shr->shad[0]= shr->shad[3];
+
+ if (shr->diff[1]!=0.0f) shr->shad[1]= shr->shad[1]/shr->diff[1];
+ else if (shr->shad[1]==0.0f) shr->shad[1]= shr->shad[3];
+
+ if (shr->diff[2]!=0.0f) shr->shad[2]= shr->shad[2]/shr->diff[2];
+ else if (shr->shad[2]==0.0f) shr->shad[2]= shr->shad[3];
+ }
+
+ /* exposure correction */
+ if ((R.wrld.exp!=0.0f || R.wrld.range!=1.0f) && !R.sss_points) {
+ wrld_exposure_correct(shr->combined); /* has no spec! */
+ wrld_exposure_correct(shr->spec);
+ }
+ }
+
+ /* alpha in end, spec can influence it */
+ if (passflag & (SCE_PASS_COMBINED)) {
+ if ((ma->fresnel_tra!=0.0f) && (shi->mode & MA_TRANSP))
+ shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
+
+ /* note: shi->mode! */
+ if (shi->mode & MA_TRANSP && (shi->mode & (MA_ZTRANSP|MA_RAYTRANSP))) {
+ if (shi->spectra!=0.0f) {
+ float t = max_fff(shr->spec[0], shr->spec[1], shr->spec[2]);
+ t *= shi->spectra;
+ if (t>1.0f) t= 1.0f;
+ shi->alpha= (1.0f-t)*shi->alpha+t;
+ }
+ }
+ }
+ shr->alpha= shi->alpha;
+
+ /* from now stuff everything in shr->combined: ambient, AO, ramps, exposure */
+ if (!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) {
+ if (R.r.mode & R_SHADOW) {
+ /* add AO in combined? */
+ if (R.wrld.mode & WO_AMB_OCC)
+ if (shi->combinedflag & SCE_PASS_AO)
+ ambient_occlusion_apply(shi, shr);
+
+ if (R.wrld.mode & WO_ENV_LIGHT)
+ if (shi->combinedflag & SCE_PASS_ENVIRONMENT)
+ environment_lighting_apply(shi, shr);
+
+ if (R.wrld.mode & WO_INDIRECT_LIGHT)
+ if (shi->combinedflag & SCE_PASS_INDIRECT)
+ indirect_lighting_apply(shi, shr);
+ }
+
+ shr->combined[0]+= shi->ambr;
+ shr->combined[1]+= shi->ambg;
+ shr->combined[2]+= shi->ambb;
+
+ if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->combined, shi);
+ }
+
+ if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shi);
+
+ /* refcol is for envmap only */
+ if (shi->refcol[0]!=0.0f) {
+ float result[3];
+
+ result[0]= shi->mirr*shi->refcol[1] + (1.0f - shi->mirr*shi->refcol[0])*shr->combined[0];
+ result[1]= shi->mirg*shi->refcol[2] + (1.0f - shi->mirg*shi->refcol[0])*shr->combined[1];
+ result[2]= shi->mirb*shi->refcol[3] + (1.0f - shi->mirb*shi->refcol[0])*shr->combined[2];
+
+ if (passflag & SCE_PASS_REFLECT)
+ sub_v3_v3v3(shr->refl, result, shr->combined);
+
+ if (shi->combinedflag & SCE_PASS_REFLECT)
+ copy_v3_v3(shr->combined, result);
+
+ }
+
+ /* and add emit and spec */
+ if (shi->combinedflag & SCE_PASS_EMIT)
+ add_v3_v3(shr->combined, shr->emit);
+ if (shi->combinedflag & SCE_PASS_SPEC)
+ add_v3_v3(shr->combined, shr->spec);
+
+
+ /* Last section of this function applies to shadeless colors too */
+finally_shadeless:
+
+ /* modulate by the object color */
+ if ((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) {
+ if (!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) {
+ float obcol[4];
+
+ copy_v4_v4(obcol, shi->obr->ob->col);
+ CLAMP(obcol[3], 0.0f, 1.0f);
+
+ shr->combined[0] *= obcol[0];
+ shr->combined[1] *= obcol[1];
+ shr->combined[2] *= obcol[2];
+ if (shi->mode & MA_TRANSP) shr->alpha *= obcol[3];
+ }
+ }
+
+ shr->combined[3]= shr->alpha;
+}
+
+/* used for "Lamp Data" shader node */
+static float lamp_get_data_internal(ShadeInput *shi, GroupObject *go, float col[4], float lv[3], float *dist, float shadow[4])
+{
+ LampRen *lar = go->lampren;
+ float visifac, inp;
+
+ if (!lar
+ || ((lar->mode & LA_LAYER) && (lar->lay & shi->obi->lay) == 0)
+ || (lar->lay & shi->lay) == 0)
+ return 0.0f;
+
+ if (lar->mode & LA_TEXTURE)
+ do_lamp_tex(lar, lv, shi, col, LA_TEXTURE);
+
+ visifac = lamp_get_visibility(lar, shi->co, lv, dist);
+
+ if (visifac == 0.0f
+ || lar->type == LA_HEMI
+ || (lar->type != LA_SPOT && !(lar->mode & LA_SHAD_RAY))
+ || (R.r.scemode & R_BUTS_PREVIEW))
+ return visifac;
+
+ inp = dot_v3v3(shi->vn, lv);
+
+ if (inp > 0.0f) {
+ float shadfac[4];
+
+ shadow[0] = lar->shdwr;
+ shadow[1] = lar->shdwg;
+ shadow[2] = lar->shdwb;
+
+ if (lar->mode & LA_SHAD_TEX)
+ do_lamp_tex(lar, lv, shi, shadow, LA_SHAD_TEX);
+
+ if (R.r.mode & R_SHADOW) {
+ lamp_get_shadow(lar, shi, inp, shadfac, shi->depth);
+
+ shadow[0] = 1.0f - ((1.0f - shadfac[0] * shadfac[3]) * (1.0f - shadow[0]));
+ shadow[1] = 1.0f - ((1.0f - shadfac[1] * shadfac[3]) * (1.0f - shadow[1]));
+ shadow[2] = 1.0f - ((1.0f - shadfac[2] * shadfac[3]) * (1.0f - shadow[2]));
+ }
+ }
+
+ return visifac;
+}
+
+float RE_lamp_get_data(ShadeInput *shi, Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4])
+{
+ col[0] = col[1] = col[2] = 0.0f;
+ col[3] = 1.0f;
+ copy_v3_v3(lv, shi->vn);
+ *dist = 1.0f;
+ shadow[0] = shadow[1] = shadow[2] = shadow[3] = 1.0f;
+
+ if (lamp_obj->type == OB_LAMP) {
+ GroupObject *go;
+ Lamp *lamp = (Lamp *)lamp_obj->data;
+
+ col[0] = lamp->r * lamp->energy;
+ col[1] = lamp->g * lamp->energy;
+ col[2] = lamp->b * lamp->energy;
+
+ if (R.r.scemode & R_BUTS_PREVIEW) {
+ for (go = R.lights.first; go; go = go->next) {
+ /* "Lamp.002" is main key light of material preview */
+ if (STREQ(go->ob->id.name + 2, "Lamp.002"))
+ return lamp_get_data_internal(shi, go, col, lv, dist, shadow);
+ }
+ return 0.0f;
+ }
+
+ if (shi->light_override) {
+ for (go = shi->light_override->gobject.first; go; go = go->next) {
+ if (go->ob == lamp_obj)
+ return lamp_get_data_internal(shi, go, col, lv, dist, shadow);
+ }
+ }
+
+ if (shi->mat && shi->mat->group) {
+ for (go = shi->mat->group->gobject.first; go; go = go->next) {
+ if (go->ob == lamp_obj)
+ return lamp_get_data_internal(shi, go, col, lv, dist, shadow);
+ }
+ }
+
+ for (go = R.lights.first; go; go = go->next) {
+ if (go->ob == lamp_obj)
+ return lamp_get_data_internal(shi, go, col, lv, dist, shadow);
+ }
+ }
+
+ return 0.0f;
+}
+
+const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4]
+{
+ if (obi) {
+ switch (matrix_id) {
+ case RE_OBJECT_INSTANCE_MATRIX_OB:
+ return (const float(*)[4])obi->obmat;
+ case RE_OBJECT_INSTANCE_MATRIX_OBINV:
+ return (const float(*)[4])obi->obinvmat;
+ case RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEW:
+ return (const float(*)[4])obi->localtoviewmat;
+ case RE_OBJECT_INSTANCE_MATRIX_LOCALTOVIEWINV:
+ return (const float(*)[4])obi->localtoviewinvmat;
+ }
+ }
+ return NULL;
+}
+
+float RE_object_instance_get_object_pass_index(struct ObjectInstanceRen *obi)
+{
+ return obi->ob->index;
+}
+
+float RE_object_instance_get_random_id(struct ObjectInstanceRen *obi)
+{
+ return obi->random_id;
+}
+
+const float (*RE_render_current_get_matrix(int matrix_id))[4]
+{
+ switch (matrix_id) {
+ case RE_VIEW_MATRIX:
+ return (const float(*)[4])R.viewmat;
+ case RE_VIEWINV_MATRIX:
+ return (const float(*)[4])R.viewinv;
+ }
+ return NULL;
+}
+
+float RE_fresnel_dielectric(float incoming[3], float normal[3], float eta)
+{
+ /* compute fresnel reflectance without explicitly computing
+ * the refracted direction */
+ float c = fabs(dot_v3v3(incoming, normal));
+ float g = eta * eta - 1.0 + c * c;
+ float result;
+
+ if (g > 0.0) {
+ g = sqrtf(g);
+ float A = (g - c) / (g + c);
+ float B = (c * (g + c) - 1.0) / (c * (g - c) + 1.0);
+ result = 0.5 * A * A * (1.0 + B * B);
+ }
+ else {
+ result = 1.0; /* TIR (no refracted component) */
+ }
+
+ return result;
+}
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
new file mode 100644
index 00000000000..5919b8130d7
--- /dev/null
+++ b/source/blender/render/intern/source/sss.c
@@ -0,0 +1,1074 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/sss.c
+ * \ingroup render
+ */
+
+/* Possible Improvements:
+ * - add fresnel terms
+ * - adapt Rd table to scale, now with small scale there are a lot of misses?
+ * - possible interesting method: perform sss on all samples in the tree,
+ * and then use those values interpolated somehow later. can also do this
+ * filtering on demand for speed. since we are doing things in screen
+ * space now there is an exact correspondence
+ * - avoid duplicate shading (filtering points in advance, irradiance cache
+ * like lookup?)
+ * - lower resolution samples
+ */
+
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <string.h>
+
+/* external modules: */
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+
+#include "BLT_translation.h"
+
+
+#include "DNA_material_types.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_scene.h"
+
+
+/* this module */
+#include "render_types.h"
+#include "sss.h"
+
+/* Generic Multiple Scattering API */
+
+/* Relevant papers:
+ * [1] A Practical Model for Subsurface Light Transport
+ * [2] A Rapid Hierarchical Rendering Technique for Translucent Materials
+ * [3] Efficient Rendering of Local Subsurface Scattering
+ * [4] Implementing a skin BSSRDF (or several...)
+ */
+
+/* Defines */
+
+#define RD_TABLE_RANGE 100.0f
+#define RD_TABLE_RANGE_2 10000.0f
+#define RD_TABLE_SIZE 10000
+
+#define MAX_OCTREE_NODE_POINTS 8
+#define MAX_OCTREE_DEPTH 15
+
+/* Struct Definitions */
+
+struct ScatterSettings {
+ float eta; /* index of refraction */
+ float sigma_a; /* absorption coefficient */
+ float sigma_s_; /* reduced scattering coefficient */
+ float sigma_t_; /* reduced extinction coefficient */
+ float sigma; /* effective extinction coefficient */
+ float Fdr; /* diffuse fresnel reflectance */
+ float D; /* diffusion constant */
+ float A;
+ float alpha_; /* reduced albedo */
+ float zr; /* distance of virtual lightsource above surface */
+ float zv; /* distance of virtual lightsource below surface */
+ float ld; /* mean free path */
+ float ro; /* diffuse reflectance */
+ float color;
+ float invsigma_t_;
+ float frontweight;
+ float backweight;
+
+ float *tableRd; /* lookup table to avoid computing Rd */
+ float *tableRd2; /* lookup table to avoid computing Rd for bigger values */
+};
+
+typedef struct ScatterPoint {
+ float co[3];
+ float rad[3];
+ float area;
+ int back;
+} ScatterPoint;
+
+typedef struct ScatterNode {
+ float co[3];
+ float rad[3];
+ float backrad[3];
+ float area, backarea;
+
+ int totpoint;
+ ScatterPoint *points;
+
+ float split[3];
+ struct ScatterNode *child[8];
+} ScatterNode;
+
+struct ScatterTree {
+ MemArena *arena;
+
+ ScatterSettings *ss[3];
+ float error, scale;
+
+ ScatterNode *root;
+ ScatterPoint *points;
+ ScatterPoint **refpoints;
+ ScatterPoint **tmppoints;
+ int totpoint;
+ float min[3], max[3];
+};
+
+typedef struct ScatterResult {
+ float rad[3];
+ float backrad[3];
+ float rdsum[3];
+ float backrdsum[3];
+} ScatterResult;
+
+/* Functions for BSSRDF reparametrization in to more intuitive parameters,
+ * see [2] section 4 for more info. */
+
+static float f_Rd(float alpha_, float A, float ro)
+{
+ float sq;
+
+ sq = sqrtf(3.0f * (1.0f - alpha_));
+ return (alpha_/2.0f)*(1.0f + expf((-4.0f/3.0f)*A*sq))*expf(-sq) - ro;
+}
+
+static float compute_reduced_albedo(ScatterSettings *ss)
+{
+ const float tolerance= 1e-8;
+ const int max_iteration_count= 20;
+ float d, fsub, xn_1= 0.0f, xn= 1.0f, fxn, fxn_1;
+ int i;
+
+ /* use secant method to compute reduced albedo using Rd function inverse
+ * with a given reflectance */
+ fxn= f_Rd(xn, ss->A, ss->ro);
+ fxn_1= f_Rd(xn_1, ss->A, ss->ro);
+
+ for (i= 0; i < max_iteration_count; i++) {
+ fsub= (fxn - fxn_1);
+ if (fabsf(fsub) < tolerance)
+ break;
+ d= ((xn - xn_1)/fsub)*fxn;
+ if (fabsf(d) < tolerance)
+ break;
+
+ xn_1= xn;
+ fxn_1= fxn;
+ xn= xn - d;
+
+ if (xn > 1.0f) xn= 1.0f;
+ if (xn_1 > 1.0f) xn_1= 1.0f;
+
+ fxn= f_Rd(xn, ss->A, ss->ro);
+ }
+
+ /* avoid division by zero later */
+ if (xn <= 0.0f)
+ xn= 0.00001f;
+
+ return xn;
+}
+
+/* Exponential falloff functions */
+
+static float Rd_rsquare(ScatterSettings *ss, float rr)
+{
+ float sr, sv, Rdr, Rdv;
+
+ sr = sqrtf(rr + ss->zr * ss->zr);
+ sv = sqrtf(rr + ss->zv * ss->zv);
+
+ Rdr= ss->zr*(1.0f + ss->sigma*sr)*expf(-ss->sigma*sr)/(sr*sr*sr);
+ Rdv= ss->zv*(1.0f + ss->sigma*sv)*expf(-ss->sigma*sv)/(sv*sv*sv);
+
+ return /*ss->alpha_*/(1.0f/(4.0f*(float)M_PI))*(Rdr + Rdv);
+}
+
+static float Rd(ScatterSettings *ss, float r)
+{
+ return Rd_rsquare(ss, r*r);
+}
+
+/* table lookups for Rd. this avoids expensive exp calls. we use two
+ * separate tables as well for lower and higher numbers to improve
+ * precision, since the number are poorly distributed because we do
+ * a lookup with the squared distance for smaller distances, saving
+ * another sqrt. */
+
+static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd)
+{
+ float indexf, t, idxf;
+ int index;
+
+ if (rr > (RD_TABLE_RANGE_2 * RD_TABLE_RANGE_2)) {
+ /* pass */
+ }
+ else if (rr > RD_TABLE_RANGE) {
+ rr = sqrtf(rr);
+ indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE_2);
+ index= (int)indexf;
+ idxf= (float)index;
+ t= indexf - idxf;
+
+ if (index >= 0 && index < RD_TABLE_SIZE) {
+ rd[0]= (ss[0]->tableRd2[index]*(1-t) + ss[0]->tableRd2[index+1]*t);
+ rd[1]= (ss[1]->tableRd2[index]*(1-t) + ss[1]->tableRd2[index+1]*t);
+ rd[2]= (ss[2]->tableRd2[index]*(1-t) + ss[2]->tableRd2[index+1]*t);
+ return;
+ }
+ }
+ else {
+ indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE);
+ index= (int)indexf;
+ idxf= (float)index;
+ t= indexf - idxf;
+
+ if (index >= 0 && index < RD_TABLE_SIZE) {
+ rd[0]= (ss[0]->tableRd[index]*(1-t) + ss[0]->tableRd[index+1]*t);
+ rd[1]= (ss[1]->tableRd[index]*(1-t) + ss[1]->tableRd[index+1]*t);
+ rd[2]= (ss[2]->tableRd[index]*(1-t) + ss[2]->tableRd[index+1]*t);
+ return;
+ }
+ }
+
+ /* fallback to slow Rd computation */
+ rd[0]= Rd_rsquare(ss[0], rr);
+ rd[1]= Rd_rsquare(ss[1], rr);
+ rd[2]= Rd_rsquare(ss[2], rr);
+}
+
+static void build_Rd_table(ScatterSettings *ss)
+{
+ float r;
+ int i, size = RD_TABLE_SIZE+1;
+
+ ss->tableRd= MEM_mallocN(sizeof(float)*size, "scatterTableRd");
+ ss->tableRd2= MEM_mallocN(sizeof(float)*size, "scatterTableRd");
+
+ for (i= 0; i < size; i++) {
+ r= i*(RD_TABLE_RANGE/RD_TABLE_SIZE);
+#if 0
+ if (r < ss->invsigma_t_*ss->invsigma_t_) {
+ r= ss->invsigma_t_*ss->invsigma_t_;
+ }
+#endif
+ ss->tableRd[i]= Rd(ss, sqrtf(r));
+
+ r= i*(RD_TABLE_RANGE_2/RD_TABLE_SIZE);
+#if 0
+ if (r < ss->invsigma_t_) {
+ r= ss->invsigma_t_;
+ }
+#endif
+ ss->tableRd2[i]= Rd(ss, r);
+ }
+}
+
+ScatterSettings *scatter_settings_new(float refl, float radius, float ior, float reflfac, float frontweight, float backweight)
+{
+ ScatterSettings *ss;
+
+ ss= MEM_callocN(sizeof(ScatterSettings), "ScatterSettings");
+
+ /* see [1] and [3] for these formulas */
+ ss->eta= ior;
+ ss->Fdr= -1.440f/ior*ior + 0.710f/ior + 0.668f + 0.0636f*ior;
+ ss->A= (1.0f + ss->Fdr)/(1.0f - ss->Fdr);
+ ss->ld= radius;
+ ss->ro= min_ff(refl, 0.99f);
+ ss->color= ss->ro*reflfac + (1.0f-reflfac);
+
+ ss->alpha_= compute_reduced_albedo(ss);
+
+ ss->sigma= 1.0f/ss->ld;
+ ss->sigma_t_= ss->sigma/sqrtf(3.0f*(1.0f - ss->alpha_));
+ ss->sigma_s_= ss->alpha_*ss->sigma_t_;
+ ss->sigma_a= ss->sigma_t_ - ss->sigma_s_;
+
+ ss->D= 1.0f/(3.0f*ss->sigma_t_);
+
+ ss->zr= 1.0f/ss->sigma_t_;
+ ss->zv= ss->zr + 4.0f*ss->A*ss->D;
+
+ ss->invsigma_t_= 1.0f/ss->sigma_t_;
+
+ ss->frontweight= frontweight;
+ ss->backweight= backweight;
+
+ /* precompute a table of Rd values for quick lookup */
+ build_Rd_table(ss);
+
+ return ss;
+}
+
+void scatter_settings_free(ScatterSettings *ss)
+{
+ MEM_freeN(ss->tableRd);
+ MEM_freeN(ss->tableRd2);
+ MEM_freeN(ss);
+}
+
+/* Hierarchical method as in [2]. */
+
+/* traversal */
+
+#define SUBNODE_INDEX(co, split) \
+ ((co[0]>=split[0]) + (co[1]>=split[1])*2 + (co[2]>=split[2])*4)
+
+static void add_radiance(ScatterTree *tree, float *frontrad, float *backrad, float area, float backarea, float rr, ScatterResult *result)
+{
+ float rd[3], frontrd[3], backrd[3];
+
+ approximate_Rd_rgb(tree->ss, rr, rd);
+
+ if (frontrad && area) {
+ frontrd[0] = rd[0]*area;
+ frontrd[1] = rd[1]*area;
+ frontrd[2] = rd[2]*area;
+
+ result->rad[0] += frontrad[0]*frontrd[0];
+ result->rad[1] += frontrad[1]*frontrd[1];
+ result->rad[2] += frontrad[2]*frontrd[2];
+
+ result->rdsum[0] += frontrd[0];
+ result->rdsum[1] += frontrd[1];
+ result->rdsum[2] += frontrd[2];
+ }
+ if (backrad && backarea) {
+ backrd[0] = rd[0]*backarea;
+ backrd[1] = rd[1]*backarea;
+ backrd[2] = rd[2]*backarea;
+
+ result->backrad[0] += backrad[0]*backrd[0];
+ result->backrad[1] += backrad[1]*backrd[1];
+ result->backrad[2] += backrad[2]*backrd[2];
+
+ result->backrdsum[0] += backrd[0];
+ result->backrdsum[1] += backrd[1];
+ result->backrdsum[2] += backrd[2];
+ }
+}
+
+static void traverse_octree(ScatterTree *tree, ScatterNode *node, const float co[3], int self, ScatterResult *result)
+{
+ float sub[3], dist;
+ int i, index = 0;
+
+ if (node->totpoint > 0) {
+ /* leaf - add radiance from all samples */
+ for (i=0; i<node->totpoint; i++) {
+ ScatterPoint *p= &node->points[i];
+
+ sub_v3_v3v3(sub, co, p->co);
+ dist= dot_v3v3(sub, sub);
+
+ if (p->back)
+ add_radiance(tree, NULL, p->rad, 0.0f, p->area, dist, result);
+ else
+ add_radiance(tree, p->rad, NULL, p->area, 0.0f, dist, result);
+ }
+ }
+ else {
+ /* branch */
+ if (self)
+ index = SUBNODE_INDEX(co, node->split);
+
+ for (i=0; i<8; i++) {
+ if (node->child[i]) {
+ ScatterNode *subnode= node->child[i];
+
+ if (self && index == i) {
+ /* always traverse node containing the point */
+ traverse_octree(tree, subnode, co, 1, result);
+ }
+ else {
+ /* decide subnode traversal based on maximum solid angle */
+ sub_v3_v3v3(sub, co, subnode->co);
+ dist= dot_v3v3(sub, sub);
+
+ /* actually area/dist > error, but this avoids division */
+ if (subnode->area+subnode->backarea>tree->error*dist) {
+ traverse_octree(tree, subnode, co, 0, result);
+ }
+ else {
+ add_radiance(tree, subnode->rad, subnode->backrad,
+ subnode->area, subnode->backarea, dist, result);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void compute_radiance(ScatterTree *tree, const float co[3], float *rad)
+{
+ ScatterResult result;
+ float rdsum[3], backrad[3], backrdsum[3];
+
+ memset(&result, 0, sizeof(result));
+
+ traverse_octree(tree, tree->root, co, 1, &result);
+
+ /* the original paper doesn't do this, but we normalize over the
+ * sampled area and multiply with the reflectance. this is because
+ * our point samples are incomplete, there are no samples on parts
+ * of the mesh not visible from the camera. this can not only make
+ * it darker, but also lead to ugly color shifts */
+
+ mul_v3_fl(result.rad, tree->ss[0]->frontweight);
+ mul_v3_fl(result.backrad, tree->ss[0]->backweight);
+
+ copy_v3_v3(rad, result.rad);
+ add_v3_v3v3(backrad, result.rad, result.backrad);
+
+ copy_v3_v3(rdsum, result.rdsum);
+ add_v3_v3v3(backrdsum, result.rdsum, result.backrdsum);
+
+ if (rdsum[0] > 1e-16f) rad[0]= tree->ss[0]->color*rad[0]/rdsum[0];
+ if (rdsum[1] > 1e-16f) rad[1]= tree->ss[1]->color*rad[1]/rdsum[1];
+ if (rdsum[2] > 1e-16f) rad[2]= tree->ss[2]->color*rad[2]/rdsum[2];
+
+ if (backrdsum[0] > 1e-16f) backrad[0]= tree->ss[0]->color*backrad[0]/backrdsum[0];
+ if (backrdsum[1] > 1e-16f) backrad[1]= tree->ss[1]->color*backrad[1]/backrdsum[1];
+ if (backrdsum[2] > 1e-16f) backrad[2]= tree->ss[2]->color*backrad[2]/backrdsum[2];
+
+ rad[0]= MAX2(rad[0], backrad[0]);
+ rad[1]= MAX2(rad[1], backrad[1]);
+ rad[2]= MAX2(rad[2], backrad[2]);
+}
+
+/* building */
+
+static void sum_leaf_radiance(ScatterTree *UNUSED(tree), ScatterNode *node)
+{
+ ScatterPoint *p;
+ float rad, totrad= 0.0f, inv;
+ int i;
+
+ node->co[0]= node->co[1]= node->co[2]= 0.0;
+ node->rad[0]= node->rad[1]= node->rad[2]= 0.0;
+ node->backrad[0]= node->backrad[1]= node->backrad[2]= 0.0;
+
+ /* compute total rad, rad weighted average position,
+ * and total area */
+ for (i=0; i<node->totpoint; i++) {
+ p= &node->points[i];
+
+ rad= p->area*fabsf(p->rad[0] + p->rad[1] + p->rad[2]);
+ totrad += rad;
+
+ node->co[0] += rad*p->co[0];
+ node->co[1] += rad*p->co[1];
+ node->co[2] += rad*p->co[2];
+
+ if (p->back) {
+ node->backrad[0] += p->rad[0]*p->area;
+ node->backrad[1] += p->rad[1]*p->area;
+ node->backrad[2] += p->rad[2]*p->area;
+
+ node->backarea += p->area;
+ }
+ else {
+ node->rad[0] += p->rad[0]*p->area;
+ node->rad[1] += p->rad[1]*p->area;
+ node->rad[2] += p->rad[2]*p->area;
+
+ node->area += p->area;
+ }
+ }
+
+ if (node->area > 1e-16f) {
+ inv= 1.0f/node->area;
+ node->rad[0] *= inv;
+ node->rad[1] *= inv;
+ node->rad[2] *= inv;
+ }
+ if (node->backarea > 1e-16f) {
+ inv= 1.0f/node->backarea;
+ node->backrad[0] *= inv;
+ node->backrad[1] *= inv;
+ node->backrad[2] *= inv;
+ }
+
+ if (totrad > 1e-16f) {
+ inv= 1.0f/totrad;
+ node->co[0] *= inv;
+ node->co[1] *= inv;
+ node->co[2] *= inv;
+ }
+ else {
+ /* make sure that if radiance is 0.0f, we still have these points in
+ * the tree at a good position, they count for rdsum too */
+ for (i=0; i<node->totpoint; i++) {
+ p= &node->points[i];
+
+ node->co[0] += p->co[0];
+ node->co[1] += p->co[1];
+ node->co[2] += p->co[2];
+ }
+
+ node->co[0] /= node->totpoint;
+ node->co[1] /= node->totpoint;
+ node->co[2] /= node->totpoint;
+ }
+}
+
+static void sum_branch_radiance(ScatterTree *UNUSED(tree), ScatterNode *node)
+{
+ ScatterNode *subnode;
+ float rad, totrad= 0.0f, inv;
+ int i, totnode;
+
+ node->co[0]= node->co[1]= node->co[2]= 0.0;
+ node->rad[0]= node->rad[1]= node->rad[2]= 0.0;
+ node->backrad[0]= node->backrad[1]= node->backrad[2]= 0.0;
+
+ /* compute total rad, rad weighted average position,
+ * and total area */
+ for (i=0; i<8; i++) {
+ if (node->child[i] == NULL)
+ continue;
+
+ subnode= node->child[i];
+
+ rad= subnode->area*fabsf(subnode->rad[0] + subnode->rad[1] + subnode->rad[2]);
+ rad += subnode->backarea*fabsf(subnode->backrad[0] + subnode->backrad[1] + subnode->backrad[2]);
+ totrad += rad;
+
+ node->co[0] += rad*subnode->co[0];
+ node->co[1] += rad*subnode->co[1];
+ node->co[2] += rad*subnode->co[2];
+
+ node->rad[0] += subnode->rad[0]*subnode->area;
+ node->rad[1] += subnode->rad[1]*subnode->area;
+ node->rad[2] += subnode->rad[2]*subnode->area;
+
+ node->backrad[0] += subnode->backrad[0]*subnode->backarea;
+ node->backrad[1] += subnode->backrad[1]*subnode->backarea;
+ node->backrad[2] += subnode->backrad[2]*subnode->backarea;
+
+ node->area += subnode->area;
+ node->backarea += subnode->backarea;
+ }
+
+ if (node->area > 1e-16f) {
+ inv= 1.0f/node->area;
+ node->rad[0] *= inv;
+ node->rad[1] *= inv;
+ node->rad[2] *= inv;
+ }
+ if (node->backarea > 1e-16f) {
+ inv= 1.0f/node->backarea;
+ node->backrad[0] *= inv;
+ node->backrad[1] *= inv;
+ node->backrad[2] *= inv;
+ }
+
+ if (totrad > 1e-16f) {
+ inv= 1.0f/totrad;
+ node->co[0] *= inv;
+ node->co[1] *= inv;
+ node->co[2] *= inv;
+ }
+ else {
+ /* make sure that if radiance is 0.0f, we still have these points in
+ * the tree at a good position, they count for rdsum too */
+ totnode= 0;
+
+ for (i=0; i<8; i++) {
+ if (node->child[i]) {
+ subnode= node->child[i];
+
+ node->co[0] += subnode->co[0];
+ node->co[1] += subnode->co[1];
+ node->co[2] += subnode->co[2];
+
+ totnode++;
+ }
+ }
+
+ node->co[0] /= totnode;
+ node->co[1] /= totnode;
+ node->co[2] /= totnode;
+ }
+}
+
+static void sum_radiance(ScatterTree *tree, ScatterNode *node)
+{
+ if (node->totpoint > 0) {
+ sum_leaf_radiance(tree, node);
+ }
+ else {
+ int i;
+
+ for (i=0; i<8; i++)
+ if (node->child[i])
+ sum_radiance(tree, node->child[i]);
+
+ sum_branch_radiance(tree, node);
+ }
+}
+
+static void subnode_middle(int i, float *mid, float *subsize, float *submid)
+{
+ int x= i & 1, y= i & 2, z= i & 4;
+
+ submid[0]= mid[0] + ((x)? subsize[0]: -subsize[0]);
+ submid[1]= mid[1] + ((y)? subsize[1]: -subsize[1]);
+ submid[2]= mid[2] + ((z)? subsize[2]: -subsize[2]);
+}
+
+static void create_octree_node(ScatterTree *tree, ScatterNode *node, float *mid, float *size, ScatterPoint **refpoints, int depth)
+{
+ ScatterNode *subnode;
+ ScatterPoint **subrefpoints, **tmppoints= tree->tmppoints;
+ int index, nsize[8], noffset[8], i, subco, used_nodes, usedi;
+ float submid[3], subsize[3];
+
+ /* stopping condition */
+ if (node->totpoint <= MAX_OCTREE_NODE_POINTS || depth == MAX_OCTREE_DEPTH) {
+ for (i=0; i<node->totpoint; i++)
+ node->points[i]= *(refpoints[i]);
+
+ return;
+ }
+
+ subsize[0]= size[0]*0.5f;
+ subsize[1]= size[1]*0.5f;
+ subsize[2]= size[2]*0.5f;
+
+ node->split[0]= mid[0];
+ node->split[1]= mid[1];
+ node->split[2]= mid[2];
+
+ memset(nsize, 0, sizeof(nsize));
+ memset(noffset, 0, sizeof(noffset));
+
+ /* count points in subnodes */
+ for (i=0; i<node->totpoint; i++) {
+ index= SUBNODE_INDEX(refpoints[i]->co, node->split);
+ tmppoints[i]= refpoints[i];
+ nsize[index]++;
+ }
+
+ /* here we check if only one subnode is used. if this is the case, we don't
+ * create a new node, but rather call this function again, with different
+ * size and middle position for the same node. */
+ for (usedi=0, used_nodes=0, i=0; i<8; i++) {
+ if (nsize[i]) {
+ used_nodes++;
+ usedi = i;
+ }
+ if (i != 0)
+ noffset[i]= noffset[i-1]+nsize[i-1];
+ }
+
+ if (used_nodes <= 1) {
+ subnode_middle(usedi, mid, subsize, submid);
+ create_octree_node(tree, node, submid, subsize, refpoints, depth+1);
+ return;
+ }
+
+ /* reorder refpoints by subnode */
+ for (i=0; i<node->totpoint; i++) {
+ index= SUBNODE_INDEX(tmppoints[i]->co, node->split);
+ refpoints[noffset[index]]= tmppoints[i];
+ noffset[index]++;
+ }
+
+ /* create subnodes */
+ for (subco=0, i=0; i<8; subco+=nsize[i], i++) {
+ if (nsize[i] > 0) {
+ subnode= BLI_memarena_alloc(tree->arena, sizeof(ScatterNode));
+ node->child[i]= subnode;
+ subnode->points= node->points + subco;
+ subnode->totpoint= nsize[i];
+ subrefpoints= refpoints + subco;
+
+ subnode_middle(i, mid, subsize, submid);
+
+ create_octree_node(tree, subnode, submid, subsize, subrefpoints,
+ depth+1);
+ }
+ else
+ node->child[i]= NULL;
+ }
+
+ node->points= NULL;
+ node->totpoint= 0;
+}
+
+/* public functions */
+
+ScatterTree *scatter_tree_new(ScatterSettings *ss[3], float scale, float error,
+ float (*co)[3], float (*color)[3], float *area, int totpoint)
+{
+ ScatterTree *tree;
+ ScatterPoint *points, **refpoints;
+ int i;
+
+ /* allocate tree */
+ tree= MEM_callocN(sizeof(ScatterTree), "ScatterTree");
+ tree->scale= scale;
+ tree->error= error;
+ tree->totpoint= totpoint;
+
+ tree->ss[0]= ss[0];
+ tree->ss[1]= ss[1];
+ tree->ss[2]= ss[2];
+
+ points = MEM_callocN(sizeof(ScatterPoint) * totpoint, "ScatterPoints");
+ refpoints = MEM_callocN(sizeof(ScatterPoint *) * totpoint, "ScatterRefPoints");
+
+ tree->points= points;
+ tree->refpoints= refpoints;
+
+ /* build points */
+ INIT_MINMAX(tree->min, tree->max);
+
+ for (i=0; i<totpoint; i++) {
+ copy_v3_v3(points[i].co, co[i]);
+ copy_v3_v3(points[i].rad, color[i]);
+ points[i].area= fabsf(area[i])/(tree->scale*tree->scale);
+ points[i].back= (area[i] < 0.0f);
+
+ mul_v3_fl(points[i].co, 1.0f / tree->scale);
+ minmax_v3v3_v3(tree->min, tree->max, points[i].co);
+
+ refpoints[i]= points + i;
+ }
+
+ return tree;
+}
+
+void scatter_tree_build(ScatterTree *tree)
+{
+ ScatterPoint *newpoints, **tmppoints;
+ float mid[3], size[3];
+ int totpoint= tree->totpoint;
+
+ newpoints = MEM_callocN(sizeof(ScatterPoint) * totpoint, "ScatterPoints");
+ tmppoints = MEM_callocN(sizeof(ScatterPoint *) * totpoint, "ScatterTmpPoints");
+ tree->tmppoints= tmppoints;
+
+ tree->arena= BLI_memarena_new(0x8000 * sizeof(ScatterNode), "sss tree arena");
+ BLI_memarena_use_calloc(tree->arena);
+
+ /* build tree */
+ tree->root= BLI_memarena_alloc(tree->arena, sizeof(ScatterNode));
+ tree->root->points= newpoints;
+ tree->root->totpoint= totpoint;
+
+ mid[0]= (tree->min[0]+tree->max[0])*0.5f;
+ mid[1]= (tree->min[1]+tree->max[1])*0.5f;
+ mid[2]= (tree->min[2]+tree->max[2])*0.5f;
+
+ size[0]= (tree->max[0]-tree->min[0])*0.5f;
+ size[1]= (tree->max[1]-tree->min[1])*0.5f;
+ size[2]= (tree->max[2]-tree->min[2])*0.5f;
+
+ create_octree_node(tree, tree->root, mid, size, tree->refpoints, 0);
+
+ MEM_freeN(tree->points);
+ MEM_freeN(tree->refpoints);
+ MEM_freeN(tree->tmppoints);
+ tree->refpoints= NULL;
+ tree->tmppoints= NULL;
+ tree->points= newpoints;
+
+ /* sum radiance at nodes */
+ sum_radiance(tree, tree->root);
+}
+
+void scatter_tree_sample(ScatterTree *tree, const float co[3], float color[3])
+{
+ float sco[3];
+
+ copy_v3_v3(sco, co);
+ mul_v3_fl(sco, 1.0f / tree->scale);
+
+ compute_radiance(tree, sco, color);
+}
+
+void scatter_tree_free(ScatterTree *tree)
+{
+ if (tree->arena) BLI_memarena_free(tree->arena);
+ if (tree->points) MEM_freeN(tree->points);
+ if (tree->refpoints) MEM_freeN(tree->refpoints);
+
+ MEM_freeN(tree);
+}
+
+/* Internal Renderer API */
+
+/* sss tree building */
+
+typedef struct SSSData {
+ ScatterTree *tree;
+ ScatterSettings *ss[3];
+} SSSData;
+
+typedef struct SSSPoints {
+ struct SSSPoints *next, *prev;
+
+ float (*co)[3];
+ float (*color)[3];
+ float *area;
+ int totpoint;
+} SSSPoints;
+
+static void sss_create_tree_mat(Render *re, Material *mat)
+{
+ SSSPoints *p;
+ RenderResult *rr;
+ ListBase points;
+ float (*co)[3] = NULL, (*color)[3] = NULL, *area = NULL;
+ int totpoint = 0, osa, osaflag, frsflag, partsdone;
+
+ if (re->test_break(re->tbh))
+ return;
+
+ points.first= points.last= NULL;
+
+ /* TODO: this is getting a bit ugly, copying all those variables and
+ * setting them back, maybe we need to create our own Render? */
+
+ /* do SSS preprocessing render */
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ rr= re->result;
+ osa= re->osa;
+ osaflag= re->r.mode & R_OSA;
+ frsflag= re->r.mode & R_EDGE_FRS;
+ partsdone= re->i.partsdone;
+
+ re->osa= 0;
+ re->r.mode &= ~(R_OSA | R_EDGE_FRS);
+ re->sss_points= &points;
+ re->sss_mat= mat;
+ re->i.partsdone = 0;
+
+ if (!(re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW)))
+ re->result= NULL;
+ BLI_rw_mutex_unlock(&re->resultmutex);
+
+ RE_TileProcessor(re);
+
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ if (!(re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))) {
+ RE_FreeRenderResult(re->result);
+ re->result= rr;
+ }
+ BLI_rw_mutex_unlock(&re->resultmutex);
+
+ re->i.partsdone= partsdone;
+ re->sss_mat= NULL;
+ re->sss_points= NULL;
+ re->osa= osa;
+ if (osaflag) re->r.mode |= R_OSA;
+ if (frsflag) re->r.mode |= R_EDGE_FRS;
+
+ /* no points? no tree */
+ if (!points.first)
+ return;
+
+ /* merge points together into a single buffer */
+ if (!re->test_break(re->tbh)) {
+ for (totpoint=0, p=points.first; p; p=p->next)
+ totpoint += p->totpoint;
+
+ co= MEM_mallocN(sizeof(*co)*totpoint, "SSSCo");
+ color= MEM_mallocN(sizeof(*color)*totpoint, "SSSColor");
+ area= MEM_mallocN(sizeof(*area)*totpoint, "SSSArea");
+
+ for (totpoint=0, p=points.first; p; p=p->next) {
+ memcpy(co+totpoint, p->co, sizeof(*co)*p->totpoint);
+ memcpy(color+totpoint, p->color, sizeof(*color)*p->totpoint);
+ memcpy(area+totpoint, p->area, sizeof(*area)*p->totpoint);
+ totpoint += p->totpoint;
+ }
+ }
+
+ /* free points */
+ for (p=points.first; p; p=p->next) {
+ MEM_freeN(p->co);
+ MEM_freeN(p->color);
+ MEM_freeN(p->area);
+ }
+ BLI_freelistN(&points);
+
+ /* build tree */
+ if (!re->test_break(re->tbh)) {
+ SSSData *sss= MEM_callocN(sizeof(*sss), "SSSData");
+ float ior= mat->sss_ior, cfac= mat->sss_colfac;
+ const float *radius = mat->sss_radius;
+ float fw= mat->sss_front, bw= mat->sss_back;
+ float error = mat->sss_error;
+
+ error= get_render_aosss_error(&re->r, error);
+ if ((re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW)) && error < 0.5f)
+ error= 0.5f;
+
+ sss->ss[0]= scatter_settings_new(mat->sss_col[0], radius[0], ior, cfac, fw, bw);
+ sss->ss[1]= scatter_settings_new(mat->sss_col[1], radius[1], ior, cfac, fw, bw);
+ sss->ss[2]= scatter_settings_new(mat->sss_col[2], radius[2], ior, cfac, fw, bw);
+ sss->tree= scatter_tree_new(sss->ss, mat->sss_scale, error,
+ co, color, area, totpoint);
+
+ MEM_freeN(co);
+ MEM_freeN(color);
+ MEM_freeN(area);
+
+ scatter_tree_build(sss->tree);
+
+ BLI_ghash_insert(re->sss_hash, mat, sss);
+ }
+ else {
+ if (co) MEM_freeN(co);
+ if (color) MEM_freeN(color);
+ if (area) MEM_freeN(area);
+ }
+}
+
+void sss_add_points(Render *re, float (*co)[3], float (*color)[3], float *area, int totpoint)
+{
+ SSSPoints *p;
+
+ if (totpoint > 0) {
+ p= MEM_callocN(sizeof(SSSPoints), "SSSPoints");
+
+ p->co= co;
+ p->color= color;
+ p->area= area;
+ p->totpoint= totpoint;
+
+ BLI_thread_lock(LOCK_CUSTOM1);
+ BLI_addtail(re->sss_points, p);
+ BLI_thread_unlock(LOCK_CUSTOM1);
+ }
+}
+
+static void sss_free_tree(SSSData *sss)
+{
+ scatter_tree_free(sss->tree);
+ scatter_settings_free(sss->ss[0]);
+ scatter_settings_free(sss->ss[1]);
+ scatter_settings_free(sss->ss[2]);
+ MEM_freeN(sss);
+}
+
+/* public functions */
+
+void make_sss_tree(Render *re)
+{
+ Material *mat;
+ bool infostr_set = false;
+ const char *prevstr = NULL;
+
+ free_sss(re);
+
+ re->sss_hash= BLI_ghash_ptr_new("make_sss_tree gh");
+
+ re->stats_draw(re->sdh, &re->i);
+
+ for (mat= re->main->mat.first; mat; mat= mat->id.next) {
+ if (mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS)) {
+ if (!infostr_set) {
+ prevstr = re->i.infostr;
+ re->i.infostr = IFACE_("SSS preprocessing");
+ infostr_set = true;
+ }
+
+ sss_create_tree_mat(re, mat);
+ }
+ }
+
+ /* XXX preview exception */
+ /* localizing preview render data is not fun for node trees :( */
+ if (re->main!=G.main) {
+ for (mat= G.main->mat.first; mat; mat= mat->id.next) {
+ if (mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS)) {
+ if (!infostr_set) {
+ prevstr = re->i.infostr;
+ re->i.infostr = IFACE_("SSS preprocessing");
+ infostr_set = true;
+ }
+
+ sss_create_tree_mat(re, mat);
+ }
+ }
+ }
+
+ if (infostr_set)
+ re->i.infostr = prevstr;
+}
+
+void free_sss(Render *re)
+{
+ if (re->sss_hash) {
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, re->sss_hash) {
+ sss_free_tree(BLI_ghashIterator_getValue(&gh_iter));
+ }
+
+ BLI_ghash_free(re->sss_hash, NULL, NULL);
+ re->sss_hash= NULL;
+ }
+}
+
+int sample_sss(Render *re, Material *mat, const float co[3], float color[3])
+{
+ if (re->sss_hash) {
+ SSSData *sss= BLI_ghash_lookup(re->sss_hash, mat);
+
+ if (sss) {
+ scatter_tree_sample(sss->tree, co, color);
+ return 1;
+ }
+ else {
+ color[0]= 0.0f;
+ color[1]= 0.0f;
+ color[2]= 0.0f;
+ }
+ }
+
+ return 0;
+}
+
+int sss_pass_done(struct Render *re, struct Material *mat)
+{
+ return ((re->flag & R_BAKING) || !(re->r.mode & R_SSS) || (re->sss_hash && BLI_ghash_lookup(re->sss_hash, mat)));
+}
+
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
new file mode 100644
index 00000000000..5fde688481a
--- /dev/null
+++ b/source/blender/render/intern/source/strand.c
@@ -0,0 +1,1069 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors: Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/strand.c
+ * \ingroup render
+ */
+
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_key_types.h"
+#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+#include "BLI_rand.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_key.h"
+
+
+#include "render_types.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "shading.h"
+#include "strand.h"
+#include "zbuf.h"
+
+/* *************** */
+
+static float strand_eval_width(Material *ma, float strandco)
+{
+ float fac;
+
+ strandco= 0.5f*(strandco + 1.0f);
+
+ if (ma->strand_ease!=0.0f) {
+ if (ma->strand_ease<0.0f)
+ fac= pow(strandco, 1.0f+ma->strand_ease);
+ else
+ fac= pow(strandco, 1.0f/(1.0f-ma->strand_ease));
+ }
+ else fac= strandco;
+
+ return ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end);
+}
+
+void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
+{
+ Material *ma;
+ StrandBuffer *strandbuf;
+ const float *simplify;
+ float p[4][3], data[4], cross[3], w, dx, dy, t;
+ int type;
+
+ strandbuf= sseg->buffer;
+ ma= sseg->buffer->ma;
+ t= spoint->t;
+ type= (strandbuf->flag & R_STRAND_BSPLINE)? KEY_BSPLINE: KEY_CARDINAL;
+
+ copy_v3_v3(p[0], sseg->v[0]->co);
+ copy_v3_v3(p[1], sseg->v[1]->co);
+ copy_v3_v3(p[2], sseg->v[2]->co);
+ copy_v3_v3(p[3], sseg->v[3]->co);
+
+ if (sseg->obi->flag & R_TRANSFORMED) {
+ mul_m4_v3(sseg->obi->mat, p[0]);
+ mul_m4_v3(sseg->obi->mat, p[1]);
+ mul_m4_v3(sseg->obi->mat, p[2]);
+ mul_m4_v3(sseg->obi->mat, p[3]);
+ }
+
+ if (t == 0.0f) {
+ copy_v3_v3(spoint->co, p[1]);
+ spoint->strandco= sseg->v[1]->strandco;
+
+ spoint->dtstrandco= (sseg->v[2]->strandco - sseg->v[0]->strandco);
+ if (sseg->v[0] != sseg->v[1])
+ spoint->dtstrandco *= 0.5f;
+ }
+ else if (t == 1.0f) {
+ copy_v3_v3(spoint->co, p[2]);
+ spoint->strandco= sseg->v[2]->strandco;
+
+ spoint->dtstrandco= (sseg->v[3]->strandco - sseg->v[1]->strandco);
+ if (sseg->v[3] != sseg->v[2])
+ spoint->dtstrandco *= 0.5f;
+ }
+ else {
+ key_curve_position_weights(t, data, type);
+ spoint->co[0]= data[0]*p[0][0] + data[1]*p[1][0] + data[2]*p[2][0] + data[3]*p[3][0];
+ spoint->co[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1];
+ spoint->co[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2];
+ spoint->strandco= (1.0f-t)*sseg->v[1]->strandco + t*sseg->v[2]->strandco;
+ }
+
+ key_curve_tangent_weights(t, data, type);
+ spoint->dtco[0]= data[0]*p[0][0] + data[1]*p[1][0] + data[2]*p[2][0] + data[3]*p[3][0];
+ spoint->dtco[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1];
+ spoint->dtco[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2];
+
+ normalize_v3_v3(spoint->tan, spoint->dtco);
+ normalize_v3_v3(spoint->nor, spoint->co);
+ negate_v3(spoint->nor);
+
+ spoint->width= strand_eval_width(ma, spoint->strandco);
+
+ /* simplification */
+ simplify= RE_strandren_get_simplify(strandbuf->obr, sseg->strand, 0);
+ spoint->alpha= (simplify)? simplify[1]: 1.0f;
+
+ /* outer points */
+ cross_v3_v3v3(cross, spoint->co, spoint->tan);
+
+ w= spoint->co[2]*strandbuf->winmat[2][3] + strandbuf->winmat[3][3];
+ dx= strandbuf->winx*cross[0]*strandbuf->winmat[0][0]/w;
+ dy= strandbuf->winy*cross[1]*strandbuf->winmat[1][1]/w;
+ w = sqrtf(dx * dx + dy * dy);
+
+ if (w > 0.0f) {
+ if (strandbuf->flag & R_STRAND_B_UNITS) {
+ const float crosslen= len_v3(cross);
+ w= 2.0f*crosslen*strandbuf->minwidth/w;
+
+ if (spoint->width < w) {
+ spoint->alpha= spoint->width/w;
+ spoint->width= w;
+ }
+
+ if (simplify)
+ /* squared because we only change width, not length */
+ spoint->width *= simplify[0]*simplify[0];
+
+ mul_v3_fl(cross, spoint->width*0.5f/crosslen);
+ }
+ else
+ mul_v3_fl(cross, spoint->width/w);
+ }
+
+ sub_v3_v3v3(spoint->co1, spoint->co, cross);
+ add_v3_v3v3(spoint->co2, spoint->co, cross);
+
+ copy_v3_v3(spoint->dsco, cross);
+}
+
+/* *************** */
+
+static void interpolate_vec1(float *v1, float *v2, float t, float negt, float *v)
+{
+ v[0]= negt*v1[0] + t*v2[0];
+}
+
+static void interpolate_vec3(float *v1, float *v2, float t, float negt, float *v)
+{
+ v[0]= negt*v1[0] + t*v2[0];
+ v[1]= negt*v1[1] + t*v2[1];
+ v[2]= negt*v1[2] + t*v2[2];
+}
+
+static void interpolate_vec4(float *v1, float *v2, float t, float negt, float *v)
+{
+ v[0]= negt*v1[0] + t*v2[0];
+ v[1]= negt*v1[1] + t*v2[1];
+ v[2]= negt*v1[2] + t*v2[2];
+ v[3]= negt*v1[3] + t*v2[3];
+}
+
+static void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float t, ShadeResult *shr, int addpassflag)
+{
+ float negt= 1.0f - t;
+
+ interpolate_vec4(shr1->combined, shr2->combined, t, negt, shr->combined);
+
+ if (addpassflag & SCE_PASS_VECTOR) {
+ interpolate_vec4(shr1->winspeed, shr2->winspeed, t, negt, shr->winspeed);
+ }
+ /* optim... */
+ if (addpassflag & ~(SCE_PASS_VECTOR)) {
+ if (addpassflag & SCE_PASS_Z)
+ interpolate_vec1(&shr1->z, &shr2->z, t, negt, &shr->z);
+ if (addpassflag & SCE_PASS_RGBA)
+ interpolate_vec4(shr1->col, shr2->col, t, negt, shr->col);
+ if (addpassflag & SCE_PASS_NORMAL) {
+ interpolate_vec3(shr1->nor, shr2->nor, t, negt, shr->nor);
+ normalize_v3(shr->nor);
+ }
+ if (addpassflag & SCE_PASS_EMIT)
+ interpolate_vec3(shr1->emit, shr2->emit, t, negt, shr->emit);
+ if (addpassflag & SCE_PASS_DIFFUSE) {
+ interpolate_vec3(shr1->diff, shr2->diff, t, negt, shr->diff);
+ interpolate_vec3(shr1->diffshad, shr2->diffshad, t, negt, shr->diffshad);
+ }
+ if (addpassflag & SCE_PASS_SPEC)
+ interpolate_vec3(shr1->spec, shr2->spec, t, negt, shr->spec);
+ if (addpassflag & SCE_PASS_SHADOW)
+ interpolate_vec3(shr1->shad, shr2->shad, t, negt, shr->shad);
+ if (addpassflag & SCE_PASS_AO)
+ interpolate_vec3(shr1->ao, shr2->ao, t, negt, shr->ao);
+ if (addpassflag & SCE_PASS_ENVIRONMENT)
+ interpolate_vec3(shr1->env, shr2->env, t, negt, shr->env);
+ if (addpassflag & SCE_PASS_INDIRECT)
+ interpolate_vec3(shr1->indirect, shr2->indirect, t, negt, shr->indirect);
+ if (addpassflag & SCE_PASS_REFLECT)
+ interpolate_vec3(shr1->refl, shr2->refl, t, negt, shr->refl);
+ if (addpassflag & SCE_PASS_REFRACT)
+ interpolate_vec3(shr1->refr, shr2->refr, t, negt, shr->refr);
+ if (addpassflag & SCE_PASS_MIST)
+ interpolate_vec1(&shr1->mist, &shr2->mist, t, negt, &shr->mist);
+ }
+}
+
+static void strand_apply_shaderesult_alpha(ShadeResult *shr, float alpha)
+{
+ if (alpha < 1.0f) {
+ shr->combined[0] *= alpha;
+ shr->combined[1] *= alpha;
+ shr->combined[2] *= alpha;
+ shr->combined[3] *= alpha;
+
+ shr->col[0] *= alpha;
+ shr->col[1] *= alpha;
+ shr->col[2] *= alpha;
+ shr->col[3] *= alpha;
+
+ shr->alpha *= alpha;
+ }
+}
+
+static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandVert *svert, StrandPoint *spoint)
+{
+ ShadeInput *shi= ssamp->shi;
+ ShadeResult *shr= ssamp->shr;
+ VlakRen vlr;
+ int seed;
+
+ memset(&vlr, 0, sizeof(vlr));
+ vlr.flag= R_SMOOTH;
+ if (sseg->buffer->ma->mode & MA_TANGENT_STR)
+ vlr.flag |= R_TANGENT;
+
+ shi->vlr= &vlr;
+ shi->v1= NULL;
+ shi->v2= NULL;
+ shi->v3= NULL;
+ shi->strand= sseg->strand;
+ shi->obi= sseg->obi;
+ shi->obr= sseg->obi->obr;
+
+ /* cache for shadow */
+ shi->samplenr= re->shadowsamplenr[shi->thread]++;
+
+ /* all samples */
+ shi->mask= 0xFFFF;
+
+ /* seed RNG for consistent results across tiles */
+ seed = shi->strand->index + (svert - shi->strand->vert);
+ BLI_thread_srandom(shi->thread, seed);
+
+ shade_input_set_strand(shi, sseg->strand, spoint);
+ shade_input_set_strand_texco(shi, sseg->strand, sseg->v[1], spoint);
+
+ /* init material vars */
+ shade_input_init_material(shi);
+
+ /* shade */
+ shade_samples_do_AO(ssamp);
+ shade_input_do_shade(shi, shr);
+
+ /* apply simplification */
+ strand_apply_shaderesult_alpha(shr, spoint->alpha);
+
+ /* include lamphalos for strand, since halo layer was added already */
+ if (re->flag & R_LAMPHALO)
+ if (shi->layflag & SCE_LAY_HALO)
+ renderspothalo(shi, shr->combined, shr->combined[3]);
+
+ shi->strand= NULL;
+}
+
+/* *************** */
+
+struct StrandShadeCache {
+ GHash *resulthash;
+ GHash *refcounthash;
+ MemArena *memarena;
+};
+
+typedef struct StrandCacheEntry {
+ GHashPair pair;
+ ShadeResult shr;
+} StrandCacheEntry;
+
+StrandShadeCache *strand_shade_cache_create(void)
+{
+ StrandShadeCache *cache;
+
+ cache= MEM_callocN(sizeof(StrandShadeCache), "StrandShadeCache");
+ cache->resulthash= BLI_ghash_pair_new("strand_shade_cache_create1 gh");
+ cache->refcounthash= BLI_ghash_pair_new("strand_shade_cache_create2 gh");
+ cache->memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand shade cache arena");
+
+ return cache;
+}
+
+void strand_shade_cache_free(StrandShadeCache *cache)
+{
+ BLI_ghash_free(cache->refcounthash, NULL, NULL);
+ BLI_ghash_free(cache->resulthash, MEM_freeN, NULL);
+ BLI_memarena_free(cache->memarena);
+ MEM_freeN(cache);
+}
+
+static GHashPair strand_shade_hash_pair(ObjectInstanceRen *obi, StrandVert *svert)
+{
+ GHashPair pair = {obi, svert};
+ return pair;
+}
+
+static void strand_shade_get(Render *re, StrandShadeCache *cache, ShadeSample *ssamp, StrandSegment *sseg, StrandVert *svert)
+{
+ StrandCacheEntry *entry;
+ StrandPoint p;
+ int *refcount;
+ GHashPair pair = strand_shade_hash_pair(sseg->obi, svert);
+
+ entry= BLI_ghash_lookup(cache->resulthash, &pair);
+ refcount= BLI_ghash_lookup(cache->refcounthash, &pair);
+
+ if (!entry) {
+ /* not shaded yet, shade and insert into hash */
+ p.t= (sseg->v[1] == svert)? 0.0f: 1.0f;
+ strand_eval_point(sseg, &p);
+ strand_shade_point(re, ssamp, sseg, svert, &p);
+
+ entry= MEM_callocN(sizeof(StrandCacheEntry), "StrandCacheEntry");
+ entry->pair = pair;
+ entry->shr = ssamp->shr[0];
+ BLI_ghash_insert(cache->resulthash, entry, entry);
+ }
+ else
+ /* already shaded, just copy previous result from hash */
+ ssamp->shr[0]= entry->shr;
+
+ /* lower reference count and remove if not needed anymore by any samples */
+ (*refcount)--;
+ if (*refcount == 0) {
+ BLI_ghash_remove(cache->resulthash, &pair, MEM_freeN, NULL);
+ BLI_ghash_remove(cache->refcounthash, &pair, NULL, NULL);
+ }
+}
+
+void strand_shade_segment(Render *re, StrandShadeCache *cache, StrandSegment *sseg, ShadeSample *ssamp, float t, float s, int addpassflag)
+{
+ ShadeResult shr1, shr2;
+
+ /* get shading for two endpoints and interpolate */
+ strand_shade_get(re, cache, ssamp, sseg, sseg->v[1]);
+ shr1= ssamp->shr[0];
+ strand_shade_get(re, cache, ssamp, sseg, sseg->v[2]);
+ shr2= ssamp->shr[0];
+
+ interpolate_shade_result(&shr1, &shr2, t, ssamp->shr, addpassflag);
+
+ /* apply alpha along width */
+ if (sseg->buffer->widthfade != -1.0f) {
+ s = 1.0f - powf(fabsf(s), sseg->buffer->widthfade);
+
+ strand_apply_shaderesult_alpha(ssamp->shr, s);
+ }
+}
+
+void strand_shade_unref(StrandShadeCache *cache, ObjectInstanceRen *obi, StrandVert *svert)
+{
+ GHashPair pair = strand_shade_hash_pair(obi, svert);
+ int *refcount;
+
+ /* lower reference count and remove if not needed anymore by any samples */
+ refcount= BLI_ghash_lookup(cache->refcounthash, &pair);
+
+ (*refcount)--;
+ if (*refcount == 0) {
+ BLI_ghash_remove(cache->resulthash, &pair, MEM_freeN, NULL);
+ BLI_ghash_remove(cache->refcounthash, &pair, NULL, NULL);
+ }
+}
+
+static void strand_shade_refcount(StrandShadeCache *cache, StrandSegment *sseg, StrandVert *svert)
+{
+ GHashPair pair = strand_shade_hash_pair(sseg->obi, svert);
+ GHashPair *key;
+ int *refcount= BLI_ghash_lookup(cache->refcounthash, &pair);
+
+ if (!refcount) {
+ key= BLI_memarena_alloc(cache->memarena, sizeof(GHashPair));
+ *key = pair;
+ refcount= BLI_memarena_alloc(cache->memarena, sizeof(int));
+ *refcount= 1;
+ BLI_ghash_insert(cache->refcounthash, key, refcount);
+ }
+ else
+ (*refcount)++;
+}
+
+/* *************** */
+
+typedef struct StrandPart {
+ Render *re;
+ ZSpan *zspan;
+
+ APixstrand *apixbuf;
+ int *totapixbuf;
+ int *rectz;
+ int *rectmask;
+ intptr_t *rectdaps;
+ int rectx, recty;
+ int sample;
+ int shadow;
+ float (*jit)[2];
+ int samples;
+
+ StrandSegment *segment;
+ float t[3], s[3];
+
+ StrandShadeCache *cache;
+} StrandPart;
+
+typedef struct StrandSortSegment {
+ struct StrandSortSegment *next;
+ int obi, strand, segment;
+ float z;
+} StrandSortSegment;
+
+static int compare_strand_segment(const void *poin1, const void *poin2)
+{
+ const StrandSortSegment *seg1= (const StrandSortSegment*)poin1;
+ const StrandSortSegment *seg2= (const StrandSortSegment*)poin2;
+
+ if (seg1->z < seg2->z)
+ return -1;
+ else if (seg1->z == seg2->z)
+ return 0;
+ else
+ return 1;
+}
+
+static void do_strand_point_project(float winmat[4][4], ZSpan *zspan, float *co, float *hoco, float *zco)
+{
+ projectvert(co, winmat, hoco);
+ hoco_to_zco(zspan, zco, hoco);
+}
+
+static void strand_project_point(float winmat[4][4], float winx, float winy, StrandPoint *spoint)
+{
+ float div;
+
+ projectvert(spoint->co, winmat, spoint->hoco);
+
+ div= 1.0f/spoint->hoco[3];
+ spoint->x= spoint->hoco[0]*div*winx*0.5f;
+ spoint->y= spoint->hoco[1]*div*winy*0.5f;
+}
+
+static APixstrand *addpsmainAstrand(ListBase *lb)
+{
+ APixstrMain *psm;
+
+ psm= MEM_mallocN(sizeof(APixstrMain), "addpsmainA");
+ BLI_addtail(lb, psm);
+ psm->ps = MEM_callocN(4096 * sizeof(APixstrand), "pixstr");
+
+ return psm->ps;
+}
+
+static APixstrand *addpsAstrand(ZSpan *zspan)
+{
+ /* make new PS */
+ if (zspan->apstrandmcounter==0) {
+ zspan->curpstrand= addpsmainAstrand(zspan->apsmbase);
+ zspan->apstrandmcounter= 4095;
+ }
+ else {
+ zspan->curpstrand++;
+ zspan->apstrandmcounter--;
+ }
+ return zspan->curpstrand;
+}
+
+#define MAX_ZROW 2000
+
+static void do_strand_fillac(void *handle, int x, int y, float u, float v, float z)
+{
+ StrandPart *spart= (StrandPart *)handle;
+ StrandShadeCache *cache= spart->cache;
+ StrandSegment *sseg= spart->segment;
+ APixstrand *apn, *apnew;
+ float t, s;
+ int offset, mask, obi, strnr, seg, zverg, bufferz, maskz=0;
+
+ offset = y*spart->rectx + x;
+ obi= sseg->obi - spart->re->objectinstance;
+ strnr= sseg->strand->index + 1;
+ seg= sseg->v[1] - sseg->strand->vert;
+ mask= (1<<spart->sample);
+
+ /* check against solid z-buffer */
+ zverg= (int)z;
+
+ if (spart->rectdaps) {
+ /* find the z of the sample */
+ PixStr *ps;
+ intptr_t *rd= spart->rectdaps + offset;
+
+ bufferz= 0x7FFFFFFF;
+ if (spart->rectmask) maskz= 0x7FFFFFFF;
+
+ if (*rd) {
+ for (ps= (PixStr *)(*rd); ps; ps= ps->next) {
+ if (mask & ps->mask) {
+ bufferz= ps->z;
+ if (spart->rectmask)
+ maskz= ps->maskz;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ bufferz= (spart->rectz)? spart->rectz[offset]: 0x7FFFFFFF;
+ if (spart->rectmask)
+ maskz= spart->rectmask[offset];
+ }
+
+#define CHECK_ADD(n) \
+ if (apn->p[n]==strnr && apn->obi[n]==obi && apn->seg[n]==seg) \
+ { if (!(apn->mask[n] & mask)) { apn->mask[n] |= mask; apn->v[n] += t; apn->u[n] += s; } break; } (void)0
+#define CHECK_ASSIGN(n) \
+ if (apn->p[n]==0) \
+ {apn->obi[n]= obi; apn->p[n]= strnr; apn->z[n]= zverg; apn->mask[n]= mask; apn->v[n]= t; apn->u[n]= s; apn->seg[n]= seg; break; } (void)0
+
+ /* add to pixel list */
+ if (zverg < bufferz && (spart->totapixbuf[offset] < MAX_ZROW)) {
+ if (!spart->rectmask || zverg > maskz) {
+ t = u * spart->t[0] + v * spart->t[1] + (1.0f - u - v) * spart->t[2];
+ s = fabsf(u * spart->s[0] + v * spart->s[1] + (1.0f - u - v) * spart->s[2]);
+
+ apn= spart->apixbuf + offset;
+ while (apn) {
+ CHECK_ADD(0);
+ CHECK_ADD(1);
+ CHECK_ADD(2);
+ CHECK_ADD(3);
+ CHECK_ASSIGN(0);
+ CHECK_ASSIGN(1);
+ CHECK_ASSIGN(2);
+ CHECK_ASSIGN(3);
+
+ apnew= addpsAstrand(spart->zspan);
+ SWAP(APixstrand, *apnew, *apn);
+ apn->next= apnew;
+ CHECK_ASSIGN(0);
+ }
+
+ if (cache) {
+ strand_shade_refcount(cache, sseg, sseg->v[1]);
+ strand_shade_refcount(cache, sseg, sseg->v[2]);
+ }
+ spart->totapixbuf[offset]++;
+ }
+ }
+}
+
+/* width is calculated in hoco space, to ensure strands are visible */
+static int strand_test_clip(float winmat[4][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy)
+{
+ float hoco[4];
+ int clipflag= 0;
+
+ projectvert(co, winmat, hoco);
+
+ /* we compare z without perspective division for segment sorting */
+ *zcomp= hoco[2];
+
+ if (hoco[0]+widthx < bounds[0]*hoco[3]) clipflag |= 1;
+ else if (hoco[0]-widthx > bounds[1]*hoco[3]) clipflag |= 2;
+
+ if (hoco[1]-widthy > bounds[3]*hoco[3]) clipflag |= 4;
+ else if (hoco[1]+widthy < bounds[2]*hoco[3]) clipflag |= 8;
+
+ clipflag |= testclip(hoco);
+
+ return clipflag;
+}
+
+static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan *zspan, float t, float dt, float *co1, float *co2, float *co3, float *co4, int sample)
+{
+ float jco1[3], jco2[3], jco3[3], jco4[3], jx, jy;
+
+ copy_v3_v3(jco1, co1);
+ copy_v3_v3(jco2, co2);
+ copy_v3_v3(jco3, co3);
+ copy_v3_v3(jco4, co4);
+
+ if (spart->jit) {
+ jx= -spart->jit[sample][0];
+ jy= -spart->jit[sample][1];
+
+ jco1[0] += jx; jco1[1] += jy;
+ jco2[0] += jx; jco2[1] += jy;
+ jco3[0] += jx; jco3[1] += jy;
+ jco4[0] += jx; jco4[1] += jy;
+
+ /* XXX mblur? */
+ }
+
+ spart->sample= sample;
+
+ spart->t[0]= t-dt;
+ spart->s[0]= -1.0f;
+ spart->t[1]= t-dt;
+ spart->s[1]= 1.0f;
+ spart->t[2]= t;
+ spart->s[2]= 1.0f;
+ zspan_scanconvert_strand(zspan, spart, jco1, jco2, jco3, do_strand_fillac);
+ spart->t[0]= t-dt;
+ spart->s[0]= -1.0f;
+ spart->t[1]= t;
+ spart->s[1]= 1.0f;
+ spart->t[2]= t;
+ spart->s[2]= -1.0f;
+ zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac);
+}
+
+static void strand_render(Render *re, StrandSegment *sseg, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2)
+{
+ if (spart) {
+ float t= p2->t;
+ float dt= p2->t - p1->t;
+ int a;
+
+ for (a=0; a<spart->samples; a++)
+ do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, a);
+ }
+ else {
+ float hoco1[4], hoco2[4];
+ int a, obi, index;
+
+ obi= sseg->obi - re->objectinstance;
+ index= sseg->strand->index;
+
+ projectvert(p1->co, winmat, hoco1);
+ projectvert(p2->co, winmat, hoco2);
+
+
+ for (a=0; a<totzspan; a++) {
+#if 0
+ /* render both strand and single pixel wire to counter aliasing */
+ zbufclip4(re, &zspan[a], obi, index, p1->hoco2, p1->hoco1, p2->hoco1, p2->hoco2, p1->clip2, p1->clip1, p2->clip1, p2->clip2);
+#endif
+ /* only render a line for now, which makes the shadow map more
+ * similar across frames, and so reduces flicker */
+ zbufsinglewire(&zspan[a], obi, index, hoco1, hoco2);
+ }
+ }
+}
+
+static int strand_segment_recursive(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
+{
+ StrandPoint p;
+ StrandBuffer *buffer= sseg->buffer;
+ float dot, d1[2], d2[2], len1, len2;
+
+ if (depth == buffer->maxdepth)
+ return 0;
+
+ p.t= (p1->t + p2->t)*0.5f;
+ strand_eval_point(sseg, &p);
+ strand_project_point(buffer->winmat, buffer->winx, buffer->winy, &p);
+
+ d1[0]= (p.x - p1->x);
+ d1[1]= (p.y - p1->y);
+ len1= d1[0]*d1[0] + d1[1]*d1[1];
+
+ d2[0]= (p2->x - p.x);
+ d2[1]= (p2->y - p.y);
+ len2= d2[0]*d2[0] + d2[1]*d2[1];
+
+ if (len1 == 0.0f || len2 == 0.0f)
+ return 0;
+
+ dot= d1[0]*d2[0] + d1[1]*d2[1];
+ if (dot*dot > sseg->sqadaptcos*len1*len2)
+ return 0;
+
+ if (spart) {
+ do_strand_point_project(winmat, zspan, p.co1, p.hoco1, p.zco1);
+ do_strand_point_project(winmat, zspan, p.co2, p.hoco2, p.zco2);
+ }
+ else {
+#if 0
+ projectvert(p.co1, winmat, p.hoco1);
+ projectvert(p.co2, winmat, p.hoco2);
+ p.clip1= testclip(p.hoco1);
+ p.clip2= testclip(p.hoco2);
+#endif
+ }
+
+ if (!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, p1, &p, depth+1))
+ strand_render(re, sseg, winmat, spart, zspan, totzspan, p1, &p);
+ if (!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, &p, p2, depth+1))
+ strand_render(re, sseg, winmat, spart, zspan, totzspan, &p, p2);
+
+ return 1;
+}
+
+void render_strand_segment(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg)
+{
+ StrandBuffer *buffer= sseg->buffer;
+ StrandPoint *p1= &sseg->point1;
+ StrandPoint *p2= &sseg->point2;
+
+ p1->t= 0.0f;
+ p2->t= 1.0f;
+
+ strand_eval_point(sseg, p1);
+ strand_project_point(buffer->winmat, buffer->winx, buffer->winy, p1);
+ strand_eval_point(sseg, p2);
+ strand_project_point(buffer->winmat, buffer->winx, buffer->winy, p2);
+
+ if (spart) {
+ do_strand_point_project(winmat, zspan, p1->co1, p1->hoco1, p1->zco1);
+ do_strand_point_project(winmat, zspan, p1->co2, p1->hoco2, p1->zco2);
+ do_strand_point_project(winmat, zspan, p2->co1, p2->hoco1, p2->zco1);
+ do_strand_point_project(winmat, zspan, p2->co2, p2->hoco2, p2->zco2);
+ }
+ else {
+#if 0
+ projectvert(p1->co1, winmat, p1->hoco1);
+ projectvert(p1->co2, winmat, p1->hoco2);
+ projectvert(p2->co1, winmat, p2->hoco1);
+ projectvert(p2->co2, winmat, p2->hoco2);
+ p1->clip1= testclip(p1->hoco1);
+ p1->clip2= testclip(p1->hoco2);
+ p2->clip1= testclip(p2->hoco1);
+ p2->clip2= testclip(p2->hoco2);
+#endif
+ }
+
+ if (!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, p1, p2, 0))
+ strand_render(re, sseg, winmat, spart, zspan, totzspan, p1, p2);
+}
+
+/* render call to fill in strands */
+int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache)
+{
+ ObjectRen *obr;
+ ObjectInstanceRen *obi;
+ ZSpan zspan;
+ StrandRen *strand = NULL;
+ StrandVert *svert;
+ StrandBound *sbound;
+ StrandPart spart;
+ StrandSegment sseg;
+ StrandSortSegment *sortsegments = NULL, *sortseg, *firstseg;
+ MemArena *memarena;
+ float z[4], bounds[4], obwinmat[4][4];
+ int a, b, c, i, totsegment, clip[4];
+
+ if (re->test_break(re->tbh))
+ return 0;
+ if (re->totstrand == 0)
+ return 0;
+
+ /* setup StrandPart */
+ memset(&spart, 0, sizeof(spart));
+
+ spart.re= re;
+ spart.rectx= pa->rectx;
+ spart.recty= pa->recty;
+ spart.apixbuf= apixbuf;
+ spart.zspan= &zspan;
+ spart.rectdaps= pa->rectdaps;
+ spart.rectz= pa->rectz;
+ spart.rectmask= pa->rectmask;
+ spart.cache= cache;
+ spart.shadow= shadow;
+ spart.jit= jit;
+ spart.samples= samples;
+
+ zbuf_alloc_span(&zspan, pa->rectx, pa->recty, clipcrop);
+
+ /* needed for transform from hoco to zbuffer co */
+ zspan.zmulx= ((float)winx)/2.0f;
+ zspan.zmuly= ((float)winy)/2.0f;
+
+ zspan.zofsx= -pa->disprect.xmin;
+ zspan.zofsy= -pa->disprect.ymin;
+
+ /* to center the sample position */
+ if (!shadow) {
+ zspan.zofsx -= 0.5f;
+ zspan.zofsy -= 0.5f;
+ }
+
+ zspan.apsmbase= apsmbase;
+
+ /* clipping setup */
+ bounds[0]= (2*pa->disprect.xmin - winx-1)/(float)winx;
+ bounds[1]= (2*pa->disprect.xmax - winx+1)/(float)winx;
+ bounds[2]= (2*pa->disprect.ymin - winy-1)/(float)winy;
+ bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy;
+
+ memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "strand sort arena");
+ firstseg= NULL;
+ totsegment= 0;
+
+ /* for all object instances */
+ for (obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) {
+ Material *ma;
+ float widthx, widthy;
+
+ obr= obi->obr;
+
+ if (!obr->strandbuf || !(obr->strandbuf->lay & lay))
+ continue;
+
+ /* compute matrix and try clipping whole object */
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_m4m4(obwinmat, winmat, obi->mat);
+ else
+ copy_m4_m4(obwinmat, winmat);
+
+ /* test if we should skip it */
+ ma = obr->strandbuf->ma;
+
+ if (shadow && (!(ma->mode2 & MA_CASTSHADOW) || !(ma->mode & MA_SHADBUF)))
+ continue;
+ else if (!shadow && (ma->mode & MA_ONLYCAST))
+ continue;
+
+ if (clip_render_object(obi->obr->boundbox, bounds, obwinmat))
+ continue;
+
+ widthx= obr->strandbuf->maxwidth*obwinmat[0][0];
+ widthy= obr->strandbuf->maxwidth*obwinmat[1][1];
+
+ /* for each bounding box containing a number of strands */
+ sbound= obr->strandbuf->bound;
+ for (c=0; c<obr->strandbuf->totbound; c++, sbound++) {
+ if (clip_render_object(sbound->boundbox, bounds, obwinmat))
+ continue;
+
+ /* for each strand in this bounding box */
+ for (a=sbound->start; a<sbound->end; a++) {
+ strand= RE_findOrAddStrand(obr, a);
+ svert= strand->vert;
+
+ /* keep clipping and z depth for 4 control points */
+ clip[1]= strand_test_clip(obwinmat, &zspan, bounds, svert->co, &z[1], widthx, widthy);
+ clip[2]= strand_test_clip(obwinmat, &zspan, bounds, (svert+1)->co, &z[2], widthx, widthy);
+ clip[0]= clip[1]; z[0]= z[1];
+
+ for (b=0; b<strand->totvert-1; b++, svert++) {
+ /* compute 4th point clipping and z depth */
+ if (b < strand->totvert-2) {
+ clip[3]= strand_test_clip(obwinmat, &zspan, bounds, (svert+2)->co, &z[3], widthx, widthy);
+ }
+ else {
+ clip[3]= clip[2]; z[3]= z[2];
+ }
+
+ /* check clipping and add to sortsegments buffer */
+ if (!(clip[0] & clip[1] & clip[2] & clip[3])) {
+ sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
+ sortseg->obi= i;
+ sortseg->strand= strand->index;
+ sortseg->segment= b;
+
+ sortseg->z= 0.5f*(z[1] + z[2]);
+
+ sortseg->next= firstseg;
+ firstseg= sortseg;
+ totsegment++;
+ }
+
+ /* shift clipping and z depth */
+ clip[0]= clip[1]; z[0]= z[1];
+ clip[1]= clip[2]; z[1]= z[2];
+ clip[2]= clip[3]; z[2]= z[3];
+ }
+ }
+ }
+ }
+
+ if (!re->test_break(re->tbh)) {
+ /* convert list to array and sort */
+ sortsegments= MEM_mallocN(sizeof(StrandSortSegment)*totsegment, "StrandSortSegment");
+ for (a=0, sortseg=firstseg; a<totsegment; a++, sortseg=sortseg->next)
+ sortsegments[a]= *sortseg;
+ qsort(sortsegments, totsegment, sizeof(StrandSortSegment), compare_strand_segment);
+ }
+
+ BLI_memarena_free(memarena);
+
+ spart.totapixbuf= MEM_callocN(sizeof(int)*pa->rectx*pa->recty, "totapixbuf");
+
+ if (!re->test_break(re->tbh)) {
+ /* render segments in sorted order */
+ sortseg= sortsegments;
+ for (a=0; a<totsegment; a++, sortseg++) {
+ if (re->test_break(re->tbh))
+ break;
+
+ obi= &re->objectinstance[sortseg->obi];
+ obr= obi->obr;
+
+ sseg.obi= obi;
+ sseg.strand= RE_findOrAddStrand(obr, sortseg->strand);
+ sseg.buffer= sseg.strand->buffer;
+ sseg.sqadaptcos= sseg.buffer->adaptcos;
+ sseg.sqadaptcos *= sseg.sqadaptcos;
+
+ svert= sseg.strand->vert + sortseg->segment;
+ sseg.v[0]= (sortseg->segment > 0)? (svert-1): svert;
+ sseg.v[1]= svert;
+ sseg.v[2]= svert+1;
+ sseg.v[3]= (sortseg->segment < sseg.strand->totvert-2)? svert+2: svert+1;
+ sseg.shaded= 0;
+
+ spart.segment= &sseg;
+
+ render_strand_segment(re, winmat, &spart, &zspan, 1, &sseg);
+ }
+ }
+
+ if (sortsegments)
+ MEM_freeN(sortsegments);
+ MEM_freeN(spart.totapixbuf);
+
+ zbuf_free_span(&zspan);
+
+ return totsegment;
+}
+
+/* *************** */
+
+StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[4][4], int timeoffset)
+{
+ StrandSurface *mesh;
+ MFace *mface;
+ MVert *mvert;
+ float (*co)[3];
+ int a, totvert, totface;
+
+ totvert= dm->getNumVerts(dm);
+ totface= dm->getNumTessFaces(dm);
+
+ for (mesh = re->strandsurface.first; mesh; mesh = mesh->next) {
+ if ((mesh->obr.ob == obr->ob) &&
+ (mesh->obr.par == obr->par) &&
+ (mesh->obr.index == obr->index) &&
+ (mesh->totvert == totvert) &&
+ (mesh->totface == totface))
+ {
+ break;
+ }
+ }
+
+ if (!mesh) {
+ mesh= MEM_callocN(sizeof(StrandSurface), "StrandSurface");
+ mesh->obr= *obr;
+ mesh->totvert= totvert;
+ mesh->totface= totface;
+ mesh->face= MEM_callocN(sizeof(int)*4*mesh->totface, "StrandSurfFaces");
+ mesh->ao= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfAO");
+ mesh->env= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfEnv");
+ mesh->indirect= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfIndirect");
+ BLI_addtail(&re->strandsurface, mesh);
+ }
+
+ if (timeoffset == -1 && !mesh->prevco)
+ mesh->prevco= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else if (timeoffset == 0 && !mesh->co)
+ mesh->co= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else if (timeoffset == 1 && !mesh->nextco)
+ mesh->nextco= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else
+ return mesh;
+
+ mvert= dm->getVertArray(dm);
+ for (a=0; a<mesh->totvert; a++, mvert++) {
+ copy_v3_v3(co[a], mvert->co);
+ mul_m4_v3(mat, co[a]);
+ }
+
+ mface= dm->getTessFaceArray(dm);
+ for (a=0; a<mesh->totface; a++, mface++) {
+ mesh->face[a][0]= mface->v1;
+ mesh->face[a][1]= mface->v2;
+ mesh->face[a][2]= mface->v3;
+ mesh->face[a][3]= mface->v4;
+ }
+
+ return mesh;
+}
+
+void free_strand_surface(Render *re)
+{
+ StrandSurface *mesh;
+
+ for (mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
+ if (mesh->co) MEM_freeN(mesh->co);
+ if (mesh->prevco) MEM_freeN(mesh->prevco);
+ if (mesh->nextco) MEM_freeN(mesh->nextco);
+ if (mesh->ao) MEM_freeN(mesh->ao);
+ if (mesh->env) MEM_freeN(mesh->env);
+ if (mesh->indirect) MEM_freeN(mesh->indirect);
+ if (mesh->face) MEM_freeN(mesh->face);
+ }
+
+ BLI_freelistN(&re->strandsurface);
+}
+
+void strand_minmax(StrandRen *strand, float min[3], float max[3], const float width)
+{
+ StrandVert *svert;
+ const float width2 = width * 2.0f;
+ float vec[3];
+ int a;
+
+ for (a=0, svert=strand->vert; a<strand->totvert; a++, svert++) {
+ copy_v3_v3(vec, svert->co);
+ minmax_v3v3_v3(min, max, vec);
+
+ if (width!=0.0f) {
+ add_v3_fl(vec, width);
+ minmax_v3v3_v3(min, max, vec);
+ add_v3_fl(vec, -width2);
+ minmax_v3v3_v3(min, max, vec);
+ }
+ }
+}
+
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
new file mode 100644
index 00000000000..80dd52c220c
--- /dev/null
+++ b/source/blender/render/intern/source/sunsky.c
@@ -0,0 +1,506 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/sunsky.c
+ * \ingroup render
+ *
+ * This feature comes from Preetham paper on "A Practical Analytic Model for Daylight"
+ * and example code from Brian Smits, another author of that paper in
+ * http://www.cs.utah.edu/vissim/papers/sunsky/code/
+ */
+
+#include "sunsky.h"
+#include "BLI_math.h"
+
+/**
+ * These macros are defined for vector operations
+ * */
+
+/**
+ * compute v1 = v2 op v3
+ * v1, v2 and v3 are vectors contains 3 float
+ * */
+#define VEC3OPV(v1, v2, op, v3) \
+ { \
+ v1[0] = (v2[0] op v3[0]); \
+ v1[1] = (v2[1] op v3[1]); \
+ v1[2] = (v2[2] op v3[2]); \
+ } (void)0
+
+/**
+ * compute v1 = v2 op f1
+ * v1, v2 are vectors contains 3 float
+ * and f1 is a float
+ * */
+#define VEC3OPF(v1, v2, op, f1) \
+ { \
+ v1[0] = (v2[0] op(f1)); \
+ v1[1] = (v2[1] op(f1)); \
+ v1[2] = (v2[2] op(f1)); \
+ } (void)0
+
+/**
+ * compute v1 = f1 op v2
+ * v1, v2 are vectors contains 3 float
+ * and f1 is a float
+ * */
+#define FOPVEC3(v1, f1, op, v2) \
+ { \
+ v1[0] = ((f1) op v2[0]); \
+ v1[1] = ((f1) op v2[1]); \
+ v1[2] = ((f1) op v2[2]); \
+ } (void)0
+
+/**
+ * ClipColor:
+ * clip a color to range [0, 1];
+ * */
+void ClipColor(float c[3])
+{
+ if (c[0] > 1.0f) c[0] = 1.0f;
+ if (c[0] < 0.0f) c[0] = 0.0f;
+ if (c[1] > 1.0f) c[1] = 1.0f;
+ if (c[1] < 0.0f) c[1] = 0.0f;
+ if (c[2] > 1.0f) c[2] = 1.0f;
+ if (c[2] < 0.0f) c[2] = 0.0f;
+}
+
+/**
+ * AngleBetween:
+ * compute angle between to direction
+ * all angles are in radians
+ * */
+static float AngleBetween(float thetav, float phiv, float theta, float phi)
+{
+ float cospsi = sinf(thetav) * sinf(theta) * cosf(phi - phiv) + cosf(thetav) * cosf(theta);
+
+ if (cospsi > 1.0f)
+ return 0;
+ if (cospsi < -1.0f)
+ return M_PI;
+
+ return acosf(cospsi);
+}
+
+/**
+ * DirectionToThetaPhi:
+ * this function convert a direction to it's theta and phi value
+ * parameters:
+ * toSun: contains direction information
+ * theta, phi, are return values from this conversion
+ * */
+static void DirectionToThetaPhi(float *toSun, float *theta, float *phi)
+{
+ *theta = acosf(toSun[2]);
+ if (fabsf(*theta) < 1e-5f)
+ *phi = 0;
+ else
+ *phi = atan2f(toSun[1], toSun[0]);
+}
+
+/**
+ * PerezFunction:
+ * compute perez function value based on input parameters
+ */
+static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, float gamma, float lvz)
+{
+ float den, num;
+
+ den = ((1 + lam[0] * expf(lam[1])) *
+ (1 + lam[2] * expf(lam[3] * sunsky->theta) + lam[4] * cosf(sunsky->theta) * cosf(sunsky->theta)));
+
+ num = ((1 + lam[0] * expf(lam[1] / cosf(theta))) *
+ (1 + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma)));
+
+ return(lvz * num / den);
+}
+
+/**
+ * InitSunSky:
+ * this function compute some sun,sky parameters according to input parameters and also initiate some other sun, sky parameters
+ * parameters:
+ * sunSky, is a structure that contains information about sun, sky and atmosphere, in this function, most of its values initiated
+ * turb, is atmosphere turbidity
+ * toSun, contains sun direction
+ * horizon_brighness, controls the brightness of the horizon colors
+ * spread, controls colors spreed at horizon
+ * sun_brightness, controls sun's brightness
+ * sun_size, controls sun's size
+ * back_scatter, controls back scatter light
+ * */
+void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness,
+ float spread, float sun_brightness, float sun_size, float back_scatter,
+ float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace)
+{
+ float theta2;
+ float theta3;
+ float T;
+ float T2;
+ float chi;
+
+ sunsky->turbidity = turb;
+
+ sunsky->horizon_brightness = horizon_brightness;
+ sunsky->spread = spread;
+ sunsky->sun_brightness = sun_brightness;
+ sunsky->sun_size = sun_size;
+ sunsky->backscattered_light = back_scatter;
+ sunsky->skyblendfac = skyblendfac;
+ sunsky->skyblendtype = skyblendtype;
+ sunsky->sky_exposure = -sky_exposure;
+ sunsky->sky_colorspace = sky_colorspace;
+
+ sunsky->toSun[0] = toSun[0];
+ sunsky->toSun[1] = toSun[1];
+ sunsky->toSun[2] = toSun[2];
+
+ DirectionToThetaPhi(sunsky->toSun, &sunsky->theta, &sunsky->phi);
+
+ sunsky->sunSolidAngle = 0.25 * M_PI * 1.39 * 1.39 / (150 * 150); /* = 6.7443e-05 */
+
+ theta2 = sunsky->theta * sunsky->theta;
+ theta3 = theta2 * sunsky->theta;
+ T = turb;
+ T2 = turb * turb;
+
+ chi = (4.0f / 9.0f - T / 120.0f) * ((float)M_PI - 2.0f * sunsky->theta);
+ sunsky->zenith_Y = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
+ sunsky->zenith_Y *= 1000; /* conversion from kcd/m^2 to cd/m^2 */
+
+ if (sunsky->zenith_Y <= 0)
+ sunsky->zenith_Y = 1e-6;
+
+ sunsky->zenith_x =
+ (+0.00165f * theta3 - 0.00374f * theta2 + 0.00208f * sunsky->theta + 0.0f) * T2 +
+ (-0.02902f * theta3 + 0.06377f * theta2 - 0.03202f * sunsky->theta + 0.00394f) * T +
+ (+0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * sunsky->theta + 0.25885f);
+
+ sunsky->zenith_y =
+ (+0.00275f * theta3 - 0.00610f * theta2 + 0.00316f * sunsky->theta + 0.0f) * T2 +
+ (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * sunsky->theta + 0.00515f) * T +
+ (+0.15346f * theta3 - 0.26756f * theta2 + 0.06669f * sunsky->theta + 0.26688f);
+
+
+ sunsky->perez_Y[0] = 0.17872f * T - 1.46303f;
+ sunsky->perez_Y[1] = -0.35540f * T + 0.42749f;
+ sunsky->perez_Y[2] = -0.02266f * T + 5.32505f;
+ sunsky->perez_Y[3] = 0.12064f * T - 2.57705f;
+ sunsky->perez_Y[4] = -0.06696f * T + 0.37027f;
+
+ sunsky->perez_x[0] = -0.01925f * T - 0.25922f;
+ sunsky->perez_x[1] = -0.06651f * T + 0.00081f;
+ sunsky->perez_x[2] = -0.00041f * T + 0.21247f;
+ sunsky->perez_x[3] = -0.06409f * T - 0.89887f;
+ sunsky->perez_x[4] = -0.00325f * T + 0.04517f;
+
+ sunsky->perez_y[0] = -0.01669f * T - 0.26078f;
+ sunsky->perez_y[1] = -0.09495f * T + 0.00921f;
+ sunsky->perez_y[2] = -0.00792f * T + 0.21023f;
+ sunsky->perez_y[3] = -0.04405f * T - 1.65369f;
+ sunsky->perez_y[4] = -0.01092f * T + 0.05291f;
+
+ /* suggested by glome in patch [#8063] */
+ sunsky->perez_Y[0] *= sunsky->horizon_brightness;
+ sunsky->perez_x[0] *= sunsky->horizon_brightness;
+ sunsky->perez_y[0] *= sunsky->horizon_brightness;
+
+ sunsky->perez_Y[1] *= sunsky->spread;
+ sunsky->perez_x[1] *= sunsky->spread;
+ sunsky->perez_y[1] *= sunsky->spread;
+
+ sunsky->perez_Y[2] *= sunsky->sun_brightness;
+ sunsky->perez_x[2] *= sunsky->sun_brightness;
+ sunsky->perez_y[2] *= sunsky->sun_brightness;
+
+ sunsky->perez_Y[3] *= sunsky->sun_size;
+ sunsky->perez_x[3] *= sunsky->sun_size;
+ sunsky->perez_y[3] *= sunsky->sun_size;
+
+ sunsky->perez_Y[4] *= sunsky->backscattered_light;
+ sunsky->perez_x[4] *= sunsky->backscattered_light;
+ sunsky->perez_y[4] *= sunsky->backscattered_light;
+}
+
+/**
+ * GetSkyXYZRadiance:
+ * this function compute sky radiance according to a view parameters `theta' and `phi'and sunSky values
+ * parameters:
+ * sunSky, sontains sun and sky parameters
+ * theta, is sun's theta
+ * phi, is sun's phi
+ * color_out, is computed color that shows sky radiance in XYZ color format
+ * */
+void GetSkyXYZRadiance(struct SunSky *sunsky, float theta, float phi, float color_out[3])
+{
+ float gamma;
+ float x, y, Y, X, Z;
+ float hfade = 1, nfade = 1;
+
+
+ if (theta > (float)M_PI_2) {
+ hfade = 1.0f - (theta * (float)M_1_PI - 0.5f) * 2.0f;
+ hfade = hfade * hfade * (3.0f - 2.0f * hfade);
+ theta = M_PI_2;
+ }
+
+ if (sunsky->theta > (float)M_PI_2) {
+ if (theta <= (float)M_PI_2) {
+ nfade = 1.0f - (0.5f - theta * (float)M_1_PI) * 2.0f;
+ nfade *= 1.0f - (sunsky->theta * (float)M_1_PI - 0.5f) * 2.0f;
+ nfade = nfade * nfade * (3.0f - 2.0f * nfade);
+ }
+ }
+
+ gamma = AngleBetween(theta, phi, sunsky->theta, sunsky->phi);
+
+ /* Compute xyY values */
+ x = PerezFunction(sunsky, sunsky->perez_x, theta, gamma, sunsky->zenith_x);
+ y = PerezFunction(sunsky, sunsky->perez_y, theta, gamma, sunsky->zenith_y);
+ Y = 6.666666667e-5f * nfade * hfade * PerezFunction(sunsky, sunsky->perez_Y, theta, gamma, sunsky->zenith_Y);
+
+ if (sunsky->sky_exposure != 0.0f)
+ Y = 1.0 - exp(Y * sunsky->sky_exposure);
+
+ X = (x / y) * Y;
+ Z = ((1 - x - y) / y) * Y;
+
+ color_out[0] = X;
+ color_out[1] = Y;
+ color_out[2] = Z;
+}
+
+/**
+ * GetSkyXYZRadiancef:
+ * this function compute sky radiance according to a view direction `varg' and sunSky values
+ * parameters:
+ * sunSky, sontains sun and sky parameters
+ * varg, shows direction
+ * color_out, is computed color that shows sky radiance in XYZ color format
+ * */
+void GetSkyXYZRadiancef(struct SunSky *sunsky, const float varg[3], float color_out[3])
+{
+ float theta, phi;
+ float v[3];
+
+ normalize_v3_v3(v, varg);
+
+ if (v[2] < 0.001f) {
+ v[2] = 0.001f;
+ normalize_v3(v);
+ }
+
+ DirectionToThetaPhi(v, &theta, &phi);
+ GetSkyXYZRadiance(sunsky, theta, phi, color_out);
+}
+
+/**
+ * ComputeAttenuatedSunlight:
+ * this function compute attenuated sun light based on sun's theta and atmosphere turbidity
+ * parameters:
+ * theta, is sun's theta
+ * turbidity: is atmosphere turbidity
+ * fTau: contains computed attenuated sun light
+ * */
+static void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3])
+{
+ float fBeta;
+ float fTauR, fTauA;
+ float m;
+ float fAlpha;
+
+ int i;
+ float fLambda[3];
+ fLambda[0] = 0.65f;
+ fLambda[1] = 0.57f;
+ fLambda[2] = 0.475f;
+
+ fAlpha = 1.3f;
+ fBeta = 0.04608365822050f * turbidity - 0.04586025928522f;
+
+ m = 1.0f / (cosf(theta) + 0.15f * powf(93.885f - theta / (float)M_PI * 180.0f, -1.253f));
+
+ for (i = 0; i < 3; i++) {
+ /* Rayleigh Scattering */
+ fTauR = expf(-m * 0.008735f * powf(fLambda[i], (float)(-4.08f)));
+
+ /* Aerosal (water + dust) attenuation */
+ fTauA = exp(-m * fBeta * powf(fLambda[i], -fAlpha));
+
+ fTau[i] = fTauR * fTauA;
+ }
+}
+
+/**
+ * InitAtmosphere:
+ * this function initiate sunSky structure with user input parameters.
+ * parameters:
+ * sunSky, contains information about sun, and in this function some atmosphere parameters will initiated
+ * sun_intens, shows sun intensity value
+ * mief, Mie scattering factor this factor currently call with 1.0
+ * rayf, Rayleigh scattering factor, this factor currently call with 1.0
+ * inscattf, inscatter light factor that range from 0.0 to 1.0, 0.0 means no inscatter light and 1.0 means full inscatter light
+ * extincf, extinction light factor that range from 0.0 to 1.0, 0.0 means no extinction and 1.0 means full extinction
+ * disf, is distance factor, multiplied to pixle's z value to compute each pixle's distance to camera,
+ * */
+void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float rayf,
+ float inscattf, float extincf, float disf)
+{
+ const float pi = M_PI;
+ const float n = 1.003f; /* refractive index */
+ const float N = 2.545e25;
+ const float pn = 0.035f;
+ const float T = 2.0f;
+ float fTemp, fTemp2, fTemp3, fBeta, fBetaDash;
+ float c = (6.544f * T - 6.51f) * 1e-17f;
+ float K[3] = {0.685f, 0.679f, 0.670f};
+ float vBetaMieTemp[3];
+
+ float fLambda[3], fLambda2[3], fLambda4[3];
+ float vLambda2[3];
+ float vLambda4[3];
+
+ int i;
+
+ sunSky->atm_SunIntensity = sun_intens;
+ sunSky->atm_BetaMieMultiplier = mief;
+ sunSky->atm_BetaRayMultiplier = rayf;
+ sunSky->atm_InscatteringMultiplier = inscattf;
+ sunSky->atm_ExtinctionMultiplier = extincf;
+ sunSky->atm_DistanceMultiplier = disf;
+
+ sunSky->atm_HGg = 0.8;
+
+ fLambda[0] = 1 / 650e-9f;
+ fLambda[1] = 1 / 570e-9f;
+ fLambda[2] = 1 / 475e-9f;
+ for (i = 0; i < 3; i++) {
+ fLambda2[i] = fLambda[i] * fLambda[i];
+ fLambda4[i] = fLambda2[i] * fLambda2[i];
+ }
+
+ vLambda2[0] = fLambda2[0];
+ vLambda2[1] = fLambda2[1];
+ vLambda2[2] = fLambda2[2];
+
+ vLambda4[0] = fLambda4[0];
+ vLambda4[1] = fLambda4[1];
+ vLambda4[2] = fLambda4[2];
+
+ /* Rayleigh scattering constants. */
+ fTemp = pi * pi * (n * n - 1) * (n * n - 1) * (6 + 3 * pn) / (6 - 7 * pn) / N;
+ fBeta = 8 * fTemp * pi / 3;
+
+ VEC3OPF(sunSky->atm_BetaRay, vLambda4, *, fBeta);
+ fBetaDash = fTemp / 2;
+ VEC3OPF(sunSky->atm_BetaDashRay, vLambda4, *, fBetaDash);
+
+
+ /* Mie scattering constants. */
+ fTemp2 = 0.434f * c * (2 * pi) * (2 * pi) * 0.5f;
+ VEC3OPF(sunSky->atm_BetaDashMie, vLambda2, *, fTemp2);
+
+ fTemp3 = 0.434f * c * pi * (2 * pi) * (2 * pi);
+
+ VEC3OPV(vBetaMieTemp, K, *, fLambda);
+ VEC3OPF(sunSky->atm_BetaMie, vBetaMieTemp, *, fTemp3);
+
+}
+
+/**
+ * AtmospherePixleShader:
+ * this function apply atmosphere effect on a pixle color `rgb' at distance `s'
+ * parameters:
+ * sunSky, contains information about sun parameters and user values
+ * view, is camera view vector
+ * s, is distance
+ * rgb, contains rendered color value for a pixle
+ * */
+void AtmospherePixleShader(struct SunSky *sunSky, float view[3], float s, float rgb[3])
+{
+ float costheta;
+ float Phase_1;
+ float Phase_2;
+ float sunColor[3];
+
+ float E[3];
+ float E1[3];
+
+
+ float I[3];
+ float fTemp;
+ float vTemp1[3], vTemp2[3];
+
+ float sunDirection[3];
+
+ s *= sunSky->atm_DistanceMultiplier;
+
+ sunDirection[0] = sunSky->toSun[0];
+ sunDirection[1] = sunSky->toSun[1];
+ sunDirection[2] = sunSky->toSun[2];
+
+ costheta = dot_v3v3(view, sunDirection); /* cos(theta) */
+ Phase_1 = 1 + (costheta * costheta); /* Phase_1 */
+
+ VEC3OPF(sunSky->atm_BetaRay, sunSky->atm_BetaRay, *, sunSky->atm_BetaRayMultiplier);
+ VEC3OPF(sunSky->atm_BetaMie, sunSky->atm_BetaMie, *, sunSky->atm_BetaMieMultiplier);
+ VEC3OPV(sunSky->atm_BetaRM, sunSky->atm_BetaRay, +, sunSky->atm_BetaMie);
+
+ /* e^(-(beta_1 + beta_2) * s) = E1 */
+ VEC3OPF(E1, sunSky->atm_BetaRM, *, -s / (float)M_LN2);
+ E1[0] = exp(E1[0]);
+ E1[1] = exp(E1[1]);
+ E1[2] = exp(E1[2]);
+
+ copy_v3_v3(E, E1);
+
+ /* Phase2(theta) = (1-g^2)/(1+g-2g*cos(theta))^(3/2) */
+ fTemp = 1 + sunSky->atm_HGg - 2 * sunSky->atm_HGg * costheta;
+ fTemp = fTemp * sqrtf(fTemp);
+ Phase_2 = (1 - sunSky->atm_HGg * sunSky->atm_HGg) / fTemp;
+
+ VEC3OPF(vTemp1, sunSky->atm_BetaDashRay, *, Phase_1);
+ VEC3OPF(vTemp2, sunSky->atm_BetaDashMie, *, Phase_2);
+
+ VEC3OPV(vTemp1, vTemp1, +, vTemp2);
+ FOPVEC3(vTemp2, 1.0f, -, E1);
+ VEC3OPV(vTemp1, vTemp1, *, vTemp2);
+
+ FOPVEC3(vTemp2, 1.0f, /, sunSky->atm_BetaRM);
+
+ VEC3OPV(I, vTemp1, *, vTemp2);
+
+ VEC3OPF(I, I, *, sunSky->atm_InscatteringMultiplier);
+ VEC3OPF(E, E, *, sunSky->atm_ExtinctionMultiplier);
+
+ /* scale to color sun */
+ ComputeAttenuatedSunlight(sunSky->theta, sunSky->turbidity, sunColor);
+ VEC3OPV(E, E, *, sunColor);
+
+ VEC3OPF(I, I, *, sunSky->atm_SunIntensity);
+
+ VEC3OPV(rgb, rgb, *, E);
+ VEC3OPV(rgb, rgb, +, I);
+}
+
+#undef VEC3OPV
+#undef VEC3OPF
+#undef FOPVEC3
+
+/* EOF */
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
new file mode 100644
index 00000000000..8e79f309814
--- /dev/null
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -0,0 +1,855 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Matt Ebb, Ra˙l Fern·ndez Hern·ndez (Farsthary).
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/volume_precache.c
+ * \ingroup render
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_task.h"
+#include "BLI_threads.h"
+#include "BLI_voxel.h"
+#include "BLI_utildefines.h"
+
+#include "BLT_translation.h"
+
+#include "PIL_time.h"
+
+#include "RE_shader_ext.h"
+
+#include "DNA_material_types.h"
+
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "render_types.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "volumetric.h"
+#include "volume_precache.h"
+
+#include "atomic_ops.h"
+
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+/* *** utility code to set up an individual raytree for objectinstance, for checking inside/outside *** */
+
+/* Recursive test for intersections, from a point inside the mesh, to outside
+ * Number of intersections (depth) determine if a point is inside or outside the mesh */
+static int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset, int limit, int depth)
+{
+ if (limit == 0) return depth;
+
+ if (RE_rayobject_raycast(tree, isect)) {
+
+ isect->start[0] = isect->start[0] + isect->dist*isect->dir[0];
+ isect->start[1] = isect->start[1] + isect->dist*isect->dir[1];
+ isect->start[2] = isect->start[2] + isect->dist*isect->dir[2];
+
+ isect->dist = FLT_MAX;
+ isect->skip = RE_SKIP_VLR_NEIGHBOUR;
+ isect->orig.face= isect->hit.face;
+ isect->orig.ob= isect->hit.ob;
+
+ return intersect_outside_volume(tree, isect, offset, limit-1, depth+1);
+ }
+ else {
+ return depth;
+ }
+}
+
+/* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */
+static int point_inside_obi(RayObject *tree, ObjectInstanceRen *obi, const float co[3])
+{
+ Isect isect= {{0}};
+ float dir[3] = {0.0f, 0.0f, 1.0f};
+ int final_depth=0, depth=0, limit=20;
+
+ /* set up the isect */
+ copy_v3_v3(isect.start, co);
+ copy_v3_v3(isect.dir, dir);
+ isect.mode= RE_RAY_MIRROR;
+ isect.last_hit= NULL;
+ isect.lay= -1;
+
+ isect.dist = FLT_MAX;
+ isect.orig.face= NULL;
+ isect.orig.ob = NULL;
+
+ RE_instance_rotate_ray(obi, &isect);
+ final_depth = intersect_outside_volume(tree, &isect, dir, limit, depth);
+ RE_instance_rotate_ray_restore(obi, &isect);
+
+ /* even number of intersections: point is outside
+ * odd number: point is inside */
+ if (final_depth % 2 == 0) return 0;
+ else return 1;
+}
+
+/* find the bounding box of an objectinstance in global space */
+void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3])
+{
+ ObjectRen *obr = obi->obr;
+ VolumePrecache *vp = obi->volume_precache;
+ VertRen *ver= NULL;
+ float co[3];
+ int a;
+
+ if (vp->bbmin != NULL && vp->bbmax != NULL) {
+ copy_v3_v3(bbmin, vp->bbmin);
+ copy_v3_v3(bbmax, vp->bbmax);
+ return;
+ }
+
+ vp->bbmin = MEM_callocN(sizeof(float)*3, "volume precache min boundbox corner");
+ vp->bbmax = MEM_callocN(sizeof(float)*3, "volume precache max boundbox corner");
+
+ INIT_MINMAX(bbmin, bbmax);
+
+ for (a=0; a<obr->totvert; a++) {
+ if ((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+ else ver++;
+
+ copy_v3_v3(co, ver->co);
+
+ /* transformed object instance in camera space */
+ if (obi->flag & R_TRANSFORMED)
+ mul_m4_v3(obi->mat, co);
+
+ /* convert to global space */
+ mul_m4_v3(re->viewinv, co);
+
+ minmax_v3v3_v3(vp->bbmin, vp->bbmax, co);
+ }
+
+ copy_v3_v3(bbmin, vp->bbmin);
+ copy_v3_v3(bbmax, vp->bbmax);
+
+}
+
+/* *** light cache filtering *** */
+
+static float get_avg_surrounds(float *cache, int *res, int xx, int yy, int zz)
+{
+ int x, y, z, x_, y_, z_;
+ int added=0;
+ float tot=0.0f;
+
+ for (z=-1; z <= 1; z++) {
+ z_ = zz+z;
+ if (z_ >= 0 && z_ <= res[2]-1) {
+
+ for (y=-1; y <= 1; y++) {
+ y_ = yy+y;
+ if (y_ >= 0 && y_ <= res[1]-1) {
+
+ for (x=-1; x <= 1; x++) {
+ x_ = xx+x;
+ if (x_ >= 0 && x_ <= res[0]-1) {
+ const int64_t i = BLI_VOXEL_INDEX(x_, y_, z_, res);
+
+ if (cache[i] > 0.0f) {
+ tot += cache[i];
+ added++;
+ }
+
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (added > 0) tot /= added;
+
+ return tot;
+}
+
+/* function to filter the edges of the light cache, where there was no volume originally.
+ * For each voxel which was originally external to the mesh, it finds the average values of
+ * the surrounding internal voxels and sets the original external voxel to that average amount.
+ * Works almost a bit like a 'dilate' filter */
+static void lightcache_filter(VolumePrecache *vp)
+{
+ int x, y, z;
+
+ for (z=0; z < vp->res[2]; z++) {
+ for (y=0; y < vp->res[1]; y++) {
+ for (x=0; x < vp->res[0]; x++) {
+ /* trigger for outside mesh */
+ const int64_t i = BLI_VOXEL_INDEX(x, y, z, vp->res);
+
+ if (vp->data_r[i] < -0.f)
+ vp->data_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
+ if (vp->data_g[i] < -0.f)
+ vp->data_g[i] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
+ if (vp->data_b[i] < -0.f)
+ vp->data_b[i] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
+ }
+ }
+ }
+}
+
+#if 0
+static void lightcache_filter2(VolumePrecache *vp)
+{
+ int x, y, z;
+ float *new_r, *new_g, *new_b;
+ int field_size = vp->res[0]*vp->res[1]*vp->res[2]*sizeof(float);
+
+ new_r = MEM_mallocN(field_size, "temp buffer for light cache filter r channel");
+ new_g = MEM_mallocN(field_size, "temp buffer for light cache filter g channel");
+ new_b = MEM_mallocN(field_size, "temp buffer for light cache filter b channel");
+
+ memcpy(new_r, vp->data_r, field_size);
+ memcpy(new_g, vp->data_g, field_size);
+ memcpy(new_b, vp->data_b, field_size);
+
+ for (z=0; z < vp->res[2]; z++) {
+ for (y=0; y < vp->res[1]; y++) {
+ for (x=0; x < vp->res[0]; x++) {
+ /* trigger for outside mesh */
+ const int64_t i = BLI_VOXEL_INDEX(x, y, z, vp->res);
+ if (vp->data_r[i] < -0.f)
+ new_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
+ if (vp->data_g[i] < -0.f)
+ new_g[i] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
+ if (vp->data_b[i] < -0.f)
+ new_b[i] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
+ }
+ }
+ }
+
+ SWAP(float *, vp->data_r, new_r);
+ SWAP(float *, vp->data_g, new_g);
+ SWAP(float *, vp->data_b, new_b);
+
+ if (new_r) { MEM_freeN(new_r); new_r=NULL; }
+ if (new_g) { MEM_freeN(new_g); new_g=NULL; }
+ if (new_b) { MEM_freeN(new_b); new_b=NULL; }
+}
+#endif
+
+/* has a pad of 1 voxel surrounding the core for boundary simulation */
+BLI_INLINE int64_t ms_I(int x, int y, int z, const int *n)
+{
+ /* different ordering to light cache */
+ return ((int64_t)x * (int64_t)(n[1] + 2) * (int64_t)(n[2] + 2) +
+ (int64_t)y * (int64_t)(n[2] + 2) +
+ (int64_t)z);
+}
+
+/* has a pad of 1 voxel surrounding the core for boundary simulation */
+BLI_INLINE int64_t v_I_pad(int x, int y, int z, const int *n)
+{
+ /* same ordering to light cache, with padding */
+ return ((int64_t)z * (int64_t)(n[1] + 2) * (int64_t)(n[0] + 2) +
+ (int64_t)y * (int64_t)(n[0] + 2) +
+ (int64_t)x);
+}
+
+BLI_INLINE int64_t lc_to_ms_I(int x, int y, int z, const int *n)
+{
+ /* converting light cache index to multiple scattering index */
+ return ((int64_t)(x - 1) * ((int64_t)n[1] * (int64_t)n[2]) +
+ (int64_t)(y - 1) * ((int64_t)n[2]) +
+ (int64_t)(z - 1));
+}
+
+/* *** multiple scattering approximation *** */
+
+/* get the total amount of light energy in the light cache. used to normalize after multiple scattering */
+static float total_ss_energy(Render *re, int do_test_break, VolumePrecache *vp)
+{
+ int x, y, z;
+ const int *res = vp->res;
+ float energy=0.f;
+
+ for (z=0; z < res[2]; z++) {
+ for (y=0; y < res[1]; y++) {
+ for (x=0; x < res[0]; x++) {
+ const int64_t i = BLI_VOXEL_INDEX(x, y, z, res);
+
+ if (vp->data_r[i] > 0.f) energy += vp->data_r[i];
+ if (vp->data_g[i] > 0.f) energy += vp->data_g[i];
+ if (vp->data_b[i] > 0.f) energy += vp->data_b[i];
+ }
+ }
+
+ if (do_test_break && re->test_break(re->tbh)) break;
+ }
+
+ return energy;
+}
+
+static float total_ms_energy(Render *re, int do_test_break, float *sr, float *sg, float *sb, const int res[3])
+{
+ int x, y, z;
+ float energy=0.f;
+
+ for (z=1;z<=res[2];z++) {
+ for (y=1;y<=res[1];y++) {
+ for (x=1;x<=res[0];x++) {
+ const int64_t i = ms_I(x, y, z, res);
+
+ if (sr[i] > 0.f) energy += sr[i];
+ if (sg[i] > 0.f) energy += sg[i];
+ if (sb[i] > 0.f) energy += sb[i];
+ }
+ }
+
+ if (do_test_break && re->test_break(re->tbh)) break;
+ }
+
+ return energy;
+}
+
+/**
+ * \param n: the unpadded resolution
+ */
+static void ms_diffuse(Render *re, int do_test_break, const float *x0, float *x, float diff, const int n[3])
+{
+ int i, j, k, l;
+ const float dt = VOL_MS_TIMESTEP;
+ int64_t size = (int64_t)n[0] * (int64_t)n[1] * (int64_t)n[2];
+ const float a = dt * diff * size;
+
+ for (l=0; l<20; l++) {
+ for (k=1; k<=n[2]; k++) {
+ for (j=1; j<=n[1]; j++) {
+ for (i=1; i<=n[0]; i++) {
+ x[v_I_pad(i, j, k, n)] =
+ ((x0[v_I_pad(i, j, k, n)]) + (
+ (x0[v_I_pad(i - 1, j, k, n)] +
+ x0[v_I_pad(i + 1, j, k, n)] +
+ x0[v_I_pad(i, j - 1, k, n)] +
+ x0[v_I_pad(i, j + 1, k, n)] +
+ x0[v_I_pad(i, j, k - 1, n)] +
+ x0[v_I_pad(i, j, k + 1, n)]) * a) / (1 + 6 * a));
+ }
+ }
+
+ if (do_test_break && re->test_break(re->tbh)) break;
+ }
+
+ if (re->test_break(re->tbh)) break;
+ }
+}
+
+static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
+{
+ const float diff = ma->vol.ms_diff * 0.001f; /* compensate for scaling for a nicer UI range */
+ const int simframes = (int)(ma->vol.ms_spread * (float)max_iii(vp->res[0], vp->res[1], vp->res[2]));
+ const int shade_type = ma->vol.shade_type;
+ float fac = ma->vol.ms_intensity;
+
+ int x, y, z, m;
+ const int *n = vp->res;
+ const int size = (n[0]+2)*(n[1]+2)*(n[2]+2);
+ const int do_test_break = (size > 100000);
+ double time, lasttime= PIL_check_seconds_timer();
+ float total;
+ float c=1.0f;
+ float origf; /* factor for blending in original light cache */
+ float energy_ss, energy_ms;
+
+ float *sr0=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer");
+ float *sr=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer");
+ float *sg0=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer");
+ float *sg=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer");
+ float *sb0=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer");
+ float *sb=(float *)MEM_callocN(size*sizeof(float), "temporary multiple scattering buffer");
+
+ total = (float)(n[0]*n[1]*n[2]*simframes);
+
+ energy_ss = total_ss_energy(re, do_test_break, vp);
+
+ /* Scattering as diffusion pass */
+ for (m=0; m<simframes; m++) {
+ /* add sources */
+ for (z=1; z<=n[2]; z++) {
+ for (y=1; y<=n[1]; y++) {
+ for (x=1; x<=n[0]; x++) {
+ const int64_t i = lc_to_ms_I(x, y, z, n); //lc index
+ const int64_t j = ms_I(x, y, z, n); //ms index
+
+ time= PIL_check_seconds_timer();
+ c++;
+ if (vp->data_r[i] > 0.0f)
+ sr[j] += vp->data_r[i];
+ if (vp->data_g[i] > 0.0f)
+ sg[j] += vp->data_g[i];
+ if (vp->data_b[i] > 0.0f)
+ sb[j] += vp->data_b[i];
+
+ /* Displays progress every second */
+ if (time-lasttime>1.0) {
+ char str[64];
+ BLI_snprintf(str, sizeof(str), IFACE_("Simulating multiple scattering: %d%%"),
+ (int)(100.0f * (c / total)));
+ re->i.infostr = str;
+ re->stats_draw(re->sdh, &re->i);
+ re->i.infostr = NULL;
+ lasttime= time;
+ }
+ }
+ }
+
+ if (do_test_break && re->test_break(re->tbh)) break;
+ }
+
+ if (re->test_break(re->tbh)) break;
+
+ SWAP(float *, sr, sr0);
+ SWAP(float *, sg, sg0);
+ SWAP(float *, sb, sb0);
+
+ /* main diffusion simulation */
+ ms_diffuse(re, do_test_break, sr0, sr, diff, n);
+ ms_diffuse(re, do_test_break, sg0, sg, diff, n);
+ ms_diffuse(re, do_test_break, sb0, sb, diff, n);
+
+ if (re->test_break(re->tbh)) break;
+ }
+
+ /* normalization factor to conserve energy */
+ energy_ms = total_ms_energy(re, do_test_break, sr, sg, sb, n);
+ fac *= (energy_ss / energy_ms);
+
+ /* blend multiple scattering back in the light cache */
+ if (shade_type == MA_VOL_SHADE_SHADEDPLUSMULTIPLE) {
+ /* conserve energy - half single, half multiple */
+ origf = 0.5f;
+ fac *= 0.5f;
+ }
+ else {
+ origf = 0.0f;
+ }
+
+ for (z=1;z<=n[2];z++) {
+ for (y=1;y<=n[1];y++) {
+ for (x=1;x<=n[0];x++) {
+ const int64_t i = lc_to_ms_I(x, y, z, n); //lc index
+ const int64_t j = ms_I(x, y, z, n); //ms index
+
+ vp->data_r[i] = origf * vp->data_r[i] + fac * sr[j];
+ vp->data_g[i] = origf * vp->data_g[i] + fac * sg[j];
+ vp->data_b[i] = origf * vp->data_b[i] + fac * sb[j];
+ }
+ }
+
+ if (do_test_break && re->test_break(re->tbh)) break;
+ }
+
+ MEM_freeN(sr0);
+ MEM_freeN(sr);
+ MEM_freeN(sg0);
+ MEM_freeN(sg);
+ MEM_freeN(sb0);
+ MEM_freeN(sb);
+}
+
+
+
+#if 0 /* debug stuff */
+static void *vol_precache_part_test(void *data)
+{
+ VolPrecachePart *pa = data;
+
+ printf("part number: %d\n", pa->num);
+ printf("done: %d\n", pa->done);
+ printf("x min: %d x max: %d\n", pa->minx, pa->maxx);
+ printf("y min: %d y max: %d\n", pa->miny, pa->maxy);
+ printf("z min: %d z max: %d\n", pa->minz, pa->maxz);
+
+ return NULL;
+}
+#endif
+
+/* Iterate over the 3d voxel grid, and fill the voxels with scattering information
+ *
+ * It's stored in memory as 3 big float grids next to each other, one for each RGB channel.
+ * I'm guessing the memory alignment may work out better this way for the purposes
+ * of doing linear interpolation, but I haven't actually tested this theory! :)
+ */
+typedef struct VolPrecacheState {
+ double lasttime;
+ unsigned int doneparts;
+ unsigned int totparts;
+} VolPrecacheState;
+
+static void vol_precache_part(TaskPool * __restrict pool, void *taskdata, int UNUSED(threadid))
+{
+ VolPrecacheState *state = (VolPrecacheState *)BLI_task_pool_userdata(pool);
+ VolPrecachePart *pa = (VolPrecachePart *)taskdata;
+ Render *re = pa->re;
+
+ ObjectInstanceRen *obi = pa->obi;
+ RayObject *tree = pa->tree;
+ ShadeInput *shi = pa->shi;
+ float scatter_col[3] = {0.f, 0.f, 0.f};
+ float co[3], cco[3], view[3];
+ int x, y, z;
+ int res[3];
+ double time;
+
+ if (re->test_break && re->test_break(re->tbh))
+ return;
+
+ //printf("thread id %d\n", threadid);
+
+ res[0]= pa->res[0];
+ res[1]= pa->res[1];
+ res[2]= pa->res[2];
+
+ for (z= pa->minz; z < pa->maxz; z++) {
+ co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
+
+ for (y= pa->miny; y < pa->maxy; y++) {
+ co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f));
+
+ for (x=pa->minx; x < pa->maxx; x++) {
+ int64_t i;
+ co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
+
+ if (re->test_break && re->test_break(re->tbh))
+ break;
+
+ /* convert from world->camera space for shading */
+ mul_v3_m4v3(cco, pa->viewmat, co);
+
+ i = BLI_VOXEL_INDEX(x, y, z, res);
+
+ /* don't bother if the point is not inside the volume mesh */
+ if (!point_inside_obi(tree, obi, cco)) {
+ obi->volume_precache->data_r[i] = -1.0f;
+ obi->volume_precache->data_g[i] = -1.0f;
+ obi->volume_precache->data_b[i] = -1.0f;
+ continue;
+ }
+
+ copy_v3_v3(view, cco);
+ normalize_v3(view);
+ vol_get_scattering(shi, scatter_col, cco, view);
+
+ obi->volume_precache->data_r[i] = scatter_col[0];
+ obi->volume_precache->data_g[i] = scatter_col[1];
+ obi->volume_precache->data_b[i] = scatter_col[2];
+
+ }
+ }
+ }
+
+ unsigned int doneparts = atomic_add_and_fetch_u(&state->doneparts, 1);
+
+ time = PIL_check_seconds_timer();
+ if (time - state->lasttime > 1.0) {
+ ThreadMutex *mutex = BLI_task_pool_user_mutex(pool);
+
+ if (BLI_mutex_trylock(mutex)) {
+ char str[64];
+ float ratio = (float)doneparts/(float)state->totparts;
+ BLI_snprintf(str, sizeof(str), IFACE_("Precaching volume: %d%%"), (int)(100.0f * ratio));
+ re->i.infostr = str;
+ re->stats_draw(re->sdh, &re->i);
+ re->i.infostr = NULL;
+ state->lasttime = time;
+
+ BLI_mutex_unlock(mutex);
+ }
+ }
+}
+
+static void precache_setup_shadeinput(Render *re, ObjectInstanceRen *obi, Material *ma, ShadeInput *shi)
+{
+ memset(shi, 0, sizeof(ShadeInput));
+ shi->depth= 1;
+ shi->mask= 1;
+ shi->mat = ma;
+ shi->vlr = NULL;
+ memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); /* note, keep this synced with render_types.h */
+ shi->har= shi->mat->har;
+ shi->obi= obi;
+ shi->obr= obi->obr;
+ shi->lay = re->lay;
+}
+
+static void precache_launch_parts(Render *re, RayObject *tree, ShadeInput *shi, ObjectInstanceRen *obi)
+{
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
+ VolumePrecache *vp = obi->volume_precache;
+ VolPrecacheState state;
+ int i=0, x, y, z;
+ float voxel[3];
+ int sizex, sizey, sizez;
+ float bbmin[3], bbmax[3];
+ const int *res;
+ int minx, maxx;
+ int miny, maxy;
+ int minz, maxz;
+ int totthread = re->r.threads;
+ int parts[3];
+
+ if (!vp) return;
+
+ /* currently we just subdivide the box, number of threads per side */
+ parts[0] = parts[1] = parts[2] = totthread;
+ res = vp->res;
+
+ /* setup task scheduler */
+ memset(&state, 0, sizeof(state));
+ state.doneparts = 0;
+ state.totparts = parts[0]*parts[1]*parts[2];
+ state.lasttime = PIL_check_seconds_timer();
+
+ task_scheduler = BLI_task_scheduler_create(totthread);
+ task_pool = BLI_task_pool_create(task_scheduler, &state);
+
+ /* using boundbox in worldspace */
+ global_bounds_obi(re, obi, bbmin, bbmax);
+ sub_v3_v3v3(voxel, bbmax, bbmin);
+
+ voxel[0] /= (float)res[0];
+ voxel[1] /= (float)res[1];
+ voxel[2] /= (float)res[2];
+
+ for (x=0; x < parts[0]; x++) {
+ sizex = ceil(res[0] / (float)parts[0]);
+ minx = x * sizex;
+ maxx = minx + sizex;
+ maxx = (maxx>res[0])?res[0]:maxx;
+
+ for (y=0; y < parts[1]; y++) {
+ sizey = ceil(res[1] / (float)parts[1]);
+ miny = y * sizey;
+ maxy = miny + sizey;
+ maxy = (maxy>res[1])?res[1]:maxy;
+
+ for (z=0; z < parts[2]; z++) {
+ VolPrecachePart *pa= MEM_callocN(sizeof(VolPrecachePart), "new precache part");
+
+ sizez = ceil(res[2] / (float)parts[2]);
+ minz = z * sizez;
+ maxz = minz + sizez;
+ maxz = (maxz>res[2])?res[2]:maxz;
+
+ pa->re = re;
+ pa->num = i;
+ pa->tree = tree;
+ pa->shi = shi;
+ pa->obi = obi;
+ copy_m4_m4(pa->viewmat, re->viewmat);
+
+ copy_v3_v3(pa->bbmin, bbmin);
+ copy_v3_v3(pa->voxel, voxel);
+ copy_v3_v3_int(pa->res, res);
+
+ pa->minx = minx; pa->maxx = maxx;
+ pa->miny = miny; pa->maxy = maxy;
+ pa->minz = minz; pa->maxz = maxz;
+
+ BLI_task_pool_push(task_pool, vol_precache_part, pa, true, TASK_PRIORITY_HIGH);
+
+ i++;
+ }
+ }
+ }
+
+ /* work and wait until tasks are done */
+ BLI_task_pool_work_and_wait(task_pool);
+
+ /* free */
+ BLI_task_pool_free(task_pool);
+ BLI_task_scheduler_free(task_scheduler);
+}
+
+/* calculate resolution from bounding box in world space */
+static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen *obi, int res)
+{
+ float dim[3], div;
+ float bbmin[3], bbmax[3];
+
+ /* bound box in global space */
+ global_bounds_obi(re, obi, bbmin, bbmax);
+ sub_v3_v3v3(dim, bbmax, bbmin);
+
+ div = max_fff(dim[0], dim[1], dim[2]);
+ dim[0] /= div;
+ dim[1] /= div;
+ dim[2] /= div;
+
+ vp->res[0] = ceil(dim[0] * res);
+ vp->res[1] = ceil(dim[1] * res);
+ vp->res[2] = ceil(dim[2] * res);
+
+ if ((vp->res[0] < 1) || (vp->res[1] < 1) || (vp->res[2] < 1))
+ return 0;
+
+ return 1;
+}
+
+/* Precache a volume into a 3D voxel grid.
+ * The voxel grid is stored in the ObjectInstanceRen,
+ * in camera space, aligned with the ObjectRen's bounding box.
+ * Resolution is defined by the user.
+ */
+static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *obi, Material *ma)
+{
+ VolumePrecache *vp;
+ RayObject *tree;
+ ShadeInput shi;
+
+ R = *re;
+
+ /* create a raytree with just the faces of the instanced ObjectRen,
+ * used for checking if the cached point is inside or outside. */
+ tree = makeraytree_object(&R, obi);
+ if (!tree) return;
+
+ vp = MEM_callocN(sizeof(VolumePrecache), "volume light cache");
+ obi->volume_precache = vp;
+
+ if (!precache_resolution(re, vp, obi, ma->vol.precache_resolution)) {
+ MEM_freeN(vp);
+ vp = NULL;
+ return;
+ }
+
+ vp->data_r = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data red channel");
+ vp->data_g = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data green channel");
+ vp->data_b = MEM_callocN(sizeof(float)*vp->res[0]*vp->res[1]*vp->res[2], "volume light cache data blue channel");
+ if (vp->data_r==NULL || vp->data_g==NULL || vp->data_b==NULL) {
+ MEM_freeN(vp);
+ return;
+ }
+
+ /* Need a shadeinput to calculate scattering */
+ precache_setup_shadeinput(re, obi, ma, &shi);
+
+ precache_launch_parts(re, tree, &shi, obi);
+
+ if (tree) {
+ /* TODO: makeraytree_object creates a tree and saves it on OBI,
+ * if we free this tree we should also clear other pointers to it */
+ //RE_rayobject_free(tree);
+ //tree= NULL;
+ }
+
+ if (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE)) {
+ /* this should be before the filtering */
+ multiple_scattering_diffusion(re, obi->volume_precache, ma);
+ }
+
+ lightcache_filter(obi->volume_precache);
+}
+
+static int using_lightcache(Material *ma)
+{
+ return (((ma->vol.shadeflag & MA_VOL_PRECACHESHADING) && (ma->vol.shade_type == MA_VOL_SHADE_SHADED)) ||
+ (ELEM(ma->vol.shade_type, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE)));
+}
+
+/* loop through all objects (and their associated materials)
+ * marked for pre-caching in convertblender.c, and pre-cache them */
+void volume_precache(Render *re)
+{
+ ObjectInstanceRen *obi;
+ VolumeOb *vo;
+
+ re->i.infostr = IFACE_("Volume preprocessing");
+ re->stats_draw(re->sdh, &re->i);
+
+ for (vo= re->volumes.first; vo; vo= vo->next) {
+ if (using_lightcache(vo->ma)) {
+ for (obi= re->instancetable.first; obi; obi= obi->next) {
+ if (obi->obr == vo->obr) {
+ vol_precache_objectinstance_threads(re, obi, vo->ma);
+
+ if (re->test_break && re->test_break(re->tbh))
+ break;
+ }
+ }
+
+ if (re->test_break && re->test_break(re->tbh))
+ break;
+ }
+ }
+
+ re->i.infostr = NULL;
+ re->stats_draw(re->sdh, &re->i);
+}
+
+void free_volume_precache(Render *re)
+{
+ ObjectInstanceRen *obi;
+
+ for (obi= re->instancetable.first; obi; obi= obi->next) {
+ if (obi->volume_precache != NULL) {
+ MEM_freeN(obi->volume_precache->data_r);
+ MEM_freeN(obi->volume_precache->data_g);
+ MEM_freeN(obi->volume_precache->data_b);
+ MEM_freeN(obi->volume_precache->bbmin);
+ MEM_freeN(obi->volume_precache->bbmax);
+ MEM_freeN(obi->volume_precache);
+ obi->volume_precache = NULL;
+ }
+ }
+
+ BLI_freelistN(&re->volumes);
+}
+
+int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3])
+{
+ RayObject *tree;
+ int inside=0;
+
+ tree = makeraytree_object(re, obi);
+ if (!tree) return 0;
+
+ inside = point_inside_obi(tree, obi, co);
+
+ //TODO: makeraytree_object creates a tree and saves it on OBI, if we free this tree we should also clear other pointers to it
+ //RE_rayobject_free(tree);
+ //tree= NULL;
+
+ return inside;
+}
+
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
new file mode 100644
index 00000000000..583353ed8cf
--- /dev/null
+++ b/source/blender/render/intern/source/volumetric.c
@@ -0,0 +1,836 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Matt Ebb, Raul Fernandez Hernandez (Farsthary)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/volumetric.c
+ * \ingroup render
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+
+#include "BLI_math.h"
+#include "BLI_rand.h"
+#include "BLI_voxel.h"
+#include "BLI_utildefines.h"
+
+#include "RE_shader_ext.h"
+
+#include "IMB_colormanagement.h"
+
+#include "DNA_material_types.h"
+#include "DNA_group_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_meta_types.h"
+
+
+#include "render_types.h"
+#include "pixelshading.h"
+#include "rayintersection.h"
+#include "rayobject.h"
+#include "renderdatabase.h"
+#include "shading.h"
+#include "shadbuf.h"
+#include "texture.h"
+#include "volumetric.h"
+#include "volume_precache.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+/* tracing */
+static float vol_get_shadow(ShadeInput *shi, LampRen *lar, const float co[3])
+{
+ float visibility = 1.f;
+
+ if (lar->shb) {
+ float dxco[3] = {0.f, 0.f, 0.f}, dyco[3] = {0.f, 0.f, 0.f};
+
+ visibility = testshadowbuf(&R, lar->shb, co, dxco, dyco, 1.0, 0.0);
+ }
+ else if (lar->mode & LA_SHAD_RAY) {
+ /* trace shadow manually, no good lamp api atm */
+ Isect is;
+
+ copy_v3_v3(is.start, co);
+ if (lar->type == LA_SUN || lar->type == LA_HEMI) {
+ is.dir[0] = -lar->vec[0];
+ is.dir[1] = -lar->vec[1];
+ is.dir[2] = -lar->vec[2];
+ is.dist = R.maxdist;
+ }
+ else {
+ sub_v3_v3v3(is.dir, lar->co, is.start);
+ is.dist = normalize_v3(is.dir);
+ }
+
+ is.mode = RE_RAY_MIRROR;
+ is.check = RE_CHECK_VLR_NON_SOLID_MATERIAL;
+ is.skip = 0;
+
+ if (lar->mode & (LA_LAYER | LA_LAYER_SHADOW))
+ is.lay = lar->lay;
+ else
+ is.lay = -1;
+
+ is.orig.ob = NULL;
+ is.orig.face = NULL;
+ is.last_hit = lar->last_hit[shi->thread];
+
+ RE_instance_rotate_ray(shi->obi, &is);
+
+ if (RE_rayobject_raycast(R.raytree, &is)) {
+ RE_instance_rotate_ray_restore(shi->obi, &is);
+
+ visibility = 0.f;
+ }
+
+ lar->last_hit[shi->thread] = is.last_hit;
+ }
+ return visibility;
+}
+
+static int vol_get_bounds(ShadeInput *shi, const float co[3], const float vec[3], float hitco[3], Isect *isect, int intersect_type)
+{
+
+ copy_v3_v3(isect->start, co);
+ copy_v3_v3(isect->dir, vec);
+ isect->dist = FLT_MAX;
+ isect->mode = RE_RAY_MIRROR;
+ isect->last_hit = NULL;
+ isect->lay = -1;
+ isect->check = RE_CHECK_VLR_NONE;
+
+ if (intersect_type == VOL_BOUNDS_DEPTH) {
+ isect->skip = RE_SKIP_VLR_NEIGHBOUR;
+ isect->orig.face = (void *)shi->vlr;
+ isect->orig.ob = (void *)shi->obi;
+ }
+ else { // if (intersect_type == VOL_BOUNDS_SS) {
+ isect->skip = 0;
+ isect->orig.face = NULL;
+ isect->orig.ob = NULL;
+ }
+
+ RE_instance_rotate_ray(shi->obi, isect);
+
+ if (RE_rayobject_raycast(R.raytree, isect)) {
+ RE_instance_rotate_ray_restore(shi->obi, isect);
+
+ hitco[0] = isect->start[0] + isect->dist * isect->dir[0];
+ hitco[1] = isect->start[1] + isect->dist * isect->dir[1];
+ hitco[2] = isect->start[2] + isect->dist * isect->dir[2];
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+static void shade_intersection(ShadeInput *shi, float col_r[4], Isect *is)
+{
+ ShadeInput shi_new;
+ ShadeResult shr_new;
+
+ memset(&shi_new, 0, sizeof(ShadeInput));
+
+ shi_new.mask = shi->mask;
+ shi_new.osatex = shi->osatex;
+ shi_new.thread = shi->thread;
+ shi_new.depth = shi->depth + 1;
+ shi_new.volume_depth = shi->volume_depth + 1;
+ shi_new.xs = shi->xs;
+ shi_new.ys = shi->ys;
+ shi_new.lay = shi->lay;
+ shi_new.passflag = SCE_PASS_COMBINED; /* result of tracing needs no pass info */
+ shi_new.combinedflag = 0xFFFFFF; /* ray trace does all options */
+ shi_new.light_override = shi->light_override;
+ shi_new.mat_override = shi->mat_override;
+
+ copy_v3_v3(shi_new.camera_co, is->start);
+
+ memset(&shr_new, 0, sizeof(ShadeResult));
+
+ /* hardcoded limit of 100 for now - prevents problems in weird geometry */
+ if (shi->volume_depth < 100) {
+ shade_ray(is, &shi_new, &shr_new);
+ }
+
+ copy_v3_v3(col_r, shr_new.combined);
+ col_r[3] = shr_new.alpha;
+}
+
+static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, const float co[3], float col_r[4])
+{
+ Isect isect;
+
+ copy_v3_v3(isect.start, co);
+ copy_v3_v3(isect.dir, shi->view);
+ isect.dist = FLT_MAX;
+
+ isect.mode = RE_RAY_MIRROR;
+ isect.check = RE_CHECK_VLR_NONE;
+ isect.skip = RE_SKIP_VLR_NEIGHBOUR;
+ isect.orig.ob = (void *) shi->obi;
+ isect.orig.face = (void *)vlr;
+ isect.last_hit = NULL;
+ isect.lay = -1;
+
+ /* check to see if there's anything behind the volume, otherwise shade the sky */
+ RE_instance_rotate_ray(shi->obi, &isect);
+
+ if (RE_rayobject_raycast(R.raytree, &isect)) {
+ RE_instance_rotate_ray_restore(shi->obi, &isect);
+
+ shade_intersection(shi, col_r, &isect);
+ }
+ else {
+ shadeSkyView(col_r, co, shi->view, NULL, shi->thread);
+ shadeSunView(col_r, shi->view);
+ }
+}
+
+
+/* trilinear interpolation */
+static void vol_get_precached_scattering(Render *re, ShadeInput *shi, float scatter_col[3], const float co[3])
+{
+ VolumePrecache *vp = shi->obi->volume_precache;
+ float bbmin[3], bbmax[3], dim[3];
+ float world_co[3], sample_co[3];
+
+ if (!vp) return;
+
+ /* find sample point in global space bounding box 0.0-1.0 */
+ global_bounds_obi(re, shi->obi, bbmin, bbmax);
+ sub_v3_v3v3(dim, bbmax, bbmin);
+ mul_v3_m4v3(world_co, re->viewinv, co);
+
+ /* sample_co in 0.0-1.0 */
+ sample_co[0] = (world_co[0] - bbmin[0]) / dim[0];
+ sample_co[1] = (world_co[1] - bbmin[1]) / dim[1];
+ sample_co[2] = (world_co[2] - bbmin[2]) / dim[2];
+
+ scatter_col[0] = BLI_voxel_sample_triquadratic(vp->data_r, vp->res, sample_co);
+ scatter_col[1] = BLI_voxel_sample_triquadratic(vp->data_g, vp->res, sample_co);
+ scatter_col[2] = BLI_voxel_sample_triquadratic(vp->data_b, vp->res, sample_co);
+}
+
+/* Meta object density, brute force for now
+ * (might be good enough anyway, don't need huge number of metaobs to model volumetric objects */
+static float metadensity(Object *ob, const float co[3])
+{
+ float mat[4][4], imat[4][4], dens = 0.f;
+ MetaBall *mb = (MetaBall *)ob->data;
+ MetaElem *ml;
+
+ /* transform co to meta-element */
+ float tco[3] = {co[0], co[1], co[2]};
+ mul_m4_m4m4(mat, R.viewmat, ob->obmat);
+ invert_m4_m4(imat, mat);
+ mul_m4_v3(imat, tco);
+
+ for (ml = mb->elems.first; ml; ml = ml->next) {
+ float bmat[3][3], dist2;
+
+ /* element rotation transform */
+ float tp[3] = {ml->x - tco[0], ml->y - tco[1], ml->z - tco[2]};
+ quat_to_mat3(bmat, ml->quat);
+ transpose_m3(bmat); /* rot.only, so inverse == transpose */
+ mul_m3_v3(bmat, tp);
+
+ /* MB_BALL default */
+ switch (ml->type) {
+ case MB_ELIPSOID:
+ tp[0] /= ml->expx;
+ tp[1] /= ml->expy;
+ tp[2] /= ml->expz;
+ break;
+ case MB_CUBE:
+ tp[2] = (tp[2] > ml->expz) ? (tp[2] - ml->expz) : ((tp[2] < -ml->expz) ? (tp[2] + ml->expz) : 0.f);
+ /* no break, xy as plane */
+ ATTR_FALLTHROUGH;
+ case MB_PLANE:
+ tp[1] = (tp[1] > ml->expy) ? (tp[1] - ml->expy) : ((tp[1] < -ml->expy) ? (tp[1] + ml->expy) : 0.f);
+ /* no break, x as tube */
+ ATTR_FALLTHROUGH;
+ case MB_TUBE:
+ tp[0] = (tp[0] > ml->expx) ? (tp[0] - ml->expx) : ((tp[0] < -ml->expx) ? (tp[0] + ml->expx) : 0.f);
+ }
+
+ /* ml->rad2 is not set */
+ dist2 = 1.0f - (dot_v3v3(tp, tp) / (ml->rad * ml->rad));
+ if (dist2 > 0.f)
+ dens += (ml->flag & MB_NEGATIVE) ? -ml->s * dist2 * dist2 * dist2 : ml->s * dist2 * dist2 * dist2;
+ }
+
+ dens -= mb->thresh;
+ return (dens < 0.f) ? 0.f : dens;
+}
+
+float vol_get_density(struct ShadeInput *shi, const float co[3])
+{
+ float density = shi->mat->vol.density;
+ float density_scale = shi->mat->vol.density_scale;
+
+ if (shi->mat->mapto_textured & MAP_DENSITY)
+ do_volume_tex(shi, co, MAP_DENSITY, NULL, &density, &R);
+
+ /* if meta-object, modulate by metadensity without increasing it */
+ if (shi->obi->obr->ob->type == OB_MBALL) {
+ const float md = metadensity(shi->obi->obr->ob, co);
+ if (md < 1.f) density *= md;
+ }
+
+ return density * density_scale;
+}
+
+
+/* Color of light that gets scattered out by the volume */
+/* Uses same physically based scattering parameter as in transmission calculations,
+ * along with artificial reflection scale/reflection color tint */
+static void vol_get_reflection_color(ShadeInput *shi, float ref_col[3], const float co[3])
+{
+ float scatter = shi->mat->vol.scattering;
+ float reflection = shi->mat->vol.reflection;
+ copy_v3_v3(ref_col, shi->mat->vol.reflection_col);
+
+ if (shi->mat->mapto_textured & (MAP_SCATTERING + MAP_REFLECTION_COL))
+ do_volume_tex(shi, co, MAP_SCATTERING + MAP_REFLECTION_COL, ref_col, &scatter, &R);
+
+ /* only one single float parameter at a time... :s */
+ if (shi->mat->mapto_textured & (MAP_REFLECTION))
+ do_volume_tex(shi, co, MAP_REFLECTION, NULL, &reflection, &R);
+
+ ref_col[0] = reflection * ref_col[0] * scatter;
+ ref_col[1] = reflection * ref_col[1] * scatter;
+ ref_col[2] = reflection * ref_col[2] * scatter;
+}
+
+/* compute emission component, amount of radiance to add per segment
+ * can be textured with 'emit' */
+static void vol_get_emission(ShadeInput *shi, float emission_col[3], const float co[3])
+{
+ float emission = shi->mat->vol.emission;
+ copy_v3_v3(emission_col, shi->mat->vol.emission_col);
+
+ if (shi->mat->mapto_textured & (MAP_EMISSION + MAP_EMISSION_COL))
+ do_volume_tex(shi, co, MAP_EMISSION + MAP_EMISSION_COL, emission_col, &emission, &R);
+
+ emission_col[0] = emission_col[0] * emission;
+ emission_col[1] = emission_col[1] * emission;
+ emission_col[2] = emission_col[2] * emission;
+}
+
+
+/* A combination of scattering and absorption -> known as sigma T.
+ * This can possibly use a specific scattering color,
+ * and absorption multiplier factor too, but these parameters are left out for simplicity.
+ * It's easy enough to get a good wide range of results with just these two parameters. */
+static void vol_get_sigma_t(ShadeInput *shi, float sigma_t[3], const float co[3])
+{
+ /* technically absorption, but named transmission color
+ * since it describes the effect of the coloring *after* absorption */
+ float transmission_col[3] = {shi->mat->vol.transmission_col[0], shi->mat->vol.transmission_col[1], shi->mat->vol.transmission_col[2]};
+ float scattering = shi->mat->vol.scattering;
+
+ if (shi->mat->mapto_textured & (MAP_SCATTERING + MAP_TRANSMISSION_COL))
+ do_volume_tex(shi, co, MAP_SCATTERING + MAP_TRANSMISSION_COL, transmission_col, &scattering, &R);
+
+ sigma_t[0] = (1.0f - transmission_col[0]) + scattering;
+ sigma_t[1] = (1.0f - transmission_col[1]) + scattering;
+ sigma_t[2] = (1.0f - transmission_col[2]) + scattering;
+}
+
+/* phase function - determines in which directions the light
+ * is scattered in the volume relative to incoming direction
+ * and view direction */
+static float vol_get_phasefunc(ShadeInput *UNUSED(shi), float g, const float w[3], const float wp[3])
+{
+ const float normalize = 0.25f; // = 1.f/4.f = M_PI/(4.f*M_PI)
+
+ /* normalization constant is 1/4 rather than 1/4pi, since
+ * Blender's shading system doesn't normalize for
+ * energy conservation - eg. multiplying by pdf ( 1/pi for a lambert brdf ).
+ * This means that lambert surfaces in Blender are pi times brighter than they 'should be'
+ * and therefore, with correct energy conservation, volumes will darker than other solid objects,
+ * for the same lighting intensity.
+ * To correct this, scale up the phase function values by pi
+ * until Blender's shading system supports this better. --matt
+ */
+
+ if (g == 0.f) { /* isotropic */
+ return normalize * 1.f;
+ }
+ else { /* schlick */
+ const float k = 1.55f * g - 0.55f * g * g * g;
+ const float kcostheta = k * dot_v3v3(w, wp);
+ return normalize * (1.f - k * k) / ((1.f - kcostheta) * (1.f - kcostheta));
+ }
+
+ /* not used, but here for reference: */
+#if 0
+ switch (phasefunc_type) {
+ case MA_VOL_PH_MIEHAZY:
+ return normalize * (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f));
+ case MA_VOL_PH_MIEMURKY:
+ return normalize * (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f));
+ case MA_VOL_PH_RAYLEIGH:
+ return normalize * 3.f / 4.f * (1 + costheta * costheta);
+ case MA_VOL_PH_HG:
+ return normalize * (1.f - g * g) / powf(1.f + g * g - 2.f * g * costheta, 1.5f);
+ case MA_VOL_PH_SCHLICK:
+ {
+ const float k = 1.55f * g - 0.55f * g * g * g;
+ const float kcostheta = k * costheta;
+ return normalize * (1.f - k * k) / ((1.f - kcostheta) * (1.f - kcostheta));
+ }
+ case MA_VOL_PH_ISOTROPIC:
+ default:
+ return normalize * 1.f;
+ }
+#endif
+}
+
+/* Compute transmittance = e^(-attenuation) */
+static void vol_get_transmittance_seg(ShadeInput *shi, float tr[3], float stepsize, const float co[3], float density)
+{
+ /* input density = density at co */
+ float tau[3] = {0.f, 0.f, 0.f};
+ const float stepd = density * stepsize;
+ float sigma_t[3];
+
+ vol_get_sigma_t(shi, sigma_t, co);
+
+ /* homogeneous volume within the sampled distance */
+ tau[0] += stepd * sigma_t[0];
+ tau[1] += stepd * sigma_t[1];
+ tau[2] += stepd * sigma_t[2];
+
+ tr[0] *= expf(-tau[0]);
+ tr[1] *= expf(-tau[1]);
+ tr[2] *= expf(-tau[2]);
+}
+
+/* Compute transmittance = e^(-attenuation) */
+static void vol_get_transmittance(ShadeInput *shi, float tr[3], const float co[3], const float endco[3])
+{
+ float p[3] = {co[0], co[1], co[2]};
+ float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]};
+ float tau[3] = {0.f, 0.f, 0.f};
+
+ float t0 = 0.f;
+ float t1 = normalize_v3(step_vec);
+ float pt0 = t0;
+
+ t0 += shi->mat->vol.stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
+ p[0] += t0 * step_vec[0];
+ p[1] += t0 * step_vec[1];
+ p[2] += t0 * step_vec[2];
+ mul_v3_fl(step_vec, shi->mat->vol.stepsize);
+
+ for (; t0 < t1; pt0 = t0, t0 += shi->mat->vol.stepsize) {
+ const float d = vol_get_density(shi, p);
+ const float stepd = (t0 - pt0) * d;
+ float sigma_t[3];
+
+ vol_get_sigma_t(shi, sigma_t, p);
+
+ tau[0] += stepd * sigma_t[0];
+ tau[1] += stepd * sigma_t[1];
+ tau[2] += stepd * sigma_t[2];
+
+ add_v3_v3(p, step_vec);
+ }
+
+ /* return transmittance */
+ tr[0] = expf(-tau[0]);
+ tr[1] = expf(-tau[1]);
+ tr[2] = expf(-tau[2]);
+}
+
+static void vol_shade_one_lamp(struct ShadeInput *shi, const float co[3], const float view[3], LampRen *lar, float lacol[3])
+{
+ float visifac, lv[3], lampdist;
+ float tr[3] = {1.0, 1.0, 1.0};
+ float hitco[3], *atten_co;
+ float p, ref_col[3];
+
+ if (lar->mode & LA_LAYER) if ((lar->lay & shi->obi->lay) == 0) return;
+ if ((lar->lay & shi->lay) == 0) return;
+ if (lar->energy == 0.0f) return;
+
+ if ((visifac = lamp_get_visibility(lar, co, lv, &lampdist)) == 0.f) return;
+
+ copy_v3_v3(lacol, &lar->r);
+
+ if (lar->mode & LA_TEXTURE) {
+ shi->osatex = 0;
+ do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE);
+ }
+
+ mul_v3_fl(lacol, visifac);
+
+ if (ELEM(lar->type, LA_SUN, LA_HEMI))
+ copy_v3_v3(lv, lar->vec);
+ negate_v3(lv);
+
+ if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADOWED) {
+ mul_v3_fl(lacol, vol_get_shadow(shi, lar, co));
+ }
+ else if (ELEM(shi->mat->vol.shade_type, MA_VOL_SHADE_SHADED, MA_VOL_SHADE_MULTIPLE, MA_VOL_SHADE_SHADEDPLUSMULTIPLE)) {
+ Isect is;
+
+ if (shi->mat->vol.shadeflag & MA_VOL_RECV_EXT_SHADOW) {
+ mul_v3_fl(lacol, vol_get_shadow(shi, lar, co));
+ if (IMB_colormanagement_get_luminance(lacol) < 0.001f) return;
+ }
+
+ /* find minimum of volume bounds, or lamp coord */
+ if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS)) {
+ float dist = len_v3v3(co, hitco);
+ VlakRen *vlr = (VlakRen *)is.hit.face;
+
+ /* simple internal shadowing */
+ if (vlr->mat->material_type == MA_TYPE_SURFACE) {
+ lacol[0] = lacol[1] = lacol[2] = 0.0f;
+ return;
+ }
+
+ if (ELEM(lar->type, LA_SUN, LA_HEMI))
+ /* infinite lights, can never be inside volume */
+ atten_co = hitco;
+ else if (lampdist < dist) {
+ atten_co = lar->co;
+ }
+ else
+ atten_co = hitco;
+
+ vol_get_transmittance(shi, tr, co, atten_co);
+
+ mul_v3_v3v3(lacol, lacol, tr);
+ }
+ else {
+ /* Point is on the outside edge of the volume,
+ * therefore no attenuation, full transmission.
+ * Radiance from lamp remains unchanged */
+ }
+ }
+
+ if (IMB_colormanagement_get_luminance(lacol) < 0.001f) return;
+
+ normalize_v3(lv);
+ p = vol_get_phasefunc(shi, shi->mat->vol.asymmetry, view, lv);
+
+ /* physically based scattering with non-physically based RGB gain */
+ vol_get_reflection_color(shi, ref_col, co);
+
+ lacol[0] *= p * ref_col[0];
+ lacol[1] *= p * ref_col[1];
+ lacol[2] *= p * ref_col[2];
+}
+
+/* single scattering only for now */
+void vol_get_scattering(ShadeInput *shi, float scatter_col[3], const float co[3], const float view[3])
+{
+ ListBase *lights;
+ GroupObject *go;
+ LampRen *lar;
+
+ zero_v3(scatter_col);
+
+ lights = get_lights(shi);
+ for (go = lights->first; go; go = go->next) {
+ float lacol[3] = {0.f, 0.f, 0.f};
+ lar = go->lampren;
+
+ if (lar) {
+ vol_shade_one_lamp(shi, co, view, lar, lacol);
+ add_v3_v3(scatter_col, lacol);
+ }
+ }
+}
+
+
+/*
+ * The main volumetric integrator, using an emission/absorption/scattering model.
+ *
+ * Incoming radiance =
+ *
+ * outgoing radiance from behind surface * beam transmittance/attenuation
+ * + added radiance from all points along the ray due to participating media
+ * --> radiance for each segment =
+ * (radiance added by scattering + radiance added by emission) * beam transmittance/attenuation
+ */
+
+/* For ease of use, I've also introduced a 'reflection' and 'reflection color' parameter, which isn't
+ * physically correct. This works as an RGB tint/gain on out-scattered light, but doesn't affect the light
+ * that is transmitted through the volume. While having wavelength dependent absorption/scattering is more correct,
+ * it also makes it harder to control the overall look of the volume since coloring the outscattered light results
+ * in the inverse color being transmitted through the rest of the volume.
+ */
+static void volumeintegrate(struct ShadeInput *shi, float col[4], const float co[3], const float endco[3])
+{
+ float radiance[3] = {0.f, 0.f, 0.f};
+ float tr[3] = {1.f, 1.f, 1.f};
+ float p[3] = {co[0], co[1], co[2]};
+ float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]};
+ const float stepsize = shi->mat->vol.stepsize;
+
+ float t0 = 0.f;
+ float pt0 = t0;
+ float t1 = normalize_v3(step_vec); /* returns vector length */
+
+ t0 += stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
+ p[0] += t0 * step_vec[0];
+ p[1] += t0 * step_vec[1];
+ p[2] += t0 * step_vec[2];
+ mul_v3_fl(step_vec, stepsize);
+
+ for (; t0 < t1; pt0 = t0, t0 += stepsize) {
+ const float density = vol_get_density(shi, p);
+
+ if (density > 0.00001f) {
+ float scatter_col[3] = {0.f, 0.f, 0.f}, emit_col[3];
+ const float stepd = (t0 - pt0) * density;
+
+ /* transmittance component (alpha) */
+ vol_get_transmittance_seg(shi, tr, stepsize, co, density);
+
+ if (t0 > t1 * 0.25f) {
+ /* only use depth cutoff after we've traced a little way into the volume */
+ if (IMB_colormanagement_get_luminance(tr) < shi->mat->vol.depth_cutoff) break;
+ }
+
+ vol_get_emission(shi, emit_col, p);
+
+ if (shi->obi->volume_precache) {
+ float p2[3];
+
+ p2[0] = p[0] + (step_vec[0] * 0.5f);
+ p2[1] = p[1] + (step_vec[1] * 0.5f);
+ p2[2] = p[2] + (step_vec[2] * 0.5f);
+
+ vol_get_precached_scattering(&R, shi, scatter_col, p2);
+ }
+ else
+ vol_get_scattering(shi, scatter_col, p, shi->view);
+
+ radiance[0] += stepd * tr[0] * (emit_col[0] + scatter_col[0]);
+ radiance[1] += stepd * tr[1] * (emit_col[1] + scatter_col[1]);
+ radiance[2] += stepd * tr[2] * (emit_col[2] + scatter_col[2]);
+ }
+ add_v3_v3(p, step_vec);
+ }
+
+ /* multiply original color (from behind volume) with transmittance over entire distance */
+ mul_v3_v3v3(col, tr, col);
+ add_v3_v3(col, radiance);
+
+ /* alpha <-- transmission luminance */
+ col[3] = 1.0f - IMB_colormanagement_get_luminance(tr);
+}
+
+/* the main entry point for volume shading */
+static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int inside_volume)
+{
+ float hitco[3], col[4] = {0.f, 0.f, 0.f, 0.f};
+ const float *startco, *endco;
+ int trace_behind = 1;
+ const int ztransp = ((shi->depth == 0) && (shi->mat->mode & MA_TRANSP) && (shi->mat->mode & MA_ZTRANSP));
+ Isect is;
+
+ /* check for shading an internal face a volume object directly */
+ if (inside_volume == VOL_SHADE_INSIDE)
+ trace_behind = 0;
+ else if (inside_volume == VOL_SHADE_OUTSIDE) {
+ if (shi->flippednor)
+ inside_volume = VOL_SHADE_INSIDE;
+ }
+
+ if (ztransp && inside_volume == VOL_SHADE_INSIDE) {
+ MatInside *mi;
+ int render_this = 0;
+
+ /* don't render the backfaces of ztransp volume materials.
+ *
+ * volume shading renders the internal volume from between the
+ * ' view intersection of the solid volume to the
+ * intersection on the other side, as part of the shading of
+ * the front face.
+ *
+ * Because ztransp renders both front and back faces independently
+ * this will double up, so here we prevent rendering the backface as well,
+ * which would otherwise render the volume in between the camera and the backface
+ * --matt */
+
+ for (mi = R.render_volumes_inside.first; mi; mi = mi->next) {
+ /* weak... */
+ if (mi->ma == shi->mat) render_this = 1;
+ }
+ if (!render_this) return;
+ }
+
+
+ if (inside_volume == VOL_SHADE_INSIDE) {
+ startco = shi->camera_co;
+ endco = shi->co;
+
+ if (trace_behind) {
+ if (!ztransp)
+ /* trace behind the volume object */
+ vol_trace_behind(shi, shi->vlr, endco, col);
+ }
+ else {
+ /* we're tracing through the volume between the camera
+ * and a solid surface, so use that pre-shaded radiance */
+ copy_v4_v4(col, shr->combined);
+ }
+
+ /* shade volume from 'camera' to 1st hit point */
+ volumeintegrate(shi, col, startco, endco);
+ }
+ /* trace to find a backface, the other side bounds of the volume */
+ /* (ray intersect ignores front faces here) */
+ else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) {
+ VlakRen *vlr = (VlakRen *)is.hit.face;
+
+ startco = shi->co;
+ endco = hitco;
+
+ if (!ztransp) {
+ /* if it's another face in the same material */
+ if (vlr->mat == shi->mat) {
+ /* trace behind the 2nd (raytrace) hit point */
+ vol_trace_behind(shi, (VlakRen *)is.hit.face, endco, col);
+ }
+ else {
+ shade_intersection(shi, col, &is);
+ }
+ }
+
+ /* shade volume from 1st hit point to 2nd hit point */
+ volumeintegrate(shi, col, startco, endco);
+ }
+
+ if (ztransp)
+ col[3] = col[3] > 1.f ? 1.f : col[3];
+ else
+ col[3] = 1.f;
+
+ copy_v3_v3(shr->combined, col);
+ shr->alpha = col[3];
+
+ copy_v3_v3(shr->diff, shr->combined);
+ copy_v3_v3(shr->diffshad, shr->diff);
+}
+
+/* Traces a shadow through the object,
+ * pretty much gets the transmission over a ray path */
+void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is)
+{
+ float hitco[3];
+ float tr[3] = {1.0, 1.0, 1.0};
+ Isect is = {{0}};
+ const float *startco, *endco;
+
+ memset(shr, 0, sizeof(ShadeResult));
+
+ /* if 1st hit normal is facing away from the camera,
+ * then we're inside the volume already. */
+ if (shi->flippednor) {
+ startco = last_is->start;
+ endco = shi->co;
+ }
+
+ /* trace to find a backface, the other side bounds of the volume */
+ /* (ray intersect ignores front faces here) */
+ else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH)) {
+ startco = shi->co;
+ endco = hitco;
+ }
+ else {
+ shr->combined[0] = shr->combined[1] = shr->combined[2] = 0.f;
+ shr->alpha = shr->combined[3] = 1.f;
+ return;
+ }
+
+ vol_get_transmittance(shi, tr, startco, endco);
+
+
+ /* if we hit another face in the same volume bounds */
+ /* shift raytrace coordinates to the hit point, to avoid shading volume twice */
+ /* due to idiosyncracy in ray_trace_shadow_tra() */
+ if (is.hit.ob == shi->obi) {
+ copy_v3_v3(shi->co, hitco);
+ last_is->dist += is.dist;
+ shi->vlr = (VlakRen *)is.hit.face;
+ }
+
+
+ copy_v3_v3(shr->combined, tr);
+ shr->combined[3] = 1.0f - IMB_colormanagement_get_luminance(tr);
+ shr->alpha = shr->combined[3];
+}
+
+
+/* delivers a fully filled in ShadeResult, for all passes */
+void shade_volume_outside(ShadeInput *shi, ShadeResult *shr)
+{
+ memset(shr, 0, sizeof(ShadeResult));
+ volume_trace(shi, shr, VOL_SHADE_OUTSIDE);
+}
+
+
+void shade_volume_inside(ShadeInput *shi, ShadeResult *shr)
+{
+ MatInside *m;
+ Material *mat_backup;
+ ObjectInstanceRen *obi_backup;
+ float prev_alpha = shr->alpha;
+
+ /* XXX: extend to multiple volumes perhaps later */
+ mat_backup = shi->mat;
+ obi_backup = shi->obi;
+
+ m = R.render_volumes_inside.first;
+ shi->mat = m->ma;
+ shi->obi = m->obi;
+ shi->obr = m->obi->obr;
+
+ volume_trace(shi, shr, VOL_SHADE_INSIDE);
+
+ shr->alpha = shr->alpha + prev_alpha;
+ CLAMP(shr->alpha, 0.0f, 1.0f);
+
+ shi->mat = mat_backup;
+ shi->obi = obi_backup;
+ shi->obr = obi_backup->obr;
+}
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
new file mode 100644
index 00000000000..2daa4123536
--- /dev/null
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -0,0 +1,571 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Raul Fernandez Hernandez (Farsthary), Matt Ebb.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/voxeldata.c
+ * \ingroup render
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
+#include "BLI_voxel.h"
+#include "BLI_utildefines.h"
+
+#include "BLT_translation.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "BKE_cloth.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_modifier.h"
+
+#include "smoke_API.h"
+#include "BPH_mass_spring.h"
+
+#include "DNA_texture_types.h"
+#include "DNA_object_force_types.h"
+#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_smoke_types.h"
+
+
+#include "render_types.h"
+#include "texture.h"
+#include "voxeldata.h"
+
+static bool is_vd_res_ok(VoxelData *vd)
+{
+ /* arbitrary large value so corrupt headers don't break */
+ const int min = 1, max = 100000;
+ return (vd->resol[0] >= min && vd->resol[0] <= max) &&
+ (vd->resol[1] >= min && vd->resol[1] <= max) &&
+ (vd->resol[2] >= min && vd->resol[2] <= max);
+}
+
+/* use size_t because the result may exceed INT_MAX */
+static size_t vd_resol_size(VoxelData *vd)
+{
+ return (size_t)vd->resol[0] * (size_t)vd->resol[1] * (size_t)vd->resol[2];
+}
+
+static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame)
+{
+ const size_t size = vd_resol_size(vd);
+ size_t offset = sizeof(VoxelDataHeader);
+
+ if (is_vd_res_ok(vd) == false)
+ return 0;
+
+ vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset");
+ if (vd->dataset == NULL) return 0;
+
+ if (fseek(fp, frame * size * sizeof(float) + offset, 0) == -1)
+ return 0;
+ if (fread(vd->dataset, sizeof(float), size, fp) != size)
+ return 0;
+
+ vd->cachedframe = frame;
+ vd->ok = 1;
+ return 1;
+}
+
+static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame)
+{
+ const size_t size = vd_resol_size(vd);
+ size_t i;
+ char *data_c;
+
+ if (is_vd_res_ok(vd) == false)
+ return 0;
+
+ vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset");
+ if (vd->dataset == NULL) return 0;
+ data_c = (char *)MEM_mallocN(sizeof(char) * size, "temporary voxel file reading storage");
+ if (data_c == NULL) {
+ MEM_freeN(vd->dataset);
+ vd->dataset = NULL;
+ return 0;
+ }
+
+ if (fseek(fp, (frame - 1) * size * sizeof(char), 0) == -1) {
+ MEM_freeN(data_c);
+ MEM_freeN(vd->dataset);
+ vd->dataset = NULL;
+ return 0;
+ }
+ if (fread(data_c, sizeof(char), size, fp) != size) {
+ MEM_freeN(data_c);
+ MEM_freeN(vd->dataset);
+ vd->dataset = NULL;
+ return 0;
+ }
+
+ for (i = 0; i < size; i++) {
+ vd->dataset[i] = (float)data_c[i] / 255.f;
+ }
+ MEM_freeN(data_c);
+
+ vd->cachedframe = frame;
+ vd->ok = 1;
+ return 1;
+}
+
+static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
+{
+ ImBuf *ibuf;
+ Image *ima = tex->ima;
+ ImageUser *tiuser = &tex->iuser;
+ ImageUser iuser = *(tiuser);
+ int x = 0, y = 0, z = 0;
+ const float *rf;
+
+ if (!ima) return;
+ if (iuser.frames == 0) return;
+
+ ima->source = IMA_SRC_SEQUENCE;
+ iuser.framenr = 1 + iuser.offset;
+
+ /* find the first valid ibuf and use it to initialize the resolution of the data set */
+ /* need to do this in advance so we know how much memory to allocate */
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ while (!ibuf && (iuser.framenr < iuser.frames)) {
+ iuser.framenr++;
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ }
+ if (!ibuf) return;
+ if (!ibuf->rect_float) IMB_float_from_rect(ibuf);
+
+ vd->flag |= TEX_VD_STILL;
+ vd->resol[0] = ibuf->x;
+ vd->resol[1] = ibuf->y;
+ vd->resol[2] = iuser.frames;
+ vd->dataset = MEM_mapallocN(sizeof(float) * vd_resol_size(vd), "voxel dataset");
+
+ for (z = 0; z < iuser.frames; z++) {
+ /* get a new ibuf for each frame */
+ if (z > 0) {
+ iuser.framenr++;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ if (!ibuf) break;
+ if (!ibuf->rect_float) IMB_float_from_rect(ibuf);
+ }
+ rf = ibuf->rect_float;
+
+ for (y = 0; y < ibuf->y; y++) {
+ for (x = 0; x < ibuf->x; x++) {
+ /* currently averaged to monchrome */
+ vd->dataset[BLI_VOXEL_INDEX(x, y, z, vd->resol)] = (rf[0] + rf[1] + rf[2]) / 3.0f;
+ rf += 4;
+ }
+ }
+
+ BKE_image_free_anim_ibufs(ima, iuser.framenr);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
+ vd->ok = 1;
+ return;
+}
+
+static int read_voxeldata_header(FILE *fp, struct VoxelData *vd)
+{
+ VoxelDataHeader *h = (VoxelDataHeader *)MEM_mallocN(sizeof(VoxelDataHeader), "voxel data header");
+
+ rewind(fp);
+ if (fread(h, sizeof(VoxelDataHeader), 1, fp) != 1) {
+ MEM_freeN(h);
+ return 0;
+ }
+
+ vd->resol[0] = h->resolX;
+ vd->resol[1] = h->resolY;
+ vd->resol[2] = h->resolZ;
+
+ MEM_freeN(h);
+ return 1;
+}
+
+static void init_frame_smoke(VoxelData *vd, int cfra)
+{
+#ifdef WITH_SMOKE
+ Object *ob;
+ ModifierData *md;
+
+ vd->dataset = NULL;
+ if (vd->object == NULL) return;
+ ob = vd->object;
+
+ /* draw code for smoke */
+ if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) {
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+ SmokeDomainSettings *sds = smd->domain;
+
+ if (sds && sds->fluid) {
+ BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
+
+ if (!sds->fluid) {
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ return;
+ }
+
+ if (cfra < sds->point_cache[0]->startframe)
+ ; /* don't show smoke before simulation starts, this could be made an option in the future */
+ else if (vd->smoked_type == TEX_VD_SMOKEHEAT) {
+ size_t totRes;
+ size_t i;
+ float *heat;
+
+ if (!smoke_has_heat(sds->fluid)) {
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ return;
+ }
+
+ copy_v3_v3_int(vd->resol, sds->res);
+ totRes = vd_resol_size(vd);
+ vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data");
+ /* get heat data */
+ heat = smoke_get_heat(sds->fluid);
+
+ /* scale heat values from -2.0-2.0 to 0.0-1.0 */
+ for (i = 0; i < totRes; i++) {
+ vd->dataset[i] = (heat[i] + 2.0f) / 4.0f;
+ }
+ }
+ else if (vd->smoked_type == TEX_VD_SMOKEVEL) {
+ size_t totRes;
+ size_t i;
+ float *xvel, *yvel, *zvel;
+
+ copy_v3_v3_int(vd->resol, sds->res);
+ totRes = vd_resol_size(vd);
+ vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data");
+ /* get velocity data */
+ xvel = smoke_get_velocity_x(sds->fluid);
+ yvel = smoke_get_velocity_y(sds->fluid);
+ zvel = smoke_get_velocity_z(sds->fluid);
+
+ /* map velocities between 0 and 0.3f */
+ for (i = 0; i < totRes; i++) {
+ vd->dataset[i] = sqrtf(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f;
+ }
+
+ }
+ else if (vd->smoked_type == TEX_VD_SMOKEFLAME) {
+ size_t totRes;
+ float *flame;
+
+ if (sds->flags & MOD_SMOKE_HIGHRES) {
+ if (!smoke_turbulence_has_fuel(sds->wt)) {
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ return;
+ }
+ smoke_turbulence_get_res(sds->wt, vd->resol);
+ flame = smoke_turbulence_get_flame(sds->wt);
+ }
+ else {
+ if (!smoke_has_fuel(sds->fluid)) {
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ return;
+ }
+ copy_v3_v3_int(vd->resol, sds->res);
+ flame = smoke_get_flame(sds->fluid);
+ }
+
+ /* always store copy, as smoke internal data can change */
+ totRes = vd_resol_size(vd);
+ vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data");
+ memcpy(vd->dataset, flame, sizeof(float)*totRes);
+ }
+ else {
+ size_t totCells;
+ int depth = 4;
+ vd->data_type = TEX_VD_RGBA_PREMUL;
+
+ /* data resolution */
+ if (sds->flags & MOD_SMOKE_HIGHRES) {
+ smoke_turbulence_get_res(sds->wt, vd->resol);
+ }
+ else {
+ copy_v3_v3_int(vd->resol, sds->res);
+ }
+
+ /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */
+ totCells = vd_resol_size(vd) * depth;
+ /* always store copy, as smoke internal data can change */
+ vd->dataset = MEM_mapallocN(sizeof(float) * totCells, "smoke data");
+
+ if (sds->flags & MOD_SMOKE_HIGHRES) {
+ if (smoke_turbulence_has_colors(sds->wt)) {
+ smoke_turbulence_get_rgba(sds->wt, vd->dataset, 1);
+ }
+ else {
+ smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, vd->dataset, 1);
+ }
+ }
+ else {
+ if (smoke_has_colors(sds->fluid)) {
+ smoke_get_rgba(sds->fluid, vd->dataset, 1);
+ }
+ else {
+ smoke_get_rgba_from_density(sds->fluid, sds->active_color, vd->dataset, 1);
+ }
+ }
+ } /* end of fluid condition */
+
+ BLI_rw_mutex_unlock(sds->fluid_mutex);
+ }
+ }
+
+ vd->ok = 1;
+
+#else // WITH_SMOKE
+ (void)vd;
+ (void)cfra;
+
+ vd->dataset = NULL;
+#endif
+}
+
+static void init_frame_hair(VoxelData *vd, int UNUSED(cfra))
+{
+ Object *ob;
+ ModifierData *md;
+
+ vd->dataset = NULL;
+ if (vd->object == NULL) return;
+ ob = vd->object;
+
+ if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_ParticleSystem))) {
+ ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
+
+ if (pmd->psys && pmd->psys->clmd) {
+ vd->ok |= BPH_cloth_solver_get_texture_data(ob, pmd->psys->clmd, vd);
+ }
+ }
+}
+
+void cache_voxeldata(Tex *tex, int scene_frame)
+{
+ VoxelData *vd = tex->vd;
+ FILE *fp;
+ int curframe;
+ char path[sizeof(vd->source_path)];
+
+ /* only re-cache if dataset needs updating */
+ if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == scene_frame))
+ if (vd->ok) return;
+
+ /* clear out old cache, ready for new */
+ if (vd->dataset) {
+ MEM_freeN(vd->dataset);
+ vd->dataset = NULL;
+ }
+ /* reset data_type */
+ vd->data_type = TEX_VD_INTENSITY;
+
+ if (vd->flag & TEX_VD_STILL)
+ curframe = vd->still_frame;
+ else
+ curframe = scene_frame;
+
+ BLI_strncpy(path, vd->source_path, sizeof(path));
+
+ /* each type is responsible for setting to true */
+ vd->ok = false;
+
+ switch (vd->file_format) {
+ case TEX_VD_IMAGE_SEQUENCE:
+ load_frame_image_sequence(vd, tex);
+ return;
+ case TEX_VD_SMOKE:
+ init_frame_smoke(vd, scene_frame);
+ return;
+ case TEX_VD_HAIR:
+ init_frame_hair(vd, scene_frame);
+ return;
+ case TEX_VD_BLENDERVOXEL:
+ BLI_path_abs(path, BKE_main_blendfile_path_from_global());
+ fp = BLI_fopen(path, "rb");
+ if (!fp) return;
+
+ if (read_voxeldata_header(fp, vd))
+ load_frame_blendervoxel(vd, fp, curframe - 1);
+
+ fclose(fp);
+ return;
+ case TEX_VD_RAW_8BIT:
+ BLI_path_abs(path, BKE_main_blendfile_path_from_global());
+ fp = BLI_fopen(path, "rb");
+ if (!fp) return;
+
+ load_frame_raw8(vd, fp, curframe);
+ fclose(fp);
+ return;
+ }
+}
+
+void make_voxeldata(struct Render *re)
+{
+ Tex *tex;
+
+ re->i.infostr = IFACE_("Loading voxel datasets");
+ re->stats_draw(re->sdh, &re->i);
+
+ /* XXX: should be doing only textures used in this render */
+ for (tex = re->main->tex.first; tex; tex = tex->id.next) {
+ if (tex->id.us && tex->type == TEX_VOXELDATA) {
+ cache_voxeldata(tex, re->r.cfra);
+ }
+ }
+
+ re->i.infostr = NULL;
+ re->stats_draw(re->sdh, &re->i);
+
+}
+
+int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres)
+{
+ VoxelData *vd = tex->vd;
+ float co[3], offset[3] = {0.5, 0.5, 0.5}, a;
+ int retval = (vd->data_type == TEX_VD_RGBA_PREMUL) ? TEX_RGB : TEX_INT;
+ int depth = (vd->data_type == TEX_VD_RGBA_PREMUL) ? 4 : 1;
+ int ch;
+
+ if (vd->dataset == NULL) {
+ texres->tin = 0.0f;
+ return 0;
+ }
+
+ /* scale lookup from 0.0-1.0 (original location) to -1.0, 1.0, consistent with image texture tex coords */
+ /* in implementation this works backwards, bringing sample locations from -1.0, 1.0
+ * to the range 0.0, 1.0, before looking up in the voxel structure. */
+ copy_v3_v3(co, texvec);
+ mul_v3_fl(co, 0.5f);
+ add_v3_v3(co, offset);
+
+ /* co is now in the range 0.0, 1.0 */
+ switch (vd->extend) {
+ case TEX_CLIP:
+ {
+ if ((co[0] < 0.f || co[0] > 1.f) || (co[1] < 0.f || co[1] > 1.f) || (co[2] < 0.f || co[2] > 1.f)) {
+ texres->tin = 0.f;
+ return retval;
+ }
+ break;
+ }
+ case TEX_REPEAT:
+ {
+ co[0] = co[0] - floorf(co[0]);
+ co[1] = co[1] - floorf(co[1]);
+ co[2] = co[2] - floorf(co[2]);
+ break;
+ }
+ case TEX_EXTEND:
+ {
+ CLAMP(co[0], 0.f, 1.f);
+ CLAMP(co[1], 0.f, 1.f);
+ CLAMP(co[2], 0.f, 1.f);
+ break;
+ }
+ }
+
+ for (ch = 0; ch < depth; ch++) {
+ float *dataset = vd->dataset + ch*vd->resol[0]*vd->resol[1]*vd->resol[2];
+ float *result = &texres->tin;
+
+ if (vd->data_type == TEX_VD_RGBA_PREMUL) {
+ switch (ch) {
+ case 0:
+ result = &texres->tr;
+ break;
+ case 1:
+ result = &texres->tg;
+ break;
+ case 2:
+ result = &texres->tb;
+ break;
+ }
+ }
+
+ switch (vd->interp_type) {
+ case TEX_VD_NEARESTNEIGHBOR:
+ *result = BLI_voxel_sample_nearest(dataset, vd->resol, co);
+ break;
+ case TEX_VD_LINEAR:
+ *result = BLI_voxel_sample_trilinear(dataset, vd->resol, co);
+ break;
+ case TEX_VD_QUADRATIC:
+ *result = BLI_voxel_sample_triquadratic(dataset, vd->resol, co);
+ break;
+ case TEX_VD_TRICUBIC_CATROM:
+ case TEX_VD_TRICUBIC_BSPLINE:
+ *result = BLI_voxel_sample_tricubic(dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE));
+ break;
+ }
+ }
+
+ a = texres->tin;
+ texres->tin *= vd->int_multiplier;
+ BRICONT;
+
+ if (vd->data_type == TEX_VD_RGBA_PREMUL) {
+ /* unmultiply */
+ if (a>0.001f) {
+ texres->tr /= a;
+ texres->tg /= a;
+ texres->tb /= a;
+ }
+ texres->talpha = 1;
+ }
+ else {
+ texres->tr = texres->tin;
+ texres->tg = texres->tin;
+ texres->tb = texres->tin;
+ }
+
+ texres->ta = texres->tin;
+ BRICONTRGB;
+
+ return retval;
+}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 3837383c4c7..436ee590f5c 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -54,10 +54,10 @@
void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
{
memset(zspan, 0, sizeof(ZSpan));
-
+
zspan->rectx= rectx;
zspan->recty= recty;
-
+
zspan->span1= MEM_mallocN(recty*sizeof(float), "zspan");
zspan->span2= MEM_mallocN(recty*sizeof(float), "zspan");
}
@@ -85,27 +85,27 @@ static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
float *span;
float xx1, dx0, xs0;
int y, my0, my2;
-
+
if (v1[1]<v2[1]) {
minv= v1; maxv= v2;
}
else {
minv= v2; maxv= v1;
}
-
+
my0= ceil(minv[1]);
my2= floor(maxv[1]);
-
+
if (my2<0 || my0>= zspan->recty) return;
-
+
/* clip top */
if (my2>=zspan->recty) my2= zspan->recty-1;
/* clip bottom */
if (my0<0) my0= 0;
-
+
if (my0>my2) return;
/* if (my0>my2) should still fill in, that way we get spans that skip nicely */
-
+
xx1= maxv[1]-minv[1];
if (xx1>FLT_EPSILON) {
dx0= (minv[0]-maxv[0])/xx1;
@@ -115,7 +115,7 @@ static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
dx0 = 0.0f;
xs0 = min_ff(minv[0], maxv[0]);
}
-
+
/* empty span */
if (zspan->maxp1 == NULL) {
span= zspan->span1;
@@ -158,9 +158,9 @@ static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
}
}
-/*-----------------------------------------------------------*/
+/*-----------------------------------------------------------*/
/* Functions */
-/*-----------------------------------------------------------*/
+/*-----------------------------------------------------------*/
/* scanconvert for strand triangles, calls func for each x, y coordinate and gives UV barycentrics and z */
@@ -170,30 +170,30 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
float u, v, uxd, uyd, vxd, vyd, uy0, vy0, xx1;
const float *span1, *span2;
int i, j, x, y, sn1, sn2, rectx = zspan->rectx, my0, my2;
-
+
/* init */
zbuf_init_span(zspan);
-
+
/* set spans */
zbuf_add_to_span(zspan, v1, v2);
zbuf_add_to_span(zspan, v2, v3);
zbuf_add_to_span(zspan, v3, v1);
-
+
/* clipped */
if (zspan->minp2==NULL || zspan->maxp2==NULL) return;
-
+
my0 = max_ii(zspan->miny1, zspan->miny2);
my2 = min_ii(zspan->maxy1, zspan->maxy2);
-
+
// printf("my %d %d\n", my0, my2);
if (my2<my0) return;
-
+
/* ZBUF DX DY, in floats still */
x1= v1[0]- v2[0];
x2= v2[0]- v3[0];
y1= v1[1]- v2[1];
y2= v2[1]- v3[1];
-
+
z1= 1.0f; /* (u1 - u2) */
z2= 0.0f; /* (u2 - u3) */
@@ -213,28 +213,28 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
x0= y1*z2-z1*y2;
y0= z1*x2-x1*z2;
-
+
xx1= (x0*v1[0] + y0*v1[1])/z0;
vxd= -(double)x0/(double)z0;
vyd= -(double)y0/(double)z0;
vy0= ((double)my2)*vyd + (double)xx1;
-
+
/* correct span */
span1= zspan->span1+my2;
span2= zspan->span2+my2;
-
+
for (i = 0, y = my2; y >= my0; i++, y--, span1--, span2--) {
-
+
sn1= floor(min_ff(*span1, *span2));
sn2= floor(max_ff(*span1, *span2));
- sn1++;
-
+ sn1++;
+
if (sn2>=rectx) sn2= rectx-1;
if (sn1<0) sn1= 0;
-
+
u = (((double)sn1 * uxd) + uy0) - (i * uyd);
v = (((double)sn1 * vxd) + vy0) - (i * vyd);
-
+
for (j = 0, x = sn1; x <= sn2; j++, x++) {
func(handle, x, y, u + (j * uxd), v + (j * vxd));
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 21e050e8e14..267aa448dc3 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -142,7 +142,7 @@ enum {
struct wmWindow *WM_window_open(struct bContext *C, const struct rcti *rect);
struct wmWindow *WM_window_open_temp(struct bContext *C, int x, int y, int sizex, int sizey, int type);
void WM_window_set_dpi(wmWindow *win);
-
+
bool WM_stereo3d_enabled(struct wmWindow *win, bool only_fullscreen_test);
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
index 04ea8611dcc..9390db400d2 100644
--- a/source/blender/windowmanager/WM_keymap.h
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -58,9 +58,9 @@ void WM_keyconfig_update_operatortype(void);
void WM_keymap_init (struct bContext *C);
void WM_keymap_free (struct wmKeyMap *keymap);
-wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type,
+wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type,
int val, int modifier, int keymodifier);
-wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type,
+wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type,
int val, int modifier, int keymodifier);
wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type,
int val, int modifier, int keymodifier);
@@ -79,7 +79,7 @@ wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap);
wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname);
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);
int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 81018348ca0..929617aab04 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -200,6 +200,7 @@ typedef enum eOperatorPropTags {
#define KM_RELEASE 2
#define KM_CLICK 3
#define KM_DBL_CLICK 4
+#define KM_CLICK_DRAG 5
/* ************** UI Handler ***************** */
@@ -211,14 +212,14 @@ typedef enum eOperatorPropTags {
typedef struct wmNotifier {
struct wmNotifier *next, *prev;
-
+
struct wmWindowManager *wm;
struct wmWindow *window;
-
+
unsigned int category, data, subtype, action;
-
+
void *reference;
-
+
} wmNotifier;
@@ -335,7 +336,7 @@ typedef struct wmNotifier {
/* NC_TEXT Text */
#define ND_CURSOR (50<<16)
#define ND_DISPLAY (51<<16)
-
+
/* NC_ANIMATION Animato */
#define ND_KEYFRAME (70<<16)
#define ND_KEYFRAME_PROP (71<<16)
@@ -433,7 +434,7 @@ typedef struct wmGesture {
uint is_active : 1;
/* Use for gestures that support both immediate or delayed activation. */
uint wait_for_input : 1;
-
+
void *customdata;
/* customdata for border is a recti */
/* customdata for circle is recti, (xmin, ymin) is center, xmax radius */
@@ -451,7 +452,7 @@ typedef struct wmGesture {
/* event comes from eventmanager and from keymap */
typedef struct wmEvent {
struct wmEvent *next, *prev;
-
+
short type; /* event code itself (short, is also in keymap) */
short val; /* press, release, scrollvalue */
int x, y; /* mouse pointer position, screen coord */
@@ -468,13 +469,14 @@ typedef struct wmEvent {
int prevx, prevy;
double prevclicktime;
int prevclickx, prevclicky;
-
+
/* modifier states */
short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */
short keymodifier; /* rawkey modifier */
-
+
/* set in case a KM_PRESS went by unhandled */
char check_click;
+ char check_drag;
char is_motion_absolute;
/* keymap item, set by handler (weak?) */
@@ -488,7 +490,7 @@ typedef struct wmEvent {
short customdatafree;
int pad2;
void *customdata; /* ascii, unicode, mouse coords, angles, vectors, dragdrop info */
-
+
} wmEvent;
/* ************** custom wmEvent data ************** */
@@ -527,17 +529,17 @@ typedef enum { /* Timer flags */
typedef struct wmTimer {
struct wmTimer *next, *prev;
-
+
struct wmWindow *win; /* window this timer is attached to (optional) */
double timestep; /* set by timer user */
int event_type; /* set by timer user, goes to event system */
wmTimerFlags flags; /* Various flags controlling timer options, see below. */
void *customdata; /* set by timer user, to allow custom values */
-
+
double duration; /* total running time in seconds */
double delta; /* time since previous step in seconds */
-
+
double ltime; /* internal, last time timer was activated */
double ntime; /* internal, next time we want to activate the timer */
double stime; /* internal, when the timer started */
@@ -653,16 +655,16 @@ typedef enum wmDragFlags {
typedef struct wmDrag {
struct wmDrag *next, *prev;
-
+
int icon, type; /* type, see WM_DRAG defines above */
void *poin;
char path[1024]; /* FILE_MAX */
double value;
-
+
struct ImBuf *imb; /* if no icon but imbuf should be drawn around cursor */
float scale;
int sx, sy;
-
+
char opname[200]; /* if set, draws operator name*/
unsigned int flags;
} wmDrag;
@@ -671,13 +673,13 @@ typedef struct wmDrag {
/* allocation and free is on startup and exit */
typedef struct wmDropBox {
struct wmDropBox *next, *prev;
-
+
/* test if the dropbox is active, then can print optype name */
int (*poll)(struct bContext *, struct wmDrag *, const wmEvent *);
/* before exec, this copies drag info to wmDrop properties */
void (*copy)(struct wmDrag *, struct wmDropBox *);
-
+
/* if poll survives, operator is called */
wmOperatorType *ot; /* not saved in file, so can be pointer */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index b6a12acd57d..6a42bf26a97 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -106,7 +106,7 @@ void WM_operator_free(wmOperator *op)
WM_operator_free(opm);
}
}
-
+
MEM_freeN(op);
}
@@ -192,11 +192,11 @@ void wm_operator_register(bContext *C, wmOperator *op)
void WM_operator_stack_clear(wmWindowManager *wm)
{
wmOperator *op;
-
+
while ((op = BLI_pophead(&wm->operators))) {
WM_operator_free(op);
}
-
+
WM_main_add_notifier(NC_WM | ND_HISTORY, NULL);
}
@@ -372,7 +372,7 @@ void WM_keymap_init(bContext *C)
wm->addonconf = WM_keyconfig_new(wm, "Blender Addon");
if (!wm->userconf)
wm->userconf = WM_keyconfig_new(wm, "Blender User");
-
+
/* initialize only after python init is done, for keymaps that
* use python operators */
if (CTX_py_init_get(C) && (wm->initialized & WM_KEYMAP_IS_INITIALIZED) == 0) {
@@ -394,8 +394,9 @@ void WM_keymap_init(bContext *C)
void WM_check(bContext *C)
{
+ Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
-
+
/* wm context */
if (wm == NULL) {
wm = CTX_data_main(C)->wm.first;
@@ -424,7 +425,7 @@ void WM_check(bContext *C)
/* case: fileread */
/* note: this runs in bg mode to set the screen context cb */
if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) {
- ED_screens_initialize(wm);
+ ED_screens_initialize(bmain, wm);
wm->initialized |= WM_WINDOW_IS_INITIALIZED;
}
}
@@ -433,7 +434,7 @@ void wm_clear_default_size(bContext *C)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win;
-
+
/* wm context */
if (wm == NULL) {
wm = CTX_data_main(C)->wm.first;
@@ -443,7 +444,7 @@ void wm_clear_default_size(bContext *C)
if (wm == NULL || BLI_listbase_is_empty(&wm->windows)) {
return;
}
-
+
for (win = wm->windows.first; win; win = win->next) {
win->sizex = 0;
win->sizey = 0;
@@ -489,7 +490,7 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
WM_window_set_active_workspace(win, NULL); /* prevent draw clear to use screen */
wm_window_free(C, wm, win);
}
-
+
while ((op = BLI_pophead(&wm->operators))) {
WM_operator_free(op);
}
@@ -507,7 +508,7 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
BLI_freelistN(&wm->paintcursors);
WM_drag_free_list(&wm->drags);
-
+
wm_reports_free(wm);
if (wm->undo_stack) {
@@ -537,16 +538,16 @@ void WM_main(bContext *C)
wm_event_do_refresh_wm_and_depsgraph(C);
while (1) {
-
+
/* get events from ghost, handle window events, add to window queues */
- wm_window_process_events(C);
-
+ wm_window_process_events(C);
+
/* per window, all events to the window, screen, area and region handlers */
wm_event_do_handlers(C);
-
+
/* events have left notes about changes, we handle and cache it */
wm_event_do_notifiers(C);
-
+
/* execute cached changes draw */
wm_draw_update(C);
}
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index 67b04662154..f13dac9cb4c 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -41,7 +41,7 @@
#include "BLI_sys_types.h"
#include "DNA_listBase.h"
-#include "DNA_userdef_types.h"
+#include "DNA_userdef_types.h"
#include "DNA_workspace_types.h"
#include "BKE_context.h"
@@ -58,7 +58,7 @@
/* Some simple ghost <-> blender conversions */
-static GHOST_TStandardCursor convert_cursor(int curs)
+static GHOST_TStandardCursor convert_cursor(int curs)
{
switch (curs) {
default:
@@ -79,23 +79,23 @@ static GHOST_TStandardCursor convert_cursor(int curs)
}
}
-static void window_set_custom_cursor(wmWindow *win, unsigned char mask[16][2],
+static void window_set_custom_cursor(wmWindow *win, unsigned char mask[16][2],
unsigned char bitmap[16][2], int hotx, int hoty)
{
GHOST_SetCustomCursorShape(win->ghostwin, bitmap, mask, hotx, hoty);
}
-static void window_set_custom_cursor_ex(wmWindow *win, BCursor *cursor, int useBig)
+static void window_set_custom_cursor_ex(wmWindow *win, BCursor *cursor, int useBig)
{
if (useBig) {
- GHOST_SetCustomCursorShapeEx(win->ghostwin,
+ GHOST_SetCustomCursorShapeEx(win->ghostwin,
(GHOST_TUns8 *)cursor->big_bm, (GHOST_TUns8 *)cursor->big_mask,
cursor->big_sizex, cursor->big_sizey,
cursor->big_hotx, cursor->big_hoty,
cursor->fg_color, cursor->bg_color);
}
else {
- GHOST_SetCustomCursorShapeEx(win->ghostwin,
+ GHOST_SetCustomCursorShapeEx(win->ghostwin,
(GHOST_TUns8 *)cursor->small_bm, (GHOST_TUns8 *)cursor->small_mask,
cursor->small_sizex, cursor->small_sizey,
cursor->small_hotx, cursor->small_hoty,
@@ -132,12 +132,12 @@ void WM_cursor_set(wmWindow *win, int curs)
#endif
GHOST_SetCursorVisibility(win->ghostwin, 1);
-
+
if (curs == CURSOR_STD && win->modalcursor)
curs = win->modalcursor;
-
+
win->cursor = curs;
-
+
/* detect if we use system cursor or Blender cursor */
if (curs >= BC_GHOST_CURSORS) {
GHOST_SetCursorShape(win->ghostwin, convert_cursor(curs));
@@ -196,7 +196,7 @@ void WM_cursor_wait(bool val)
if (!G.background) {
wmWindowManager *wm = G.main->wm.first;
wmWindow *win = wm ? wm->windows.first : NULL;
-
+
for (; win; win = win->next) {
if (val) {
WM_cursor_modal_set(win, BC_WAITCURSOR);
@@ -214,7 +214,7 @@ void WM_cursor_wait(bool val)
void WM_cursor_grab_enable(wmWindow *win, bool wrap, bool hide, int bounds[4])
{
/* Only grab cursor when not running debug.
- * It helps not to get a stuck WM when hitting a breakpoint
+ * It helps not to get a stuck WM when hitting a breakpoint
* */
GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
@@ -222,7 +222,7 @@ void WM_cursor_grab_enable(wmWindow *win, bool wrap, bool hide, int bounds[4])
wm_cursor_position_to_ghost(win, &bounds[0], &bounds[1]);
wm_cursor_position_to_ghost(win, &bounds[2], &bounds[3]);
}
-
+
if (hide) {
mode = GHOST_kGrabHide;
}
@@ -311,12 +311,12 @@ void WM_cursor_time(wmWindow *win, int nr)
unsigned char mask[16][2];
unsigned char bitmap[16][2] = {{0}};
int i, idx;
-
+
if (win->lastcursor == 0)
win->lastcursor = win->cursor;
-
+
memset(&mask, 0xFF, sizeof(mask));
-
+
/* print number bottom right justified */
for (idx = 3; nr && idx >= 0; idx--) {
const char *digit = number_bitmaps[nr % 10];
@@ -327,7 +327,7 @@ void WM_cursor_time(wmWindow *win, int nr)
bitmap[i + y * 8][x] = digit[i];
nr /= 10;
}
-
+
window_set_custom_cursor(win, mask, bitmap, 7, 7);
}
@@ -441,7 +441,7 @@ BEGIN_CURSOR_BLOCK
};
BlenderCursor[BC_NS_ARROWCURSOR] = &NSArrowCursor;
-
+
END_CURSOR_BLOCK
/********************** EW_ARROW Cursor *************************/
BEGIN_CURSOR_BLOCK
@@ -462,7 +462,7 @@ BEGIN_CURSOR_BLOCK
static BCursor EWArrowCursor = {
/*small*/
ew_sbm, ew_smsk,
- 16, 16,
+ 16, 16,
7, 6,
/*big*/
NULL, NULL,
@@ -532,7 +532,7 @@ BEGIN_CURSOR_BLOCK
static BCursor WaitCursor = {
/*small*/
wait_sbm, wait_smsk,
- 16, 16,
+ 16, 16,
7, 7,
/*big*/
wait_lbm, wait_lmsk,
@@ -601,7 +601,7 @@ BEGIN_CURSOR_BLOCK
static BCursor CrossCursor = {
/*small*/
cross_sbm, cross_smsk,
- 16, 16,
+ 16, 16,
7, 7,
/*big*/
cross_lbm, cross_lmsk,
@@ -633,7 +633,7 @@ BEGIN_CURSOR_BLOCK
static BCursor EditCrossCursor = {
/*small*/
editcross_sbm, editcross_smsk,
- 16, 16,
+ 16, 16,
9, 8,
/*big*/
NULL, NULL,
@@ -666,7 +666,7 @@ BEGIN_CURSOR_BLOCK
static BCursor BoxSelCursor = {
/*small*/
box_sbm, box_smsk,
- 16, 16,
+ 16, 16,
9, 8,
/*big*/
NULL, NULL,
@@ -738,7 +738,7 @@ BEGIN_CURSOR_BLOCK
static BCursor KnifeCursor = {
/*small*/
knife_sbm, knife_smsk,
- 16, 16,
+ 16, 16,
0, 15,
/*big*/
knife_lbm, knife_lmsk,
@@ -751,7 +751,7 @@ BEGIN_CURSOR_BLOCK
BlenderCursor[BC_KNIFECURSOR] = &KnifeCursor;
END_CURSOR_BLOCK
-
+
/********************** Loop Select Cursor ***********************/
BEGIN_CURSOR_BLOCK
@@ -814,7 +814,7 @@ BEGIN_CURSOR_BLOCK
static BCursor VLoopCursor = {
/*small*/
vloop_sbm, vloop_smsk,
- 16, 16,
+ 16, 16,
0, 0,
/*big*/
vloop_lbm, vloop_lmsk,
@@ -827,7 +827,7 @@ BEGIN_CURSOR_BLOCK
BlenderCursor[BC_VLOOPCURSOR] = &VLoopCursor;
END_CURSOR_BLOCK
-
+
/********************** TextEdit Cursor ***********************/
BEGIN_CURSOR_BLOCK
@@ -848,7 +848,7 @@ BEGIN_CURSOR_BLOCK
static BCursor TextEditCursor = {
/*small*/
textedit_sbm, textedit_smsk,
- 16, 16,
+ 16, 16,
9, 8,
/*big*/
NULL, NULL,
@@ -887,7 +887,7 @@ BEGIN_CURSOR_BLOCK
static BCursor PaintBrushCursor = {
/*small*/
paintbrush_sbm, paintbrush_smsk,
- 16, 16,
+ 16, 16,
0, 15,
/*big*/
NULL, NULL,
@@ -1060,7 +1060,7 @@ BEGIN_CURSOR_BLOCK
0x7e, 0x00, 0x3f, 0x00, 0x0c, 0x00, 0x04, 0x00,
};
-
+
static BCursor EyedropperCursor = {
/*small*/
eyedropper_sbm, eyedropper_smsk,
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 319ce99f700..16ed51cbd80 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -69,29 +69,29 @@ static ListBase dropboxes = {NULL, NULL};
typedef struct wmDropBoxMap {
struct wmDropBoxMap *next, *prev;
-
+
ListBase dropboxes;
short spaceid, regionid;
char idname[KMAP_MAX_NAME];
-
+
} wmDropBoxMap;
/* spaceid/regionid is zero for window drop maps */
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
{
wmDropBoxMap *dm;
-
+
for (dm = dropboxes.first; dm; dm = dm->next)
if (dm->spaceid == spaceid && dm->regionid == regionid)
if (STREQLEN(idname, dm->idname, KMAP_MAX_NAME))
return &dm->dropboxes;
-
+
dm = MEM_callocN(sizeof(struct wmDropBoxMap), "dropmap list");
BLI_strncpy(dm->idname, idname, KMAP_MAX_NAME);
dm->spaceid = spaceid;
dm->regionid = regionid;
BLI_addtail(&dropboxes, dm);
-
+
return &dm->dropboxes;
}
@@ -101,31 +101,31 @@ wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(bContext
void (*copy)(wmDrag *, wmDropBox *))
{
wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
-
+
drop->poll = poll;
drop->copy = copy;
drop->ot = WM_operatortype_find(idname, 0);
drop->opcontext = WM_OP_INVOKE_DEFAULT;
-
+
if (drop->ot == NULL) {
MEM_freeN(drop);
printf("Error: dropbox with unknown operator: %s\n", idname);
return NULL;
}
WM_operator_properties_alloc(&(drop->ptr), &(drop->properties), idname);
-
+
BLI_addtail(lb, drop);
-
+
return drop;
}
void wm_dropbox_free(void)
{
wmDropBoxMap *dm;
-
+
for (dm = dropboxes.first; dm; dm = dm->next) {
wmDropBox *drop;
-
+
for (drop = dm->dropboxes.first; drop; drop = drop->next) {
if (drop->ptr) {
WM_operator_properties_free(drop->ptr);
@@ -134,7 +134,7 @@ void wm_dropbox_free(void)
}
BLI_freelistN(&dm->dropboxes);
}
-
+
BLI_freelistN(&dropboxes);
}
@@ -145,10 +145,10 @@ wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin,
{
wmWindowManager *wm = CTX_wm_manager(C);
wmDrag *drag = MEM_callocN(sizeof(struct wmDrag), "new drag");
-
+
/* keep track of future multitouch drag too, add a mousepointer id or so */
/* if multiple drags are added, they're drawn as list */
-
+
BLI_addtail(&wm->drags, drag);
drag->flags = flags;
drag->icon = icon;
@@ -158,7 +158,7 @@ wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin,
else
drag->poin = poin;
drag->value = value;
-
+
return drag;
}
@@ -211,13 +211,13 @@ static const char *wm_dropbox_active(bContext *C, wmDrag *drag, const wmEvent *e
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
const char *name;
-
+
name = dropbox_active(C, &win->handlers, drag, event);
if (name) return name;
-
+
name = dropbox_active(C, &sa->handlers, drag, event);
if (name) return name;
-
+
name = dropbox_active(C, &ar->handlers, drag, event);
if (name) return name;
@@ -234,16 +234,16 @@ static void wm_drop_operator_options(bContext *C, wmDrag *drag, const wmEvent *e
/* for multiwin drags, we only do this if mouse inside */
if (event->x < 0 || event->y < 0 || event->x > winsize_x || event->y > winsize_y)
return;
-
+
drag->opname[0] = 0;
-
+
/* check buttons (XXX todo rna and value) */
if (UI_but_active_drop_name(C)) {
BLI_strncpy(drag->opname, IFACE_("Paste name"), sizeof(drag->opname));
}
else {
const char *opname = wm_dropbox_active(C, drag, event);
-
+
if (opname) {
BLI_strncpy(drag->opname, opname, sizeof(drag->opname));
// WM_cursor_modal_set(win, CURSOR_COPY);
@@ -259,7 +259,7 @@ void wm_drags_check_ops(bContext *C, const wmEvent *event)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmDrag *drag;
-
+
for (drag = wm->drags.first; drag; drag = drag->next) {
wm_drop_operator_options(C, drag, event);
}
@@ -312,25 +312,25 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
wmDrag *drag;
const int winsize_y = WM_window_pixels_y(win);
int cursorx, cursory, x, y;
-
+
cursorx = win->eventstate->x;
cursory = win->eventstate->y;
if (rect) {
rect->xmin = rect->xmax = cursorx;
rect->ymin = rect->ymax = cursory;
}
-
+
/* XXX todo, multiline drag draws... but maybe not, more types mixed wont work well */
glEnable(GL_BLEND);
for (drag = wm->drags.first; drag; drag = drag->next) {
int iconsize = UI_DPI_ICON_SIZE;
int padding = 4 * UI_DPI_FAC;
-
+
/* image or icon */
if (drag->imb) {
x = cursorx - drag->sx / 2;
y = cursory - drag->sy / 2;
-
+
if (rect)
drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy);
else {
@@ -343,13 +343,13 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
else {
x = cursorx - 2 * padding;
y = cursory - 2 * UI_DPI_FAC;
-
+
if (rect)
drag_rect_minmax(rect, x, y, x + iconsize, y + iconsize);
else
UI_icon_draw_aspect(x, y, drag->icon, 1.0f / UI_DPI_FAC, 0.8);
}
-
+
/* item name */
if (drag->imb) {
x = cursorx - drag->sx / 2;
@@ -359,7 +359,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
x = cursorx + 10 * UI_DPI_FAC;
y = cursory + 1 * UI_DPI_FAC;
}
-
+
if (rect) {
int w = UI_fontstyle_string_width(fstyle, wm_drag_name(drag));
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
@@ -368,7 +368,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
const unsigned char col[] = {255, 255, 255, 255};
UI_fontstyle_draw_simple(fstyle, x, y, wm_drag_name(drag), col);
}
-
+
/* operator name with roundbox */
if (drag->opname[0]) {
if (drag->imb) {
@@ -389,14 +389,14 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
y = (cursory - iconsize) - padding;
}
}
-
+
if (rect) {
int w = UI_fontstyle_string_width(fstyle, wm_drag_name(drag));
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
}
- else
+ else
wm_drop_operator_draw(drag->opname, x, y);
-
+
}
}
glDisable(GL_BLEND);
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 3ce64926a95..df958f35e91 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -755,7 +755,7 @@ static bool wm_draw_update_test_window(wmWindow *win)
if (do_draw)
return true;
-
+
if (screen->do_refresh)
return true;
if (screen->do_draw)
@@ -766,7 +766,7 @@ static bool wm_draw_update_test_window(wmWindow *win)
return true;
if (screen->do_draw_drag)
return true;
-
+
return false;
}
@@ -788,7 +788,7 @@ void wm_draw_update(bContext *C)
#endif
GPU_free_unused_buffers();
-
+
for (win = wm->windows.first; win; win = win->next) {
#ifdef WIN32
GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin);
@@ -806,7 +806,7 @@ void wm_draw_update(bContext *C)
bScreen *screen = WM_window_get_active_screen(win);
CTX_wm_window_set(C, win);
-
+
/* sets context window+screen */
wm_window_make_drawable(wm, win);
@@ -818,7 +818,7 @@ void wm_draw_update(bContext *C)
screen->do_draw_gesture = false;
screen->do_draw_paintcursor = false;
screen->do_draw_drag = false;
-
+
wm_window_swap_buffers(win);
CTX_wm_window_set(C, NULL);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 31b51fce858..1e3a08bdcbc 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -105,7 +105,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA
wmEvent *wm_event_add_ex(wmWindow *win, const wmEvent *event_to_add, const wmEvent *event_to_add_after)
{
wmEvent *event = MEM_mallocN(sizeof(wmEvent), "wmEvent");
-
+
*event = *event_to_add;
update_tablet_data(win, event);
@@ -157,7 +157,7 @@ void wm_event_free(wmEvent *event)
void wm_event_free_all(wmWindow *win)
{
wmEvent *event;
-
+
while ((event = BLI_pophead(&win->queue))) {
wm_event_free(event);
}
@@ -180,7 +180,7 @@ static bool wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, v
for (note = wm->queue.first; note; note = note->next)
if ((note->category | note->data | note->subtype | note->action) == type && note->reference == reference)
return 1;
-
+
return 0;
}
@@ -194,17 +194,17 @@ void WM_event_add_notifier(const bContext *C, unsigned int type, void *reference
return;
note = MEM_callocN(sizeof(wmNotifier), "notifier");
-
+
note->wm = wm;
BLI_addtail(&note->wm->queue, note);
-
+
note->window = CTX_wm_window(C);
-
+
note->category = type & NOTE_CATEGORY;
note->data = type & NOTE_DATA;
note->subtype = type & NOTE_SUBTYPE;
note->action = type & NOTE_ACTION;
-
+
note->reference = reference;
}
@@ -218,15 +218,15 @@ void WM_main_add_notifier(unsigned int type, void *reference)
return;
note = MEM_callocN(sizeof(wmNotifier), "notifier");
-
+
note->wm = wm;
BLI_addtail(&note->wm->queue, note);
-
+
note->category = type & NOTE_CATEGORY;
note->data = type & NOTE_DATA;
note->subtype = type & NOTE_SUBTYPE;
note->action = type & NOTE_ACTION;
-
+
note->reference = reference;
}
@@ -353,7 +353,7 @@ void wm_event_do_notifiers(bContext *C)
wmWindowManager *wm = CTX_wm_manager(C);
wmNotifier *note, *next;
wmWindow *win;
-
+
if (wm == NULL)
return;
@@ -363,9 +363,9 @@ void wm_event_do_notifiers(bContext *C)
for (win = wm->windows.first; win; win = win->next) {
Scene *scene = WM_window_get_active_scene(win);
bool do_anim = false;
-
+
CTX_wm_window_set(C, win);
-
+
for (note = wm->queue.first; note; note = next) {
next = note->next;
@@ -443,7 +443,7 @@ void wm_event_do_notifiers(bContext *C)
}
}
}
-
+
/* the notifiers are sent without context, to keep it clean */
while ((note = BLI_pophead(&wm->queue))) {
for (win = wm->windows.first; win; win = win->next) {
@@ -484,7 +484,7 @@ void wm_event_do_notifiers(bContext *C)
}
}
}
-
+
MEM_freeN(note);
}
#endif /* if 1 (postpone disabling for in favor of message-bus), eventually. */
@@ -517,8 +517,8 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, const wmEven
static bool do_wheel_ui = true;
const bool is_wheel = ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN);
int retval;
-
- /* UI code doesn't handle return values - it just always returns break.
+
+ /* UI code doesn't handle return values - it just always returns break.
* to make the DBL_CLICK conversion work, we just don't send this to UI, except mouse clicks */
if (((handler->flag & WM_HANDLER_ACCEPT_DBL_CLICK) == 0) &&
(event->type != LEFTMOUSE) &&
@@ -526,7 +526,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, const wmEven
{
return WM_HANDLER_CONTINUE;
}
-
+
/* UI is quite aggressive with swallowing events, like scrollwheel */
/* I realize this is not extremely nice code... when UI gets keymaps it can be maybe smarter */
if (do_wheel_ui == false) {
@@ -535,7 +535,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, const wmEven
else if (wm_event_always_pass(event) == 0)
do_wheel_ui = true;
}
-
+
/* we set context to where ui handler came from */
if (handler->ui_area) CTX_wm_area_set(C, handler->ui_area);
if (handler->ui_region) CTX_wm_region_set(C, handler->ui_region);
@@ -555,14 +555,14 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, const wmEven
CTX_wm_region_set(C, NULL);
CTX_wm_menu_set(C, NULL);
}
-
+
if (retval == WM_UI_HANDLER_BREAK)
return WM_HANDLER_BREAK;
-
+
/* event not handled in UI, if wheel then we temporarily disable it */
if (is_wheel)
do_wheel_ui = false;
-
+
return WM_HANDLER_CONTINUE;
}
@@ -593,14 +593,14 @@ static void wm_handler_ui_cancel(bContext *C)
int WM_operator_poll(bContext *C, wmOperatorType *ot)
{
wmOperatorTypeMacro *otmacro;
-
+
for (otmacro = ot->macro.first; otmacro; otmacro = otmacro->next) {
wmOperatorType *ot_macro = WM_operatortype_find(otmacro->idname, 0);
-
+
if (0 == WM_operator_poll(C, ot_macro))
return 0;
}
-
+
/* python needs operator type, so we added exception for it */
if (ot->pyop_poll)
return ot->pyop_poll(C, ot);
@@ -807,7 +807,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, bool ca
CTX_wm_region_set(C, ar_prev);
}
}
-
+
if (retval & OPERATOR_FINISHED) {
CLOG_STR_INFO_N(WM_LOG_OPERATORS, 1, WM_operator_pystring(C, op, false, true));
@@ -885,15 +885,15 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons
{
wmWindowManager *wm = CTX_wm_manager(C);
int retval = OPERATOR_CANCELLED;
-
+
CTX_wm_operator_poll_msg_set(C, NULL);
-
+
if (op == NULL || op->type == NULL)
return retval;
-
+
if (0 == WM_operator_poll(C, op->type))
return retval;
-
+
if (op->type->exec) {
if (op->type->flag & OPTYPE_UNDO) {
wm->op_undo_depth++;
@@ -912,13 +912,13 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons
wm->op_undo_depth--;
}
}
-
+
/* XXX Disabled the repeat check to address part 2 of #31840.
* Carefully checked all calls to wm_operator_exec and WM_operator_repeat, don't see any reason
* why this was needed, but worth to note it in case something turns bad. (mont29) */
if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED) /* && repeat == 0 */)
wm_operator_reports(C, op, retval, false);
-
+
if (retval & OPERATOR_FINISHED) {
wm_operator_finished(C, op, repeat, store && wm->op_undo_depth == 0);
}
@@ -928,9 +928,9 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons
WM_operator_free(op);
}
}
-
+
return retval | OPERATOR_HANDLED;
-
+
}
/* simply calls exec with basic checks */
@@ -1033,11 +1033,11 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot,
{
/* XXX operatortype names are static still. for debug */
wmOperator *op = MEM_callocN(sizeof(wmOperator), ot->idname);
-
+
/* XXX adding new operator could be function, only happens here now */
op->type = ot;
BLI_strncpy(op->idname, ot->idname, OP_MAX_TYPENAME);
-
+
/* initialize properties, either copy or create */
op->ptr = MEM_callocN(sizeof(PointerRNA), "wmOperatorPtrRNA");
if (properties && properties->data) {
@@ -1057,20 +1057,20 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot,
op->reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
BKE_reports_init(op->reports, RPT_STORE | RPT_FREE);
}
-
+
/* recursive filling of operator macro list */
if (ot->macro.first) {
static wmOperator *motherop = NULL;
wmOperatorTypeMacro *otmacro;
int root = 0;
-
+
/* ensure all ops are in execution order in 1 list */
if (motherop == NULL) {
motherop = op;
root = 1;
}
-
+
/* if properties exist, it will contain everything needed */
if (properties) {
otmacro = ot->macro.first;
@@ -1106,11 +1106,11 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot,
opm->opm = motherop; /* pointer to mom, for modal() */
}
}
-
+
if (root)
motherop = NULL;
}
-
+
WM_operator_properties_sanitize(op->ptr, 0);
return op;
@@ -1250,7 +1250,7 @@ static int wm_operator_invoke(
wmWindowManager *wm = CTX_wm_manager(C);
wmOperator *op = wm_operator_create(wm, ot, properties, reports); /* if reports == NULL, they'll be initialized */
const bool is_nested_call = (wm->op_undo_depth != 0);
-
+
if (event != NULL) {
op->flag |= OP_IS_INVOKE;
}
@@ -1388,7 +1388,7 @@ static int wm_operator_call_internal(
const short context, const bool poll_only)
{
wmEvent *event;
-
+
int retval;
CTX_wm_operator_poll_msg_set(C, NULL);
@@ -1421,39 +1421,39 @@ static int wm_operator_call_internal(
}
switch (context) {
-
+
case WM_OP_EXEC_REGION_WIN:
- case WM_OP_INVOKE_REGION_WIN:
+ case WM_OP_INVOKE_REGION_WIN:
case WM_OP_EXEC_REGION_CHANNELS:
case WM_OP_INVOKE_REGION_CHANNELS:
case WM_OP_EXEC_REGION_PREVIEW:
case WM_OP_INVOKE_REGION_PREVIEW:
{
/* forces operator to go to the region window/channels/preview, for header menus
- * but we stay in the same region if we are already in one
+ * but we stay in the same region if we are already in one
*/
ARegion *ar = CTX_wm_region(C);
ScrArea *area = CTX_wm_area(C);
int type = RGN_TYPE_WINDOW;
-
+
switch (context) {
case WM_OP_EXEC_REGION_CHANNELS:
case WM_OP_INVOKE_REGION_CHANNELS:
type = RGN_TYPE_CHANNELS;
break;
-
+
case WM_OP_EXEC_REGION_PREVIEW:
case WM_OP_INVOKE_REGION_PREVIEW:
type = RGN_TYPE_PREVIEW;
break;
-
+
case WM_OP_EXEC_REGION_WIN:
- case WM_OP_INVOKE_REGION_WIN:
+ case WM_OP_INVOKE_REGION_WIN:
default:
type = RGN_TYPE_WINDOW;
break;
}
-
+
if (!(ar && ar->regiontype == type) && area) {
ARegion *ar1;
if (type == RGN_TYPE_WINDOW) {
@@ -1466,12 +1466,12 @@ static int wm_operator_call_internal(
if (ar1)
CTX_wm_region_set(C, ar1);
}
-
+
retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only, true);
-
+
/* set region back */
CTX_wm_region_set(C, ar);
-
+
return retval;
}
case WM_OP_EXEC_AREA:
@@ -1506,7 +1506,7 @@ static int wm_operator_call_internal(
return wm_operator_invoke(C, ot, event, properties, reports, poll_only, true);
}
}
-
+
return 0;
}
@@ -1582,7 +1582,7 @@ int WM_operator_call_py(
if (!is_undo && wm) wm->op_undo_depth++;
retval = wm_operator_call_internal(C, ot, properties, reports, context, false);
-
+
if (!is_undo && wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--;
return retval;
@@ -1602,7 +1602,7 @@ static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wm
{
wmWindow *win = CTX_wm_window(C);
bScreen *screen = CTX_wm_screen(C);
-
+
if (screen && handler->op) {
if (handler->op_area == NULL)
CTX_wm_area_set(C, NULL);
@@ -1659,7 +1659,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
{
wmEventHandler *handler;
wmWindowManager *wm = CTX_wm_manager(C);
-
+
/* C is zero on freeing database, modal handlers then already were freed */
while ((handler = BLI_pophead(handlers))) {
if (handler->op) {
@@ -1667,7 +1667,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
if (handler->op->type->cancel) {
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
-
+
wm_handler_op_context(C, handler, win->eventstate);
if (handler->op->type->flag & OPTYPE_UNDO)
@@ -1689,7 +1689,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
ARegion *menu = CTX_wm_menu(C);
-
+
if (handler->ui_area) CTX_wm_area_set(C, handler->ui_area);
if (handler->ui_region) CTX_wm_region_set(C, handler->ui_region);
if (handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu);
@@ -1722,7 +1722,7 @@ int WM_userdef_event_map(int kmitype)
case WHEELINMOUSE:
return (U.uiflag & USER_WHEELZOOMDIR) ? WHEELDOWNMOUSE : WHEELUPMOUSE;
}
-
+
return kmitype;
}
@@ -1768,13 +1768,13 @@ static int wm_eventmatch(const wmEvent *winevent, wmKeyMapItem *kmi)
if (winevent->val == KM_PRESS) { /* prevent double clicks */
/* NOT using ISTEXTINPUT anymore because (at least on Windows) some key codes above 255
* could have printable ascii keys - BUG [#30479] */
- if (ISKEYBOARD(winevent->type) && (winevent->ascii || winevent->utf8_buf[0])) return 1;
+ if (ISKEYBOARD(winevent->type) && (winevent->ascii || winevent->utf8_buf[0])) return 1;
}
if (kmitype != KM_ANY) {
if (ELEM(kmitype, TABLET_STYLUS, TABLET_ERASER)) {
const wmTabletData *wmtab = winevent->tablet_data;
-
+
if (wmtab == NULL)
return 0;
else if (winevent->type != LEFTMOUSE) /* tablet events can occur on hover + keypress */
@@ -1789,10 +1789,10 @@ static int wm_eventmatch(const wmEvent *winevent, wmKeyMapItem *kmi)
return 0;
}
}
-
+
if (kmi->val != KM_ANY)
if (winevent->val != kmi->val) return 0;
-
+
/* modifiers also check bits, so it allows modifier order */
if (kmi->shift != KM_ANY)
if (winevent->shift != kmi->shift && !(winevent->shift & kmi->shift)) return 0;
@@ -1802,12 +1802,12 @@ static int wm_eventmatch(const wmEvent *winevent, wmKeyMapItem *kmi)
if (winevent->alt != kmi->alt && !(winevent->alt & kmi->alt)) return 0;
if (kmi->oskey != KM_ANY)
if (winevent->oskey != kmi->oskey && !(winevent->oskey & kmi->oskey)) return 0;
-
+
/* only keymap entry with keymodifier is checked, means all keys without modifier get handled too. */
/* that is currently needed to make overlapping events work (when you press A - G fast or so). */
if (kmi->keymodifier)
if (winevent->keymodifier != kmi->keymodifier) return 0;
-
+
return 1;
}
@@ -1825,12 +1825,12 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve
for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
if (wm_eventmatch(event, kmi)) {
-
+
event->prevtype = event->type;
event->prevval = event->val;
event->type = EVT_MODAL_MAP;
event->val = kmi->propvalue;
-
+
break;
}
}
@@ -1883,7 +1883,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
wmEvent *event, PointerRNA *properties)
{
int retval = OPERATOR_PASS_THROUGH;
-
+
/* derived, modal or blocking operator */
if (handler->op) {
wmOperator *op = handler->op;
@@ -1911,7 +1911,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
/* warning, after this call all context data and 'event' may be freed. see check below */
retval = ot->modal(C, op, event);
OPERATOR_RETVAL_CHECK(retval);
-
+
/* when this is _not_ the case the modal modifier may have loaded
* a new blend file (demo mode does this), so we have to assume
* the event, operator etc have all been freed. - campbell */
@@ -1979,7 +1979,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
bool use_last_properties = true;
PointerRNA tool_properties = {{0}};
bool use_tool_properties = (handler->keymap_tool != NULL);
-
+
if (use_tool_properties) {
WM_toolsystem_ref_properties_init_for_keymap(handler->keymap_tool, &tool_properties, properties, ot);
properties = &tool_properties;
@@ -2058,11 +2058,11 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
sfile->op = handler->op;
ED_fileselect_set_params(sfile);
-
+
action = WM_HANDLER_BREAK;
break;
}
-
+
case EVT_FILESELECT_EXEC:
case EVT_FILESELECT_CANCEL:
case EVT_FILESELECT_EXTERNAL_CANCEL:
@@ -2150,11 +2150,11 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
wm->op_undo_depth++;
handler->op->type->cancel(C, handler->op);
-
+
if (handler->op->type->flag & OPTYPE_UNDO)
wm->op_undo_depth--;
}
-
+
WM_operator_free(handler->op);
}
@@ -2166,19 +2166,19 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
break;
}
}
-
+
return action;
}
static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHandler *handler, const wmEvent *event)
{
int action = WM_HANDLER_CONTINUE;
-
+
if (event->type != EVT_FILESELECT)
return action;
if (handler->op != (wmOperator *)event->customdata)
return action;
-
+
return wm_handler_fileselect_do(C, handlers, handler, event->val);
}
@@ -2239,7 +2239,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
for (handler = handlers->first; handler && handlers->first; handler = nexthandler) {
nexthandler = handler->next;
-
+
/* during this loop, ui handlers for nested menus can tag multiple handlers free */
if (handler->flag & WM_HANDLER_DO_FREE) {
/* pass */
@@ -2247,7 +2247,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
else if (handler_boundbox_test(handler, event)) { /* optional boundbox */
/* in advance to avoid access to freed event on window close */
always_pass = wm_event_always_pass(event);
-
+
/* modal+blocking handler */
if (handler->flag & WM_HANDLER_BLOCKING)
action |= WM_HANDLER_BREAK;
@@ -2272,7 +2272,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
event->keymap_idname = kmi->idname;
action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
-
+
if (action & WM_HANDLER_BREAK) {
/* not always_pass here, it denotes removed handler */
CLOG_INFO(WM_LOG_HANDLERS, 2, "handled! '%s'", kmi->idname);
@@ -2315,24 +2315,24 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
if (event->custom == EVT_DATA_DRAGDROP) {
ListBase *lb = (ListBase *)event->customdata;
wmDrag *drag;
-
+
for (drag = lb->first; drag; drag = drag->next) {
if (drop->poll(C, drag, event)) {
drop->copy(drag, drop);
-
+
/* free the drags before calling operator */
WM_drag_free_list(lb);
event->customdata = NULL;
event->custom = 0;
-
+
WM_operator_name_call_ptr(C, drop->ot, drop->opcontext, drop->ptr);
action |= WM_HANDLER_BREAK;
-
+
/* XXX fileread case */
if (CTX_wm_window(C) == NULL)
return action;
-
+
/* escape from drag loop, got freed */
break;
}
@@ -2491,7 +2491,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
break;
}
}
-
+
/* XXX fileread case, if the wm is freed then the handler's
* will have been too so the code below need not run. */
if (CTX_wm_window(C) == NULL) {
@@ -2499,8 +2499,8 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
/* XXX code this for all modal ops, and ensure free only happens here */
-
- /* modal ui handler can be tagged to be freed */
+
+ /* modal ui handler can be tagged to be freed */
if (BLI_findindex(handlers, handler) != -1) { /* could be freed already by regular modal ops */
if (handler->flag & WM_HANDLER_DO_FREE) {
BLI_remlink(handlers, handler);
@@ -2521,26 +2521,56 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
{
int action = wm_handlers_do_intern(C, event, handlers);
-
+
/* fileread case */
if (CTX_wm_window(C) == NULL)
return action;
- if (!ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE, EVENT_NONE) && !ISTIMER(event->type)) {
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ if (event->check_drag) {
+ wmWindow *win = CTX_wm_window(C);
+ if ((abs(event->x - win->eventstate->prevclickx)) >= U.tweak_threshold ||
+ (abs(event->y - win->eventstate->prevclicky)) >= U.tweak_threshold)
+ {
+ short val = event->val;
+ short type = event->type;
+ event->val = KM_CLICK_DRAG;
+ event->type = win->eventstate->type;
+
+ CLOG_INFO(WM_LOG_HANDLERS, 1, "handling PRESS_DRAG");
+
+ action |= wm_handlers_do_intern(C, event, handlers);
+
+ event->val = val;
+ event->type = type;
+
+ win->eventstate->check_click = 0;
+ win->eventstate->check_drag = 0;
+ }
+ }
+ }
+ else if (ISMOUSE(event->type) || ISKEYBOARD(event->type)) {
+ /* All events that don't set wmEvent.prevtype must be ignored. */
/* test for CLICK events */
if (wm_action_not_handled(action)) {
wmWindow *win = CTX_wm_window(C);
-
- /* eventstate stores if previous event was a KM_PRESS, in case that
+
+ /* eventstate stores if previous event was a KM_PRESS, in case that
* wasn't handled, the KM_RELEASE will become a KM_CLICK */
-
- if (win && event->val == KM_PRESS) {
- win->eventstate->check_click = true;
+
+ if (win != NULL) {
+ if (event->val == KM_PRESS) {
+ win->eventstate->check_click = true;
+ win->eventstate->check_drag = true;
+ }
+ else if (event->val == KM_RELEASE) {
+ win->eventstate->check_drag = false;
+ }
}
-
+
if (win && win->eventstate->prevtype == event->type) {
-
+
if ((event->val == KM_RELEASE) &&
(win->eventstate->prevval == KM_PRESS) &&
(win->eventstate->check_click == true))
@@ -2551,19 +2581,20 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
event->val = KM_CLICK;
CLOG_INFO(WM_LOG_HANDLERS, 1, "handling CLICK");
-
+
action |= wm_handlers_do_intern(C, event, handlers);
event->val = KM_RELEASE;
}
else {
win->eventstate->check_click = 0;
+ win->eventstate->check_drag = 0;
}
}
else if (event->val == KM_DBL_CLICK) {
event->val = KM_PRESS;
action |= wm_handlers_do_intern(C, event, handlers);
-
+
/* revert value if not handled */
if (wm_action_not_handled(action)) {
event->val = KM_DBL_CLICK;
@@ -2578,7 +2609,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
win->eventstate->check_click = 0;
}
}
-
+
return action;
}
@@ -2595,7 +2626,7 @@ static ScrArea *area_event_inside(bContext *C, const int xy[2])
{
wmWindow *win = CTX_wm_window(C);
bScreen *screen = CTX_wm_screen(C);
-
+
if (screen) {
ED_screen_areas_iter(win, screen, sa) {
if (BLI_rcti_isect_pt_v(&sa->totrct, xy))
@@ -2610,7 +2641,7 @@ static ARegion *region_event_inside(bContext *C, const int xy[2])
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = CTX_wm_area(C);
ARegion *ar;
-
+
if (screen && area)
for (ar = area->regionbase.first; ar; ar = ar->next)
if (BLI_rcti_isect_pt_v(&ar->winrct, xy))
@@ -2635,22 +2666,22 @@ static void wm_paintcursor_tag(bContext *C, wmPaintCursor *pc, ARegion *ar)
static void wm_paintcursor_test(bContext *C, const wmEvent *event)
{
wmWindowManager *wm = CTX_wm_manager(C);
-
+
if (wm->paintcursors.first) {
ARegion *ar = CTX_wm_region(C);
-
+
if (ar)
wm_paintcursor_tag(C, wm->paintcursors.first, ar);
-
+
/* if previous position was not in current region, we have to set a temp new context */
if (ar == NULL || !BLI_rcti_isect_pt_v(&ar->winrct, &event->prevx)) {
ScrArea *sa = CTX_wm_area(C);
-
+
CTX_wm_area_set(C, area_event_inside(C, &event->prevx));
CTX_wm_region_set(C, region_event_inside(C, &event->prevx));
wm_paintcursor_tag(C, wm->paintcursors.first, CTX_wm_region(C));
-
+
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
}
@@ -2664,7 +2695,7 @@ static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *even
if (BLI_listbase_is_empty(&wm->drags)) {
return;
}
-
+
if (event->type == MOUSEMOVE || ISKEYMODIFIER(event->type)) {
screen->do_draw_drag = true;
}
@@ -2675,20 +2706,20 @@ static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *even
}
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
event->type = EVT_DROP;
-
+
/* create customdata, first free existing */
if (event->customdata) {
if (event->customdatafree)
MEM_freeN(event->customdata);
}
-
+
event->custom = EVT_DATA_DRAGDROP;
event->customdata = &wm->drags;
event->customdatafree = 1;
-
+
/* clear drop icon */
screen->do_draw_drag = true;
-
+
/* restore cursor (disabled, see wm_dragdrop.c) */
// WM_cursor_modal_restore(win);
}
@@ -2738,12 +2769,12 @@ void wm_event_do_handlers(bContext *C)
if (scene) {
int is_playing_sound = BKE_sound_scene_playing(scene);
-
+
if (is_playing_sound != -1) {
bool is_playing_screen;
CTX_wm_window_set(C, win);
CTX_data_scene_set(C, scene);
-
+
is_playing_screen = (ED_screen_animation_playing(wm) != NULL);
if (((is_playing_sound == 1) && (is_playing_screen == 0)) ||
@@ -2751,7 +2782,7 @@ void wm_event_do_handlers(bContext *C)
{
ED_screen_animation_play(C, -1, 1);
}
-
+
if (is_playing_sound == 0) {
const float time = BKE_sound_sync_scene(scene);
if (isfinite(time)) {
@@ -2764,14 +2795,14 @@ void wm_event_do_handlers(bContext *C)
}
}
}
-
+
CTX_data_scene_set(C, NULL);
CTX_wm_screen_set(C, NULL);
CTX_wm_window_set(C, NULL);
}
}
}
-
+
while ( (event = win->queue.first) ) {
int action = WM_HANDLER_CONTINUE;
@@ -2805,16 +2836,16 @@ void wm_event_do_handlers(bContext *C)
/* we let modal handlers get active area/region, also wm_paintcursor_test needs it */
CTX_wm_area_set(C, area_event_inside(C, &event->x));
CTX_wm_region_set(C, region_event_inside(C, &event->x));
-
+
/* MVC demands to not draw in event handlers... but we need to leave it for ogl selecting etc */
wm_window_make_drawable(wm, win);
-
+
wm_region_mouse_co(C, event);
/* first we do priority handlers, modal + some limited keymaps */
action |= wm_handlers_do(C, event, &win->modalhandlers);
-
+
/* fileread case */
if (CTX_wm_window(C) == NULL)
return;
@@ -2830,13 +2861,13 @@ void wm_event_do_handlers(bContext *C)
/* check dragging, creates new event or frees, adds draw tag */
wm_event_drag_test(wm, win, event);
-
+
/* builtin tweak, if action is break it removes tweak */
wm_tweakevent_test(C, event, action);
if ((action & WM_HANDLER_BREAK) == 0) {
ARegion *ar;
-
+
/* Note: setting subwin active should be done here, after modal handlers have been done */
if (event->type == MOUSEMOVE) {
/* state variables in screen, cursors. Also used in wm_draw.c, fails for modal handlers though */
@@ -2871,7 +2902,7 @@ void wm_event_do_handlers(bContext *C)
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (wm_event_inside_i(event, &ar->winrct)) {
CTX_wm_region_set(C, ar);
-
+
/* call even on non mouse events, since the */
wm_region_mouse_co(C, event);
@@ -2945,7 +2976,7 @@ void wm_event_do_handlers(bContext *C)
/* NOTE: do not escape on WM_HANDLER_BREAK, mousemove needs handled for previous area */
}
}
-
+
if ((action & WM_HANDLER_BREAK) == 0) {
/* also some non-modal handlers need active area/region */
CTX_wm_area_set(C, area_event_inside(C, &event->x));
@@ -2969,9 +3000,9 @@ void wm_event_do_handlers(bContext *C)
/* unlink and free here, blender-quit then frees all */
BLI_remlink(&win->queue, event);
wm_event_free(event);
-
+
}
-
+
/* only add mousemove when queue was read entirely */
if (win->addmousemove && win->eventstate) {
wmEvent tevent = *(win->eventstate);
@@ -2982,7 +3013,7 @@ void wm_event_do_handlers(bContext *C)
wm_event_add(win, &tevent);
win->addmousemove = 0;
}
-
+
CTX_wm_window_set(C, NULL);
}
@@ -2997,10 +3028,10 @@ void WM_event_fileselect_event(wmWindowManager *wm, void *ophandle, int eventval
{
/* add to all windows! */
wmWindow *win;
-
+
for (win = wm->windows.first; win; win = win->next) {
wmEvent event = *win->eventstate;
-
+
event.type = EVT_FILESELECT;
event.val = eventval;
event.customdata = ophandle; // only as void pointer type check
@@ -3027,7 +3058,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
/* only allow 1 file selector open per window */
for (handler = win->modalhandlers.first; handler; handler = handlernext) {
handlernext = handler->next;
-
+
if (handler->type == WM_HANDLER_FILESELECT) {
bScreen *screen = CTX_wm_screen(C);
bool cancel_handler = true;
@@ -3052,16 +3083,16 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
}
}
}
-
+
handler = MEM_callocN(sizeof(wmEventHandler), "fileselect handler");
-
+
handler->type = WM_HANDLER_FILESELECT;
handler->op = op;
handler->op_area = CTX_wm_area(C);
handler->op_region = CTX_wm_region(C);
-
+
BLI_addhead(&win->modalhandlers, handler);
-
+
/* check props once before invoking if check is available
* ensures initial properties are valid */
if (op->type->check) {
@@ -3083,7 +3114,7 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
{
wmEventHandler *handler = MEM_callocN(sizeof(wmEventHandler), "event modal handler");
wmWindow *win = CTX_wm_window(C);
-
+
/* operator was part of macro */
if (op->opm) {
/* give the mother macro to the handler */
@@ -3093,11 +3124,11 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
}
else
handler->op = op;
-
+
handler->op_area = CTX_wm_area(C); /* means frozen screen context for modal handlers! */
handler->op_region = CTX_wm_region(C);
handler->op_region_type = handler->op_region ? handler->op_region->regiontype : -1;
-
+
BLI_addhead(&win->modalhandlers, handler);
return handler;
@@ -3144,7 +3175,7 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap
for (handler = handlers->first; handler; handler = handler->next)
if (handler->keymap == keymap)
return handler;
-
+
handler = MEM_callocN(sizeof(wmEventHandler), "event keymap handler");
BLI_addtail(handlers, handler);
handler->keymap = keymap;
@@ -3156,20 +3187,20 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap
wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, wmKeyMap *keymap, int UNUSED(priority))
{
wmEventHandler *handler;
-
+
WM_event_remove_keymap_handler(handlers, keymap);
-
+
handler = MEM_callocN(sizeof(wmEventHandler), "event keymap handler");
BLI_addhead(handlers, handler);
handler->keymap = keymap;
-
+
return handler;
}
wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, wmKeyMap *keymap, const rcti *bblocal, const rcti *bbwin)
{
wmEventHandler *handler = WM_event_add_keymap_handler(handlers, keymap);
-
+
if (handler) {
handler->bblocal = bblocal;
handler->bbwin = bbwin;
@@ -3180,7 +3211,7 @@ wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, wmKeyMap *key
void WM_event_remove_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
{
wmEventHandler *handler;
-
+
for (handler = handlers->first; handler; handler = handler->next) {
if (handler->keymap == keymap) {
BLI_remlink(handlers, handler);
@@ -3221,9 +3252,9 @@ wmEventHandler *WM_event_add_ui_handler(
BLI_assert((flag & WM_HANDLER_DO_FREE) == 0);
handler->flag = flag;
-
+
BLI_addhead(handlers, handler);
-
+
return handler;
}
@@ -3234,7 +3265,7 @@ void WM_event_remove_ui_handler(
void *userdata, const bool postpone)
{
wmEventHandler *handler;
-
+
for (handler = handlers->first; handler; handler = handler->next) {
if ((handler->ui_handle == ui_handle) &&
(handler->ui_remove == ui_remove) &&
@@ -3279,13 +3310,13 @@ wmEventHandler *WM_event_add_dropbox_handler(ListBase *handlers, ListBase *dropb
for (handler = handlers->first; handler; handler = handler->next)
if (handler->dropboxes == dropboxes)
return handler;
-
+
handler = MEM_callocN(sizeof(wmEventHandler), "dropbox handler");
-
+
/* dropbox stored static, no free or copy */
handler->dropboxes = dropboxes;
BLI_addhead(handlers, handler);
-
+
return handler;
}
@@ -3316,7 +3347,7 @@ static void WM_event_remove_handler(ListBase *handlers, wmEventHandler *handler)
void WM_event_add_mousemove(const bContext *C)
{
wmWindow *window = CTX_wm_window(C);
-
+
window->addmousemove = 1;
}
@@ -3324,7 +3355,7 @@ void WM_event_add_mousemove(const bContext *C)
/* for modal callbacks, check configuration for how to interpret exit with tweaks */
bool WM_event_is_modal_tweak_exit(const wmEvent *event, int tweak_event)
{
- /* if the release-confirm userpref setting is enabled,
+ /* if the release-confirm userpref setting is enabled,
* tweak events can be canceled when mouse is released
*/
if (U.flag & USER_RELEASECONFIRM) {
@@ -3353,13 +3384,13 @@ bool WM_event_is_modal_tweak_exit(const wmEvent *event, int tweak_event)
if (event->val != KM_RELEASE)
return 1;
}
-
+
return 0;
}
/* ********************* ghost stuff *************** */
-static int convert_key(GHOST_TKey key)
+static int convert_key(GHOST_TKey key)
{
if (key >= GHOST_kKeyA && key <= GHOST_kKeyZ) {
return (AKEY + ((int) key - GHOST_kKeyA));
@@ -3438,7 +3469,7 @@ static int convert_key(GHOST_TKey key)
case GHOST_kKeyMediaStop: return MEDIASTOP;
case GHOST_kKeyMediaFirst: return MEDIAFIRST;
case GHOST_kKeyMediaLast: return MEDIALAST;
-
+
default:
return UNKNOWNKEY; /* GHOST_kKeyUnknown */
}
@@ -3450,11 +3481,11 @@ static void wm_eventemulation(wmEvent *event)
/* Store last mmb/rmb event value to make emulation work when modifier keys
* are released first. This really should be in a data structure somewhere. */
static int emulating_event = EVENT_NONE;
-
+
/* middlemouse and rightmouse emulation */
if (U.flag & USER_TWOBUTTONMOUSE) {
if (event->type == LEFTMOUSE) {
-
+
if (event->val == KM_PRESS && event->alt) {
event->type = MIDDLEMOUSE;
event->alt = 0;
@@ -3480,9 +3511,9 @@ static void wm_eventemulation(wmEvent *event)
emulating_event = EVENT_NONE;
}
}
-
+
}
-
+
/* numpad emulation */
if (U.flag & USER_NONUMPAD) {
switch (event->type) {
@@ -3507,16 +3538,16 @@ static void wm_eventemulation(wmEvent *event)
static void update_tablet_data(wmWindow *win, wmEvent *event)
{
const GHOST_TabletData *td = GHOST_GetTabletData(win->ghostwin);
-
+
/* if there's tablet data from an active tablet device then add it */
if ((td != NULL) && td->Active != GHOST_kTabletModeNone) {
struct wmTabletData *wmtab = MEM_mallocN(sizeof(wmTabletData), "customdata tablet");
-
+
wmtab->Active = (int)td->Active;
wmtab->Pressure = td->Pressure;
wmtab->Xtilt = td->Xtilt;
wmtab->Ytilt = td->Ytilt;
-
+
event->tablet_data = wmtab;
// printf("%s: using tablet %.5f\n", __func__, wmtab->Pressure);
}
@@ -3559,40 +3590,40 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
{
int mx = event->x, my = event->y;
-
+
if (wm->windows.first == wm->windows.last)
return NULL;
-
+
/* in order to use window size and mouse position (pixels), we have to use a WM function */
-
+
/* check if outside, include top window bar... */
if (mx < 0 || my < 0 || mx > WM_window_pixels_x(win) || my > WM_window_pixels_y(win) + 30) {
wmWindow *owin;
wmEventHandler *handler;
-
+
/* let's skip windows having modal handlers now */
/* potential XXX ugly... I wouldn't have added a modalhandlers list (introduced in rev 23331, ton) */
for (handler = win->modalhandlers.first; handler; handler = handler->next)
if (handler->ui_handle || handler->op)
return NULL;
-
+
/* to desktop space */
mx += (int) (U.pixelsize * win->posx);
my += (int) (U.pixelsize * win->posy);
-
+
/* check other windows to see if it has mouse inside */
for (owin = wm->windows.first; owin; owin = owin->next) {
-
+
if (owin != win) {
int posx = (int) (U.pixelsize * owin->posx);
int posy = (int) (U.pixelsize * owin->posy);
-
+
if (mx - posx >= 0 && owin->posy >= 0 &&
mx - posx <= WM_window_pixels_x(owin) && my - posy <= WM_window_pixels_y(owin))
{
event->x = mx - (int)(U.pixelsize * owin->posx);
event->y = my - (int)(U.pixelsize * owin->posy);
-
+
return owin;
}
}
@@ -3671,7 +3702,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
copy_v2_v2_int(&evt->x, &event_new->x);
evt->is_motion_absolute = event_new->is_motion_absolute;
}
-
+
/* also add to other window if event is there, this makes overdraws disappear nicely */
/* it remaps mousecoord to other window in event */
owin = wm_event_cursor_other_windows(wm, win, &event);
@@ -3688,7 +3719,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
oevt->is_motion_absolute = event_new->is_motion_absolute;
}
}
-
+
break;
}
case GHOST_kEventTrackpad:
@@ -3712,11 +3743,11 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
event.x = evt->x = pd->x;
event.y = evt->y = pd->y;
event.val = KM_NOTHING;
-
+
/* Use prevx/prevy so we can calculate the delta later */
event.prevx = event.x - pd->deltaX;
event.prevy = event.y - (-pd->deltaY);
-
+
wm_event_add(win, &event);
break;
}
@@ -3725,10 +3756,10 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
case GHOST_kEventButtonUp:
{
GHOST_TEventButtonData *bd = customdata;
-
+
/* get value and type from ghost */
event.val = (type == GHOST_kEventButtonDown) ? KM_PRESS : KM_RELEASE;
-
+
if (bd->button == GHOST_kButtonMaskLeft)
event.type = LEFTMOUSE;
else if (bd->button == GHOST_kButtonMaskRight)
@@ -3743,9 +3774,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
event.type = BUTTON7MOUSE;
else
event.type = MIDDLEMOUSE;
-
+
wm_eventemulation(&event);
-
+
/* copy previous state to prev event state (two old!) */
evt->prevval = evt->val;
evt->prevtype = evt->type;
@@ -3756,14 +3787,14 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
if (win->active == 0) {
int cx, cy;
-
+
/* entering window, update mouse pos. (ghost sends win-activate *after* the mouseclick in window!) */
wm_get_cursor_position(win, &cx, &cy);
event.x = evt->x = cx;
event.y = evt->y = cy;
}
-
+
/* double click test */
if (wm_event_is_double_click(&event, evt)) {
CLOG_INFO(WM_LOG_HANDLERS, 1, "Send double click");
@@ -3774,23 +3805,23 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
evt->prevclickx = event.x;
evt->prevclicky = event.y;
}
-
+
/* add to other window if event is there (not to both!) */
owin = wm_event_cursor_other_windows(wm, win, &event);
if (owin) {
wmEvent oevent = *(owin->eventstate);
-
+
oevent.x = event.x;
oevent.y = event.y;
oevent.type = event.type;
oevent.val = event.val;
-
+
wm_event_add(owin, &oevent);
}
else {
wm_event_add(win, &event);
}
-
+
break;
}
/* keyboard */
@@ -3803,9 +3834,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
event.ascii = kd->ascii;
memcpy(event.utf8_buf, kd->utf8_buf, sizeof(event.utf8_buf)); /* might be not null terminated*/
event.val = (type == GHOST_kEventKeyDown) ? KM_PRESS : KM_RELEASE;
-
+
wm_eventemulation(&event);
-
+
/* copy previous state to prev event state (two old!) */
evt->prevval = evt->val;
evt->prevtype = evt->type;
@@ -3813,7 +3844,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
/* copy to event state */
evt->val = event.val;
evt->type = event.type;
-
+
/* exclude arrow keys, esc, etc from text input */
if (type == GHOST_kEventKeyUp) {
event.ascii = '\0';
@@ -3887,19 +3918,19 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
CLOG_INFO(WM_LOG_HANDLERS, 1, "Send double click");
evt->val = event.val = KM_DBL_CLICK;
}
-
+
/* this case happens on holding a key pressed, it should not generate
* press events events with the same key as modifier */
if (event.keymodifier == event.type)
event.keymodifier = 0;
-
+
/* this case happens with an external numpad, and also when using 'dead keys' (to compose complex latin
* characters e.g.), it's not really clear why.
* Since it's impossible to map a key modifier to an unknown key, it shouldn't harm to clear it. */
if (event.keymodifier == UNKNOWNKEY) {
evt->keymodifier = event.keymodifier = 0;
}
-
+
/* if test_break set, it catches this. Do not set with modifier presses. XXX Keep global for now? */
if ((event.type == ESCKEY && event.val == KM_PRESS) &&
/* check other modifiers because ms-windows uses these to bring up the task manager */
@@ -3907,31 +3938,34 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
{
G.is_break = true;
}
-
+
/* double click test - only for press */
if (event.val == KM_PRESS) {
- evt->prevclicktime = PIL_check_seconds_timer();
- evt->prevclickx = event.x;
- evt->prevclicky = event.y;
+ /* Don't reset timer & location when holding the key generates repeat events. */
+ if ((evt->prevtype != event.type) || (evt->prevval != KM_PRESS)) {
+ evt->prevclicktime = PIL_check_seconds_timer();
+ evt->prevclickx = event.x;
+ evt->prevclicky = event.y;
+ }
}
-
+
wm_event_add(win, &event);
-
+
break;
}
-
+
case GHOST_kEventWheel:
{
GHOST_TEventWheelData *wheelData = customdata;
-
+
if (wheelData->z > 0)
event.type = WHEELUPMOUSE;
else
event.type = WHEELDOWNMOUSE;
-
+
event.val = KM_PRESS;
wm_event_add(win, &event);
-
+
break;
}
case GHOST_kEventTimer:
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 68be37ef709..3aaec875627 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -152,27 +152,27 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist)
{
wmWindowManager *wm;
wmWindow *win, *active_win;
-
+
*wmlist = G.main->wm;
BLI_listbase_clear(&G.main->wm);
-
+
active_win = CTX_wm_window(C);
/* first wrap up running stuff */
/* code copied from wm_init_exit.c */
for (wm = wmlist->first; wm; wm = wm->id.next) {
-
+
WM_jobs_kill_all(wm);
-
+
for (win = wm->windows.first; win; win = win->next) {
-
+
CTX_wm_window_set(C, win); /* needed by operator close callbacks */
WM_event_remove_handlers(C, &win->handlers);
WM_event_remove_handlers(C, &win->modalhandlers);
ED_screen_exit(C, win, WM_window_get_active_screen(win));
}
}
-
+
/* reset active window */
CTX_wm_window_set(C, active_win);
@@ -215,6 +215,7 @@ static void wm_window_match_keep_current_wm(
const bool load_ui,
ListBase *r_new_wm_list)
{
+ Main *bmain = CTX_data_main(C);
wmWindowManager *wm = current_wm_list->first;
bScreen *screen = NULL;
@@ -236,7 +237,7 @@ static void wm_window_match_keep_current_wm(
}
else {
WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
- WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(workspace, layout_old, win);
+ WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_old, win);
WM_window_set_active_layout(win, workspace, layout_new);
}
@@ -339,8 +340,8 @@ static void wm_window_match_do(
static void wm_init_userdef(Main *bmain, const bool read_userdef_from_memory)
{
/* versioning is here */
- UI_init_userdef();
-
+ UI_init_userdef(bmain);
+
MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024);
BKE_sound_init(bmain);
@@ -569,7 +570,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* it throws error box when file doesn't exist and returns -1 */
/* note; it should set some error message somewhere... (ton) */
retval = wm_read_exotic(filepath);
-
+
/* we didn't succeed, now try to read Blender file */
if (retval == BKE_READ_EXOTIC_OK_BLEND) {
int G_f = G.f;
@@ -578,12 +579,16 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* put aside screens to match with persistent windows later */
/* also exit screens and editors */
wm_window_match_init(C, &wmbase);
-
+
/* confusing this global... */
G.relbase_valid = 1;
retval = BKE_blendfile_read(C, filepath, reports, 0);
+
+ /* BKE_file_read sets new Main into context. */
+ Main *bmain = CTX_data_main(C);
+
/* when loading startup.blend's, we can be left with a blank path */
- if (G.main->name[0]) {
+ if (BKE_main_blendfile_path(bmain)) {
G.save_over = 1;
}
else {
@@ -599,14 +604,14 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
}
/* match the read WM with current WM */
- wm_window_match_do(C, &wmbase, &G.main->wm, &G.main->wm);
+ wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
WM_check(C); /* opens window(s), checks keymaps */
if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) {
/* in case a userdef is read from regular .blend */
- wm_init_userdef(G.main, false);
+ wm_init_userdef(bmain, false);
}
-
+
if (retval != BKE_BLENDFILE_READ_FAIL) {
if (do_history) {
wm_history_file_update();
@@ -672,6 +677,7 @@ int wm_homefile_read(
bool use_factory_settings, bool use_empty_data, bool use_userdef,
const char *filepath_startup_override, const char *app_template_override)
{
+ Main *bmain = G.main; /* Context does not always have valid main pointer here... */
ListBase wmbase;
bool success = false;
@@ -863,16 +869,18 @@ int wm_homefile_read(
* can remove this eventually, only in a 2.53 and older, now its not written */
G.fileflags &= ~G_FILE_RELATIVE_REMAP;
- if (use_userdef) {
+ bmain = CTX_data_main(C);
+
+ if (use_userdef) {
/* check userdef before open window, keymaps etc */
- wm_init_userdef(CTX_data_main(C), read_userdef_from_memory);
+ wm_init_userdef(bmain, read_userdef_from_memory);
}
-
+
/* match the read WM with current WM */
- wm_window_match_do(C, &wmbase, &G.main->wm, &G.main->wm);
+ wm_window_match_do(C, &wmbase, &bmain->wm, &bmain->wm);
WM_check(C); /* opens window(s), checks keymaps */
- G.main->name[0] = '\0';
+ bmain->name[0] = '\0';
/* start with save preference untitled.blend */
G.save_over = 0;
@@ -913,7 +921,7 @@ void wm_history_file_read(void)
num++;
}
}
-
+
BLI_file_free_lines(lines);
}
@@ -969,16 +977,18 @@ static void wm_history_file_write(void)
static void wm_history_file_update(void)
{
RecentFile *recent;
+ const char *blendfile_name = BKE_main_blendfile_path_from_global();
/* no write history for recovered startup files */
- if (G.main->name[0] == 0)
+ if (blendfile_name[0] == '\0') {
return;
+ }
recent = G.recent_files.first;
/* refresh recent-files.txt of recent opened files, when current file was changed */
- if (!(recent) || (BLI_path_cmp(recent->filepath, G.main->name) != 0)) {
+ if (!(recent) || (BLI_path_cmp(recent->filepath, blendfile_name) != 0)) {
- recent = wm_file_history_find(G.main->name);
+ recent = wm_file_history_find(blendfile_name);
if (recent) {
BLI_remlink(&G.recent_files, recent);
}
@@ -988,7 +998,7 @@ static void wm_history_file_update(void)
recent_next = recent->next;
wm_history_file_free(recent);
}
- recent = wm_history_file_new(G.main->name);
+ recent = wm_history_file_new(blendfile_name);
}
/* add current file to the beginning of list */
@@ -998,7 +1008,7 @@ static void wm_history_file_update(void)
wm_history_file_write();
/* also update most recent files on System */
- GHOST_addToSystemRecentFiles(G.main->name);
+ GHOST_addToSystemRecentFiles(blendfile_name);
}
}
@@ -1066,7 +1076,7 @@ static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, bScreen *screen,
/* add pretty overlay */
IMB_thumb_overlay_blend(ibuf->rect, ibuf->x, ibuf->y, aspect);
-
+
thumb = BKE_main_thumbnail_from_imbuf(NULL, ibuf);
}
else {
@@ -1074,10 +1084,10 @@ static ImBuf *blend_file_thumb(const bContext *C, Scene *scene, bScreen *screen,
fprintf(stderr, "blend_file_thumb failed to create thumbnail: %s\n", err_out);
thumb = NULL;
}
-
+
/* must be freed by caller */
*thumb_pt = thumb;
-
+
return ibuf;
}
@@ -1087,7 +1097,7 @@ bool write_crash_blend(void)
char path[FILE_MAX];
int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on crash file */
- BLI_strncpy(path, G.main->name, sizeof(path));
+ BLI_strncpy(path, BKE_main_blendfile_path_from_global(), sizeof(path));
BLI_replace_extension(path, sizeof(path), "_crash.blend");
if (BLO_write_file(G.main, path, fileflags, NULL, NULL)) {
printf("written: %s\n", path);
@@ -1104,6 +1114,7 @@ bool write_crash_blend(void)
*/
static int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList *reports)
{
+ Main *bmain = CTX_data_main(C);
Library *li;
int len;
int ret = -1;
@@ -1111,7 +1122,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
ImBuf *ibuf_thumb = NULL;
len = strlen(filepath);
-
+
if (len == 0) {
BKE_report(reports, RPT_ERROR, "Path is empty, cannot save");
return ret;
@@ -1121,7 +1132,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
BKE_report(reports, RPT_ERROR, "Path too long, cannot save");
return ret;
}
-
+
/* Check if file write permission is ok */
if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) {
BKE_reportf(reports, RPT_ERROR, "Cannot save blend file, path '%s' is not writable", filepath);
@@ -1131,9 +1142,9 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
/* note: used to replace the file extension (to ensure '.blend'),
* no need to now because the operator ensures,
* its handy for scripts to save to a predefined name without blender editing it */
-
+
/* send the OnSave event */
- for (li = G.main->library.first; li; li = li->id.next) {
+ for (li = bmain->library.first; li; li = li->id.next) {
if (BLI_path_cmp(li->filepath, filepath) == 0) {
BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath);
return ret;
@@ -1141,12 +1152,12 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
}
/* Call pre-save callbacks befores writing preview, that way you can generate custom file thumbnail... */
- BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE);
+ BLI_callback_exec(bmain, NULL, BLI_CB_EVT_SAVE_PRE);
/* blend file thumbnail */
/* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */
/* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */
- main_thumb = thumb = CTX_data_main(C)->blen_thumb;
+ main_thumb = thumb = bmain->blen_thumb;
if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) {
ibuf_thumb = blend_file_thumb(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb);
}
@@ -1154,32 +1165,32 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
/* operator now handles overwrite checks */
if (G.fileflags & G_AUTOPACK) {
- packAll(G.main, reports, false);
+ packAll(bmain, reports, false);
}
/* don't forget not to return without! */
WM_cursor_wait(1);
-
+
ED_editors_flush_edits(C, false);
fileflags |= G_FILE_HISTORY; /* write file history */
/* first time saving */
/* XXX temp solution to solve bug, real fix coming (ton) */
- if ((G.main->name[0] == '\0') && !(fileflags & G_FILE_SAVE_COPY)) {
- BLI_strncpy(G.main->name, filepath, sizeof(G.main->name));
+ if ((BKE_main_blendfile_path(bmain)[0] == '\0') && !(fileflags & G_FILE_SAVE_COPY)) {
+ BLI_strncpy(bmain->name, filepath, sizeof(bmain->name));
}
/* XXX temp solution to solve bug, real fix coming (ton) */
- G.main->recovered = 0;
-
+ bmain->recovered = 0;
+
if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) {
const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0);
if (!(fileflags & G_FILE_SAVE_COPY)) {
G.relbase_valid = 1;
- BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); /* is guaranteed current file */
-
+ BLI_strncpy(bmain->name, filepath, sizeof(bmain->name)); /* is guaranteed current file */
+
G.save_over = 1; /* disable untitled.blend convention */
}
@@ -1190,7 +1201,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
wm_history_file_update();
}
- BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST);
+ BLI_callback_exec(bmain, NULL, BLI_CB_EVT_SAVE_POST);
/* run this function after because the file cant be written before the blend is */
if (ibuf_thumb) {
@@ -1224,7 +1235,7 @@ void wm_autosave_location(char *filepath)
#endif
if (G.main && G.relbase_valid) {
- const char *basename = BLI_path_basename(G.main->name);
+ const char *basename = BLI_path_basename(BKE_main_blendfile_path_from_global());
int len = strlen(basename) - 6;
BLI_snprintf(path, sizeof(path), "%.*s.blend", len, basename);
}
@@ -1264,7 +1275,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w
wmWindow *win;
wmEventHandler *handler;
char filepath[FILE_MAX];
-
+
WM_event_remove_timer(wm, NULL, wm->autosavetimer);
/* if a modal operator is running, don't autosave, but try again in 10 seconds */
@@ -1313,7 +1324,7 @@ void wm_autosave_timer_ended(wmWindowManager *wm)
void wm_autosave_delete(void)
{
char filename[FILE_MAX];
-
+
wm_autosave_location(filename);
if (BLI_exists(filename)) {
@@ -1754,7 +1765,8 @@ struct FileRuntime {
static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- const char *openname = G.main->name;
+ Main *bmain = CTX_data_main(C);
+ const char *openname = BKE_main_blendfile_path(bmain);
if (CTX_wm_window(C) == NULL) {
/* in rare cases this could happen, when trying to invoke in background
@@ -1893,6 +1905,7 @@ void WM_OT_open_mainfile(wmOperatorType *ot)
static int wm_revert_mainfile_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
bool success;
char filepath[FILE_MAX];
@@ -1903,7 +1916,7 @@ static int wm_revert_mainfile_exec(bContext *C, wmOperator *op)
else
G.f &= ~G_SCRIPT_AUTOEXEC;
- BLI_strncpy(filepath, G.main->name, sizeof(filepath));
+ BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
success = wm_file_read_opwrap(C, filepath, op->reports, !(G.f & G_SCRIPT_AUTOEXEC));
if (success) {
@@ -1941,6 +1954,7 @@ void WM_OT_revert_mainfile(wmOperatorType *ot)
void WM_recover_last_session(bContext *C, ReportList *reports)
{
+ Main *bmain = CTX_data_main(C);
char filepath[FILE_MAX];
BLI_make_file_string("/", filepath, BKE_tempdir_base(), BLENDER_QUIT_FILE);
@@ -1953,8 +1967,9 @@ void WM_recover_last_session(bContext *C, ReportList *reports)
G.fileflags &= ~G_FILE_RECOVER;
/* XXX bad global... fixme */
- if (G.main->name[0])
+ if (BKE_main_blendfile_path(bmain)[0] != '\0') {
G.file_loaded = 1; /* prevents splash to show */
+ }
else {
G.relbase_valid = 0;
G.save_over = 0; /* start with save preference untitled.blend */
@@ -2053,20 +2068,21 @@ static void save_set_compress(wmOperator *op)
}
}
-static void save_set_filepath(wmOperator *op)
+static void save_set_filepath(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
PropertyRNA *prop;
char name[FILE_MAX];
prop = RNA_struct_find_property(op->ptr, "filepath");
if (!RNA_property_is_set(op->ptr, prop)) {
/* if not saved before, get the name of the most recently used .blend file */
- if (G.main->name[0] == 0 && G.recent_files.first) {
+ if (BKE_main_blendfile_path(bmain)[0] == '\0' && G.recent_files.first) {
struct RecentFile *recent = G.recent_files.first;
BLI_strncpy(name, recent->filepath, FILE_MAX);
}
else {
- BLI_strncpy(name, G.main->name, FILE_MAX);
+ BLI_strncpy(name, bmain->name, FILE_MAX);
}
wm_filepath_default(name);
@@ -2078,7 +2094,7 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent
{
save_set_compress(op);
- save_set_filepath(op);
+ save_set_filepath(C, op);
WM_event_add_fileselect(C, op);
@@ -2088,6 +2104,7 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent
/* function used for WM_OT_save_mainfile too */
static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
char path[FILE_MAX];
int fileflags;
@@ -2097,7 +2114,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", path);
}
else {
- BLI_strncpy(path, G.main->name, FILE_MAX);
+ BLI_strncpy(path, BKE_main_blendfile_path(bmain), FILE_MAX);
wm_filepath_default(path);
}
@@ -2193,7 +2210,7 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *U
return OPERATOR_CANCELLED;
save_set_compress(op);
- save_set_filepath(op);
+ save_set_filepath(C, op);
/* if we're saving for the first time and prefer relative paths - any existing paths will be absolute,
* enable the option to remap paths to avoid confusion [#37240] */
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index 0f2da2e8f36..c7d55b290f5 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -115,7 +115,7 @@ static int wm_link_append_invoke(bContext *C, wmOperator *op, const wmEvent *UNU
}
else if (G.relbase_valid) {
char path[FILE_MAX];
- BLI_strncpy(path, G.main->name, sizeof(G.main->name));
+ BLI_strncpy(path, BKE_main_blendfile_path_from_global(), sizeof(path));
BLI_parent_dir(path);
RNA_string_set(op->ptr, "filepath", path);
}
@@ -333,7 +333,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path);
return OPERATOR_CANCELLED;
}
- else if (BLI_path_cmp(bmain->name, libname) == 0) {
+ else if (BLI_path_cmp(BKE_main_blendfile_path(bmain), libname) == 0) {
BKE_reportf(op->reports, RPT_ERROR, "'%s': cannot use current file as library", path);
return OPERATOR_CANCELLED;
}
@@ -372,7 +372,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
if (view_layer && RNA_boolean_get(op->ptr, "autoselect")) {
BKE_view_layer_base_deselect_all(view_layer);
}
-
+
/* tag everything, all untagged data can be made local
* its also generally useful to know what is new
*
@@ -531,18 +531,18 @@ void WM_OT_link(wmOperatorType *ot)
ot->name = "Link from Library";
ot->idname = "WM_OT_link";
ot->description = "Link from a Library .blend file";
-
+
ot->invoke = wm_link_append_invoke;
ot->exec = wm_link_append_exec;
ot->poll = wm_link_append_poll;
-
+
ot->flag |= OPTYPE_UNDO;
WM_operator_properties_filesel(
ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER | FILE_TYPE_BLENDERLIB, FILE_LOADLIB, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES,
FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
-
+
wm_link_append_properties_common(ot, true);
}
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 2c3583a9f02..144bb38ae76 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -63,20 +63,20 @@ wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
wmGesture *gesture = MEM_callocN(sizeof(wmGesture), "new gesture");
wmWindow *window = CTX_wm_window(C);
ARegion *ar = CTX_wm_region(C);
-
+
BLI_addtail(&window->gesture, gesture);
-
+
gesture->type = type;
gesture->event_type = event->type;
gesture->winrct = ar->winrct;
gesture->userdata_free = true; /* Free if userdata is set. */
gesture->modal_state = GESTURE_MODAL_NOP;
-
+
if (ELEM(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK,
WM_GESTURE_CIRCLE, WM_GESTURE_STRAIGHTLINE))
{
rcti *rect = MEM_callocN(sizeof(rcti), "gesture rect new");
-
+
gesture->customdata = rect;
rect->xmin = event->x - gesture->winrct.xmin;
rect->ymin = event->y - gesture->winrct.ymin;
@@ -96,14 +96,14 @@ wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
lasso[1] = event->y - gesture->winrct.ymin;
gesture->points = 1;
}
-
+
return gesture;
}
void WM_gesture_end(bContext *C, wmGesture *gesture)
{
wmWindow *win = CTX_wm_window(C);
-
+
if (win->tweak == gesture)
win->tweak = NULL;
BLI_remlink(&win->gesture, gesture);
@@ -117,7 +117,7 @@ void WM_gesture_end(bContext *C, wmGesture *gesture)
void WM_gestures_remove(bContext *C)
{
wmWindow *win = CTX_wm_window(C);
-
+
while (win->gesture.first)
WM_gesture_end(C, win->gesture.first);
}
@@ -141,7 +141,7 @@ int wm_gesture_evaluate(wmGesture *gesture)
else if (theta == -1) val = EVT_GESTURE_SE;
else if (theta == -2) val = EVT_GESTURE_S;
else if (theta == -3) val = EVT_GESTURE_SW;
-
+
#if 0
/* debug */
if (val == 1) printf("tweak north\n");
@@ -421,7 +421,7 @@ void wm_gesture_draw(wmWindow *win)
for (; gt; gt = gt->next) {
/* all in subwindow space */
wmViewport(&gt->winrct);
-
+
if (gt->type == WM_GESTURE_RECT)
wm_gesture_draw_rect(gt);
// else if (gt->type == WM_GESTURE_TWEAK)
@@ -448,7 +448,7 @@ void wm_gesture_draw(wmWindow *win)
void wm_gesture_tag_redraw(bContext *C)
{
bScreen *screen = CTX_wm_screen(C);
-
+
if (screen)
screen->do_draw_gesture = true;
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 480287ce6b1..c5a57147dd6 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -186,6 +186,8 @@ void WM_init_opengl(void)
GPU_set_anisotropic(U.anisotropic_filter);
GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
+ GPU_pass_cache_init();
+
#ifdef WITH_OPENSUBDIV
BKE_subsurf_osd_init();
#endif
@@ -195,7 +197,7 @@ void WM_init_opengl(void)
/* only called once, for startup */
void WM_init(bContext *C, int argc, const char **argv)
{
-
+
if (!G.background) {
wm_ghost_init(C); /* note: it assigns C to ghost! */
wm_init_cursor_data();
@@ -222,12 +224,12 @@ void WM_init(bContext *C, int argc, const char **argv)
BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); /* screen.c */
DEG_editors_set_update_cb(ED_render_id_flush_update,
ED_render_scene_update);
-
+
ED_spacetypes_init(); /* editors/space_api/spacetype.c */
-
+
ED_file_init(); /* for fsmenu */
ED_node_init_butfuncs();
-
+
BLF_init();
BLT_lang_init();
@@ -293,11 +295,11 @@ void WM_init(bContext *C, int argc, const char **argv)
/* allow a path of "", this is what happens when making a new file */
#if 0
- if (G.main->name[0] == 0)
+ if (BKE_main_blendfile_path_from_global()[0] == '\0')
BLI_make_file_string("/", G.main->name, BKE_appdir_folder_default(), "untitled.blend");
#endif
- BLI_strncpy(G.lib, G.main->name, FILE_MAX);
+ BLI_strncpy(G.lib, BKE_main_blendfile_path_from_global(), sizeof(G.lib));
#ifdef WITH_COMPOSITOR
if (1) {
@@ -305,7 +307,7 @@ void WM_init(bContext *C, int argc, const char **argv)
COM_linker_hack = COM_execute;
}
#endif
-
+
/* load last session, uses regular file reading so it has to be in end (after init py etc) */
if (U.uiflag2 & USER_KEEP_SESSION) {
/* calling WM_recover_last_session(C, NULL) has been moved to creator.c */
@@ -338,7 +340,7 @@ void WM_init_splash(bContext *C)
if ((U.uiflag & USER_SPLASH_DISABLE) == 0) {
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *prevwin = CTX_wm_window(C);
-
+
if (wm->windows.first) {
CTX_wm_window_set(C, wm->windows.first);
WM_operator_name_call(C, "WM_OT_splash", WM_OP_INVOKE_DEFAULT, NULL);
@@ -351,10 +353,10 @@ void WM_init_splash(bContext *C)
static void free_openrecent(void)
{
struct RecentFile *recent;
-
+
for (recent = G.recent_files.first; recent; recent = recent->next)
MEM_freeN(recent->filepath);
-
+
BLI_freelistN(&(G.recent_files));
}
@@ -437,11 +439,11 @@ void WM_exit_ext(bContext *C, const bool do_python)
}
}
}
-
+
WM_jobs_kill_all(wm);
for (win = wm->windows.first; win; win = win->next) {
-
+
CTX_wm_window_set(C, win); /* needed by operator close callbacks */
WM_event_remove_handlers(C, &win->handlers);
WM_event_remove_handlers(C, &win->modalhandlers);
@@ -462,13 +464,13 @@ void WM_exit_ext(bContext *C, const bool do_python)
ED_undosys_type_free();
free_openrecent();
-
+
BKE_mball_cubeTable_free();
-
+
/* render code might still access databases */
RE_FreeAllRender();
RE_engines_exit();
-
+
ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */
if (C && wm)
@@ -478,7 +480,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
BKE_tracking_clipboard_free();
BKE_mask_clipboard_free();
BKE_vfont_clipboard_free();
-
+
#ifdef WITH_COMPOSITOR
COM_deinitialize();
#endif
@@ -492,7 +494,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
GPU_exit();
}
-
+
BKE_blender_free(); /* blender.c, does entire library and spacetypes */
// free_matcopybuf();
ANIM_fcurves_copybuf_free();
@@ -521,11 +523,11 @@ void WM_exit_ext(bContext *C, const bool do_python)
BLF_free_unifont_mono();
BLT_lang_free();
#endif
-
+
ANIM_keyingset_infos_exit();
-
+
// free_txt_data();
-
+
#ifdef WITH_PYTHON
/* option not to close python so we can use 'atexit' */
@@ -549,11 +551,11 @@ void WM_exit_ext(bContext *C, const bool do_python)
BKE_blender_userdef_data_free(&U, false);
RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */
-
+
wm_ghost_exit();
CTX_free(C);
-
+
GHOST_DisposeSystemPaths();
DNA_sdna_current_free();
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 28f978909f7..3a4195ae1ae 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -78,10 +78,10 @@
struct wmJob {
struct wmJob *next, *prev;
-
+
/* job originating from, keep track of this when deleting windows */
wmWindow *win;
-
+
/* should store entire own context, for start, update, free */
void *customdata;
/* to prevent cpu overhead, use this one which only gets called when job really starts, not in thread */
@@ -95,14 +95,14 @@ struct wmJob {
void (*free)(void *);
/* gets called when job is stopped, not in thread */
void (*endjob)(void *);
-
+
/* running jobs each have own timer */
double timestep;
wmTimer *wt;
/* the notifier event timers should send */
unsigned int note, endnote;
-
-
+
+
/* internal */
void *owner;
int flag;
@@ -115,7 +115,7 @@ struct wmJob {
/* once running, we store this separately */
void *run_customdata;
void (*run_free)(void *);
-
+
/* we use BLI_threads api, but per job only 1 thread runs */
ListBase threads;
@@ -152,7 +152,7 @@ static void wm_job_main_thread_yield(wmJob *wm_job)
static wmJob *wm_job_find(wmWindowManager *wm, void *owner, const int job_type)
{
wmJob *wm_job;
-
+
if (owner && job_type) {
for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next)
if (wm_job->owner == owner && wm_job->job_type == job_type)
@@ -168,7 +168,7 @@ static wmJob *wm_job_find(wmWindowManager *wm, void *owner, const int job_type)
if (wm_job->job_type == job_type)
return wm_job;
}
-
+
return NULL;
}
@@ -183,7 +183,7 @@ static wmJob *wm_job_find(wmWindowManager *wm, void *owner, const int job_type)
wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
{
wmJob *wm_job = wm_job_find(wm, owner, job_type);
-
+
if (wm_job == NULL) {
wm_job = MEM_callocN(sizeof(wmJob), "new job");
@@ -198,7 +198,7 @@ wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *
WM_job_main_thread_lock_acquire(wm_job);
}
/* else: a running job, be careful */
-
+
/* prevent creating a job with an invalid type */
BLI_assert(wm_job->job_type != WM_JOB_TYPE_ANY);
@@ -209,7 +209,7 @@ wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *
bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
{
wmJob *wm_job;
-
+
/* job can be running or about to run (suspended) */
for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
if (wm_job->owner == owner) {
@@ -227,10 +227,10 @@ bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
float WM_jobs_progress(wmWindowManager *wm, void *owner)
{
wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY);
-
+
if (wm_job && wm_job->flag & WM_JOB_PROGRESS)
return wm_job->progress;
-
+
return 0.0;
}
@@ -248,30 +248,30 @@ double WM_jobs_starttime(wmWindowManager *wm, void *owner)
char *WM_jobs_name(wmWindowManager *wm, void *owner)
{
wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY);
-
+
if (wm_job)
return wm_job->name;
-
+
return NULL;
}
void *WM_jobs_customdata(wmWindowManager *wm, void *owner)
{
wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY);
-
+
if (wm_job)
return WM_jobs_customdata_get(wm_job);
-
+
return NULL;
}
void *WM_jobs_customdata_from_type(wmWindowManager *wm, int job_type)
{
wmJob *wm_job = wm_job_find(wm, NULL, job_type);
-
+
if (wm_job)
return WM_jobs_customdata_get(wm_job);
-
+
return NULL;
}
@@ -301,7 +301,7 @@ void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void (*free)(void *
/* pending job? just free */
if (wm_job->customdata)
wm_job->free(wm_job->customdata);
-
+
wm_job->customdata = customdata;
wm_job->free = free;
@@ -333,10 +333,10 @@ void WM_jobs_callbacks(wmJob *wm_job,
static void *do_job_thread(void *job_v)
{
wmJob *wm_job = job_v;
-
+
wm_job->startjob(wm_job->run_customdata, &wm_job->stop, &wm_job->do_update, &wm_job->progress);
wm_job->ready = true;
-
+
return NULL;
}
@@ -345,7 +345,7 @@ static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
{
wmJob *wm_job;
bool suspend = false;
-
+
/* job added with suspend flag, we wait 1 timer step before activating it */
if (test->flag & WM_JOB_SUSPEND) {
suspend = true;
@@ -358,12 +358,12 @@ static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
if (wm_job == test || !wm_job->running) {
continue;
}
-
+
/* if new job is not render, then check for same startjob */
if (0 == (test->flag & WM_JOB_EXCL_RENDER))
if (wm_job->startjob != test->startjob)
continue;
-
+
/* if new job is render, any render job should be stopped */
if (test->flag & WM_JOB_EXCL_RENDER)
if (0 == (wm_job->flag & WM_JOB_EXCL_RENDER))
@@ -378,7 +378,7 @@ static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
}
}
}
-
+
/* Possible suspend ourselves, waiting for other jobs, or de-suspend. */
test->suspended = suspend;
// if (suspend) printf("job suspended: %s\n", test->name);
@@ -396,11 +396,11 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
// printf("job started a running job, ending... %s\n", wm_job->name);
}
else {
-
+
if (wm_job->customdata && wm_job->startjob) {
-
+
wm_jobs_test_suspend_stop(wm, wm_job);
-
+
if (wm_job->suspended == false) {
/* copy to ensure proper free in end */
wm_job->run_customdata = wm_job->customdata;
@@ -408,20 +408,20 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
wm_job->free = NULL;
wm_job->customdata = NULL;
wm_job->running = true;
-
+
if (wm_job->initjob)
wm_job->initjob(wm_job->run_customdata);
-
+
wm_job->stop = false;
wm_job->ready = false;
wm_job->progress = 0.0;
// printf("job started: %s\n", wm_job->name);
-
+
BLI_threadpool_init(&wm_job->threads, do_job_thread, 1);
BLI_threadpool_insert(&wm_job->threads, wm_job);
}
-
+
/* restarted job has timer already */
if (wm_job->wt == NULL)
wm_job->wt = WM_event_add_timer(wm, wm_job->win, TIMERJOBS, wm_job->timestep);
@@ -456,14 +456,14 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job)
if (wm_job->endjob)
wm_job->endjob(wm_job->run_customdata);
}
-
+
if (wm_job->wt)
WM_event_remove_timer(wm, wm_job->win, wm_job->wt);
if (wm_job->customdata)
wm_job->free(wm_job->customdata);
if (wm_job->run_customdata)
wm_job->run_free(wm_job->run_customdata);
-
+
/* remove wm_job */
wm_job_free(wm, wm_job);
}
@@ -472,17 +472,17 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job)
void WM_jobs_kill_all(wmWindowManager *wm)
{
wmJob *wm_job;
-
+
while ((wm_job = wm->jobs.first))
wm_jobs_kill_job(wm, wm_job);
-
+
}
/* wait until every job ended, except for one owner (used in undo to keep screen job alive) */
void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner)
{
wmJob *wm_job, *next_job;
-
+
for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
next_job = wm_job->next;
@@ -495,7 +495,7 @@ void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner)
void WM_jobs_kill_type(struct wmWindowManager *wm, void *owner, int job_type)
{
wmJob *wm_job, *next_job;
-
+
for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
next_job = wm_job->next;
@@ -509,7 +509,7 @@ void WM_jobs_kill_type(struct wmWindowManager *wm, void *owner, int job_type)
void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob)
{
wmJob *wm_job;
-
+
for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
if (wm_job->owner == owner || wm_job->startjob == startjob) {
if (wm_job->running) {
@@ -523,7 +523,7 @@ void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob)
void WM_jobs_kill(wmWindowManager *wm, void *owner, void (*startjob)(void *, short int *, short int *, float *))
{
wmJob *wm_job;
-
+
wm_job = wm->jobs.first;
while (wm_job) {
if (wm_job->owner == owner || wm_job->startjob == startjob) {
@@ -542,7 +542,7 @@ void WM_jobs_kill(wmWindowManager *wm, void *owner, void (*startjob)(void *, sho
void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt)
{
wmJob *wm_job;
-
+
for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
if (wm_job->wt == wt) {
wm_jobs_kill_job(wm, wm_job);
@@ -557,18 +557,18 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
wmJob *wm_job, *wm_jobnext;
float total_progress = 0.f;
float jobs_progress = 0;
-
+
for (wm_job = wm->jobs.first; wm_job; wm_job = wm_jobnext) {
wm_jobnext = wm_job->next;
-
+
if (wm_job->wt == wt) {
-
+
/* running threads */
if (wm_job->threads.first) {
/* let threads get temporary lock over main thread if needed */
wm_job_main_thread_yield(wm_job);
-
+
/* always call note and update when ready */
if (wm_job->do_update || wm_job->ready) {
if (wm_job->update)
@@ -580,7 +580,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
WM_event_add_notifier(C, NC_WM | ND_JOB, NULL);
wm_job->do_update = false;
}
-
+
if (wm_job->ready) {
if (wm_job->endjob)
wm_job->endjob(wm_job->run_customdata);
@@ -589,7 +589,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
wm_job->run_free(wm_job->run_customdata);
wm_job->run_customdata = NULL;
wm_job->run_free = NULL;
-
+
// if (wm_job->stop) printf("job ready but stopped %s\n", wm_job->name);
// else printf("job finished %s\n", wm_job->name);
@@ -603,10 +603,10 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
WM_job_main_thread_lock_release(wm_job);
BLI_threadpool_end(&wm_job->threads);
WM_job_main_thread_lock_acquire(wm_job);
-
+
if (wm_job->endnote)
WM_event_add_notifier(C, wm_job->endnote, NULL);
-
+
WM_event_add_notifier(C, NC_WM | ND_JOB, NULL);
/* new job added for wm_job? */
@@ -617,7 +617,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
else {
WM_event_remove_timer(wm, wm_job->win, wm_job->wt);
wm_job->wt = NULL;
-
+
/* remove wm_job */
wm_job_free(wm, wm_job);
}
@@ -640,8 +640,8 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
}
}
}
-
-
+
+
/* if there are running jobs, set the global progress indicator */
if (jobs_progress > 0) {
wmWindow *win;
@@ -656,7 +656,7 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
for (win = wm->windows.first; win; win = win->next)
WM_progress_clear(win);
}
-
+
}
bool WM_jobs_has_running(wmWindowManager *wm)
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 1fcfcee0a4c..67493454e8f 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -238,7 +238,7 @@ static wmKeyMapDiffItem *wm_keymap_diff_item_copy(wmKeyMapDiffItem *kmdi)
kmdin->add_item = wm_keymap_item_copy(kmdi->add_item);
if (kmdi->remove_item)
kmdin->remove_item = wm_keymap_item_copy(kmdi->remove_item);
-
+
return kmdin;
}
@@ -261,7 +261,7 @@ static void wm_keymap_diff_item_free(wmKeyMapDiffItem *kmdi)
wmKeyConfig *WM_keyconfig_new(wmWindowManager *wm, const char *idname)
{
wmKeyConfig *keyconf;
-
+
keyconf = MEM_callocN(sizeof(wmKeyConfig), "wmKeyConfig");
BLI_strncpy(keyconf->idname, idname, sizeof(keyconf->idname));
BLI_addtail(&wm->keyconfigs, keyconf);
@@ -316,7 +316,7 @@ static wmKeyConfig *WM_keyconfig_active(wmWindowManager *wm)
keyconf = BLI_findstring(&wm->keyconfigs, U.keyconfigstr, offsetof(wmKeyConfig, idname));
if (keyconf)
return keyconf;
-
+
/* otherwise use default */
return wm->defaultconf;
}
@@ -457,16 +457,16 @@ static void keymap_item_set_id(wmKeyMap *keymap, wmKeyMapItem *kmi)
wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
{
wmKeyMapItem *kmi;
-
+
for (kmi = keymap->items.first; kmi; kmi = kmi->next)
if (STREQLEN(kmi->idname, idname, OP_MAX_TYPENAME))
break;
if (kmi == NULL) {
kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
-
+
BLI_addtail(&keymap->items, kmi);
BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
-
+
keymap_item_set_id(keymap, kmi);
keymap_event_set(kmi, type, val, modifier, keymodifier);
@@ -479,7 +479,7 @@ wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int ty
wmKeyMapItem *WM_keymap_add_item(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
{
wmKeyMapItem *kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
-
+
BLI_addtail(&keymap->items, kmi);
BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
@@ -557,7 +557,7 @@ static wmKeyMapItem *wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *need
for (kmi = km->items.first; kmi; kmi = kmi->next)
if (wm_keymap_item_equals(kmi, needle))
return kmi;
-
+
return NULL;
}
@@ -568,7 +568,7 @@ static wmKeyMapItem *wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapIte
for (kmi = km->items.first; kmi; kmi = kmi->next)
if (wm_keymap_item_equals_result(kmi, needle))
return kmi;
-
+
return NULL;
}
@@ -731,7 +731,7 @@ static wmKeyMap *wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKe
/* add to list */
BLI_addtail(lb, km);
-
+
return km;
}
@@ -779,7 +779,7 @@ static void wm_keymap_diff_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *
/* ****************** storage in WM ************ */
-/* name id's are for storing general or multiple keymaps,
+/* name id's are for storing general or multiple keymaps,
* space/region ids are same as DNA_space_types.h */
/* gets freed in wm.c */
@@ -791,21 +791,21 @@ wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int
if (km->spaceid == spaceid && km->regionid == regionid)
if (STREQLEN(idname, km->idname, KMAP_MAX_NAME))
return km;
-
+
return NULL;
}
wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
{
wmKeyMap *km = WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
-
+
if (km == NULL) {
km = wm_keymap_new(idname, spaceid, regionid);
BLI_addtail(&keyconf->keymaps, km);
WM_keyconfig_update_tag(km, NULL);
}
-
+
return km;
}
@@ -838,19 +838,19 @@ wmKeyMap *WM_modalkeymap_add(wmKeyConfig *keyconf, const char *idname, const Enu
}
}
}
-
+
return km;
}
wmKeyMap *WM_modalkeymap_get(wmKeyConfig *keyconf, const char *idname)
{
wmKeyMap *km;
-
+
for (km = keyconf->keymaps.first; km; km = km->next)
if (km->flag & KEYMAP_MODAL)
if (STREQLEN(idname, km->idname, KMAP_MAX_NAME))
break;
-
+
return km;
}
@@ -858,10 +858,10 @@ wmKeyMap *WM_modalkeymap_get(wmKeyConfig *keyconf, const char *idname)
wmKeyMapItem *WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value)
{
wmKeyMapItem *kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
-
+
BLI_addtail(&km->items, kmi);
kmi->propvalue = value;
-
+
keymap_event_set(kmi, type, val, modifier, keymodifier);
keymap_item_set_id(km, kmi);
@@ -1129,7 +1129,7 @@ static wmKeyMapItem *wm_keymap_item_find_handlers(
/* skip disabled keymap items [T38447] */
if (kmi->flag & KMI_INACTIVE)
continue;
-
+
if (STREQ(kmi->idname, opname) && WM_key_event_string(kmi->type, false)[0]) {
if (is_hotkey) {
if (!ISHOTKEY(kmi->type))
@@ -1197,7 +1197,7 @@ static wmKeyMapItem *wm_keymap_item_find_handlers(
}
}
}
-
+
/* ensure un-initialized keymap is never used */
if (r_keymap) *r_keymap = NULL;
return NULL;
@@ -1231,7 +1231,7 @@ static wmKeyMapItem *wm_keymap_item_find_props(
if (sa) {
if (!(ar && ar->regiontype == RGN_TYPE_WINDOW))
ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
-
+
if (ar)
found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, is_hotkey, r_keymap);
}
@@ -1447,7 +1447,7 @@ static bool wm_keymap_test_and_clear_update(wmKeyMap *km)
{
wmKeyMapItem *kmi;
int update;
-
+
update = (km->flag & KEYMAP_UPDATE);
km->flag &= ~KEYMAP_UPDATE;
@@ -1455,7 +1455,7 @@ static bool wm_keymap_test_and_clear_update(wmKeyMap *km)
update = update || (kmi->flag & KMI_UPDATE);
kmi->flag &= ~KMI_UPDATE;
}
-
+
return (update != 0);
}
@@ -1513,7 +1513,7 @@ void WM_keyconfig_update(wmWindowManager *wm)
if (wm_keymap_update_flag == 0)
return;
-
+
/* update operator properties for non-modal user keymaps */
for (km = U.user_keymaps.first; km; km = km->next) {
if ((km->flag & KEYMAP_MODAL) == 0) {
@@ -1586,7 +1586,7 @@ wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap)
if (!keymap)
return NULL;
-
+
/* first user defined keymaps */
km = WM_keymap_list_find(&wm->userconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
@@ -1678,13 +1678,13 @@ void WM_keymap_restore_to_default(wmKeyMap *keymap, bContext *C)
wmKeyMapItem *WM_keymap_item_find_id(wmKeyMap *keymap, int id)
{
wmKeyMapItem *kmi;
-
+
for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
if (kmi->id == id) {
return kmi;
}
}
-
+
return NULL;
}
@@ -1708,7 +1708,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
wmKeyMap *km = NULL;
SpaceLink *sl = CTX_wm_space_data(C);
-
+
/* Window */
if (STRPREFIX(opname, "WM_OT")) {
km = WM_keymap_find_all(C, "Window", 0, 0);
@@ -1735,8 +1735,8 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
{
km = WM_keymap_find_all(C, "Window", 0, 0);
}
-
-
+
+
/* 3D View */
else if (STRPREFIX(opname, "VIEW3D_OT")) {
km = WM_keymap_find_all(C, "3D View", sl->spacetype, 0);
@@ -1756,11 +1756,11 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
{
km = WM_keymap_find_all(C, "Object Mode", 0, 0);
}
-
+
/* Editing Modes */
else if (STRPREFIX(opname, "MESH_OT")) {
km = WM_keymap_find_all(C, "Mesh", 0, 0);
-
+
/* some mesh operators are active in object mode too, like add-prim */
if (km && !WM_keymap_poll((bContext *)C, km)) {
km = WM_keymap_find_all(C, "Object Mode", 0, 0);
@@ -1770,7 +1770,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
STRPREFIX(opname, "SURFACE_OT"))
{
km = WM_keymap_find_all(C, "Curve", 0, 0);
-
+
/* some curve operators are active in object mode too, like add-prim */
if (km && !WM_keymap_poll((bContext *)C, km)) {
km = WM_keymap_find_all(C, "Object Mode", 0, 0);
@@ -1798,7 +1798,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
}
else if (STRPREFIX(opname, "MBALL_OT")) {
km = WM_keymap_find_all(C, "Metaball", 0, 0);
-
+
/* some mball operators are active in object mode too, like add-prim */
if (km && !WM_keymap_poll((bContext *)C, km)) {
km = WM_keymap_find_all(C, "Object Mode", 0, 0);
@@ -1939,7 +1939,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
break;
}
}
-
+
return km;
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 965c3115199..926e87cc3b4 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -252,15 +252,15 @@ static int wm_macro_exec(bContext *C, wmOperator *op)
{
wmOperator *opm;
int retval = OPERATOR_FINISHED;
-
+
wm_macro_start(op);
for (opm = op->macro.first; opm; opm = opm->next) {
-
+
if (opm->type->exec) {
retval = opm->type->exec(C, opm);
OPERATOR_RETVAL_CHECK(retval);
-
+
if (retval & OPERATOR_FINISHED) {
MacroData *md = op->customdata;
md->retval = OPERATOR_FINISHED; /* keep in mind that at least one operator finished */
@@ -273,7 +273,7 @@ static int wm_macro_exec(bContext *C, wmOperator *op)
CLOG_WARN(WM_LOG_OPERATORS, "'%s' cant exec macro", opm->type->idname);
}
}
-
+
return wm_macro_end(op, retval);
}
@@ -291,7 +291,7 @@ static int wm_macro_invoke_internal(bContext *C, wmOperator *op, const wmEvent *
OPERATOR_RETVAL_CHECK(retval);
BLI_movelisttolist(&op->reports->list, &opm->reports->list);
-
+
if (retval & OPERATOR_FINISHED) {
MacroData *md = op->customdata;
md->retval = OPERATOR_FINISHED; /* keep in mind that at least one operator finished */
@@ -314,7 +314,7 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmOperator *opm = op->opm;
int retval = OPERATOR_FINISHED;
-
+
if (opm == NULL) {
CLOG_ERROR(WM_LOG_OPERATORS, "macro error, calling NULL modal()");
}
@@ -389,20 +389,20 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
{
wmOperatorType *ot;
const char *i18n_context;
-
+
if (WM_operatortype_find(idname, true)) {
CLOG_ERROR(WM_LOG_OPERATORS, "operator %s exists, cannot create macro", idname);
return NULL;
}
-
+
ot = MEM_callocN(sizeof(wmOperatorType), "operatortype");
ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties);
-
+
ot->idname = idname;
ot->name = name;
ot->description = description;
ot->flag = OPTYPE_MACRO | flag;
-
+
ot->exec = wm_macro_exec;
ot->invoke = wm_macro_invoke;
ot->modal = wm_macro_modal;
@@ -411,7 +411,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
if (!ot->description) /* XXX All ops should have a description but for now allow them not to. */
ot->description = UNDOCUMENTED_OPERATOR_TIP;
-
+
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
/* Use i18n context from ext.srna if possible (py operators). */
@@ -479,7 +479,7 @@ wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char
static void wm_operatortype_free_macro(wmOperatorType *ot)
{
wmOperatorTypeMacro *otmacro;
-
+
for (otmacro = ot->macro.first; otmacro; otmacro = otmacro->next) {
if (otmacro->ptr) {
WM_operator_properties_free(otmacro->ptr);
@@ -598,7 +598,7 @@ void WM_operator_py_idname(char *to, const char *from)
const char *sep = strstr(from, "_OT_");
if (sep) {
int ofs = (sep - from);
-
+
/* note, we use ascii tolower instead of system tolower, because the
* latter depends on the locale, and can lead to idname mismatch */
memcpy(to, from, sizeof(char) * ofs);
@@ -1317,7 +1317,7 @@ int WM_operator_confirm_message_ex(bContext *C, wmOperator *op,
layout = UI_popup_menu_layout(pup);
uiItemFullO_ptr(layout, op->type, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0, NULL);
UI_popup_menu_end(C, pup);
-
+
return OPERATOR_INTERFACE;
}
@@ -1437,7 +1437,7 @@ ID *WM_operator_drop_load_path(struct bContext *C, wmOperator *op, const short i
if (is_relative_path ) {
if (exists == false) {
if (idcode == ID_IM) {
- BLI_path_rel(((Image *)id)->name, bmain->name);
+ BLI_path_rel(((Image *)id)->name, BKE_main_blendfile_path(bmain));
}
else {
BLI_assert(0);
@@ -1522,7 +1522,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
uiTemplateOperatorPropertyButs(C, layout, op, NULL, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
}
-
+
UI_block_bounds_set_popup(block, 4, 0, 0);
return block;
@@ -1588,10 +1588,10 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NUMSELECT);
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
-
+
uiTemplateOperatorPropertyButs(C, layout, op, NULL, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
-
+
/* clear so the OK button is left alone */
UI_block_func_set(block, NULL, NULL, NULL);
@@ -1663,7 +1663,7 @@ static void wm_operator_ui_popup_ok(struct bContext *C, void *arg, int retval)
if (op && retval > 0)
WM_operator_call_ex(C, op, true);
-
+
MEM_freeN(data);
}
@@ -1739,7 +1739,7 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, const wmEvent *UNUSED(e
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height)
{
wmOpPopUp *data = MEM_callocN(sizeof(wmOpPopUp), "WM_operator_props_dialog_popup");
-
+
data->op = op;
data->width = width;
data->height = height;
@@ -1763,7 +1763,7 @@ int WM_operator_redo_popup(bContext *C, wmOperator *op)
BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s': wrong context", op->type->idname);
return OPERATOR_CANCELLED;
}
-
+
UI_popup_block_invoke(C, wm_block_create_redo, op);
return OPERATOR_CANCELLED;
@@ -1791,11 +1791,11 @@ static void WM_OT_debug_menu(wmOperatorType *ot)
ot->name = "Debug Menu";
ot->idname = "WM_OT_debug_menu";
ot->description = "Open a popup to set the debug level";
-
+
ot->invoke = wm_debug_menu_invoke;
ot->exec = wm_debug_menu_exec;
ot->poll = WM_operator_winactive;
-
+
RNA_def_int(ot->srna, "debug_value", 0, SHRT_MIN, SHRT_MAX, "Debug Value", "", -10000, 10000);
}
@@ -1898,7 +1898,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
/* Builds made from tag only shows tag sha */
BLI_snprintf(hash_buf, sizeof(hash_buf), "Hash: %s", build_hash);
BLI_snprintf(date_buf, sizeof(date_buf), "Date: %s %s", build_commit_date, build_commit_time);
-
+
BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi);
hash_width = (int)BLF_width(style->widgetlabel.uifont_id, hash_buf, sizeof(hash_buf)) + U.widget_unit;
date_width = (int)BLF_width(style->widgetlabel.uifont_id, date_buf, sizeof(date_buf)) + U.widget_unit;
@@ -2011,9 +2011,9 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
UI_but_flag_enable(but, 1);
}
#endif /* WITH_BUILDINFO */
-
+
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style);
-
+
UI_block_emboss_set(block, UI_EMBOSS);
/* show the splash menu (containing interaction presets), using python */
if (mt) {
@@ -2022,10 +2022,10 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
// wmWindowManager *wm = CTX_wm_manager(C);
// uiItemM(layout, C, "USERPREF_MT_keyconfigs", U.keyconfigstr, ICON_NONE);
}
-
+
UI_block_emboss_set(block, UI_EMBOSS_PULLDOWN);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
-
+
split = uiLayoutSplit(layout, 0.0f, false);
col = uiLayoutColumn(split, false);
uiItemL(col, IFACE_("Links"), ICON_NONE);
@@ -2071,21 +2071,21 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiItemS(col);
uiItemO(col, NULL, ICON_RECOVER_LAST, "WM_OT_recover_last_session");
uiItemL(col, "", ICON_NONE);
-
+
mt = WM_menutype_find("USERPREF_MT_splash_footer", false);
if (mt) {
UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
}
UI_block_bounds_set_centered(block, 0);
-
+
return block;
}
static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
UI_popup_block_invoke(C, wm_block_create_splash, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -2094,7 +2094,7 @@ static void WM_OT_splash(wmOperatorType *ot)
ot->name = "Splash Screen";
ot->idname = "WM_OT_splash";
ot->description = "Open the splash screen with release info";
-
+
ot->invoke = wm_splash_invoke;
ot->poll = WM_operator_winactive;
}
@@ -2114,26 +2114,26 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *userdata)
wmWindow *win = CTX_wm_window(C);
uiBlock *block;
uiBut *but;
-
+
block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
-
+
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, init_data->size[0], UI_UNIT_Y, 0, 0, "");
UI_but_func_operator_search(but);
-
+
/* fake button, it holds space for search items */
uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - init_data->size[1],
init_data->size[0], init_data->size[1], NULL, 0, 0, 0, 0, NULL);
-
+
UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
-
+
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
event.customdatafree = false;
wm_event_add(win, &event);
-
+
return block;
}
@@ -2152,7 +2152,7 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
};
UI_popup_block_invoke(C, wm_block_search_menu, &data);
-
+
return OPERATOR_INTERFACE;
}
@@ -2181,7 +2181,7 @@ static void WM_OT_search_menu(wmOperatorType *ot)
ot->name = "Search Menu";
ot->idname = "WM_OT_search_menu";
ot->description = "Pop-up a search menu over all available operators in current context";
-
+
ot->invoke = wm_search_menu_invoke;
ot->exec = wm_search_menu_exec;
ot->poll = wm_search_menu_poll;
@@ -2246,8 +2246,9 @@ static int wm_call_panel_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "name", idname);
const int space_type = RNA_enum_get(op->ptr, "space_type");
const int region_type = RNA_enum_get(op->ptr, "region_type");
+ const bool keep_open = RNA_boolean_get(op->ptr, "keep_open");
- return UI_popover_panel_invoke(C, space_type, region_type, idname, true, op->reports);
+ return UI_popover_panel_invoke(C, space_type, region_type, idname, keep_open, op->reports);
}
static void WM_OT_call_panel(wmOperatorType *ot)
@@ -2261,9 +2262,16 @@ static void WM_OT_call_panel(wmOperatorType *ot)
ot->flag = OPTYPE_INTERNAL;
- RNA_def_string(ot->srna, "name", NULL, BKE_ST_MAXNAME, "Name", "Name of the menu");
- RNA_def_enum(ot->srna, "space_type", rna_enum_space_type_items, SPACE_EMPTY, "Space Type", "");
- RNA_def_enum(ot->srna, "region_type", rna_enum_region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
+ PropertyRNA *prop;
+
+ prop = RNA_def_string(ot->srna, "name", NULL, BKE_ST_MAXNAME, "Name", "Name of the menu");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_enum(ot->srna, "space_type", rna_enum_space_type_items, SPACE_EMPTY, "Space Type", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_enum(ot->srna, "region_type", rna_enum_region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "keep_open", true, "Keep Open", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************ window / screen operator definitions ************** */
@@ -2364,7 +2372,7 @@ static void WM_OT_console_toggle(wmOperatorType *ot)
ot->name = CTX_N_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Toggle System Console");
ot->idname = "WM_OT_console_toggle";
ot->description = N_("Toggle System Console");
-
+
ot->exec = wm_console_toggle_exec;
ot->poll = WM_operator_winactive;
}
@@ -2382,20 +2390,20 @@ void *WM_paint_cursor_activate(wmWindowManager *wm, int (*poll)(bContext *C),
wmPaintCursorDraw draw, void *customdata)
{
wmPaintCursor *pc = MEM_callocN(sizeof(wmPaintCursor), "paint cursor");
-
+
BLI_addtail(&wm->paintcursors, pc);
-
+
pc->customdata = customdata;
pc->poll = poll;
pc->draw = draw;
-
+
return pc;
}
void WM_paint_cursor_end(wmWindowManager *wm, void *handle)
{
wmPaintCursor *pc;
-
+
for (pc = wm->paintcursors.first; pc; pc = pc->next) {
if (pc == (wmPaintCursor *)handle) {
BLI_remlink(&wm->paintcursors, pc);
@@ -2438,7 +2446,7 @@ static void radial_control_update_header(wmOperator *op, bContext *C)
char msg[UI_MAX_DRAW_STR];
ScrArea *sa = CTX_wm_area(C);
Scene *scene = CTX_data_scene(C);
-
+
if (sa) {
if (hasNumInput(&rc->num_input)) {
char num_str[NUM_STR_REP_LEN];
@@ -2555,7 +2563,7 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph
RNA_property_float_get_array(fill_ptr, fill_prop, col);
}
-
+
Gwn_VertFormat *format = immVertexFormat();
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -2592,10 +2600,10 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph
immAttrib2f(texCoord, 1, 0);
immVertex2f(pos, radius, -radius);
-
+
immAttrib2f(texCoord, 1, 1);
immVertex2f(pos, radius, radius);
-
+
immAttrib2f(texCoord, 0, 1);
immVertex2f(pos, -radius, radius);
@@ -2611,7 +2619,7 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph
immUniformColor3fvAlpha(col, alpha);
imm_draw_circle_fill_2d(pos, 0.0f, 0.0f, radius, 40);
}
-
+
immUnbindProgram();
}
@@ -2626,7 +2634,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void
short strdrawlen = 0;
float strwidth, strheight;
float r1 = 0.0f, r2 = 0.0f, rmin = 0.0, tex_radius, alpha;
- float zoom[2], col[3] = {1, 1, 1};
+ float zoom[2], col[3] = {1, 1, 1};
switch (rc->subtype) {
case PROP_NONE:
@@ -2800,7 +2808,7 @@ static int radial_control_get_path(
return 0;
}
}
-
+
/* check property's array length */
if (*r_prop && (len = RNA_property_array_length(r_ptr, *r_prop)) != req_length) {
MEM_freeN(str);
@@ -2849,7 +2857,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op)
/* data path is required */
if (!rc->prop)
return 0;
-
+
if (!radial_control_get_path(&ctx_ptr, op, "rotation_path", &rc->rot_ptr, &rc->rot_prop, 0, RC_PROP_REQUIRE_FLOAT))
return 0;
if (!radial_control_get_path(&ctx_ptr, op, "color_path", &rc->col_ptr, &rc->col_prop, 3, RC_PROP_REQUIRE_FLOAT))
@@ -2884,7 +2892,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op)
{
return 0;
}
-
+
if (!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0))
return 0;
else if (rc->image_id_ptr.data) {
@@ -3007,7 +3015,7 @@ static void radial_control_cancel(bContext *C, wmOperator *op)
if (sa) {
ED_area_headerprint(sa, NULL);
}
-
+
WM_paint_cursor_end(wm, rc->cursor);
/* restore original paint cursors */
@@ -3048,10 +3056,10 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
if (numValue < 0.0f)
numValue += 2.0f * (float)M_PI;
}
-
+
CLAMP(numValue, rc->min_value, rc->max_value);
new_value = numValue;
-
+
radial_control_set_value(rc, new_value);
rc->current_value = new_value;
radial_control_update_header(op, C);
@@ -3202,9 +3210,9 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
CLAMP(numValue, rc->min_value, rc->max_value);
new_value = numValue;
-
+
radial_control_set_value(rc, new_value);
-
+
rc->current_value = new_value;
radial_control_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
@@ -3408,7 +3416,7 @@ static int redraw_timer_exec(bContext *C, wmOperator *op)
a = 0;
}
}
-
+
time_delta = (PIL_check_seconds_timer() - time_start) * 1000;
RNA_enum_description(redraw_timer_type_items, type, &infostr);
@@ -3418,7 +3426,7 @@ static int redraw_timer_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_WARNING,
"%d x %s: %.4f ms, average: %.8f ms",
iter_steps, infostr, time_delta, time_delta / iter_steps);
-
+
return OPERATOR_FINISHED;
}
@@ -3452,7 +3460,7 @@ static void WM_OT_memory_statistics(wmOperatorType *ot)
ot->name = "Memory Statistics";
ot->idname = "WM_OT_memory_statistics";
ot->description = "Print memory statistics to the console";
-
+
ot->exec = memory_statistics_exec;
}
@@ -3817,21 +3825,21 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf)
{GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Straight Line");
-
+
/* this function is called for each spacetype, only needs to add map once */
if (keymap && keymap->modal_items) return;
-
+
keymap = WM_modalkeymap_add(keyconf, "Gesture Straight Line", modal_items);
-
+
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL);
-
+
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
-
+
/* assign map to operators */
WM_modalkeymap_assign(keymap, "IMAGE_OT_sample_line");
WM_modalkeymap_assign(keymap, "PAINT_OT_weight_gradient");
@@ -3859,7 +3867,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
-
+
/* Note: cancel only on press otherwise you cannot map this to RMB-gesture */
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
@@ -3871,10 +3879,10 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
/* any unhandled leftclick release handles select */
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
-
+
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_DESELECT);
-
+
/* assign map to operators */
WM_modalkeymap_assign(keymap, "ACTION_OT_select_border");
WM_modalkeymap_assign(keymap, "ANIM_OT_channels_select_border");
@@ -3928,7 +3936,7 @@ static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_IN);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_IN);
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_OUT);
@@ -3944,7 +3952,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Window", 0, 0);
wmKeyMapItem *kmi;
-
+
/* note, this doesn't replace existing keymap items */
WM_keymap_verify_item(keymap, "WM_OT_window_new", WKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
#ifdef __APPLE__
@@ -3956,7 +3964,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "WM_OT_quit_blender", QKEY, KM_PRESS, KM_OSKEY, 0);
#endif
WM_keymap_add_item(keymap, "WM_OT_read_homefile", NKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_menu(keymap, "INFO_MT_file_open_recent", OKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "WM_OT_open_mainfile", F1KEY, KM_PRESS, 0, 0);
@@ -3981,7 +3989,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
/* menus that can be accessed anywhere in blender */
- WM_keymap_verify_item(keymap, "WM_OT_search_menu", TABKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "WM_OT_search_menu", ACCENTGRAVEKEY, KM_RELEASE, 0, 0);
#ifdef WITH_INPUT_NDOF
WM_keymap_add_menu(keymap, "USERPREF_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0);
@@ -4029,7 +4037,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F12KEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "area.type");
RNA_string_set(kmi->ptr, "value", "DOPESHEET_EDITOR");
-
+
#ifdef WITH_INPUT_NDOF
/* ndof speed */
const char *data_path = "user_preferences.inputs.ndof_sensitivity";
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index d6a1eb81981..d93d51df105 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -101,7 +101,7 @@ typedef struct PlayState {
/* window and viewport size */
int win_x, win_y;
-
+
/* current zoom level */
float zoom;
@@ -122,7 +122,7 @@ typedef struct PlayState {
bool loading;
/* x/y image flip */
bool draw_flip[2];
-
+
int fstep;
/* current picture */
@@ -134,7 +134,7 @@ typedef struct PlayState {
/* saves passing args */
struct ImBuf *curframe_ibuf;
-
+
/* restarts player for file drop */
char dropped_file[FILE_MAX];
} PlayState;
@@ -946,13 +946,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
{
GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
int cx, cy, sizex, sizey, inside_window;
-
+
GHOST_GetCursorPosition(g_WS.ghost_system, &cx, &cy);
GHOST_ScreenToClient(g_WS.ghost_window, cx, cy, &cx, &cy);
playanim_window_get_size(&sizex, &sizey);
inside_window = (cx >= 0 && cx < sizex && cy >= 0 && cy <= sizey);
-
+
if (bd->button == GHOST_kButtonMaskLeft) {
if (type == GHOST_kEventButtonDown) {
if (inside_window) {
@@ -1016,23 +1016,23 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kEventWindowMove:
{
float zoomx, zoomy;
-
+
playanim_window_get_size(&ps->win_x, &ps->win_y);
GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
zoomx = (float) ps->win_x / ps->ibufx;
zoomy = (float) ps->win_y / ps->ibufy;
-
+
/* zoom always show entire image */
ps->zoom = MIN2(zoomx, zoomy);
-
+
/* zoom steps of 2 for speed */
ps->zoom = floor(ps->zoom + 0.5f);
if (ps->zoom < 1.0f) ps->zoom = 1.0f;
-
+
glViewport(0, 0, ps->win_x, ps->win_y);
glScissor(0, 0, ps->win_x, ps->win_y);
-
+
playanim_gl_matrix();
ptottime = 0.0;
@@ -1049,11 +1049,11 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kEventDraggingDropDone:
{
GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
-
+
if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
GHOST_TStringArray *stra = ddd->data;
int a;
-
+
for (a = 0; a < stra->count; a++) {
BLI_strncpy(ps->dropped_file, (char *)stra->strings[a], sizeof(ps->dropped_file));
ps->go = false;
@@ -1120,7 +1120,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
int sfra = -1;
int efra = -1;
int totblock;
-
+
PlayState ps = {0};
/* ps.doubleb = true;*/ /* UNUSED */
@@ -1271,14 +1271,14 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
ps.ibufx = ibuf->x;
ps.ibufy = ibuf->y;
-
+
ps.win_x = ps.ibufx;
ps.win_y = ps.ibufy;
if (maxwinx % ibuf->x) maxwinx = ibuf->x * (1 + (maxwinx / ibuf->x));
if (maxwiny % ibuf->y) maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y));
-
+
glClearColor(0.1, 0.1, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -1547,7 +1547,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
BLI_strncpy(filepath, ps.dropped_file, sizeof(filepath));
return filepath;
}
-
+
IMB_exit();
BKE_images_exit();
DEG_free_node_types();
@@ -1560,7 +1560,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
MEM_printmemlist();
#endif
}
-
+
return NULL;
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 28fb4f2e011..e1528551c12 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -35,7 +35,7 @@
#include <stdio.h>
#include <string.h>
-#include "DNA_listBase.h"
+#include "DNA_listBase.h"
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_workspace_types.h"
@@ -85,6 +85,8 @@
#include "GPU_framebuffer.h"
#include "GPU_init_exit.h"
#include "GPU_immediate.h"
+#include "GPU_material.h"
+#include "GPU_texture.h"
#include "BLF_api.h"
#include "UI_resources.h"
@@ -112,7 +114,7 @@ static struct WMInitStruct {
int windowstate;
WinOverrideFlag override_flag;
-
+
bool native_pixels;
} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0, true};
@@ -124,7 +126,7 @@ void wm_get_screensize(int *r_width, int *r_height)
{
unsigned int uiwidth;
unsigned int uiheight;
-
+
GHOST_GetMainDisplayDimensions(g_system, &uiwidth, &uiheight);
*r_width = uiwidth;
*r_height = uiheight;
@@ -146,9 +148,9 @@ void wm_get_desktopsize(int *r_width, int *r_height)
static void wm_window_check_position(rcti *rect)
{
int width, height, d;
-
+
wm_get_screensize(&width, &height);
-
+
if (rect->xmin < 0) {
rect->xmax -= rect->xmin;
rect->xmin = 0;
@@ -167,7 +169,7 @@ static void wm_window_check_position(rcti *rect)
rect->ymax -= d;
rect->ymin -= d;
}
-
+
if (rect->xmin < 0) rect->xmin = 0;
if (rect->ymin < 0) rect->ymin = 0;
}
@@ -193,12 +195,12 @@ static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win)
}
}
-/* including window itself, C can be NULL.
+/* including window itself, C can be NULL.
* ED_screen_exit should have been called */
void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win)
{
wmTimer *wt, *wtnext;
-
+
/* update context */
if (C) {
WM_event_remove_handlers(C, &win->handlers);
@@ -216,7 +218,7 @@ void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win)
if (wt->win == win && wt->event_type == TIMERJOBS)
wm_jobs_timer_ended(wm, wt);
}
-
+
/* timer removing, need to call this api function */
for (wt = wm->timers.first; wt; wt = wtnext) {
wtnext = wt->next;
@@ -225,7 +227,7 @@ void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win)
}
if (win->eventstate) MEM_freeN(win->eventstate);
-
+
wm_event_free_all(win);
wm_ghostwindow_destroy(wm, win);
@@ -240,11 +242,11 @@ static int find_free_winid(wmWindowManager *wm)
{
wmWindow *win;
int id = 1;
-
+
for (win = wm->windows.first; win; win = win->next)
if (id <= win->winid)
id = win->winid + 1;
-
+
return id;
}
@@ -287,6 +289,7 @@ static wmWindow *wm_window_new_test(bContext *C)
/* part of wm_window.c api */
wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_layout)
{
+ Main *bmain = CTX_data_main(C);
wmWindow *win_dst = wm_window_new(C);
WorkSpace *workspace = WM_window_get_active_workspace(win_src);
WorkSpaceLayout *layout_old = WM_window_get_active_layout(win_src);
@@ -300,7 +303,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *win_src, const bool duplicate_la
win_dst->scene = scene;
WM_window_set_active_workspace(win_dst, workspace);
- layout_new = duplicate_layout ? ED_workspace_layout_duplicate(workspace, layout_old, win_dst) : layout_old;
+ layout_new = duplicate_layout ? ED_workspace_layout_duplicate(bmain, workspace, layout_old, win_dst) : layout_old;
WM_window_set_active_layout(win_dst, workspace, layout_new);
*win_dst->stereo3d_format = *win_src->stereo3d_format;
@@ -373,6 +376,7 @@ static void wm_block_confirm_quit_save(bContext *C, void *arg_block, void *UNUSE
/* Build the confirm dialog UI */
static uiBlock *block_create_confirm_quit(struct bContext *C, struct ARegion *ar, void *UNUSED(arg1))
{
+ Main *bmain = CTX_data_main(C);
uiStyle *style = UI_style_get();
uiBlock *block = UI_block_begin(C, ar, "confirm_quit_popup", UI_EMBOSS);
@@ -386,11 +390,11 @@ static uiBlock *block_create_confirm_quit(struct bContext *C, struct ARegion *ar
/* Text and some vertical space */
{
char *message;
- if (G.main->name[0] == '\0') {
+ if (BKE_main_blendfile_path(bmain)[0] == '\0') {
message = BLI_strdup(IFACE_("This file has not been saved yet. Save before closing?"));
}
else {
- const char *basename = BLI_path_basename(G.main->name);
+ const char *basename = BLI_path_basename(BKE_main_blendfile_path(bmain));
message = BLI_sprintfN(IFACE_("Save changes to \"%s\" before closing?"), basename);
}
uiItemL(layout, message, ICON_ERROR);
@@ -483,7 +487,7 @@ void wm_quit_with_optional_confirmation_prompt(bContext *C, wmWindow *win)
void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
wmWindow *tmpwin;
-
+
/* first check if we have to quit (there are non-temp remaining windows) */
for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) {
if (tmpwin == win)
@@ -501,7 +505,7 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
WorkSpaceLayout *layout = BKE_workspace_active_layout_get(win->workspace_hook);
BLI_remlink(&wm->windows, win);
-
+
CTX_wm_window_set(C, win); /* needed by handlers */
WM_event_remove_handlers(C, &win->handlers);
WM_event_remove_handlers(C, &win->modalhandlers);
@@ -545,9 +549,10 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
}
else if (win->ghostwin) {
/* this is set to 1 if you don't have startup.blend open */
- if (G.save_over && G.main->name[0]) {
- char str[sizeof(G.main->name) + 24];
- BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*", G.main->name,
+ if (G.save_over && BKE_main_blendfile_path_from_global()[0]) {
+ char str[sizeof(((Main *)NULL)->name) + 24];
+ BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*",
+ BKE_main_blendfile_path_from_global(),
G.main->recovered ? " (Recovered)" : "");
GHOST_SetTitle(win->ghostwin, str);
}
@@ -558,7 +563,7 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
* and to give hint of unsaved changes for a user warning mechanism
* in case of OS application terminate request (e.g. OS Shortcut Alt+F4, Cmd+Q, (...), or session end) */
GHOST_SetWindowModifiedState(win->ghostwin, (GHOST_TUns8) !wm->file_saved);
-
+
}
}
@@ -624,7 +629,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
GHOST_WindowHandle ghostwin;
GHOST_GLSettings glSettings = {0};
int scr_w, scr_h, posy;
-
+
/* a new window is created when pageflip mode is required for a window */
if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP)
glSettings.flags |= GHOST_glStereoVisual;
@@ -635,7 +640,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
wm_get_screensize(&scr_w, &scr_h);
posy = (scr_h - win->posy - win->sizey);
-
+
ghostwin = GHOST_CreateWindow(g_system, title,
win->posx, posy, win->sizex, win->sizey,
(GHOST_TWindowState)win->windowstate,
@@ -651,16 +656,16 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
gpu_batch_presets_reset();
win->gwnctx = GWN_context_create();
-
+
/* the new window has already been made drawable upon creation */
wm->windrawable = win;
/* needed so we can detect the graphics card below */
GPU_init();
-
+
win->ghostwin = ghostwin;
GHOST_SetWindowUserData(ghostwin, win); /* pointer back */
-
+
wm_window_ensure_eventstate(win);
/* store actual window size in blender window */
@@ -672,7 +677,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
win->sizey = GHOST_GetHeightRectangle(bounds);
}
GHOST_DisposeRectangle(bounds);
-
+
#ifndef __APPLE__
/* set the state here, so minimized state comes up correct on windows */
GHOST_SetWindowState(ghostwin, (GHOST_TWindowState)win->windowstate);
@@ -683,14 +688,14 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
if (!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
glClear(GL_COLOR_BUFFER_BIT);
}
-
+
/* needed here, because it's used before it reads userdef */
WM_window_set_dpi(win);
-
+
wm_window_swap_buffers(win);
-
+
//GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified);
-
+
/* standard state vars for window */
GPU_state_init();
}
@@ -713,7 +718,7 @@ void wm_window_ghostwindows_ensure(wmWindowManager *wm)
{
wmKeyMap *keymap;
wmWindow *win;
-
+
BLI_assert(G.background == false);
/* no commandline prefsize? then we set this.
@@ -722,7 +727,7 @@ void wm_window_ghostwindows_ensure(wmWindowManager *wm)
*/
if (wm_init_state.size_x == 0) {
wm_get_screensize(&wm_init_state.size_x, &wm_init_state.size_y);
-
+
/* note!, this isnt quite correct, active screen maybe offset 1000s if PX,
* we'd need a wm_get_screensize like function that gives offset,
* in practice the window manager will likely move to the correct monitor */
@@ -740,7 +745,7 @@ void wm_window_ghostwindows_ensure(wmWindowManager *wm)
wm_init_state.size_y -= WM_WIN_INIT_PAD * 2;
#endif
}
-
+
for (win = wm->windows.first; win; win = win->next) {
if (win->ghostwin == NULL) {
if ((win->sizex == 0) || (wm_init_state.override_flag & WIN_OVERRIDE_GEOM)) {
@@ -771,13 +776,13 @@ void wm_window_ghostwindows_ensure(wmWindowManager *wm)
/* add keymap handlers (1 handler for all keys in map!) */
keymap = WM_keymap_find(wm->defaultconf, "Window", 0, 0);
WM_event_add_keymap_handler(&win->handlers, keymap);
-
+
keymap = WM_keymap_find(wm->defaultconf, "Screen", 0, 0);
WM_event_add_keymap_handler(&win->handlers, keymap);
keymap = WM_keymap_find(wm->defaultconf, "Screen Editing", 0, 0);
WM_event_add_keymap_handler(&win->modalhandlers, keymap);
-
+
/* add drop boxes */
{
ListBase *lb = WM_dropboxmap_find("Window", 0, 0);
@@ -820,7 +825,7 @@ wmWindow *WM_window_open(bContext *C, const rcti *rect)
{
wmWindow *win_prev = CTX_wm_window(C);
wmWindow *win = wm_window_new(C);
-
+
win->posx = rect->xmin;
win->posy = rect->ymin;
win->sizex = BLI_rcti_size_x(rect);
@@ -871,16 +876,16 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
/* changes rect to fit within desktop */
wm_window_check_position(&rect);
-
+
/* test if we have a temp screen already */
for (win = CTX_wm_manager(C)->windows.first; win; win = win->next)
if (WM_window_is_temp_screen(win))
break;
-
+
/* add new window? */
if (win == NULL) {
win = wm_window_new(C);
-
+
win->posx = rect.xmin;
win->posy = rect.ymin;
}
@@ -903,7 +908,7 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
if (screen == NULL) {
/* add new screen layout */
WorkSpace *workspace = WM_window_get_active_workspace(win);
- WorkSpaceLayout *layout = ED_workspace_layout_add(workspace, win, "temp");
+ WorkSpaceLayout *layout = ED_workspace_layout_add(bmain, workspace, win, "temp");
screen = BKE_workspace_layout_screen_get(layout);
WM_window_set_active_layout(win, workspace, layout);
@@ -932,7 +937,7 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
/* ensure it shows the right spacetype editor */
sa = screen->areabase.first;
CTX_wm_area_set(C, sa);
-
+
if (type == WM_WINDOW_RENDER) {
ED_area_newspace(C, sa, SPACE_IMAGE, false);
}
@@ -942,26 +947,26 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
else {
ED_area_newspace(C, sa, SPACE_USERPREF, false);
}
-
+
ED_screen_change(C, screen);
ED_screen_refresh(CTX_wm_manager(C), win); /* test scale */
-
+
/* do additional setup for specific editor type */
if (type == WM_WINDOW_DRIVERS) {
/* Configure editor - mode, tabs, framing */
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
sipo->mode = SIPO_MODE_DRIVERS;
-
+
ARegion *ar_props = BKE_area_find_region_type(sa, RGN_TYPE_UI);
if (ar_props) {
UI_panel_category_active_set(ar_props, "Drivers");
-
+
ar_props->flag &= ~RGN_FLAG_HIDDEN;
/* XXX: Adjust width of this too? */
-
+
ED_region_visibility_change_update(C, ar_props);
}
-
+
ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
if (ar_main) {
/* XXX: Ideally we recenter based on the range instead... */
@@ -969,11 +974,11 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
ar_main->v2d.tot.ymin = -2.0f;
ar_main->v2d.tot.xmax = 2.0f;
ar_main->v2d.tot.ymax = 2.0f;
-
+
ar_main->v2d.cur = ar_main->v2d.tot;
}
}
-
+
if (sa->spacetype == SPACE_IMAGE)
title = IFACE_("Blender Render");
else if (ELEM(sa->spacetype, SPACE_OUTLINER, SPACE_USERPREF))
@@ -1028,6 +1033,7 @@ static WorkSpaceLayout *wm_window_new_find_layout(wmOperator *op, WorkSpace *wor
/* new window operator callback */
int wm_window_new_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
wmWindow *win_src = CTX_wm_window(C);
WorkSpace *workspace = WM_window_get_active_workspace(win_src);
WorkSpaceLayout *layout_new = wm_window_new_find_layout(op, workspace);
@@ -1037,7 +1043,7 @@ int wm_window_new_exec(bContext *C, wmOperator *op)
if ((win_dst = wm_window_new_test(C))) {
if (screen_new->winid) {
/* layout/screen is already used, duplicate it */
- layout_new = ED_workspace_layout_duplicate(workspace, layout_new, win_dst);
+ layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_new, win_dst);
screen_new = BKE_workspace_layout_screen_get(layout_new);
}
/* New window with a different screen but same workspace */
@@ -1128,7 +1134,7 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
GHOST_SetWindowState(window->ghostwin, GHOST_kWindowStateNormal);
return OPERATOR_FINISHED;
-
+
}
@@ -1137,10 +1143,10 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
void wm_cursor_position_from_ghost(wmWindow *win, int *x, int *y)
{
float fac = GHOST_GetNativePixelSize(win->ghostwin);
-
+
GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
*x *= fac;
-
+
*y = (win->sizey - 1) - *y;
*y *= fac;
}
@@ -1170,11 +1176,11 @@ typedef enum {
} modifierKeyType;
/* check if specified modifier key type is pressed */
-static int query_qual(modifierKeyType qual)
+static int query_qual(modifierKeyType qual)
{
GHOST_TModifierKeyMask left, right;
int val = 0;
-
+
switch (qual) {
case SHIFT:
left = GHOST_kModifierKeyLeftShift;
@@ -1193,15 +1199,15 @@ static int query_qual(modifierKeyType qual)
right = GHOST_kModifierKeyRightAlt;
break;
}
-
+
GHOST_GetModifierKeyState(g_system, left, &val);
if (!val)
GHOST_GetModifierKeyState(g_system, right, &val);
-
+
return val;
}
-void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
+void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
{
BLI_assert(GPU_framebuffer_current_get() == 0);
@@ -1255,7 +1261,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
wmWindowManager *wm = CTX_wm_manager(C);
GHOST_TEventType type = GHOST_GetEventType(evt);
int time = GHOST_GetEventTime(evt);
-
+
if (type == GHOST_kEventQuit) {
WM_exit(C);
}
@@ -1263,7 +1269,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
GHOST_WindowHandle ghostwin = GHOST_GetEventWindow(evt);
GHOST_TEventDataPtr data = GHOST_GetEventData(evt);
wmWindow *win;
-
+
/* Ghost now can call this function for life resizes, but it should return if WM didn't initialize yet.
* Can happen on file read (especially full size window) */
if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) {
@@ -1284,12 +1290,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
else {
win = GHOST_GetWindowUserData(ghostwin);
}
-
+
switch (type) {
case GHOST_kEventWindowDeactivate:
wm_event_add_ghostevent(wm, win, type, time, data);
win->active = 0; /* XXX */
-
+
/* clear modifiers for inactive windows */
win->eventstate->alt = 0;
win->eventstate->ctrl = 0;
@@ -1298,7 +1304,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
win->eventstate->keymodifier = 0;
break;
- case GHOST_kEventWindowActivate:
+ case GHOST_kEventWindowActivate:
{
GHOST_TEventKeyData kdata;
wmEvent event;
@@ -1314,10 +1320,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
#endif
wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
-
+
win->active = 1;
// window_handle(win, INPUTCHANGE, win->active);
-
+
/* bad ghost support for modifier keys... so on activate we set the modifiers again */
/* TODO: This is not correct since a modifier may be held when a window is activated...
@@ -1386,15 +1392,15 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
/* keymodifier zero, it hangs on hotkeys that open windows otherwise */
win->eventstate->keymodifier = 0;
-
+
/* entering window, update mouse pos. but no event */
wm_get_cursor_position(win, &wx, &wy);
win->eventstate->x = wx;
win->eventstate->y = wy;
-
+
win->addmousemove = 1; /* enables highlighted buttons */
-
+
wm_window_make_drawable(wm, win);
/* window might be focused by mouse click in configuration of window manager
@@ -1425,7 +1431,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
if (G.debug & G_DEBUG_EVENTS) {
printf("%s: ghost redraw %d\n", __func__, win->winid);
}
-
+
wm_window_make_drawable(wm, win);
WM_event_add_notifier(C, NC_WINDOW, NULL);
@@ -1444,18 +1450,18 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
}
WM_window_set_dpi(win);
-
+
/* win32: gives undefined window size when minimized */
if (state != GHOST_kWindowStateMinimized) {
GHOST_RectangleHandle client_rect;
int l, t, r, b, scr_w, scr_h;
int sizex, sizey, posx, posy;
-
+
client_rect = GHOST_GetClientBounds(win->ghostwin);
GHOST_GetRectangle(client_rect, &l, &t, &r, &b);
-
+
GHOST_DisposeRectangle(client_rect);
-
+
wm_get_desktopsize(&scr_w, &scr_h);
sizex = r - l;
sizey = b - t;
@@ -1466,8 +1472,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
* Ghost sometimes send size or move events when the window hasn't changed.
* One case of this is using compiz on linux. To alleviate the problem
* we ignore all such event here.
- *
- * It might be good to eventually do that at Ghost level, but that is for
+ *
+ * It might be good to eventually do that at Ghost level, but that is for
* another time.
*/
if (win->sizex != sizex ||
@@ -1510,12 +1516,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
win->posx, win->posy, win->sizex, win->sizey);
}
}
-
+
wm_window_make_drawable(wm, win);
BKE_icon_changed(screen->id.icon_id);
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
-
+
#if defined(__APPLE__) || defined(WIN32)
/* OSX and Win32 don't return to the mainloop while resize */
wm_event_do_notifiers(C);
@@ -1546,19 +1552,19 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
PointerRNA props_ptr;
wmWindow *oldWindow;
const char *path = GHOST_GetEventData(evt);
-
+
if (path) {
wmOperatorType *ot = WM_operatortype_find("WM_OT_open_mainfile", false);
/* operator needs a valid window in context, ensures
* it is correctly set */
oldWindow = CTX_wm_window(C);
CTX_wm_window_set(C, win);
-
+
WM_operator_properties_create_ptr(&props_ptr, ot);
RNA_string_set(&props_ptr, "filepath", path);
WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr);
WM_operator_properties_free(&props_ptr);
-
+
CTX_wm_window_set(C, oldWindow);
}
break;
@@ -1568,53 +1574,53 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
wmEvent event;
GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
int wx, wy;
-
+
/* entering window, update mouse pos */
wm_get_cursor_position(win, &wx, &wy);
win->eventstate->x = wx;
win->eventstate->y = wy;
-
+
wm_event_init_from_window(win, &event); /* copy last state, like mouse coords */
-
+
/* activate region */
event.type = MOUSEMOVE;
event.prevx = event.x;
event.prevy = event.y;
-
+
wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
win->active = 1;
-
+
wm_event_add(win, &event);
-
-
+
+
/* make blender drop event with custom data pointing to wm drags */
event.type = EVT_DROP;
event.val = KM_RELEASE;
event.custom = EVT_DATA_DRAGDROP;
event.customdata = &wm->drags;
event.customdatafree = 1;
-
+
wm_event_add(win, &event);
-
+
/* printf("Drop detected\n"); */
-
+
/* add drag data to wm for paths: */
-
+
if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
GHOST_TStringArray *stra = ddd->data;
int a, icon;
-
+
for (a = 0; a < stra->count; a++) {
printf("drop file %s\n", stra->strings[a]);
/* try to get icon type from extension */
icon = ED_file_extension_icon((char *)stra->strings[a]);
-
+
WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0, WM_DRAG_NOP);
/* void poin should point to string, it makes a copy */
break; /* only one drop element supported now */
}
}
-
+
break;
}
case GHOST_kEventNativeResolutionChange:
@@ -1644,7 +1650,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
case GHOST_kEventTrackpad:
{
GHOST_TEventTrackpadData *pd = data;
-
+
wm_cursor_position_from_ghost(win, &pd->x, &pd->y);
wm_event_add_ghostevent(wm, win, type, time, data);
break;
@@ -1652,7 +1658,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
case GHOST_kEventCursorMove:
{
GHOST_TEventCursorData *cd = data;
-
+
wm_cursor_position_from_ghost(win, &cd->x, &cd->y);
wm_event_add_ghostevent(wm, win, type, time, data);
break;
@@ -1680,7 +1686,7 @@ static int wm_window_timer(const bContext *C)
wmWindow *win;
double time = PIL_check_seconds_timer();
int retval = 0;
-
+
for (wt = wm->timers.first; wt; wt = wtnext) {
wtnext = wt->next; /* in case timer gets removed */
win = wt->win;
@@ -1701,7 +1707,7 @@ static int wm_window_timer(const bContext *C)
else if (win) {
wmEvent event;
wm_event_init_from_window(win, &event);
-
+
event.type = wt->event_type;
event.val = KM_NOTHING;
event.keymodifier = 0;
@@ -1717,7 +1723,7 @@ static int wm_window_timer(const bContext *C)
return retval;
}
-void wm_window_process_events(const bContext *C)
+void wm_window_process_events(const bContext *C)
{
int hasevent;
@@ -1727,7 +1733,7 @@ void wm_window_process_events(const bContext *C)
if (hasevent)
GHOST_DispatchEvents(g_system);
-
+
hasevent |= wm_window_timer(C);
/* no event, we sleep 5 milliseconds */
@@ -1735,7 +1741,7 @@ void wm_window_process_events(const bContext *C)
PIL_sleep_ms(5);
}
-void wm_window_process_events_nosleep(void)
+void wm_window_process_events_nosleep(void)
{
if (GHOST_ProcessEvents(g_system, 0))
GHOST_DispatchEvents(g_system);
@@ -1754,10 +1760,10 @@ void wm_window_testbreak(void)
*/
if ((curtime - ltime) > 0.05) {
int hasevent = GHOST_ProcessEvents(g_system, 0); /* 0 is no wait */
-
+
if (hasevent)
GHOST_DispatchEvents(g_system);
-
+
ltime = curtime;
}
}
@@ -1774,13 +1780,13 @@ void wm_ghost_init(bContext *C)
if (C != NULL) {
consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
}
-
+
g_system = GHOST_CreateSystem();
if (C != NULL) {
GHOST_AddEventConsumer(g_system, consumer);
}
-
+
if (wm_init_state.native_pixels) {
GHOST_UseNativePixels();
}
@@ -1801,7 +1807,7 @@ void wm_ghost_exit(void)
void WM_event_timer_sleep(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *timer, bool do_sleep)
{
wmTimer *wt;
-
+
for (wt = wm->timers.first; wt; wt = wt->next)
if (wt == timer)
break;
@@ -1820,9 +1826,9 @@ wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type,
wt->stime = wt->ltime;
wt->timestep = timestep;
wt->win = win;
-
+
BLI_addtail(&wm->timers, wt);
-
+
return wt;
}
@@ -1847,23 +1853,23 @@ wmTimer *WM_event_add_timer_notifier(wmWindowManager *wm, wmWindow *win, unsigne
void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *timer)
{
wmTimer *wt;
-
+
/* extra security check */
for (wt = wm->timers.first; wt; wt = wt->next)
if (wt == timer)
break;
if (wt) {
wmWindow *win;
-
+
if (wm->reports.reporttimer == wt)
wm->reports.reporttimer = NULL;
-
+
BLI_remlink(&wm->timers, wt);
if (wt->customdata != NULL && (wt->flags & WM_TIMER_NO_FREE_CUSTOM_DATA) == 0) {
MEM_freeN(wt->customdata);
}
MEM_freeN(wt);
-
+
/* there might be events in queue with this timer as customdata */
for (win = wm->windows.first; win; win = win->next) {
wmEvent *event;
@@ -1900,7 +1906,7 @@ static char *wm_clipboard_text_get_ex(bool selection, int *r_len,
*r_len = 0;
return NULL;
}
-
+
/* always convert from \r\n to \n */
p2 = newbuf = MEM_mallocN(strlen(buf) + 1, __func__);
@@ -1926,7 +1932,7 @@ static char *wm_clipboard_text_get_ex(bool selection, int *r_len,
*p2 = '\0';
free(buf); /* ghost uses regular malloc */
-
+
*r_len = (p2 - newbuf);
return newbuf;
@@ -1958,16 +1964,16 @@ void WM_clipboard_text_set(const char *buf, bool selection)
const char *p;
char *p2, *newbuf;
int newlen = 0;
-
+
for (p = buf; *p; p++) {
if (*p == '\n')
newlen += 2;
else
newlen++;
}
-
+
newbuf = MEM_callocN(newlen + 1, "WM_clipboard_text_set");
-
+
for (p = buf, p2 = newbuf; *p; p++, p2++) {
if (*p == '\n') {
*(p2++) = '\r'; *p2 = '\n';
@@ -1977,7 +1983,7 @@ void WM_clipboard_text_set(const char *buf, bool selection)
}
}
*p2 = '\0';
-
+
GHOST_putClipboard((GHOST_TInt8 *)newbuf, selection);
MEM_freeN(newbuf);
#else
@@ -2006,23 +2012,25 @@ void wm_window_get_position(wmWindow *win, int *r_pos_x, int *r_pos_y)
*r_pos_y = win->posy;
}
-void wm_window_set_size(wmWindow *win, int width, int height)
+void wm_window_set_size(wmWindow *win, int width, int height)
{
GHOST_SetClientSize(win->ghostwin, width, height);
}
-void wm_window_lower(wmWindow *win)
+void wm_window_lower(wmWindow *win)
{
GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderBottom);
}
-void wm_window_raise(wmWindow *win)
+void wm_window_raise(wmWindow *win)
{
GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderTop);
}
void wm_window_swap_buffers(wmWindow *win)
{
+ GPU_texture_orphans_delete(); /* XXX should be done elsewhere. */
+ GPU_material_orphans_delete(); /* XXX Amen to that. */
GHOST_SwapWindowBuffers(win->ghostwin);
}
@@ -2117,13 +2125,13 @@ float WM_cursor_pressure(const struct wmWindow *win)
int WM_window_pixels_x(const wmWindow *win)
{
float f = GHOST_GetNativePixelSize(win->ghostwin);
-
+
return (int)(f * (float)win->sizex);
}
int WM_window_pixels_y(const wmWindow *win)
{
float f = GHOST_GetNativePixelSize(win->ghostwin);
-
+
return (int)(f * (float)win->sizey);
}
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 33ca415b664..c92691eb65e 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -41,7 +41,7 @@ typedef struct wmPaintCursor {
struct wmPaintCursor *next, *prev;
void *customdata;
-
+
int (*poll)(struct bContext *C);
void (*draw)(bContext *C, int, int, void *customdata);
} wmPaintCursor;
@@ -54,7 +54,7 @@ extern void wm_close_and_free_all(bContext *C, ListBase *);
extern void wm_add_default(struct Main *bmain, bContext *C);
extern void wm_clear_default_size(bContext *C);
-
+
/* register to windowmanager for redo or macro */
void wm_operator_register(bContext *C, wmOperator *op);
diff --git a/source/blender/windowmanager/wm_cursors.h b/source/blender/windowmanager/wm_cursors.h
index c695a12f52c..939409f9511 100644
--- a/source/blender/windowmanager/wm_cursors.h
+++ b/source/blender/windowmanager/wm_cursors.h
@@ -39,12 +39,12 @@ void wm_init_cursor_data(void);
/* old cursors */
enum {
CURSOR_FACESEL = BC_GHOST_CURSORS,
- CURSOR_WAIT,
- CURSOR_EDIT,
- CURSOR_X_MOVE,
- CURSOR_Y_MOVE,
- CURSOR_HELP,
- CURSOR_STD,
+ CURSOR_WAIT,
+ CURSOR_EDIT,
+ CURSOR_X_MOVE,
+ CURSOR_Y_MOVE,
+ CURSOR_HELP,
+ CURSOR_STD,
CURSOR_NONE,
CURSOR_PENCIL,
CURSOR_COPY
@@ -57,21 +57,21 @@ typedef struct BCursor {
char *small_bm;
char *small_mask;
- char small_sizex;
- char small_sizey;
- char small_hotx;
- char small_hoty;
+ char small_sizex;
+ char small_sizey;
+ char small_hotx;
+ char small_hoty;
- char *big_bm;
+ char *big_bm;
char *big_mask;
- char big_sizex;
- char big_sizey;
- char big_hotx;
- char big_hoty;
+ char big_sizex;
+ char big_sizey;
+ char big_hotx;
+ char big_hoty;
- char fg_color;
- char bg_color;
+ char fg_color;
+ char bg_color;
} BCursor;
@@ -101,7 +101,7 @@ enum {
enum {
BC_BLACK = 0,
- BC_WHITE,
+ BC_WHITE,
BC_RED,
BC_BLUE,
BC_GREEN,
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 5edd4a76127..db2fd5ce7f2 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -92,7 +92,7 @@ enum {
WM_IME_COMPOSITE_EVENT = 0x0015,
/* IME event, GHOST_kEventImeCompositionEnd in ghost */
WM_IME_COMPOSITE_END = 0x0016,
-
+
/* Tablet/Pen Specific Events */
TABLET_STYLUS = 0x001a,
TABLET_ERASER = 0x001b,
diff --git a/source/tools b/source/tools
-Subproject 6bcd05cf6aaafae07b8a15313d7fdda1471ff59
+Subproject 9d7d338cb25a071f9646cf9ba16f17004c963f7
diff --git a/tests/gtests/alembic/abc_export_test.cc b/tests/gtests/alembic/abc_export_test.cc
index dab1e3ae040..c950084ef64 100644
--- a/tests/gtests/alembic/abc_export_test.cc
+++ b/tests/gtests/alembic/abc_export_test.cc
@@ -16,9 +16,8 @@ extern "C" {
class TestableAbcExporter : public AbcExporter {
public:
TestableAbcExporter(Main *bmain,
- Scene *scene, Depsgraph *depsgraph,
const char *filename, ExportSettings &settings)
- : AbcExporter(bmain, scene, depsgraph, filename, settings)
+ : AbcExporter(bmain, filename, settings)
{
}
@@ -57,7 +56,10 @@ protected:
/* TODO(sergey): Pass scene layer somehow? */
ViewLayer *view_layer = (ViewLayer *)scene.view_layers.first;
- depsgraph = DEG_graph_new(&scene, view_layer, DAG_EVAL_VIEWPORT);
+ settings.depsgraph = depsgraph = DEG_graph_new(&scene, view_layer, DAG_EVAL_VIEWPORT);
+
+ settings.scene = &scene;
+ settings.view_layer = view_layer;
exporter = NULL;
}
@@ -72,7 +74,7 @@ protected:
// Call after setting up the settings.
void createExporter()
{
- exporter = new TestableAbcExporter(bmain, &scene, depsgraph, "somefile.abc", settings);
+ exporter = new TestableAbcExporter(bmain, "somefile.abc", settings);
}
};
diff --git a/tests/gtests/blenlib/BLI_heap_test.cc b/tests/gtests/blenlib/BLI_heap_test.cc
index 82acdabd7eb..dd0bc3451ce 100644
--- a/tests/gtests/blenlib/BLI_heap_test.cc
+++ b/tests/gtests/blenlib/BLI_heap_test.cc
@@ -40,7 +40,7 @@ TEST(heap, One)
const char *in = "test";
heap = BLI_heap_new();
-
+
BLI_heap_insert(heap, 0.0f, (void *)in);
EXPECT_FALSE(BLI_heap_is_empty(heap));
EXPECT_EQ(BLI_heap_len(heap), 1);
diff --git a/tests/python/bl_pyapi_mathutils.py b/tests/python/bl_pyapi_mathutils.py
index 9ca0376192a..b2d3d79fd56 100644
--- a/tests/python/bl_pyapi_mathutils.py
+++ b/tests/python/bl_pyapi_mathutils.py
@@ -127,7 +127,7 @@ class MatrixTesting(unittest.TestCase):
(0, 0, 0, 1)))
vec = Vector((1, 2, 3))
-
+
prod_mat_vec = Vector((7, 12, 4))
prod_vec_mat = Vector((1, 12, 5))
diff --git a/tests/python/collada/animation/test_animation_simple.py b/tests/python/collada/animation/test_animation_simple.py
index 6686d429261..bdfae03aafb 100644
--- a/tests/python/collada/animation/test_animation_simple.py
+++ b/tests/python/collada/animation/test_animation_simple.py
@@ -113,37 +113,37 @@ class MeshExportTest4(AbstractColladaTest):
test = "suzannes_parent_inverse_sample_10_matrix"
reference_dae = self.testdir / Path("%s.dae" % test)
outfile = tempdir / Path("%s_out.dae" % test)
-
+
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
- check_existing=True,
- filemode=8,
- display_type='DEFAULT',
- sort_method='FILE_SORT_ALPHA',
- apply_modifiers=True,
- export_mesh_type=0,
- export_mesh_type_selection='view',
- selected=True,
- include_children=True,
- include_armatures=True,
- include_shapekeys=False,
- deform_bones_only=False,
- include_animations=True,
- sample_animations=True,
- sampling_rate=10,
- active_uv_only=False,
- use_texture_copies=True,
- triangulate=False,
- use_object_instantiation=True,
- use_blender_profile=True,
- sort_by_name=False,
- export_transformation_type=0,
- export_transformation_type_selection='matrix',
- export_texture_type=0,
- export_texture_type_selection='mat',
- open_sim=False,
- limit_precision=True,
+ check_existing=True,
+ filemode=8,
+ display_type='DEFAULT',
+ sort_method='FILE_SORT_ALPHA',
+ apply_modifiers=True,
+ export_mesh_type=0,
+ export_mesh_type_selection='view',
+ selected=True,
+ include_children=True,
+ include_armatures=True,
+ include_shapekeys=False,
+ deform_bones_only=False,
+ include_animations=True,
+ sample_animations=True,
+ sampling_rate=10,
+ active_uv_only=False,
+ use_texture_copies=True,
+ triangulate=False,
+ use_object_instantiation=True,
+ use_blender_profile=True,
+ sort_by_name=False,
+ export_transformation_type=0,
+ export_transformation_type_selection='matrix',
+ export_texture_type=0,
+ export_texture_type_selection='mat',
+ open_sim=False,
+ limit_precision=True,
keep_bind_info=False)
-
+
# Now check the resulting Collada file.
if not self.checkdae(reference_dae, outfile):
self.fail()
@@ -154,37 +154,37 @@ class MeshExportTest3(AbstractColladaTest):
test = "suzannes_parent_inverse_sample_10_channels"
reference_dae = self.testdir / Path("%s.dae" % test)
outfile = tempdir / Path("%s_out.dae" % test)
-
+
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
- check_existing=True,
- filemode=8,
- display_type='DEFAULT',
- sort_method='FILE_SORT_ALPHA',
- apply_modifiers=True,
- export_mesh_type=0,
- export_mesh_type_selection='view',
- selected=True,
- include_children=True,
- include_armatures=True,
- include_shapekeys=False,
- deform_bones_only=False,
- include_animations=True,
- sample_animations=True,
- sampling_rate=10,
- active_uv_only=False,
- use_texture_copies=True,
- triangulate=False,
- use_object_instantiation=True,
- use_blender_profile=True,
- sort_by_name=False,
- export_transformation_type=0,
- export_transformation_type_selection='transrotloc',
- export_texture_type=0,
- export_texture_type_selection='mat',
- open_sim=False,
- limit_precision=True,
+ check_existing=True,
+ filemode=8,
+ display_type='DEFAULT',
+ sort_method='FILE_SORT_ALPHA',
+ apply_modifiers=True,
+ export_mesh_type=0,
+ export_mesh_type_selection='view',
+ selected=True,
+ include_children=True,
+ include_armatures=True,
+ include_shapekeys=False,
+ deform_bones_only=False,
+ include_animations=True,
+ sample_animations=True,
+ sampling_rate=10,
+ active_uv_only=False,
+ use_texture_copies=True,
+ triangulate=False,
+ use_object_instantiation=True,
+ use_blender_profile=True,
+ sort_by_name=False,
+ export_transformation_type=0,
+ export_transformation_type_selection='transrotloc',
+ export_texture_type=0,
+ export_texture_type_selection='mat',
+ open_sim=False,
+ limit_precision=True,
keep_bind_info=False)
-
+
# Now check the resulting Collada file.
if not self.checkdae(reference_dae, outfile):
self.fail()
@@ -195,37 +195,37 @@ class MeshExportTest2(AbstractColladaTest):
test = "suzannes_parent_inverse_keyframes_matrix"
reference_dae = self.testdir / Path("%s.dae" % test)
outfile = tempdir / Path("%s_out.dae" % test)
-
+
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
- check_existing=True,
- filemode=8,
- display_type='DEFAULT',
- sort_method='FILE_SORT_ALPHA',
- apply_modifiers=True,
- export_mesh_type=0,
- export_mesh_type_selection='view',
- selected=True,
- include_children=True,
- include_armatures=True,
- include_shapekeys=False,
- deform_bones_only=False,
- include_animations=True,
- sample_animations=False,
- sampling_rate=1,
- active_uv_only=False,
- use_texture_copies=True,
- triangulate=False,
- use_object_instantiation=True,
- use_blender_profile=True,
- sort_by_name=False,
- export_transformation_type=0,
- export_transformation_type_selection='matrix',
- export_texture_type=0,
- export_texture_type_selection='mat',
- open_sim=False,
- limit_precision=True,
+ check_existing=True,
+ filemode=8,
+ display_type='DEFAULT',
+ sort_method='FILE_SORT_ALPHA',
+ apply_modifiers=True,
+ export_mesh_type=0,
+ export_mesh_type_selection='view',
+ selected=True,
+ include_children=True,
+ include_armatures=True,
+ include_shapekeys=False,
+ deform_bones_only=False,
+ include_animations=True,
+ sample_animations=False,
+ sampling_rate=1,
+ active_uv_only=False,
+ use_texture_copies=True,
+ triangulate=False,
+ use_object_instantiation=True,
+ use_blender_profile=True,
+ sort_by_name=False,
+ export_transformation_type=0,
+ export_transformation_type_selection='matrix',
+ export_texture_type=0,
+ export_texture_type_selection='mat',
+ open_sim=False,
+ limit_precision=True,
keep_bind_info=False)
-
+
# Now check the resulting Collada file.
if not self.checkdae(reference_dae, outfile):
self.fail()
@@ -236,45 +236,45 @@ class MeshExportTest1(AbstractColladaTest):
test = "suzannes_parent_inverse_keyframes_channels"
reference_dae = self.testdir / Path("%s.dae" % test)
outfile = tempdir / Path("%s_out.dae" % test)
-
+
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
- check_existing=True,
- filemode=8,
- display_type='DEFAULT',
- sort_method='FILE_SORT_ALPHA',
- apply_modifiers=True,
- export_mesh_type=0,
- export_mesh_type_selection='view',
- selected=True,
- include_children=True,
- include_armatures=True,
- include_shapekeys=False,
- deform_bones_only=False,
- include_animations=True,
- sample_animations=False,
- sampling_rate=1,
- active_uv_only=False,
- use_texture_copies=True,
- triangulate=False,
- use_object_instantiation=True,
- use_blender_profile=True,
- sort_by_name=False,
- export_transformation_type=0,
- export_transformation_type_selection='transrotloc',
- export_texture_type=0,
- export_texture_type_selection='mat',
- open_sim=False,
- limit_precision=True,
+ check_existing=True,
+ filemode=8,
+ display_type='DEFAULT',
+ sort_method='FILE_SORT_ALPHA',
+ apply_modifiers=True,
+ export_mesh_type=0,
+ export_mesh_type_selection='view',
+ selected=True,
+ include_children=True,
+ include_armatures=True,
+ include_shapekeys=False,
+ deform_bones_only=False,
+ include_animations=True,
+ sample_animations=False,
+ sampling_rate=1,
+ active_uv_only=False,
+ use_texture_copies=True,
+ triangulate=False,
+ use_object_instantiation=True,
+ use_blender_profile=True,
+ sort_by_name=False,
+ export_transformation_type=0,
+ export_transformation_type_selection='transrotloc',
+ export_texture_type=0,
+ export_texture_type_selection='mat',
+ open_sim=False,
+ limit_precision=True,
keep_bind_info=False)
-
+
# Now check the resulting Collada file.
if not self.checkdae(reference_dae, outfile):
self.fail()
-
+
if __name__ == '__main__':
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
parser = argparse.ArgumentParser()
parser.add_argument('--testdir', required=True)
args, remaining = parser.parse_known_args()
- unittest.main(argv=sys.argv[0:1]+remaining) \ No newline at end of file
+ unittest.main(argv=sys.argv[0:1]+remaining)
diff --git a/tests/python/collada/mesh/test_mesh_simple.py b/tests/python/collada/mesh/test_mesh_simple.py
index f592160f6aa..213c6177fde 100644
--- a/tests/python/collada/mesh/test_mesh_simple.py
+++ b/tests/python/collada/mesh/test_mesh_simple.py
@@ -113,7 +113,7 @@ class MeshExportTest(AbstractColladaTest):
test = "mesh_simple_001"
reference_dae = self.testdir / Path("%s.dae" % test)
outfile = tempdir / Path("%s_out.dae" % test)
-
+
bpy.ops.wm.collada_export(filepath="%s" % str(outfile),
check_existing=True,
filemode=8,
@@ -141,7 +141,7 @@ class MeshExportTest(AbstractColladaTest):
open_sim=False,
limit_precision=False,
keep_bind_info=False)
-
+
# Now check the resulting Collada file.
if not self.checkdae(reference_dae, outfile):
self.fail()
@@ -151,4 +151,4 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--testdir', required=True)
args, remaining = parser.parse_known_args()
- unittest.main(argv=sys.argv[0:1]+remaining) \ No newline at end of file
+ unittest.main(argv=sys.argv[0:1]+remaining)
diff --git a/tests/python/ffmpeg_tests.py b/tests/python/ffmpeg_tests.py
index 9493d6f7a17..70677677667 100755
--- a/tests/python/ffmpeg_tests.py
+++ b/tests/python/ffmpeg_tests.py
@@ -60,7 +60,7 @@ class AbstractFFmpegSequencerTest(AbstractFFmpegTest):
class FPSDetectionTest(AbstractFFmpegSequencerTest):
def test_T51153(self):
self.assertAlmostEqual(
- self.get_movie_file_fps('T51153_bad_clip_2.mts'),
+ self.get_movie_file_fps('T51153_bad_clip_2.mts'),
29.97,
places=2)
diff --git a/tests/python/modules/test_utils.py b/tests/python/modules/test_utils.py
index 55ef882c49c..c4496c3e3ac 100755
--- a/tests/python/modules/test_utils.py
+++ b/tests/python/modules/test_utils.py
@@ -61,7 +61,7 @@ class AbstractBlenderRunnerTest(unittest.TestCase):
# Set in a subclass
blender: pathlib.Path = None
testdir: pathlib.Path = None
-
+
def run_blender(self, filepath: str, python_script: str, timeout: int=300) -> str:
"""Runs Blender by opening a blendfile and executing a script.
diff --git a/tests/python/rna_array.py b/tests/python/rna_array.py
index f9777a5b438..dda13d2c3ae 100644
--- a/tests/python/rna_array.py
+++ b/tests/python/rna_array.py
@@ -23,7 +23,7 @@ class TestArray(unittest.TestCase):
test.farr= (1.0, 2.0, 3.0)
test.iarr= (7, 8, 9)
test.barr= (False, True, False)
-
+
# test access
# test slice access, negative indices
def test_access(self):
@@ -40,7 +40,7 @@ class TestArray(unittest.TestCase):
def test_access_fail(self):
for arr in (test.farr, test.iarr, test.barr):
self.assertRaises(IndexError, lambda : arr[4])
-
+
# test assignment of a whole array
def test_assign_array(self):
# should accept int as float
@@ -83,7 +83,7 @@ class TestArray(unittest.TestCase):
for i in range(len(arr)):
val= rand_func()
arr[i] = val
-
+
self.assertEqual(arr[i], val)
# float prop should accept also int
@@ -92,7 +92,7 @@ class TestArray(unittest.TestCase):
test.farr[i] = val
self.assertEqual(test.farr[i], float(val))
- #
+ #
def test_assign_item_fail(self):
def assign_bad_index(arr):
@@ -100,12 +100,12 @@ class TestArray(unittest.TestCase):
def assign_bad_type(arr):
arr[1] = "123"
-
+
for arr in [test.farr, test.iarr, test.barr]:
self.assertRaises(IndexError, assign_bad_index, arr)
# not testing bool because bool allows not only (True|False)
- for arr in [test.farr, test.iarr]:
+ for arr in [test.farr, test.iarr]:
self.assertRaises(TypeError, assign_bad_type, arr)
def test_dynamic_assign_array(self):
@@ -118,7 +118,7 @@ class TestArray(unittest.TestCase):
def test_dynamic_assign_array_fail(self):
# could also test too big length here
-
+
def assign_empty_list(arr):
setattr(test, arr, ())
@@ -236,7 +236,7 @@ def make_random_array(len, rand_func):
arr= []
for i in range(len):
arr.append(rand_func())
-
+
return arr
def make_random_2d_array(dimsize, rand_func):
diff --git a/tests/python/view_layer/CMakeLists.txt b/tests/python/view_layer/CMakeLists.txt
index 69f7af20ad2..cec839a3efc 100644
--- a/tests/python/view_layer/CMakeLists.txt
+++ b/tests/python/view_layer/CMakeLists.txt
@@ -18,7 +18,7 @@
#
# ***** END GPL LICENSE BLOCK *****
-# --env-system-scripts allows to run without the install target.
+# --env-system-scripts allows to run without the install target.
# Use '--write-blend=/tmp/test.blend' to view output
@@ -43,7 +43,7 @@ else()
set(TEST_BLENDER_EXE ${EXECUTABLE_OUTPUT_PATH}/blender)
endif()
-# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
+# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
set(TEST_BLENDER_EXE ${TEST_BLENDER_EXE} --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)